|
19 | 19 | #include <string.h>
|
20 | 20 | #include <sys/resource.h>
|
21 | 21 | #include <sys/stat.h>
|
| 22 | +#include <sys/syscall.h> |
22 | 23 | #include <sys/time.h>
|
23 | 24 | #include <sys/types.h>
|
24 | 25 | #include <sys/wait.h>
|
|
45 | 46 |
|
46 | 47 | #define TLOG_SEGMENT_MAGIC 0xFF446154
|
47 | 48 |
|
| 49 | +struct linux_dirent64 { |
| 50 | + unsigned long long d_ino; |
| 51 | + long long d_off; |
| 52 | + unsigned short d_reclen; |
| 53 | + unsigned char d_type; |
| 54 | + char d_name[256]; |
| 55 | +}; |
| 56 | + |
48 | 57 | struct tlog_log {
|
49 | 58 | char *buff;
|
50 | 59 | int buffsize;
|
@@ -508,7 +517,7 @@ static int _tlog_vprintf(struct tlog_log *log, vprint_callback print_callback, v
|
508 | 517 | buff[len - 1] = '\0';
|
509 | 518 | buff[len - 2] = '\n';
|
510 | 519 | buff[len - 3] = '.';
|
511 |
| - buff[len - 5] = '.'; |
| 520 | + buff[len - 4] = '.'; |
512 | 521 | buff[len - 5] = '.';
|
513 | 522 | }
|
514 | 523 |
|
@@ -922,47 +931,67 @@ static void _tlog_close_all_fd_by_res(void)
|
922 | 931 | }
|
923 | 932 | }
|
924 | 933 |
|
| 934 | +static int _tlog_str_to_int(const char *str) |
| 935 | +{ |
| 936 | + int num = 0; |
| 937 | + |
| 938 | + while (*str >= '0' && *str <= '9') { |
| 939 | + num = num * 10 + (*str - '0'); |
| 940 | + ++str; |
| 941 | + } |
| 942 | + |
| 943 | + if (*str) { |
| 944 | + return -1; |
| 945 | + } |
| 946 | + |
| 947 | + return num; |
| 948 | +} |
| 949 | + |
925 | 950 | static void _tlog_close_all_fd(void)
|
926 | 951 | {
|
927 |
| - char path_name[PATH_MAX]; |
928 |
| - DIR *dir = NULL; |
929 |
| - struct dirent *ent; |
| 952 | +#if defined(__linux__) |
930 | 953 | int dir_fd = -1;
|
931 | 954 |
|
932 |
| - snprintf(path_name, sizeof(path_name), "/proc/self/fd/"); |
933 |
| - dir = opendir(path_name); |
934 |
| - if (dir == NULL) { |
| 955 | + dir_fd = open("/proc/self/fd/", O_RDONLY | O_DIRECTORY); |
| 956 | + if (dir_fd < 0) { |
935 | 957 | goto errout;
|
936 | 958 | }
|
937 | 959 |
|
938 |
| - dir_fd = dirfd(dir); |
| 960 | + char buffer[sizeof(struct linux_dirent64)]; |
| 961 | + int bytes; |
| 962 | + while ((bytes = syscall(SYS_getdents64, dir_fd, |
| 963 | + (struct linux_dirent64 *)buffer, |
| 964 | + sizeof(buffer))) |
| 965 | + > 0) { |
| 966 | + struct linux_dirent64 *entry; |
| 967 | + int offset; |
939 | 968 |
|
940 |
| - while ((ent = readdir(dir)) != NULL) { |
941 |
| - int fd = atoi(ent->d_name); |
942 |
| - if (fd < 0 || dir_fd == fd) { |
943 |
| - continue; |
944 |
| - } |
945 |
| - switch (fd) { |
946 |
| - case STDIN_FILENO: |
947 |
| - case STDOUT_FILENO: |
948 |
| - case STDERR_FILENO: |
949 |
| - continue; |
950 |
| - break; |
951 |
| - default: |
952 |
| - break; |
953 |
| - } |
| 969 | + for (offset = 0; offset < bytes; offset += entry->d_reclen) { |
| 970 | + int fd; |
| 971 | + entry = (struct linux_dirent64 *)(buffer + offset); |
| 972 | + if ((fd = _tlog_str_to_int(entry->d_name)) < 0) { |
| 973 | + continue; |
| 974 | + } |
954 | 975 |
|
955 |
| - close(fd); |
| 976 | + if (fd == dir_fd || fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO) { |
| 977 | + continue; |
| 978 | + } |
| 979 | + close(fd); |
| 980 | + } |
956 | 981 | }
|
957 | 982 |
|
958 |
| - closedir(dir); |
| 983 | + close(dir_fd); |
| 984 | + |
| 985 | + if (bytes < 0) { |
| 986 | + goto errout; |
| 987 | + } |
959 | 988 |
|
960 | 989 | return;
|
961 | 990 | errout:
|
962 |
| - if (dir) { |
963 |
| - closedir(dir); |
| 991 | + if (dir_fd > 0) { |
| 992 | + close(dir_fd); |
964 | 993 | }
|
965 |
| - |
| 994 | +#endif |
966 | 995 | _tlog_close_all_fd_by_res();
|
967 | 996 | return;
|
968 | 997 | }
|
|
0 commit comments