From 1a958c66539ebf0e7f6083ba71b466b11dc6499f Mon Sep 17 00:00:00 2001 From: "Tim J. Robbins" Date: Sun, 19 May 2002 06:03:05 +0000 Subject: [PATCH] Implement the -C (-o noclobber) option, which prevents existing regular files from being overwritten by shell redirection. --- bin/sh/error.c | 1 + bin/sh/eval.c | 1 + bin/sh/jobs.c | 2 ++ bin/sh/nodetypes | 1 + bin/sh/parser.c | 2 ++ bin/sh/redir.c | 11 +++++++++++ bin/sh/sh.1 | 1 - bin/sh/show.c | 1 + 8 files changed, 19 insertions(+), 1 deletion(-) diff --git a/bin/sh/error.c b/bin/sh/error.c index 0cf20b39743e..96e653459776 100644 --- a/bin/sh/error.c +++ b/bin/sh/error.c @@ -247,6 +247,7 @@ STATIC const struct errname errormsg[] = { #ifdef ELIBACC { ELIBACC, E_EXEC, "shared library missing" }, #endif + { EEXIST, E_CREAT, "file exists" }, { 0, 0, NULL }, }; diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 9f65d90fd073..0c3f85bf480e 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -448,6 +448,7 @@ expredir(union node *n) case NTO: case NFROMTO: case NAPPEND: + case NCLOBBER: expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); redir->nfile.expfname = fn.list->text; break; diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c index 14f190973a1f..b1cc2de5768b 100644 --- a/bin/sh/jobs.c +++ b/bin/sh/jobs.c @@ -1057,6 +1057,8 @@ cmdtxt(union node *n) p = ">>"; i = 1; goto redir; case NTOFD: p = ">&"; i = 1; goto redir; + case NCLOBBER: + p = ">|"; i = 1; goto redir; case NFROM: p = "<"; i = 0; goto redir; case NFROMTO: diff --git a/bin/sh/nodetypes b/bin/sh/nodetypes index 53dd18f40845..27fbcd171a04 100644 --- a/bin/sh/nodetypes +++ b/bin/sh/nodetypes @@ -120,6 +120,7 @@ NTO nfile # fd> fname NFROM nfile # fd< fname NFROMTO nfile # fd<> fname NAPPEND nfile # fd>> fname +NCLOBBER nfile # fd>| fname type int next nodeptr # next redirection in list fd int # file descriptor being redirected diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 08cd7378f25c..6e0f23bedb50 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -1145,6 +1145,8 @@ parseredir: { np->type = NAPPEND; else if (c == '&') np->type = NTOFD; + else if (c == '|') + np->type = NCLOBBER; else { np->type = NTO; pungetc(); diff --git a/bin/sh/redir.c b/bin/sh/redir.c index b5964630ff76..60a61517f3e3 100644 --- a/bin/sh/redir.c +++ b/bin/sh/redir.c @@ -43,6 +43,7 @@ static const char rcsid[] = #endif /* not lint */ #include +#include #include #include #include @@ -62,6 +63,7 @@ static const char rcsid[] = #include "output.h" #include "memalloc.h" #include "error.h" +#include "options.h" #define EMPTY -2 /* marks an unused slot in redirtab */ @@ -161,6 +163,7 @@ redirect(union node *redir, int flags) STATIC void openredirect(union node *redir, char memory[10]) { + struct stat sb; int fd = redir->nfile.fd; char *fname; int f; @@ -207,6 +210,9 @@ openredirect(union node *redir, char memory[10]) 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, + errmsg(EEXIST, E_CREAT)); #ifdef O_CREAT if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); @@ -215,6 +221,11 @@ openredirect(union node *redir, char memory[10]) error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); #endif goto movefd; + case NCLOBBER: + fname = redir->nfile.expfname; + if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) + error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); + goto movefd; case NAPPEND: fname = redir->nfile.expfname; #ifdef O_APPEND diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index 9c8cc34a69a3..e9f5f080956c 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -195,7 +195,6 @@ completion. .It Fl C Li noclobber Do not overwrite existing files with .Dq Li > . -(UNIMPLEMENTED) .It Fl E Li emacs Enable the builtin .Xr emacs 1 diff --git a/bin/sh/show.c b/bin/sh/show.c index 3880d38fa5e7..0e9a181609b7 100644 --- a/bin/sh/show.c +++ b/bin/sh/show.c @@ -142,6 +142,7 @@ shcmd(union node *cmd, FILE *fp) case NTO: s = ">"; dftfd = 1; break; case NAPPEND: s = ">>"; dftfd = 1; break; case NTOFD: s = ">&"; dftfd = 1; break; + case NCLOBBER: s = ">|"; dftfd = 1; break; case NFROM: s = "<"; dftfd = 0; break; case NFROMTO: s = "<>"; dftfd = 0; break; case NFROMFD: s = "<&"; dftfd = 0; break;