aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-07-25 17:47:48 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-07-25 17:47:48 +0200
commitf1a5cb0548f647e628032ea8645c0d0d2d07b02f (patch)
tree6063135a5059b3f137322726699e33e91c6ba095
parent2990aa45d188b1d9814c89dd44658f068eb37e83 (diff)
downloadbusybox-w32-f1a5cb0548f647e628032ea8645c0d0d2d07b02f.tar.gz
busybox-w32-f1a5cb0548f647e628032ea8645c0d0d2d07b02f.tar.bz2
busybox-w32-f1a5cb0548f647e628032ea8645c0d0d2d07b02f.zip
ash: [REDIR] Replace GPL noclobberopen code with the FreeBSD version
Upstream commit: Date: Thu, 10 Mar 2011 16:52:13 +0800 [REDIR] Replace GPL noclobberopen code with the FreeBSD version Replace noclobberopen() from bash with the FreeBSD code for noclobber opens. This also reduces code size by eliminating an unnecessary check. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> function old new delta changepath 192 194 +2 localcmd 366 364 -2 expmeta 521 517 -4 redirect 1210 1135 -75 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/3 up/down: 2/-81) Total: -79 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c81
1 files changed, 17 insertions, 64 deletions
diff --git a/shell/ash.c b/shell/ash.c
index c353834a4..b4b0d5253 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -5175,68 +5175,6 @@ stoppedjobs(void)
5175#define CLOSED -3 /* marks a slot of previously-closed fd */ 5175#define CLOSED -3 /* marks a slot of previously-closed fd */
5176 5176
5177/* 5177/*
5178 * Open a file in noclobber mode.
5179 * The code was copied from bash.
5180 */
5181static int
5182noclobberopen(const char *fname)
5183{
5184 int r, fd;
5185 struct stat finfo, finfo2;
5186
5187 /*
5188 * If the file exists and is a regular file, return an error
5189 * immediately.
5190 */
5191 r = stat(fname, &finfo);
5192 if (r == 0 && S_ISREG(finfo.st_mode)) {
5193 errno = EEXIST;
5194 return -1;
5195 }
5196
5197 /*
5198 * If the file was not present (r != 0), make sure we open it
5199 * exclusively so that if it is created before we open it, our open
5200 * will fail. Make sure that we do not truncate an existing file.
5201 * Note that we don't turn on O_EXCL unless the stat failed -- if the
5202 * file was not a regular file, we leave O_EXCL off.
5203 */
5204 if (r != 0)
5205 return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
5206 fd = open(fname, O_WRONLY|O_CREAT, 0666);
5207
5208 /* If the open failed, return the file descriptor right away. */
5209 if (fd < 0)
5210 return fd;
5211
5212 /*
5213 * OK, the open succeeded, but the file may have been changed from a
5214 * non-regular file to a regular file between the stat and the open.
5215 * We are assuming that the O_EXCL open handles the case where FILENAME
5216 * did not exist and is symlinked to an existing file between the stat
5217 * and open.
5218 */
5219
5220 /*
5221 * If we can open it and fstat the file descriptor, and neither check
5222 * revealed that it was a regular file, and the file has not been
5223 * replaced, return the file descriptor.
5224 */
5225 if (fstat(fd, &finfo2) == 0
5226 && !S_ISREG(finfo2.st_mode)
5227 && finfo.st_dev == finfo2.st_dev
5228 && finfo.st_ino == finfo2.st_ino
5229 ) {
5230 return fd;
5231 }
5232
5233 /* The file has been replaced. badness. */
5234 close(fd);
5235 errno = EEXIST;
5236 return -1;
5237}
5238
5239/*
5240 * Handle here documents. Normally we fork off a process to write the 5178 * Handle here documents. Normally we fork off a process to write the
5241 * data to a pipe. If the document is short, we can stuff the data in 5179 * data to a pipe. If the document is short, we can stuff the data in
5242 * the pipe without forking. 5180 * the pipe without forking.
@@ -5280,6 +5218,7 @@ openhere(union node *redir)
5280static int 5218static int
5281openredirect(union node *redir) 5219openredirect(union node *redir)
5282{ 5220{
5221 struct stat sb;
5283 char *fname; 5222 char *fname;
5284 int f; 5223 int f;
5285 5224
@@ -5319,9 +5258,23 @@ openredirect(union node *redir)
5319#endif 5258#endif
5320 /* Take care of noclobber mode. */ 5259 /* Take care of noclobber mode. */
5321 if (Cflag) { 5260 if (Cflag) {
5322 f = noclobberopen(fname); 5261 if (stat(fname, &sb) < 0) {
5323 if (f < 0) 5262 f = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
5263 if (f < 0)
5264 goto ecreate;
5265 } else if (!S_ISREG(sb.st_mode)) {
5266 f = open(fname, O_WRONLY, 0666);
5267 if (f < 0)
5268 goto ecreate;
5269 if (fstat(f, &sb) < 0 && S_ISREG(sb.st_mode)) {
5270 close(f);
5271 errno = EEXIST;
5272 goto ecreate;
5273 }
5274 } else {
5275 errno = EEXIST;
5324 goto ecreate; 5276 goto ecreate;
5277 }
5325 break; 5278 break;
5326 } 5279 }
5327 /* FALLTHROUGH */ 5280 /* FALLTHROUGH */