mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-11-01 06:20:55 +01:00
46026: Add CLOBBER_EMPTY option.
This commit is contained in:
parent
172b646a6b
commit
3df604a4be
6 changed files with 59 additions and 5 deletions
27
Src/exec.c
27
Src/exec.c
|
|
@ -2143,14 +2143,15 @@ clobber_open(struct redir *f)
|
|||
{
|
||||
struct stat buf;
|
||||
int fd, oerrno;
|
||||
char *ufname = unmeta(f->name);
|
||||
|
||||
/* If clobbering, just open. */
|
||||
if (isset(CLOBBER) || IS_CLOBBER_REDIR(f->type))
|
||||
return open(unmeta(f->name),
|
||||
return open(ufname,
|
||||
O_WRONLY | O_CREAT | O_TRUNC | O_NOCTTY, 0666);
|
||||
|
||||
/* If not clobbering, attempt to create file exclusively. */
|
||||
if ((fd = open(unmeta(f->name),
|
||||
if ((fd = open(ufname,
|
||||
O_WRONLY | O_CREAT | O_EXCL | O_NOCTTY, 0666)) >= 0)
|
||||
return fd;
|
||||
|
||||
|
|
@ -2158,11 +2159,27 @@ clobber_open(struct redir *f)
|
|||
* Try opening, and if it's a regular file then close it again *
|
||||
* because we weren't supposed to open it. */
|
||||
oerrno = errno;
|
||||
if ((fd = open(unmeta(f->name), O_WRONLY | O_NOCTTY)) != -1) {
|
||||
if(!fstat(fd, &buf) && !S_ISREG(buf.st_mode))
|
||||
return fd;
|
||||
if ((fd = open(ufname, O_WRONLY | O_NOCTTY)) != -1) {
|
||||
if(!fstat(fd, &buf)) {
|
||||
if (!S_ISREG(buf.st_mode))
|
||||
return fd;
|
||||
/*
|
||||
* If CLOBBER_EMPTY is in effect and the file is empty,
|
||||
* we are allowed to re-use it.
|
||||
*
|
||||
* Note: there is an intrinsic race here because another
|
||||
* process can write to this file at any time. The only fix
|
||||
* would be file locking, which we wish to avoid in basic
|
||||
* file operations at this level. This would not be
|
||||
* fixed. just additionally complicated, by re-opening the
|
||||
* file and truncating.
|
||||
*/
|
||||
if (isset(CLOBBEREMPTY) && buf.st_size == 0)
|
||||
return fd;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
errno = oerrno;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ static struct optname optns[] = {
|
|||
{{NULL, "checkjobs", OPT_EMULATE|OPT_ZSH}, CHECKJOBS},
|
||||
{{NULL, "checkrunningjobs", OPT_EMULATE|OPT_ZSH}, CHECKRUNNINGJOBS},
|
||||
{{NULL, "clobber", OPT_EMULATE|OPT_ALL}, CLOBBER},
|
||||
{{NULL, "clobberempty", 0}, CLOBBEREMPTY},
|
||||
{{NULL, "combiningchars", 0}, COMBININGCHARS},
|
||||
{{NULL, "completealiases", 0}, COMPLETEALIASES},
|
||||
{{NULL, "completeinword", 0}, COMPLETEINWORD},
|
||||
|
|
|
|||
|
|
@ -2378,6 +2378,7 @@ enum {
|
|||
CHECKJOBS,
|
||||
CHECKRUNNINGJOBS,
|
||||
CLOBBER,
|
||||
CLOBBEREMPTY,
|
||||
APPENDCREATE,
|
||||
COMBININGCHARS,
|
||||
COMPLETEALIASES,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue