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 char *strdup_malloc(const char *s
)
45 retval
= (char *) malloc(strlen(s
)+1);
52 static void signal_process(pid_t pid
)
56 result
= kill(pid
, UST_SIGNAL
);
65 int send_message_fd(int fd
, const char *msg
, char **reply
)
69 result
= send(fd
, msg
, strlen(msg
), 0);
74 else if(result
== 0) {
81 *reply
= (char *) malloc(MSG_MAX
+1);
82 result
= recv(fd
, *reply
, MSG_MAX
, 0);
87 else if(result
== 0) {
91 (*reply
)[result
] = '\0';
96 int send_message_path(const char *path
, const char *msg
, char **reply
, int signalpid
)
100 struct sockaddr_un addr
;
102 result
= fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
108 addr
.sun_family
= AF_UNIX
;
110 result
= snprintf(addr
.sun_path
, UNIX_PATH_MAX
, "%s", path
);
111 if(result
>= UNIX_PATH_MAX
) {
112 ERR("string overflow allocating socket name");
117 signal_process(signalpid
);
119 result
= connect(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));
125 return send_message_fd(fd
, msg
, reply
);
128 /* pid: the pid of the trace process that must receive the msg
129 msg: pointer to a null-terminated message to send
130 reply: location where to put the null-terminated string of the reply;
131 it must be free'd after usage
134 int send_message(pid_t pid
, const char *msg
, char **reply
)
137 char path
[UNIX_PATH_MAX
];
139 result
= snprintf(path
, UNIX_PATH_MAX
, "%s/%d", SOCK_DIR
, pid
);
140 if(result
>= UNIX_PATH_MAX
) {
141 fprintf(stderr
, "string overflow allocating socket name");
145 send_message_path(path
, msg
, reply
, pid
);
150 /* Called by an app to ask the consumer daemon to connect to it. */
152 int ustcomm_request_consumer(pid_t pid
, const char *channel
)
154 char path
[UNIX_PATH_MAX
];
158 result
= snprintf(path
, UNIX_PATH_MAX
, "%s/ustd", SOCK_DIR
);
159 if(result
>= UNIX_PATH_MAX
) {
160 fprintf(stderr
, "string overflow allocating socket name");
164 asprintf(&msg
, "collect %d %s", pid
, channel
);
166 send_message_path(path
, msg
, NULL
, -1);
172 /* returns 1 to indicate a message was received
173 * returns 0 to indicate no message was received (cannot happen)
174 * returns -1 to indicate an error
177 static int recv_message_fd(int fd
, char **msg
, struct ustcomm_source
*src
)
181 *msg
= (char *) malloc(MSG_MAX
+1);
183 result
= recv(fd
, *msg
, MSG_MAX
, 0);
189 (*msg
)[result
] = '\0';
191 DBG("ustcomm_app_recv_message: result is %d, message is %s", result
, (*msg
));
199 int ustcomm_send_reply(struct ustcomm_server
*server
, char *msg
, struct ustcomm_source
*src
)
203 result
= send_message_fd(src
->fd
, msg
, NULL
);
205 ERR("error in send_message_fd");
212 /* @timeout: max blocking time in milliseconds, -1 means infinity
214 * returns 1 to indicate a message was received
215 * returns 0 to indicate no message was received
216 * returns -1 to indicate an error
219 int ustcomm_recv_message(struct ustcomm_server
*server
, char **msg
, struct ustcomm_source
*src
, int timeout
)
222 struct ustcomm_connection
*conn
;
230 list_for_each_entry(conn
, &server
->connections
, list
) {
234 fds
= (struct pollfd
*) malloc(n_fds
* sizeof(struct pollfd
));
236 ERR("malloc returned NULL");
240 /* special idx 0 is for listening socket */
241 fds
[idx
].fd
= server
->listen_fd
;
242 fds
[idx
].events
= POLLIN
;
245 list_for_each_entry(conn
, &server
->connections
, list
) {
246 fds
[idx
].fd
= conn
->fd
;
247 fds
[idx
].events
= POLLIN
;
251 result
= poll(fds
, n_fds
, timeout
);
261 struct ustcomm_connection
*newconn
;
264 result
= newfd
= accept(server
->listen_fd
, NULL
, NULL
);
270 newconn
= (struct ustcomm_connection
*) malloc(sizeof(struct ustcomm_connection
));
271 if(newconn
== NULL
) {
272 ERR("malloc returned NULL");
278 list_add(&newconn
->list
, &server
->connections
);
281 for(idx
=1; idx
<n_fds
; idx
++) {
282 if(fds
[idx
].revents
) {
283 retval
= recv_message_fd(fds
[idx
].fd
, msg
, src
);
285 /* connection finished */
288 list_for_each_entry(conn
, &server
->connections
, list
) {
289 if(conn
->fd
== fds
[idx
].fd
) {
290 list_del(&conn
->list
);
296 goto free_fds_return
;
309 int ustcomm_ustd_recv_message(struct ustcomm_ustd
*ustd
, char **msg
, struct ustcomm_source
*src
, int timeout
)
311 return ustcomm_recv_message(&ustd
->server
, msg
, src
, timeout
);
314 int ustcomm_app_recv_message(struct ustcomm_app
*app
, char **msg
, struct ustcomm_source
*src
, int timeout
)
316 return ustcomm_recv_message(&app
->server
, msg
, src
, timeout
);
319 /* This removes src from the list of active connections of app.
322 int ustcomm_app_detach_client(struct ustcomm_app
*app
, struct ustcomm_source
*src
)
324 struct ustcomm_server
*server
= (struct ustcomm_server
*)app
;
325 struct ustcomm_connection
*conn
;
327 list_for_each_entry(conn
, &server
->connections
, list
) {
328 if(conn
->fd
== src
->fd
) {
329 list_del(&conn
->list
);
339 static int init_named_socket(char *name
, char **path_out
)
344 struct sockaddr_un addr
;
346 result
= fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
352 addr
.sun_family
= AF_UNIX
;
354 strncpy(addr
.sun_path
, name
, UNIX_PATH_MAX
);
355 addr
.sun_path
[UNIX_PATH_MAX
-1] = '\0';
357 result
= access(name
, F_OK
);
360 result
= unlink(name
);
362 PERROR("unlink of socket file");
365 WARN("socket already exists; overwriting");
368 result
= bind(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));
374 result
= listen(fd
, 1);
382 *path_out
= strdupa(addr
.sun_path
);
393 int ustcomm_init_app(pid_t pid
, struct ustcomm_app
*handle
)
398 result
= asprintf(&name
, "%s/%d", SOCK_DIR
, (int)pid
);
399 if(result
>= UNIX_PATH_MAX
) {
400 ERR("string overflow allocating socket name");
404 handle
->server
.listen_fd
= init_named_socket(name
, &(handle
->server
.socketpath
));
405 if(handle
->server
.listen_fd
< 0) {
406 ERR("error initializing named socket");
411 INIT_LIST_HEAD(&handle
->server
.connections
);
420 int ustcomm_init_ustd(struct ustcomm_ustd
*handle
)
425 result
= asprintf(&name
, "%s/%s", SOCK_DIR
, "ustd");
426 if(result
>= UNIX_PATH_MAX
) {
427 ERR("string overflow allocating socket name");
431 handle
->server
.listen_fd
= init_named_socket(name
, &handle
->server
.socketpath
);
432 if(handle
->server
.listen_fd
< 0) {
433 ERR("error initializing named socket");
438 INIT_LIST_HEAD(&handle
->server
.connections
);
447 static char *find_tok(char *str
)
459 static char *find_sep(char *str
)
471 int nth_token_is(char *str
, char *token
, int tok_no
)
477 for(i
=0; i
<=tok_no
; i
++) {
491 if(end
-start
!= strlen(token
))
494 if(strncmp(start
, token
, end
-start
))
500 char *nth_token(char *str
, int tok_no
)
502 static char *retval
= NULL
;
507 for(i
=0; i
<=tok_no
; i
++) {
526 asprintf(&retval
, "%.*s", (int)(end
-start
), start
);
This page took 0.050833 seconds and 4 git commands to generate.