1
|
#include <sys/types.h>
|
2
|
#include <sys/socket.h>
|
3
|
#include <sys/un.h>
|
4
|
#include <unistd.h>
|
5
|
#include <assert.h>
|
6
|
#include <string.h>
|
7
|
#include <pthread.h>
|
8
|
#include <stdio.h>
|
9
|
#include <signal.h>
|
10
|
#include <ucred.h>
|
11
|
|
12
|
static void* echo_loop(void *arg)
|
13
|
{
|
14
|
int sock = *(int*)arg;
|
15
|
int rec;
|
16
|
int sent;
|
17
|
char buf[256];
|
18
|
|
19
|
while ((rec = read(sock, buf, sizeof(buf)-1)) > 0) {
|
20
|
buf[rec] = 0;
|
21
|
printf("got '%s' %d\n", buf, rec);
|
22
|
while (rec > 0) {
|
23
|
sent = send(sock, buf, rec, 0);
|
24
|
printf("sent %d bytes\n", sent);
|
25
|
if (sent > 0)
|
26
|
rec -= sent;
|
27
|
else {
|
28
|
printf("write failed\n");
|
29
|
break;
|
30
|
}
|
31
|
}
|
32
|
}
|
33
|
|
34
|
printf("client is dead\n");
|
35
|
close(sock);
|
36
|
|
37
|
return NULL;
|
38
|
}
|
39
|
|
40
|
int main(int argc, char **argv)
|
41
|
{
|
42
|
struct sockaddr_un saddr;
|
43
|
int sock;
|
44
|
int ret;
|
45
|
int nc;
|
46
|
|
47
|
signal(SIGPIPE, SIG_IGN);
|
48
|
|
49
|
assert(argc > 1);
|
50
|
saddr.sun_family = AF_UNIX;
|
51
|
strcpy(saddr.sun_path, argv[1]);
|
52
|
|
53
|
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
54
|
assert(sock != -1);
|
55
|
|
56
|
unlink(argv[1]);
|
57
|
ret = bind(sock, (struct sockaddr*)&saddr, sizeof(saddr));
|
58
|
assert(ret != -1);
|
59
|
|
60
|
ret = listen(sock, SOMAXCONN);
|
61
|
assert(ret != -1);
|
62
|
|
63
|
while ((nc = accept(sock, NULL, 0)) != -1) {
|
64
|
pthread_t pt;
|
65
|
ucred_t *uc = NULL;
|
66
|
printf("new client\n");
|
67
|
if (getpeerucred(nc, &uc) != -1) {
|
68
|
printf("remote: pid %ld, euid: %d, egid: %d\n",
|
69
|
ucred_getpid(uc),
|
70
|
ucred_geteuid(uc),
|
71
|
ucred_getegid(uc));
|
72
|
ucred_free(uc);
|
73
|
}
|
74
|
pthread_create(&pt, NULL, echo_loop, &nc);
|
75
|
}
|
76
|
|
77
|
close(sock);
|
78
|
unlink(argv[1]);
|
79
|
|
80
|
return 0;
|
81
|
}
|