[go: up one dir, main page]

File: socket.c

package info (click to toggle)
uftrace 0.13-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 5,212 kB
  • sloc: ansic: 53,313; python: 9,846; makefile: 838; asm: 703; cpp: 602; sh: 560; javascript: 191
file content (77 lines) | stat: -rw-r--r-- 1,900 bytes parent folder | download
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
#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#include "uftrace.h"
#include "utils/socket.h"
#include "utils/utils.h"

/* unlink socket file if it exists */
void socket_unlink(struct sockaddr_un *addr)
{
	if (unlink(addr->sun_path) == -1) {
		if (errno != ENOENT) {
			pr_dbg("cannot unlink %s\n", addr->sun_path);
		}
	}
}

/* Create socket for communication between the client and the agent */
int socket_create(struct sockaddr_un *addr, pid_t pid)
{
	int fd;
	char *channel = NULL;

	fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (fd == -1) {
		pr_warn("socket creation failed: %s\n", strerror(errno));
		return fd;
	}
	memset(addr, 0, sizeof(struct sockaddr_un));
	xasprintf(&channel, "%s/%d.socket", MCOUNT_AGENT_SOCKET_DIR, pid);
	addr->sun_family = AF_UNIX;
	strncpy(addr->sun_path, channel, sizeof(addr->sun_path) - 1);
	free(channel);
	return fd;
}

/* Setup socket on agent side so it can accept client connection */
int socket_listen(int fd, struct sockaddr_un *addr)
{
	if (bind(fd, (struct sockaddr *)addr, sizeof(struct sockaddr_un)) == -1) {
		pr_warn("cannot bind to socket %s: %s\n", addr->sun_path, strerror(errno));
		close(fd);
		return -1;
	}
	if (listen(fd, 1) == -1) {
		pr_warn("cannot listen to socket %s\n", addr->sun_path);
		close(fd);
		return -1;
	}
	return 0;
}

/* Send a single option to the agent through its socket */
int socket_send_option(int fd, enum uftrace_dopt opt, void *value, size_t size)
{
	if (!write(fd, &opt, sizeof(enum uftrace_dopt)))
		return -1;
	if (value)
		return write(fd, value, size);
	return 0;
}

int socket_connect(int fd, struct sockaddr_un *addr)
{
	if (connect(fd, (struct sockaddr *)addr, sizeof(struct sockaddr_un)) == -1) {
		pr_warn("cannot connect to socket '%s': %s\n", addr->sun_path, strerror(errno));
		return -1;
	}
	return 0;
}

int socket_accept(int fd)
{
	return accept(fd, NULL, NULL);
}