"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/stress-access.c" (15 Mar 2019, 5247 Bytes) of package /linux/privat/stress-ng-0.09.56.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "stress-access.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.49_vs_0.09.50.

    1 /*
    2  * Copyright (C) 2013-2019 Canonical, Ltd.
    3  *
    4  * This program is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public License
    6  * as published by the Free Software Foundation; either version 2
    7  * of the License, or (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   17  *
   18  * This code is a complete clean re-write of the stress tool by
   19  * Colin Ian King <colin.king@canonical.com> and attempts to be
   20  * backwardly compatible with the stress tool by Amos Waterland
   21  * <apw@rossby.metr.ou.edu> but has more stress tests and more
   22  * functionality.
   23  *
   24  */
   25 #include "stress-ng.h"
   26 
   27 typedef struct {
   28     const mode_t    chmod_mode;
   29     const int   access_mode;
   30 } access_t;
   31 
   32 static const access_t modes[] = {
   33 #if defined(S_IRUSR) && defined(R_OK)
   34     { S_IRUSR, R_OK },
   35 #endif
   36 #if defined(S_IWUSR) && defined(W_OK)
   37     { S_IWUSR, W_OK },
   38 #endif
   39 #if defined(S_IXUSR) && defined(X_OK)
   40     { S_IXUSR, X_OK },
   41 #endif
   42 
   43 #if defined(S_IRUSR) && defined(F_OK)
   44     { S_IRUSR, F_OK },
   45 #endif
   46 #if defined(S_IWUSR) && defined(F_OK)
   47     { S_IWUSR, F_OK },
   48 #endif
   49 #if defined(S_IXUSR) && defined(F_OK)
   50     { S_IXUSR, F_OK },
   51 #endif
   52 
   53 #if defined(S_IRUSR) && defined(R_OK) && \
   54     defined(S_IWUSR) && defined(W_OK)
   55     { S_IRUSR | S_IWUSR, R_OK | W_OK },
   56 #endif
   57 #if defined(S_IRUSR) && defined(R_OK) && \
   58     defined(S_IXUSR) && defined(X_OK)
   59     { S_IRUSR | S_IXUSR, R_OK | X_OK },
   60 #endif
   61 #if defined(S_IWUSR) && defined(W_OK) && \
   62     defined(S_IXUSR) && defined(X_OK)
   63     { S_IRUSR | S_IWUSR, R_OK | W_OK },
   64 #endif
   65 
   66 #if defined(S_IRUSR) && defined(F_OK) && \
   67     defined(S_IWUSR)
   68     { S_IRUSR | S_IWUSR, F_OK },
   69 #endif
   70 #if defined(S_IRUSR) && defined(F_OK) && \
   71     defined(S_IXUSR)
   72     { S_IRUSR | S_IXUSR, F_OK },
   73 #endif
   74 #if defined(S_IWUSR) && defined(F_OK) && \
   75     defined(S_IXUSR)
   76     { S_IRUSR | S_IWUSR, F_OK },
   77 #endif
   78 };
   79 
   80 /*
   81  *  BSD systems can return EFTYPE which we can ignore
   82  *  as a "known" error on invalid chmod mode bits
   83  */
   84 #if defined(EFTYPE)
   85 #define CHMOD_ERR(x) ((x) && (errno != EFTYPE))
   86 #else
   87 #define CHMOD_ERR(x) (x)
   88 #endif
   89 
   90 /*
   91  *  stress_access
   92  *  stress access family of system calls
   93  */
   94 static int stress_access(const args_t *args)
   95 {
   96     int fd = -1, ret, rc = EXIT_FAILURE;
   97     char filename[PATH_MAX];
   98     const mode_t all_mask = 0700;
   99     size_t i;
  100     const bool is_root = (geteuid() == 0);
  101 
  102     ret = stress_temp_dir_mk_args(args);
  103     if (ret < 0)
  104         return exit_status(-ret);
  105 
  106     (void)stress_temp_filename_args(args,
  107         filename, sizeof(filename), mwc32());
  108 
  109     (void)umask(0700);
  110     if ((fd = creat(filename, S_IRUSR | S_IWUSR)) < 0) {
  111         rc = exit_status(errno);
  112         pr_fail_err("creat");
  113         goto tidy;
  114     }
  115 
  116     do {
  117         for (i = 0; i < SIZEOF_ARRAY(modes); i++) {
  118             ret = fchmod(fd, modes[i].chmod_mode);
  119             if (CHMOD_ERR(ret)) {
  120                 pr_err("%s: fchmod %3.3o failed: %d (%s)\n",
  121                     args->name, (unsigned int)modes[i].chmod_mode,
  122                     errno, strerror(errno));
  123                 goto tidy;
  124             }
  125             ret = access(filename, modes[i].access_mode);
  126             if (ret < 0) {
  127                 pr_fail("%s: access %3.3o on chmod mode %3.3o failed: %d (%s)\n",
  128                     args->name,
  129                     modes[i].access_mode, (unsigned int)modes[i].chmod_mode,
  130                     errno, strerror(errno));
  131             }
  132 #if defined(HAVE_FACCESSAT)
  133             ret = faccessat(AT_FDCWD, filename, modes[i].access_mode, 0);
  134             if (ret < 0) {
  135                 pr_fail("%s: faccessat %3.3o on chmod mode %3.3o failed: %d (%s)\n",
  136                     args->name,
  137                     modes[i].access_mode, (unsigned int)modes[i].chmod_mode,
  138                     errno, strerror(errno));
  139             }
  140 #endif
  141             if (modes[i].access_mode != 0) {
  142                 const mode_t chmod_mode = modes[i].chmod_mode ^ all_mask;
  143                 const bool s_ixusr = chmod_mode & S_IXUSR;
  144                 const bool dont_ignore = !(is_root && s_ixusr);
  145 
  146                 ret = fchmod(fd, chmod_mode);
  147                 if (CHMOD_ERR(ret)) {
  148                     pr_err("%s: fchmod %3.3o failed: %d (%s)\n",
  149                         args->name, (unsigned int)chmod_mode,
  150                         errno, strerror(errno));
  151                     goto tidy;
  152                 }
  153                 ret = access(filename, modes[i].access_mode);
  154                 if ((ret == 0) && dont_ignore) {
  155                     pr_fail("%s: access %3.3o on chmod mode %3.3o was ok (not expected): %d (%s)\n",
  156                         args->name,
  157                         modes[i].access_mode, (unsigned int)chmod_mode,
  158                         errno, strerror(errno));
  159                 }
  160 #if defined(HAVE_FACCESSAT)
  161                 ret = faccessat(AT_FDCWD, filename, modes[i].access_mode, AT_SYMLINK_NOFOLLOW);
  162                 if ((ret == 0) && dont_ignore) {
  163                     pr_fail("%s: faccessat %3.3o on chmod mode %3.3o was ok (not expected): %d (%s)\n",
  164                         args->name,
  165                         modes[i].access_mode, (unsigned int)chmod_mode,
  166                         errno, strerror(errno));
  167                 }
  168 #endif
  169             }
  170         }
  171         inc_counter(args);
  172     } while (keep_stressing());
  173 
  174     rc = EXIT_SUCCESS;
  175 tidy:
  176     if (fd >= 0) {
  177         (void)fchmod(fd, 0666);
  178         (void)close(fd);
  179     }
  180     (void)unlink(filename);
  181     (void)stress_temp_dir_rm_args(args);
  182 
  183     return rc;
  184 }
  185 
  186 stressor_info_t stress_access_info = {
  187     .stressor = stress_access,
  188     .class = CLASS_FILESYSTEM | CLASS_OS
  189 };