svn commit: r194560 - head/bin/sh

Jilles Tjoelker jilles at FreeBSD.org
Sat Jun 20 20:44:28 UTC 2009


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)


More information about the svn-src-all mailing list