From: Jilles Tjoelker <jilles@stack.nl>
To: dash@vger.kernel.org
Subject: [PATCH] [REDIR] Replace GPL noclobberopen code with the FreeBSD version.
Date: Sat, 20 Nov 2010 15:47:33 +0100 [thread overview]
Message-ID: <20101120144733.GA17293@stack.nl> (raw)
Replace noclobberopen() from bash with the FreeBSD code for noclobber
opens.
This also reduces code size by eliminating an unnecessary check.
---
src/redir.c | 77 +++++++++++-----------------------------------------------
1 files changed, 15 insertions(+), 62 deletions(-)
diff --git a/src/redir.c b/src/redir.c
index b4e49c0..f96a76b 100644
--- a/src/redir.c
+++ b/src/redir.c
@@ -84,7 +84,6 @@ STATIC void dupredirect(union node *, int, char[10]);
STATIC void dupredirect(union node *, int);
#endif
STATIC int openhere(union node *);
-STATIC int noclobberopen(const char *);
/*
@@ -168,6 +167,7 @@ redirect(union node *redir, int flags)
STATIC int
openredirect(union node *redir)
{
+ struct stat64 sb;
char *fname;
int f;
@@ -186,8 +186,21 @@ openredirect(union node *redir)
/* Take care of noclobber mode. */
if (Cflag) {
fname = redir->nfile.expfname;
- if ((f = noclobberopen(fname)) < 0)
+ if (stat64(fname, &sb) < 0) {
+ if ((f = open64(fname, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0)
+ goto ecreate;
+ } else if (!S_ISREG(sb.st_mode)) {
+ if ((f = open64(fname, O_WRONLY, 0666)) < 0)
+ goto ecreate;
+ if (fstat64(f, &sb) < 0 && S_ISREG(sb.st_mode)) {
+ close(f);
+ errno = EEXIST;
+ goto ecreate;
+ }
+ } else {
+ errno = EEXIST;
goto ecreate;
+ }
break;
}
/* FALLTHROUGH */
@@ -397,66 +410,6 @@ savefd(int from, int ofd)
}
-/*
- * Open a file in noclobber mode.
- * The code was copied from bash.
- */
-int
-noclobberopen(fname)
- const char *fname;
-{
- int r, fd;
- struct stat64 finfo, finfo2;
-
- /*
- * If the file exists and is a regular file, return an error
- * immediately.
- */
- r = stat64(fname, &finfo);
- if (r == 0 && S_ISREG(finfo.st_mode)) {
- errno = EEXIST;
- return -1;
- }
-
- /*
- * If the file was not present (r != 0), make sure we open it
- * exclusively so that if it is created before we open it, our open
- * will fail. Make sure that we do not truncate an existing file.
- * Note that we don't turn on O_EXCL unless the stat failed -- if the
- * file was not a regular file, we leave O_EXCL off.
- */
- if (r != 0)
- return open64(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
- fd = open64(fname, O_WRONLY|O_CREAT, 0666);
-
- /* If the open failed, return the file descriptor right away. */
- if (fd < 0)
- return fd;
-
- /*
- * OK, the open succeeded, but the file may have been changed from a
- * non-regular file to a regular file between the stat and the open.
- * We are assuming that the O_EXCL open handles the case where FILENAME
- * did not exist and is symlinked to an existing file between the stat
- * and open.
- */
-
- /*
- * If we can open it and fstat the file descriptor, and neither check
- * revealed that it was a regular file, and the file has not been
- * replaced, return the file descriptor.
- */
- if (fstat64(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) &&
- finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
- return fd;
-
- /* The file has been replaced. badness. */
- close(fd);
- errno = EEXIST;
- return -1;
-}
-
next reply other threads:[~2010-11-20 14:47 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-20 14:47 Jilles Tjoelker [this message]
2011-03-10 8:53 ` [PATCH] [REDIR] Replace GPL noclobberopen code with the FreeBSD version Herbert Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101120144733.GA17293@stack.nl \
--to=jilles@stack.nl \
--cc=dash@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.