1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-01-17 22:31:12 +01:00

41142: Ensure close-on-exec is passed to moved file descriptor

This commit is contained in:
Stephane Chazelas 2017-05-23 16:46:25 +01:00 committed by Peter Stephenson
parent dd672b79ce
commit 99fff8f15c
2 changed files with 25 additions and 10 deletions

View file

@ -1,3 +1,8 @@
2017-05-23 Peter Stephenson <p.stephenson@samsung.com>
* Stephane: 41142: Src/Modules/system.c: ensure close-on-exec is
applied to moved file descriptor.
2017-05-22 Peter Stephenson <p.stephenson@samsung.com>
* Marko Myllenen: 41087: Completion/Unix/Command/_kvno: Update

View file

@ -313,7 +313,7 @@ bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func))
int flags = O_NOCTTY | append | ((append || write) ?
(read ? O_RDWR : O_WRONLY) : O_RDONLY);
char *opt, *ptr, *nextopt, *fdvar;
int o, fd, explicit = -1;
int o, fd, moved_fd, explicit = -1;
mode_t perms = 0666;
#if defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
int fdflags;
@ -376,22 +376,32 @@ bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func))
zwarnnam(nam, "can't open file %s: %e", *args, errno);
return 1;
}
fd = (explicit > -1) ? redup(fd, explicit) : movefd(fd);
if (fd == -1) {
moved_fd = (explicit > -1) ? redup(fd, explicit) : movefd(fd);
if (moved_fd == -1) {
zwarnnam(nam, "can't open file %s", *args);
return 1;
}
#if defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
#ifdef FD_CLOEXEC
#ifdef O_CLOEXEC
/*
* the O_CLOEXEC is a flag attached to the *file descriptor*, not the
* *open file description* so it doesn't survive a dup(). If that flag was
* requested and the fd was moved, we need to reapply it to the moved fd
* even if the original one was open with O_CLOEXEC
*/
if ((flags & O_CLOEXEC) && fd != moved_fd)
#else
if (fdflags)
fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif
#endif /* O_CLOEXEC */
fcntl(moved_fd, F_SETFD, FD_CLOEXEC);
#endif /* FD_CLOEXEC */
if (explicit == -1) {
fdtable[fd] = FDT_EXTERNAL;
setiparam(fdvar, fd);
/* if setting the variable failed, close fd to avoid leak */
fdtable[moved_fd] = FDT_EXTERNAL;
setiparam(fdvar, moved_fd);
/* if setting the variable failed, close moved_fd to avoid leak */
if (errflag)
zclose(fd);
zclose(moved_fd);
}
return 0;