Author: jilles
Date: Sat Jun 20 20:44:27 2009
New Revision: 194560
URL: http://svn.freebsd.org/changeset/base/194560

Log:
  Fix race condition in noclobber option.
  
  Formerly, it was possible for the file to be created between the check if it
  existed and the open; the contents would then be lost.
  
  Because this must use O_EXCL, noclobber > will not create a file through a
  symlink anymore. This agrees with behaviour of other shells.
  
  Approved by:  ed (mentor) (implicit)

Modified:
  head/bin/sh/redir.c

Modified: head/bin/sh/redir.c
==============================================================================
--- head/bin/sh/redir.c Sat Jun 20 20:36:51 2009        (r194559)
+++ head/bin/sh/redir.c Sat Jun 20 20:44:27 2009        (r194560)
@@ -188,13 +188,25 @@ movefd:
                        error("cannot create %s: %s", fname, strerror(errno));
                goto movefd;
        case NTO:
-               fname = redir->nfile.expfname;
-               if (Cflag && stat(fname, &sb) != -1 && S_ISREG(sb.st_mode))
-                       error("cannot create %s: %s", fname,
-                           strerror(EEXIST));
-               if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
-                       error("cannot create %s: %s", fname, strerror(errno));
-               goto movefd;
+               if (Cflag) {
+                       fname = redir->nfile.expfname;
+                       if (stat(fname, &sb) == -1) {
+                               if ((f = open(fname, O_WRONLY|O_CREAT|O_EXCL, 
0666)) < 0)
+                                       error("cannot create %s: %s", fname, 
strerror(errno));
+                       } else if (!S_ISREG(sb.st_mode)) {
+                               if ((f = open(fname, O_WRONLY, 0666)) < 0)
+                                       error("cannot create %s: %s", fname, 
strerror(errno));
+                               if (fstat(f, &sb) != -1 && S_ISREG(sb.st_mode)) 
{
+                                       close(f);
+                                       error("cannot create %s: %s", fname,
+                                           strerror(EEXIST));
+                               }
+                       } else
+                               error("cannot create %s: %s", fname,
+                                   strerror(EEXIST));
+                       goto movefd;
+               }
+               /* FALLTHROUGH */
        case NCLOBBER:
                fname = redir->nfile.expfname;
                if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to