380df2f51a645fc1a8f56680322ff44c3455c6e7
[ust.git] / libustcomm / ustcomm.c
1 #define _GNU_SOURCE
2 #include <sys/types.h>
3 #include <signal.h>
4 #include <errno.h>
5 #include <sys/socket.h>
6 #include <sys/un.h>
7 #include <unistd.h>
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include "ustcomm.h"
14 #include "localerr.h"
15
16 #define UNIX_PATH_MAX 108
17 #define SOCK_DIR "/tmp/socks"
18 #define UST_SIGNAL SIGIO
19
20 #define MSG_MAX 1000
21
22 static void signal_process(pid_t pid)
23 {
24 int result;
25
26 result = kill(pid, UST_SIGNAL);
27 if(result == -1) {
28 perror("kill");
29 return;
30 }
31
32 sleep(1);
33 }
34
35 /* pid: the pid of the trace process that must receive the msg
36 msg: pointer to a null-terminated message to send
37 reply: location where to put the null-terminated string of the reply;
38 it must be free'd after usage
39 */
40
41 int send_message(pid_t pid, const char *msg, char **reply)
42 {
43 int fd;
44 int result;
45 struct sockaddr_un addr;
46
47 result = fd = socket(PF_UNIX, SOCK_DGRAM, 0);
48 if(result == -1) {
49 perror("socket");
50 return -1;
51 }
52
53 addr.sun_family = AF_UNIX;
54
55 result = snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%d", SOCK_DIR, pid);
56 if(result >= UNIX_PATH_MAX) {
57 fprintf(stderr, "string overflow allocating socket name");
58 return -1;
59 }
60
61 signal_process(pid);
62
63 result = sendto(fd, msg, strlen(msg), 0, (struct sockaddr *)&addr, sizeof(addr));
64 if(result == -1) {
65 perror("sendto");
66 return -1;
67 }
68
69 if(!reply)
70 return 0;
71
72 *reply = (char *) malloc(MSG_MAX+1);
73 result = recvfrom(fd, *reply, MSG_MAX, 0, NULL, NULL);
74 if(result == -1) {
75 perror("recvfrom");
76 return -1;
77 }
78
79 (*reply)[result] = '\0';
80
81 return 0;
82 }
83
84 int ustcomm_app_recv_message(struct ustcomm_app *app, char **msg)
85 {
86 int fd;
87 int result;
88 struct sockaddr_un addr;
89
90 *msg = (char *) malloc(MSG_MAX+1);
91 result = recvfrom(app->fd, *msg, MSG_MAX, 0, NULL, NULL);
92 if(result == -1) {
93 PERROR("recvfrom");
94 return -1;
95 }
96
97 DBG("ustcomm_app_recv_message: result is %d, message[1] is %hhd", result, (*msg)[1]);
98 (*msg)[result] = '\0';
99
100 return 0;
101 }
102
103 static int init_named_socket(char *name, char **path_out)
104 {
105 int result;
106 int fd;
107
108 struct sockaddr_un addr;
109
110 result = fd = socket(PF_UNIX, SOCK_DGRAM, 0);
111 if(result == -1) {
112 PERROR("socket");
113 return -1;
114 }
115
116 addr.sun_family = AF_UNIX;
117
118 strncpy(addr.sun_path, name, UNIX_PATH_MAX);
119 addr.sun_path[UNIX_PATH_MAX-1] = '\0';
120
121 result = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
122 if(result == -1) {
123 PERROR("bind");
124 goto close_sock;
125 }
126
127 if(path_out)
128 *path_out = strdupa(addr.sun_path);
129
130 return fd;
131
132 close_sock:
133 close(fd);
134
135 return -1;
136 }
137
138 int ustcomm_init_app(pid_t pid, struct ustcomm_app *handle)
139 {
140 int result;
141 char *name;
142
143 result = asprintf(&name, "%s/%d", SOCK_DIR, (int)pid);
144 if(result >= UNIX_PATH_MAX) {
145 ERR("string overflow allocating socket name");
146 return -1;
147 }
148
149 handle->fd = init_named_socket(name, &handle->socketpath);
150 if(handle->fd < 0) {
151 goto free_name;
152 }
153 free(name);
154
155 return 0;
156
157 free_name:
158 free(name);
159 return -1;
160 }
161
162 int ustcomm_init_ustd(struct ustcomm_ustd *handle)
163 {
164 handle->fd = init_named_socket("ustd", &handle->socketpath);
165 if(handle->fd < 0)
166 return handle->fd;
167
168 return 0;
169 }
This page took 0.03618 seconds and 3 git commands to generate.