2773b1a0a4fc7c299a95e3a6897a993c5eefbb60
5 #include <sys/socket.h>
18 #define UNIX_PATH_MAX 108
19 #define SOCK_DIR "/tmp/socks"
20 #define UST_SIGNAL SIGIO
24 /* FIXME: ustcomm blocks on message sending, which might be problematic in
25 * some cases. Fix the poll() usage so sends are buffered until they don't
29 //static void bt(void)
34 // result = backtrace(&buffer, 100);
35 // backtrace_symbols_fd(buffer, result, STDERR_FILENO);
38 static void signal_process(pid_t pid
)
42 result
= kill(pid
, UST_SIGNAL
);
51 int send_message_path(const char *path
, const char *msg
, char **reply
, int signalpid
)
55 struct sockaddr_un addr
;
57 result
= fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
63 addr
.sun_family
= AF_UNIX
;
65 result
= snprintf(addr
.sun_path
, UNIX_PATH_MAX
, "%s", path
);
66 if(result
>= UNIX_PATH_MAX
) {
67 ERR("string overflow allocating socket name");
72 signal_process(signalpid
);
74 result
= connect(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));
80 result
= send(fd
, msg
, strlen(msg
), 0);
89 *reply
= (char *) malloc(MSG_MAX
+1);
90 result
= recvfrom(fd
, *reply
, MSG_MAX
, 0, NULL
, NULL
);
96 (*reply
)[result
] = '\0';
101 /* pid: the pid of the trace process that must receive the msg
102 msg: pointer to a null-terminated message to send
103 reply: location where to put the null-terminated string of the reply;
104 it must be free'd after usage
107 int send_message(pid_t pid
, const char *msg
, char **reply
)
110 char path
[UNIX_PATH_MAX
];
112 result
= snprintf(path
, UNIX_PATH_MAX
, "%s/%d", SOCK_DIR
, pid
);
113 if(result
>= UNIX_PATH_MAX
) {
114 fprintf(stderr
, "string overflow allocating socket name");
118 send_message_path(path
, msg
, reply
, pid
);
123 /* Called by an app to ask the consumer daemon to connect to it. */
125 int ustcomm_request_consumer(pid_t pid
, const char *channel
)
127 char path
[UNIX_PATH_MAX
];
131 result
= snprintf(path
, UNIX_PATH_MAX
, "%s/ustd", SOCK_DIR
);
132 if(result
>= UNIX_PATH_MAX
) {
133 fprintf(stderr
, "string overflow allocating socket name");
137 asprintf(&msg
, "collect %d %s", pid
, channel
);
139 send_message_path(path
, msg
, NULL
, -1);
145 static int recv_message_fd(int fd
, char **msg
, struct ustcomm_source
*src
)
149 *msg
= (char *) malloc(MSG_MAX
+1);
151 result
= recv(fd
, *msg
, MSG_MAX
, 0);
157 (*msg
)[result
] = '\0';
159 DBG("ustcomm_app_recv_message: result is %d, message is %s", result
, (*msg
));
164 int ustcomm_ustd_recv_message(struct ustcomm_ustd
*ustd
, char **msg
, struct ustcomm_source
*src
)
167 struct ustcomm_connection
*conn
;
175 list_for_each_entry(conn
, &ustd
->connections
, list
) {
179 fds
= (struct pollfd
*) malloc(n_fds
* sizeof(struct pollfd
));
181 ERR("malloc returned NULL");
185 /* special idx 0 is for listening socket */
186 fds
[idx
].fd
= ustd
->listen_fd
;
187 fds
[idx
].events
= POLLIN
;
190 list_for_each_entry(conn
, &ustd
->connections
, list
) {
191 fds
[idx
].fd
= conn
->fd
;
192 fds
[idx
].events
= POLLIN
;
196 result
= poll(fds
, n_fds
, -1);
203 struct ustcomm_connection
*newconn
;
206 result
= newfd
= accept(ustd
->listen_fd
, NULL
, NULL
);
212 newconn
= (struct ustcomm_connection
*) malloc(sizeof(struct ustcomm_connection
));
213 if(newconn
== NULL
) {
214 ERR("malloc returned NULL");
220 list_add(&newconn
->list
, &ustd
->connections
);
223 for(idx
=1; idx
<n_fds
; idx
++) {
224 if(fds
[idx
].revents
) {
225 retval
= recv_message_fd(fds
[idx
].fd
, msg
, src
);
227 /* connection finished */
230 list_for_each_entry(conn
, &ustd
->connections
, list
) {
231 if(conn
->fd
== fds
[idx
].fd
) {
232 list_del(&conn
->list
);
238 goto free_fds_return
;
251 int ustcomm_app_recv_message(struct ustcomm_app
*app
, char **msg
, struct ustcomm_source
*src
)
253 return ustcomm_ustd_recv_message((struct ustcomm_ustd
*)app
, msg
, src
);
256 static int init_named_socket(char *name
, char **path_out
)
261 struct sockaddr_un addr
;
263 result
= fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
269 addr
.sun_family
= AF_UNIX
;
271 strncpy(addr
.sun_path
, name
, UNIX_PATH_MAX
);
272 addr
.sun_path
[UNIX_PATH_MAX
-1] = '\0';
274 result
= access(name
, F_OK
);
277 result
= unlink(name
);
279 PERROR("unlink of socket file");
282 WARN("socket already exists; overwriting");
285 result
= bind(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));
291 result
= listen(fd
, 1);
299 *path_out
= strdupa(addr
.sun_path
);
310 int ustcomm_init_app(pid_t pid
, struct ustcomm_app
*handle
)
315 result
= asprintf(&name
, "%s/%d", SOCK_DIR
, (int)pid
);
316 if(result
>= UNIX_PATH_MAX
) {
317 ERR("string overflow allocating socket name");
321 handle
->listen_fd
= init_named_socket(name
, &(handle
->socketpath
));
322 if(handle
->listen_fd
< 0) {
323 ERR("error initializing named socket");
328 INIT_LIST_HEAD(&handle
->connections
);
337 int ustcomm_init_ustd(struct ustcomm_ustd
*handle
)
342 result
= asprintf(&name
, "%s/%s", SOCK_DIR
, "ustd");
343 if(result
>= UNIX_PATH_MAX
) {
344 ERR("string overflow allocating socket name");
348 handle
->listen_fd
= init_named_socket(name
, &handle
->socketpath
);
349 if(handle
->listen_fd
< 0) {
350 ERR("error initializing named socket");
355 INIT_LIST_HEAD(&handle
->connections
);
364 static char *find_tok(char *str
)
376 static char *find_sep(char *str
)
388 int nth_token_is(char *str
, char *token
, int tok_no
)
394 for(i
=0; i
<=tok_no
; i
++) {
408 if(end
-start
!= strlen(token
))
411 if(strncmp(start
, token
, end
-start
))
417 char *nth_token(char *str
, int tok_no
)
419 static char *retval
= NULL
;
424 for(i
=0; i
<=tok_no
; i
++) {
443 asprintf(&retval
, "%.*s", (int)(end
-start
), start
);
This page took 0.0703 seconds and 4 git commands to generate.