aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlns <matzeton@googlemail.com>2019-11-11 19:52:52 +0100
committerlns <matzeton@googlemail.com>2019-11-11 19:52:52 +0100
commit7aa6d69a8ece3f62eebbc18a716c33196d43bacf (patch)
treee0f10d69b93b8c90534ef96eaa52a2a1afc312b0
parentec3f5d405ed8feacdfb86c10f9be3b91d010f0a4 (diff)
progressbar fd position extraction
-rw-r--r--progressbar.c101
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);
}