diff options
author | lns <matzeton@googlemail.com> | 2019-11-11 19:52:52 +0100 |
---|---|---|
committer | lns <matzeton@googlemail.com> | 2019-11-11 19:52:52 +0100 |
commit | 7aa6d69a8ece3f62eebbc18a716c33196d43bacf (patch) | |
tree | e0f10d69b93b8c90534ef96eaa52a2a1afc312b0 | |
parent | ec3f5d405ed8feacdfb86c10f9be3b91d010f0a4 (diff) |
progressbar fd position extraction
-rw-r--r-- | progressbar.c | 101 |
1 files changed, 93 insertions, 8 deletions
diff --git a/progressbar.c b/progressbar.c index a8c183e..8c5900a 100644 --- a/progressbar.c +++ b/progressbar.c @@ -4,6 +4,11 @@ #include <stdlib.h> #include <unistd.h> #include <errno.h> +#include <string.h> +#include <stdbool.h> +#include <fcntl.h> +#include <sys/stat.h> + struct filtered_dir_entries { struct dirent ** entries; @@ -20,7 +25,6 @@ static int search_dir(const char * const dir, n = scandir(dir, &names, filter_fn, alphasort); if (n < 0) { - perror("scandir"); return 1; } @@ -75,10 +79,17 @@ int main(int argc, char **argv) struct filtered_dir_entries proc_pid_entries = {}; struct filtered_dir_entries proc_fd_entries = {}; ssize_t realpath_used; - char realpath[BUFSIZ]; - - (void) argc; - (void) argv; + size_t target_filepath_len; + char file_realpath[BUFSIZ] = {}; + char pid[32]; + char fd[32]; + bool found_target = false; + + if (argc != 2) { + fprintf(stderr, "usage: %s [FILE]\n", (argc > 0 ? argv[0] : "progressbar")); + exit(EXIT_FAILURE); + } + target_filepath_len = strlen(argv[1]); if (search_dir("/proc", dirent_filter_only_numeric, &proc_pid_entries)) { exit(EXIT_FAILURE); @@ -93,13 +104,87 @@ int main(int argc, char **argv) realpath_used = realpath_procfs_fd("/proc", proc_pid_entries.entries[i]->d_name, proc_fd_entries.entries[j]->d_name, - &realpath[0], sizeof realpath); - if (realpath_used < 0) { + &file_realpath[0], sizeof file_realpath); + if (realpath_used <= 0) { continue; } - printf("%s: __%.*s__\n", proc_pid_entries.entries[i]->d_name, (int)realpath_used, realpath); + file_realpath[realpath_used] = '\0'; + if (realpath_used == target_filepath_len) { + if (!strncmp(argv[1], file_realpath, realpath_used)) { + found_target = true; + if (snprintf(pid, sizeof pid, "%s", proc_pid_entries.entries[i]->d_name) <= 0) { + found_target = false; + } + if (snprintf(fd, sizeof fd, "%s", proc_fd_entries.entries[j]->d_name) <= 0) { + found_target = false; + } + break; + } + } } free_filtered_dir_entries(&proc_fd_entries); + + if (found_target) { + break; + } } free_filtered_dir_entries(&proc_pid_entries); + + if (!found_target) { + fprintf(stderr, "%s: file '%s' not found in /proc\n", argv[0], argv[1]); + exit(EXIT_FAILURE); + } + + printf("PID: %s, FD: %s, FILE: '%.*s'\n", pid, fd, (int)realpath_used, file_realpath); + + char proc_fd_path[BUFSIZ]; + if (snprintf(proc_fd_path, sizeof proc_fd_path, "%s/%s/fd/%s", "/proc", pid, fd) <= 0) { + exit(EXIT_FAILURE); + } + + int proc_fd_fd = open(proc_fd_path, 0); + if (proc_fd_fd < 0) { + perror("open proc_fd"); + exit(EXIT_FAILURE); + } + + struct stat buf = {}; + if (fstat(proc_fd_fd, &buf)) { + perror("stat proc_fd"); + exit(EXIT_FAILURE); + } + close(proc_fd_fd); + + printf("Total size: %lld\n", (long long) buf.st_size); + + char proc_fdinfo_path[BUFSIZ]; + if (snprintf(proc_fdinfo_path, sizeof proc_fdinfo_path, "%s/%s/fdinfo/%s", "/proc", pid, fd) <= 0) { + exit(EXIT_FAILURE); + } + + int proc_fdinfo_fd = open(proc_fdinfo_path, 0); + if (proc_fdinfo_fd < 0) { + perror("open proc_fdinfo"); + exit(EXIT_FAILURE); + } + + ssize_t nread; + char proc_fdinfo[BUFSIZ]; + nread = read(proc_fdinfo_fd, &proc_fdinfo[0], sizeof proc_fdinfo); + if (nread <= 0) { + perror("read proc_fdinfo"); + exit(EXIT_FAILURE); + } + proc_fdinfo[nread - 1] = '\0'; + close(proc_fdinfo_fd); + + static const char needle[] = "pos:\t"; + char * pospos = strstr(&proc_fdinfo[0], &needle[0]); + if (!pospos) { + exit(EXIT_FAILURE); + } + pospos += (sizeof(needle) - 1) / sizeof(needle[0]); + + unsigned long long int current_position = strtoull(pospos, NULL, 10); + printf("Current position: %llu\n", current_position); } |