public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
blob bfe36114adc379c4c44506929701f42a3f597721 2317 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
 
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/un.h>

#define die(...)				\
	do {					\
		fprintf(stderr, __VA_ARGS__);	\
		exit(1);			\
	} while (0)

static void usage(void)
{
	die("Usage: holder <socket path> hold|pid\n");
}

static void hold(int fd, const struct sockaddr_un *addr)
{
	int rc;

	rc = bind(fd, (struct sockaddr *)addr, sizeof(*addr));
	if (rc < 0)
		die("bind(): %s\n", strerror(errno));

	rc = listen(fd, 0);
	if (rc < 0)
		die("listen(): %s\n", strerror(errno));

	printf("nsholder: local PID=%d  local UID=%d  local GID=%d\n",
	       getpid(), getuid(), getgid());
	do {
		int afd = accept(fd, NULL, NULL);
		char buf;

		if (afd < 0)
			die("accept(): %s\n", strerror(errno));

		rc = read(afd, &buf, sizeof(buf));
		if (rc < 0)
			die("read(): %s\n", strerror(errno));
	} while (rc == 0);

	unlink(addr->sun_path);
}

static void pid(int fd, const struct sockaddr_un *addr)
{
	int rc;
	struct ucred peercred;
	socklen_t optlen = sizeof(peercred);

	do {
		rc = connect(fd, (struct sockaddr *)addr, sizeof(*addr));
		if (rc < 0 && errno != ENOENT && errno != ECONNREFUSED)
			die("connect(): %s\n", strerror(errno));
	} while (rc < 0);

	rc = getsockopt(fd, SOL_SOCKET, SO_PEERCRED,
			&peercred, &optlen);
	if (rc < 0)
		die("getsockopet(SO_PEERCRED): %s\n", strerror(errno));

	close(fd);

	printf("%d\n", peercred.pid);
}

static void stop(int fd, const struct sockaddr_un *addr)
{
	int rc;
	char buf = 'Q';

	rc = connect(fd, (struct sockaddr *)addr, sizeof(*addr));
	if (rc < 0)
		die("connect(): %s\n", strerror(errno));

	rc = write(fd, &buf, sizeof(buf));
	if (rc < 0)
		die("write(): %s\n",  strerror(errno));

	close(fd);
}

int main(int argc, char *argv[])
{
	int fd;
	const char *sockname;
	struct sockaddr_un sockaddr = {
		.sun_family = AF_UNIX,
	};

	if (argc != 3)
		usage();

	sockname = argv[1];
	strncpy(sockaddr.sun_path, sockname, UNIX_PATH_MAX);

	fd = socket(AF_UNIX, SOCK_STREAM, PF_UNIX);
	if (fd < 0)
		die("socket(): %s\n", strerror(errno));

	if (strcmp(argv[2], "hold") == 0)
		hold(fd, &sockaddr);
	else if (strcmp(argv[2], "pid") == 0)
		pid(fd, &sockaddr);
	else if (strcmp(argv[2], "stop") == 0)
		stop(fd, &sockaddr);
	else
		usage();

	exit(0);
}

debug log:

solving bfe3611 ...
found bfe3611 in https://archives.passt.top/passt-dev/20220902021500.25358-8-david@gibson.dropbear.id.au/ ||
	https://archives.passt.top/passt-dev/20220908061621.2430844-8-david@gibson.dropbear.id.au/ ||
	https://archives.passt.top/passt-dev/20220908014920.1474597-8-david@gibson.dropbear.id.au/

applying [1/1] https://archives.passt.top/passt-dev/20220902021500.25358-8-david@gibson.dropbear.id.au/
diff --git a/test/nsholder.c b/test/nsholder.c
new file mode 100644
index 0000000..bfe3611

Checking patch test/nsholder.c...
Applied patch test/nsholder.c cleanly.

skipping https://archives.passt.top/passt-dev/20220908061621.2430844-8-david@gibson.dropbear.id.au/ for bfe3611
skipping https://archives.passt.top/passt-dev/20220908014920.1474597-8-david@gibson.dropbear.id.au/ for bfe3611
index at:
100644 bfe36114adc379c4c44506929701f42a3f597721	test/nsholder.c

Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).