On Fri, 20 Oct 2023, RVP wrote:
/* printf("%d %d %s ", uid, pid, execname); system("pr_realpath -p %d %s", pid, copyinstr(arg0)); printf("\n"); */
I forgot to provide you with pr_realpath (in case you wanted the full path): ``` #include <errno.h> #include <limits.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> /* Functions */ static int do_opts(int argc, char* argv[]); static void usage(FILE* fp); static void error(char* fmt, ...); /* Globals */ static struct options { pid_t pid; } opts; static char* prog; int main(int argc, char* argv[]) { char cwd[PATH_MAX]; char buf[PATH_MAX]; char* fname, *p; int idx, len, rc; prog = argv[0]; rc = EXIT_FAILURE; idx = do_opts(argc, argv); argc -= idx; argv += idx; if (argc != 1) { usage(stderr); exit(rc); } fname = argv[0]; if (opts.pid == 0) opts.pid = getpid(); snprintf(buf, sizeof buf, "/proc/%d/cwd", opts.pid); if ((len = readlink(buf, cwd, sizeof(cwd)-1)) == -1) { error("%s: %s: readlink failed.", prog, buf); exit(rc); } cwd[len] = '\0'; if (*fname != '/') /* relative path */ snprintf(buf, sizeof buf, "%s/%s", cwd, fname); else strcpy(buf, fname); if ((p = realpath(buf, NULL)) == NULL) { error("%s: %s: realpath failed.", prog, buf); exit(rc); } printf("%s\n", p); free(p); rc = EXIT_SUCCESS; exit(rc); } /** * Process program options. */ static int do_opts(int argc, char* argv[]) { int opt; /* defaults */ opts.pid = 0; /* use own PID */ while ((opt = getopt(argc, argv, "hp:")) != -1) { switch (opt) { case 'h': usage(stdout); exit(EXIT_SUCCESS); break; case 'p': opts.pid = atoi(optarg); if (opts.pid <= 0) { error("%s: PID must be > 0", prog); exit(EXIT_FAILURE); } break; default: usage(stderr); exit(EXIT_FAILURE); break; } } return optind; } /** * Print usage information. */ static void usage(FILE* fp) { fprintf(fp, "Usage: %s [-h] [-p PID] FILENAME\n", prog); fprintf(fp, "%s: Canonicalize FILENAME belonging to PID using realpath(3)\n", prog); fprintf(fp, "\n"); fprintf(fp, " -h This message.\n"); fprintf(fp, " -p PID Owner of FILENAME (default: self)\n"); } /** * Print an error message. */ static void error(char* fmt, ...) { va_list ap; int e = errno; fflush(stdout); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); if (e != 0) { fprintf(stderr, " (%s)", strerror(e)); errno = 0; } fprintf(stderr, "\n"); fflush(stderr); } ``` You must have /proc mounted for this to work. I should make it use kinfo, but this too was written a couple of years ago--when I was a NetBSD newbie :) -RVP