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);

Reply via email to