Implement the -C (-o noclobber) option, which prevents existing regular

files from being overwritten by shell redirection.
This commit is contained in:
Tim J. Robbins 2002-05-19 06:03:05 +00:00
parent ce1c850d62
commit 1a958c6653
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=96922
8 changed files with 19 additions and 1 deletions

View File

@ -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 },
};

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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();

View File

@ -43,6 +43,7 @@ static const char rcsid[] =
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
@ -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

View File

@ -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

View File

@ -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;