Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: dtracing unlink



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


Home | Main Index | Thread Index | Old Index