/* * Close all open file descriptors. */ #include #include #include #include #include #include #include #include const char dirpath[] = "/proc/self/fd"; static void close_fds_linux() { printf("close_fds_linux()\n"); DIR *dirp = opendir(dirpath); if (!dirp) perror("opendir()"); long name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX); if (name_max == -1) /* Limit not defined, or error */ name_max = 255; /* Take a guess */ size_t len = offsetof(struct dirent, d_name) + name_max + 1; struct dirent *result, *entryp = malloc(len); if (!entryp) perror("malloc()"); for (;;) { int ret = readdir_r(dirp, entryp, &result); if (ret) perror("readdir_r()"); if (!result) break; switch (result->d_name[0]) { case '0': /* STDIN */ case '1': /* STDOUT */ case '2': /* STDERR */ if (result->d_name[1] != '\0') break; /* fall-through */ case '.': continue; } int fd = atoi(result->d_name); if (fd == dirfd(dirp)) continue; printf("Closing %d...\n", fd); ret = close(fd); if (ret) perror("close()"); } free(entryp); int ret = closedir(dirp); if (ret) perror("closedir()"); } static void close_fds_generic() { printf("close_fds_generic()\n"); int fd = sysconf(_SC_OPEN_MAX); if (fd < 0) perror("sysconf()"); while (fd > STDERR_FILENO) { printf("Closing %d...\n", fd); int ret = close(fd--); if (ret && errno != EBADF) perror("close()"); } } static void close_fds() { struct stat buf; int ret = stat(dirpath, &buf); if (!ret && S_ISDIR(buf.st_mode)) close_fds_linux(); else if (ret && errno == ENOENT) close_fds_generic(); else perror("stat()"); } int main(void) { close_fds(); return 0; }