diff --git a/common/os_calls.c b/common/os_calls.c index ba8eaf60..6625723b 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -2292,6 +2292,59 @@ g_file_set_cloexec(int fd, int status) return rv; } +/*****************************************************************************/ +struct list * +g_get_open_fds(int min, int max) +{ + struct list *result = list_create(); + + if (result != NULL) + { + if (max < 0) + { + max = sysconf(_SC_OPEN_MAX); + } + + if (max > min) + { + struct pollfd *fds = g_new0(struct pollfd, max - min); + int i; + + if (fds == NULL) + { + goto nomem; + } + + for (i = min ; i < max ; ++i) + { + fds[i - min].fd = i; + } + + if (poll(fds, max - min, 0) >= 0) + { + for (i = min ; i < max ; ++i) + { + if (fds[i - min].revents != POLLNVAL) + { + // Descriptor is open + if (!list_add_item(result, i)) + { + goto nomem; + } + } + } + } + g_free(fds); + } + } + + return result; + +nomem: + list_delete(result); + return NULL; +} + /*****************************************************************************/ /* Converts a hex mask to a mode_t value */ #if !defined(_WIN32) diff --git a/common/os_calls.h b/common/os_calls.h index e9dcb4d9..c7fdcf3c 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -217,6 +217,16 @@ int g_file_lock(int fd, int start, int len); int g_file_duplicate_on(int fd, int target_fd); int g_file_get_cloexec(int fd); int g_file_set_cloexec(int fd, int status); +/** + * Get a list of open file descriptors + * + * @param min Min FD to consider + * @param max Max FD to consider (+1), or -1 for no limit + * @result Array of file descriptors, in ascending order. + * + * Call delete_list() on the result when you've finished with it. + */ +struct list *g_get_open_fds(int min, int max); int g_chmod_hex(const char *filename, int flags); int g_umask_hex(int flags); int g_chown(const char *name, int uid, int gid);