Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Jun 2009 20:44:28 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r194560 - head/bin/sh
Message-ID:  <200906202044.n5KKiSY4086461@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906202044.n5KKiSY4086461>