Hi! This patch allows the command line option '-x', which enables create-if-exist. On file opening, if the file already exists, touch will exit with errorcode 1 without changing the state of the target file. If the file doesn't exist, it is created and the return code of touch is 0. This is an atomic operation allowing touch to do TAS (test-and-set). This allows creation of critical regions in bash scripts. if touch -x .lock; then # critical region begin # critical region end rm -f .lock fi Best regards, Andreas
--- src/touch.c.bak Sat Mar 17 10:27:41 2001 +++ src/touch.c Fri Sep 7 13:50:13 2001 @@ -75,6 +75,9 @@ /* (-t) If nonzero, date supplied on command line in POSIX format. */ static int posix_date; +/* (-x) If nonzero, files are only created if they do not already exist. */ +static int create_if_noexist; + /* If nonzero, the only thing we have to do is change both the modification and access time to the current time, so we don't have to own the file, just be able to read and write it. @@ -105,6 +108,7 @@ {"date", required_argument, 0, 'd'}, {"file", required_argument, 0, 'r'}, /* FIXME: phase out --file */ {"reference", required_argument, 0, 'r'}, + {"create-if-noexist", no_argument, 0, 'x'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {0, 0, 0, 0} @@ -136,8 +140,16 @@ if (! no_create) { /* Try to open FILE, creating it if necessary. */ - fd = open (file, O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + if (create_if_noexist) { + fd = open (file, O_EXCL | O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + + if (fd == -1) + return fd; + } else + fd = open (file, O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + if (fd == -1) open_errno = errno; } @@ -198,9 +210,12 @@ if (status) { - if (open_errno) - error (0, open_errno, _("creating %s"), quote (file)); - else + if (open_errno) { + if (create_if_noexist) + error (0, open_errno, _("creating %s (exists)"), quote (file)); + else + error (0, open_errno, _("creating %s"), quote (file)); + } else error (0, errno, _("setting times of %s"), quote (file)); return 1; } @@ -233,6 +248,7 @@ modify mtime (same as -m)\n\ --help display this help and exit\n\ --version output version information and exit\n\ + -x, --create-if-noexist only create the file if it didn't exist already\n\ \n\ Note that the three time-date formats recognized for the -d and -t options\n\ and for the obsolescent argument are all different.\n\ @@ -257,9 +273,10 @@ atexit (close_stdout); change_times = no_create = use_ref = posix_date = flexible_date = 0; + create_if_noexist = 0; newtime = (time_t) -1; - while ((c = getopt_long (argc, argv, "acd:fmr:t:", longopts, NULL)) != -1) + while ((c = getopt_long (argc, argv, "acd:fmr:t:x", longopts, NULL)) != -1) { switch (c) { @@ -311,6 +328,10 @@ case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); + + case 'x': + create_if_noexist++; + break; default: usage (1);