The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/tests/zfs-tests/cmd/ctime.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * CDDL HEADER START
    3  *
    4  * The contents of this file are subject to the terms of the
    5  * Common Development and Distribution License (the "License").
    6  * You may not use this file except in compliance with the License.
    7  *
    8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    9  * or https://opensource.org/licenses/CDDL-1.0.
   10  * See the License for the specific language governing permissions
   11  * and limitations under the License.
   12  *
   13  * When distributing Covered Code, include this CDDL HEADER in each
   14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   15  * If applicable, add the following below this CDDL HEADER, with the
   16  * fields enclosed by brackets "[]" replaced with your own identifying
   17  * information: Portions Copyright [yyyy] [name of copyright owner]
   18  *
   19  * CDDL HEADER END
   20  */
   21 
   22 /*
   23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   24  * Use is subject to license terms.
   25  */
   26 
   27 /*
   28  * Copyright (c) 2013 by Delphix. All rights reserved.
   29  */
   30 
   31 
   32 #include <sys/types.h>
   33 #include <sys/stat.h>
   34 #ifndef __FreeBSD__
   35 #include <sys/xattr.h>
   36 #endif
   37 #include <utime.h>
   38 #include <stdio.h>
   39 #include <stdlib.h>
   40 #include <unistd.h>
   41 #include <errno.h>
   42 #include <fcntl.h>
   43 #include <libgen.h>
   44 #include <string.h>
   45 
   46 #define ST_ATIME 0
   47 #define ST_CTIME 1
   48 #define ST_MTIME 2
   49 
   50 #define ALL_MODE (mode_t)(S_IRWXU|S_IRWXG|S_IRWXO)
   51 
   52 typedef struct timetest {
   53         int     type;
   54         const char      *name;
   55         int     (*func)(const char *pfile);
   56 } timetest_t;
   57 
   58 static char tfile[BUFSIZ] = { 0 };
   59 
   60 /*
   61  * DESCRIPTION:
   62  *      Verify time will be changed correctly after each operation.
   63  *
   64  * STRATEGY:
   65  *      1. Define time test array.
   66  *      2. Loop through each item in this array.
   67  *      3. Verify the time is changed after each operation.
   68  *
   69  */
   70 
   71 static int
   72 get_file_time(const char *pfile, int what, time_t *ptr)
   73 {
   74         struct stat stat_buf;
   75 
   76         if (pfile == NULL || ptr == NULL) {
   77                 return (-1);
   78         }
   79 
   80         if (stat(pfile, &stat_buf) == -1) {
   81                 return (-1);
   82         }
   83 
   84         switch (what) {
   85                 case ST_ATIME:
   86                         *ptr = stat_buf.st_atime;
   87                         return (0);
   88                 case ST_CTIME:
   89                         *ptr = stat_buf.st_ctime;
   90                         return (0);
   91                 case ST_MTIME:
   92                         *ptr = stat_buf.st_mtime;
   93                         return (0);
   94                 default:
   95                         return (-1);
   96         }
   97 }
   98 
   99 static ssize_t
  100 get_dirnamelen(const char *path)
  101 {
  102         const char *end = strrchr(path, '/');
  103         return (end ? end - path : -1);
  104 }
  105 
  106 static int
  107 do_read(const char *pfile)
  108 {
  109         int fd, ret = 0;
  110         char buf[BUFSIZ] = { 0 };
  111 
  112         if (pfile == NULL) {
  113                 return (-1);
  114         }
  115 
  116         if ((fd = open(pfile, O_RDONLY, ALL_MODE)) == -1) {
  117                 return (-1);
  118         }
  119         if (read(fd, buf, sizeof (buf)) == -1) {
  120                 (void) fprintf(stderr, "read(%d, buf, %zd) failed with errno "
  121                     "%d\n", fd, sizeof (buf), errno);
  122                 (void) close(fd);
  123                 return (1);
  124         }
  125         (void) close(fd);
  126 
  127         return (ret);
  128 }
  129 
  130 static int
  131 do_write(const char *pfile)
  132 {
  133         int fd, ret = 0;
  134         char buf[BUFSIZ] = "call function do_write()";
  135 
  136         if (pfile == NULL) {
  137                 return (-1);
  138         }
  139 
  140         if ((fd = open(pfile, O_WRONLY, ALL_MODE)) == -1) {
  141                 return (-1);
  142         }
  143         if (write(fd, buf, strlen(buf)) == -1) {
  144                 (void) fprintf(stderr, "write(%d, buf, %d) failed with errno "
  145                     "%d\n", fd, (int)strlen(buf), errno);
  146                 (void) close(fd);
  147                 return (1);
  148         }
  149         (void) close(fd);
  150 
  151         return (ret);
  152 }
  153 
  154 static int
  155 do_link(const char *pfile)
  156 {
  157         int ret = 0;
  158         char link_file[BUFSIZ + 16] = { 0 };
  159 
  160         if (pfile == NULL) {
  161                 return (-1);
  162         }
  163 
  164         /*
  165          * Figure out source file directory name, and create
  166          * the link file in the same directory.
  167          */
  168         (void) snprintf(link_file, sizeof (link_file),
  169             "%.*s/%s", (int)get_dirnamelen(pfile), pfile, "link_file");
  170 
  171         if (link(pfile, link_file) == -1) {
  172                 (void) fprintf(stderr, "link(%s, %s) failed with errno %d\n",
  173                     pfile, link_file, errno);
  174                 return (1);
  175         }
  176 
  177         (void) unlink(link_file);
  178 
  179         return (ret);
  180 }
  181 
  182 static int
  183 do_creat(const char *pfile)
  184 {
  185         int fd, ret = 0;
  186 
  187         if (pfile == NULL) {
  188                 return (-1);
  189         }
  190 
  191         if ((fd = creat(pfile, ALL_MODE)) == -1) {
  192                 (void) fprintf(stderr, "creat(%s, ALL_MODE) failed with errno "
  193                     "%d\n", pfile, errno);
  194                 return (1);
  195         }
  196         (void) close(fd);
  197 
  198         return (ret);
  199 }
  200 
  201 static int
  202 do_utime(const char *pfile)
  203 {
  204         int ret = 0;
  205 
  206         if (pfile == NULL) {
  207                 return (-1);
  208         }
  209 
  210         /*
  211          * Times of the file are set to the current time
  212          */
  213         if (utime(pfile, NULL) == -1) {
  214                 (void) fprintf(stderr, "utime(%s, NULL) failed with errno "
  215                     "%d\n", pfile, errno);
  216                 return (1);
  217         }
  218 
  219         return (ret);
  220 }
  221 
  222 static int
  223 do_chmod(const char *pfile)
  224 {
  225         int ret = 0;
  226 
  227         if (pfile == NULL) {
  228                 return (-1);
  229         }
  230 
  231         if (chmod(pfile, ALL_MODE) == -1) {
  232                 (void) fprintf(stderr, "chmod(%s, ALL_MODE) failed with "
  233                     "errno %d\n", pfile, errno);
  234                 return (1);
  235         }
  236 
  237         return (ret);
  238 }
  239 
  240 static int
  241 do_chown(const char *pfile)
  242 {
  243         int ret = 0;
  244 
  245         if (pfile == NULL) {
  246                 return (-1);
  247         }
  248 
  249         if (chown(pfile, getuid(), getgid()) == -1) {
  250                 (void) fprintf(stderr, "chown(%s, %d, %d) failed with errno "
  251                     "%d\n", pfile, (int)getuid(), (int)getgid(), errno);
  252                 return (1);
  253         }
  254 
  255         return (ret);
  256 }
  257 
  258 #ifndef __FreeBSD__
  259 static int
  260 do_xattr(const char *pfile)
  261 {
  262         int ret = 0;
  263         const char *value = "user.value";
  264 
  265         if (pfile == NULL) {
  266                 return (-1);
  267         }
  268 
  269         if (setxattr(pfile, "user.x", value, strlen(value), 0) == -1) {
  270                 (void) fprintf(stderr, "setxattr(%s, %d, %d) failed with errno "
  271                     "%d\n", pfile, (int)getuid(), (int)getgid(), errno);
  272                 return (1);
  273         }
  274         return (ret);
  275 }
  276 #endif
  277 
  278 static void
  279 cleanup(void)
  280 {
  281         if ((strlen(tfile) != 0) && (access(tfile, F_OK) == 0)) {
  282                 (void) unlink(tfile);
  283         }
  284 }
  285 
  286 static timetest_t timetest_table[] = {
  287         { ST_ATIME,     "st_atime",     do_read         },
  288         { ST_ATIME,     "st_atime",     do_utime        },
  289         { ST_MTIME,     "st_mtime",     do_creat        },
  290         { ST_MTIME,     "st_mtime",     do_write        },
  291         { ST_MTIME,     "st_mtime",     do_utime        },
  292         { ST_CTIME,     "st_ctime",     do_creat        },
  293         { ST_CTIME,     "st_ctime",     do_write        },
  294         { ST_CTIME,     "st_ctime",     do_chmod        },
  295         { ST_CTIME,     "st_ctime",     do_chown        },
  296         { ST_CTIME,     "st_ctime",     do_link         },
  297         { ST_CTIME,     "st_ctime",     do_utime        },
  298 #ifndef __FreeBSD__
  299         { ST_CTIME,     "st_ctime",     do_xattr        },
  300 #endif
  301 };
  302 
  303 #define NCOMMAND (sizeof (timetest_table) / sizeof (timetest_table[0]))
  304 
  305 int
  306 main(void)
  307 {
  308         int i, ret, fd;
  309         const char *penv[] = {"TESTDIR", "TESTFILE0"};
  310 
  311         (void) atexit(cleanup);
  312 
  313         /*
  314          * Get the environment variable values.
  315          */
  316         for (i = 0; i < sizeof (penv) / sizeof (char *); i++) {
  317                 if ((penv[i] = getenv(penv[i])) == NULL) {
  318                         (void) fprintf(stderr, "getenv(penv[%d])\n", i);
  319                         return (1);
  320                 }
  321         }
  322         (void) snprintf(tfile, sizeof (tfile), "%s/%s", penv[0], penv[1]);
  323 
  324         /*
  325          * If the test file exists, remove it first.
  326          */
  327         if (access(tfile, F_OK) == 0) {
  328                 (void) unlink(tfile);
  329         }
  330         if ((fd = open(tfile, O_WRONLY | O_CREAT | O_TRUNC, ALL_MODE)) == -1) {
  331                 (void) fprintf(stderr, "open(%s) failed: %d\n", tfile, errno);
  332                 return (1);
  333         }
  334         (void) close(fd);
  335 
  336         for (i = 0; i < NCOMMAND; i++) {
  337                 time_t t1, t2;
  338 
  339                 /*
  340                  * Get original time before operating.
  341                  */
  342                 ret = get_file_time(tfile, timetest_table[i].type, &t1);
  343                 if (ret != 0) {
  344                         (void) fprintf(stderr, "get_file_time(%s %d) = %d\n",
  345                             tfile, timetest_table[i].type, ret);
  346                         return (1);
  347                 }
  348 
  349                 /*
  350                  * Sleep 2 seconds, then invoke command on given file
  351                  */
  352                 (void) sleep(2);
  353                 timetest_table[i].func(tfile);
  354 
  355                 /*
  356                  * Get time after operating.
  357                  */
  358                 ret = get_file_time(tfile, timetest_table[i].type, &t2);
  359                 if (ret != 0) {
  360                         (void) fprintf(stderr, "get_file_time(%s %d) = %d\n",
  361                             tfile, timetest_table[i].type, ret);
  362                         return (1);
  363                 }
  364 
  365                 if (t1 == t2) {
  366                         (void) fprintf(stderr, "%s: t1(%ld) == t2(%ld)\n",
  367                             timetest_table[i].name, (long)t1, (long)t2);
  368                         return (1);
  369                 } else {
  370                         (void) fprintf(stderr, "%s: t1(%ld) != t2(%ld)\n",
  371                             timetest_table[i].name, (long)t1, (long)t2);
  372                 }
  373         }
  374 
  375         return (0);
  376 }

Cache object: a6e657e89e2176f293a47f81a135ef08


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.