lib/fileutils: make close_all_fds() to be similar with close_range()

The util-linux close_all_fds() serves the same purpose as close_range()
that will over time obsolete local implementation completely.  For
upcoming few years it is best to have a fallback that uses same input
arguments as the new system call.  That allows surrounding code and
variables not to be affected by version of mass file descriptor closing
function.

Proposed-by: Karel Zak <kzak@redhat.com>
Reference: https://github.com/karelzak/util-linux/pull/1205#discussion_r534080128
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Sami Kerola 2020-12-02 22:56:16 +00:00
parent f0649c0d83
commit a75700d86e
No known key found for this signature in database
GPG Key ID: 0D46FEF7E61DBB46
3 changed files with 24 additions and 28 deletions

View File

@ -53,7 +53,7 @@ static inline int is_same_inode(const int fd, const struct stat *st)
}
extern int dup_fd_cloexec(int oldfd, int lowfd);
extern int get_fd_tabsize(void);
extern unsigned int get_fd_tabsize(void);
extern int mkdir_p(const char *path, mode_t mode);
extern char *stripoff_last_component(char *path);
@ -86,7 +86,9 @@ static inline int close_range(unsigned int first, unsigned int last)
# endif /* SYS_close_range */
#endif /* __linux__ */
extern void close_all_fds(const int exclude[], size_t exsz);
#ifndef HAVE_CLOSE_RANGE
extern void close_all_fds(unsigned int first, unsigned int last);
#endif
#define UL_COPY_READ_ERROR (-1)
#define UL_COPY_WRITE_ERROR (-2)

View File

@ -110,7 +110,7 @@ unwind:
/*
* portable getdtablesize()
*/
int get_fd_tabsize(void)
unsigned int get_fd_tabsize(void)
{
int m;
@ -129,18 +129,8 @@ int get_fd_tabsize(void)
return m;
}
static inline int in_set(int x, const int set[], size_t setsz)
{
size_t i;
for (i = 0; i < setsz; i++) {
if (set[i] == x)
return 1;
}
return 0;
}
void close_all_fds(const int exclude[], size_t exsz)
#ifndef HAVE_CLOSE_RANGE
void close_all_fds(unsigned int first, unsigned int last)
{
struct dirent *d;
DIR *dir;
@ -149,29 +139,34 @@ void close_all_fds(const int exclude[], size_t exsz)
if (dir) {
while ((d = xreaddir(dir))) {
char *end;
int fd;
unsigned int fd;
int dfd;
errno = 0;
fd = strtol(d->d_name, &end, 10);
fd = strtoul(d->d_name, &end, 10);
if (errno || end == d->d_name || !end || *end)
continue;
if (dirfd(dir) == fd)
dfd = dirfd(dir);
if (dfd < 0)
continue;
if (in_set(fd, exclude, exsz))
if ((unsigned int)dfd == fd)
continue;
if (fd < first || last < fd)
continue;
close(fd);
}
closedir(dir);
} else {
int fd, tbsz = get_fd_tabsize();
unsigned fd, tbsz = get_fd_tabsize();
for (fd = 0; fd < tbsz; fd++) {
if (!in_set(fd, exclude, exsz))
if (first <= fd && fd <= last)
close(fd);
}
}
}
#endif
#ifdef TEST_PROGRAM_FILEUTILS
int main(int argc, char *argv[])
@ -196,7 +191,11 @@ int main(int argc, char *argv[])
ignore_result( dup(STDIN_FILENO) );
ignore_result( dup(STDIN_FILENO) );
close_all_fds(wanted_fds, ARRAY_SIZE(wanted_fds));
# ifdef HAVE_CLOSE_RANGE
close_range(STDERR_FILENO + 1, ~0U);
# else
close_all_fds(STDERR_FILENO + 1, ~0U);
# endif
} else if (strcmp(argv[1], "--copy-file") == 0) {
int ret = ul_copy_file(STDIN_FILENO, STDOUT_FILENO);
if (ret == UL_COPY_READ_ERROR)

View File

@ -1294,11 +1294,6 @@ static void initialize(int argc, char **argv, struct login_context *cxt)
{"version", no_argument, NULL, 'V'},
{NULL, 0, NULL, 0}
};
#ifndef HAVE_CLOSE_RANGE
const int wanted_fds[] = {
STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO
};
#endif
timeout = (unsigned int)getlogindefs_num("LOGIN_TIMEOUT", LOGIN_TIMEOUT);
@ -1370,7 +1365,7 @@ static void initialize(int argc, char **argv, struct login_context *cxt)
#ifdef HAVE_CLOSE_RANGE
close_range(STDERR_FILENO + 1, ~0U);
#else
close_all_fds(wanted_fds, ARRAY_SIZE(wanted_fds));
close_all_fds(STDERR_FILENO + 1, ~0U);
#endif
}