ash: use F_DUPFD_CLOEXEC and O_CLOEXEC

function                                             old     new   delta
setjobctl                                            371     367      -4
setinputfile                                         226     220      -6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-10)             Total: -10 bytes

Based on patch by Mark Marshall <mark.marshall@omicronenergy.com>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2018-03-30 22:15:14 +02:00
parent df65dc89b4
commit 60fb98e51d

View File

@ -258,6 +258,9 @@ typedef long arith_t;
#ifndef F_DUPFD_CLOEXEC #ifndef F_DUPFD_CLOEXEC
# define F_DUPFD_CLOEXEC F_DUPFD # define F_DUPFD_CLOEXEC F_DUPFD
#endif #endif
#ifndef O_CLOEXEC
# define O_CLOEXEC 0
#endif
#ifndef PIPE_BUF #ifndef PIPE_BUF
# define PIPE_BUF 4096 /* amount of buffering in a pipe */ # define PIPE_BUF 4096 /* amount of buffering in a pipe */
#endif #endif
@ -3972,11 +3975,12 @@ setjobctl(int on)
goto out; goto out;
} }
/* fd is a tty at this point */ /* fd is a tty at this point */
fd = fcntl(fd, F_DUPFD, 10); fd = fcntl(fd, F_DUPFD_CLOEXEC, 10);
if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, don't */ if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, don't */
close(ofd); close(ofd);
if (fd < 0) if (fd < 0)
goto out; /* F_DUPFD failed */ goto out; /* F_DUPFD failed */
if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
close_on_exec_on(fd); close_on_exec_on(fd);
while (1) { /* while we are in the background */ while (1) { /* while we are in the background */
pgrp = tcgetpgrp(fd); pgrp = tcgetpgrp(fd);
@ -5427,13 +5431,14 @@ savefd(int from)
int newfd; int newfd;
int err; int err;
newfd = fcntl(from, F_DUPFD, 10); newfd = fcntl(from, F_DUPFD_CLOEXEC, 10);
err = newfd < 0 ? errno : 0; err = newfd < 0 ? errno : 0;
if (err != EBADF) { if (err != EBADF) {
if (err) if (err)
ash_msg_and_raise_perror("%d", from); ash_msg_and_raise_perror("%d", from);
close(from); close(from);
fcntl(newfd, F_SETFD, FD_CLOEXEC); if (F_DUPFD_CLOEXEC == F_DUPFD)
close_on_exec_on(newfd);
} }
return newfd; return newfd;
@ -5458,7 +5463,7 @@ dup_CLOEXEC(int fd, int avoid_fd)
newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1); newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
if (newfd >= 0) { if (newfd >= 0) {
if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */ if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
fcntl(newfd, F_SETFD, FD_CLOEXEC); close_on_exec_on(newfd);
} else { /* newfd < 0 */ } else { /* newfd < 0 */
if (errno == EBUSY) if (errno == EBUSY)
goto repeat; goto repeat;
@ -5472,7 +5477,7 @@ xdup_CLOEXEC_and_close(int fd, int avoid_fd)
{ {
int newfd; int newfd;
repeat: repeat:
newfd = fcntl(fd, F_DUPFD, avoid_fd + 1); newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
if (newfd < 0) { if (newfd < 0) {
if (errno == EBUSY) if (errno == EBUSY)
goto repeat; goto repeat;
@ -5483,7 +5488,8 @@ xdup_CLOEXEC_and_close(int fd, int avoid_fd)
return fd; return fd;
ash_msg_and_raise_perror("%d", newfd); ash_msg_and_raise_perror("%d", newfd);
} }
fcntl(newfd, F_SETFD, FD_CLOEXEC); if (F_DUPFD_CLOEXEC == F_DUPFD)
close_on_exec_on(newfd);
close(fd); close(fd);
return newfd; return newfd;
} }
@ -10753,7 +10759,7 @@ setinputfile(const char *fname, int flags)
int fd; int fd;
INT_OFF; INT_OFF;
fd = open(fname, O_RDONLY); fd = open(fname, O_RDONLY | O_CLOEXEC);
if (fd < 0) { if (fd < 0) {
if (flags & INPUT_NOFILE_OK) if (flags & INPUT_NOFILE_OK)
goto out; goto out;
@ -10762,8 +10768,9 @@ setinputfile(const char *fname, int flags)
} }
if (fd < 10) if (fd < 10)
fd = savefd(fd); fd = savefd(fd);
else else if (O_CLOEXEC == 0) /* old libc */
close_on_exec_on(fd); close_on_exec_on(fd);
setinputfd(fd, flags & INPUT_PUSH_FILE); setinputfd(fd, flags & INPUT_PUSH_FILE);
out: out:
INT_ON; INT_ON;