summaryrefslogtreecommitdiffstats
path: root/bin/sh/redir.c
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2009-06-20 20:44:27 +0000
committerjilles <jilles@FreeBSD.org>2009-06-20 20:44:27 +0000
commite3cb9d1015e8283f4f9d116cf50f510741f8c0dd (patch)
tree2ece574b3d59a8e84626752587e1eb579a3c0428 /bin/sh/redir.c
parent5125e5db2794d27b9f32c23a7439b1c456b334f5 (diff)
downloadFreeBSD-src-e3cb9d1015e8283f4f9d116cf50f510741f8c0dd.zip
FreeBSD-src-e3cb9d1015e8283f4f9d116cf50f510741f8c0dd.tar.gz
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)
Diffstat (limited to 'bin/sh/redir.c')
-rw-r--r--bin/sh/redir.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/bin/sh/redir.c b/bin/sh/redir.c
index bc18975..695e150 100644
--- a/bin/sh/redir.c
+++ b/bin/sh/redir.c
@@ -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)
OpenPOWER on IntegriCloud