e445ed96b55339a52f98bd3c98238bd4bc490206
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_fd(int fd
, const char *msg
, char **reply
)
55 result
= send(fd
, msg
, strlen(msg
), 0);
64 *reply
= (char *) malloc(MSG_MAX
+1);
65 result
= recv(fd
, *reply
, MSG_MAX
, 0);
71 (*reply
)[result
] = '\0';
76 int send_message_path(const char *path
, const char *msg
, char **reply
, int signalpid
)
80 struct sockaddr_un addr
;
82 result
= fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
88 addr
.sun_family
= AF_UNIX
;
90 result
= snprintf(addr
.sun_path
, UNIX_PATH_MAX
, "%s", path
);
91 if(result
>= UNIX_PATH_MAX
) {
92 ERR("string overflow allocating socket name");
97 signal_process(signalpid
);
99 result
= connect(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));
105 return send_message_fd(fd
, msg
, reply
);
108 /* pid: the pid of the trace process that must receive the msg
109 msg: pointer to a null-terminated message to send
110 reply: location where to put the null-terminated string of the reply;
111 it must be free'd after usage
114 int send_message(pid_t pid
, const char *msg
, char **reply
)
117 char path
[UNIX_PATH_MAX
];
119 result
= snprintf(path
, UNIX_PATH_MAX
, "%s/%d", SOCK_DIR
, pid
);
120 if(result
>= UNIX_PATH_MAX
) {
121 fprintf(stderr
, "string overflow allocating socket name");
125 send_message_path(path
, msg
, reply
, pid
);
130 /* Called by an app to ask the consumer daemon to connect to it. */
132 int ustcomm_request_consumer(pid_t pid
, const char *channel
)
134 char path
[UNIX_PATH_MAX
];
138 result
= snprintf(path
, UNIX_PATH_MAX
, "%s/ustd", SOCK_DIR
);
139 if(result
>= UNIX_PATH_MAX
) {
140 fprintf(stderr
, "string overflow allocating socket name");
144 asprintf(&msg
, "collect %d %s", pid
, channel
);
146 send_message_path(path
, msg
, NULL
, -1);
154 static int recv_message_fd(int fd
, char **msg
, struct ustcomm_source
*src
)
158 *msg
= (char *) malloc(MSG_MAX
+1);
160 result
= recv(fd
, *msg
, MSG_MAX
, 0);
166 (*msg
)[result
] = '\0';
168 DBG("ustcomm_app_recv_message: result is %d, message is %s", result
, (*msg
));
176 int ustcomm_send_reply(struct ustcomm_server
*server
, char *msg
, struct ustcomm_source
*src
)
180 result
= send_message_fd(src
->fd
, msg
, NULL
);
182 ERR("error in send_message_fd");
189 int ustcomm_recv_message(struct ustcomm_server
*server
, char **msg
, struct ustcomm_source
*src
)
192 struct ustcomm_connection
*conn
;
200 list_for_each_entry(conn
, &server
->connections
, list
) {
204 fds
= (struct pollfd
*) malloc(n_fds
* sizeof(struct pollfd
));
206 ERR("malloc returned NULL");
210 /* special idx 0 is for listening socket */
211 fds
[idx
].fd
= server
->listen_fd
;
212 fds
[idx
].events
= POLLIN
;
215 list_for_each_entry(conn
, &server
->connections
, list
) {
216 fds
[idx
].fd
= conn
->fd
;
217 fds
[idx
].events
= POLLIN
;
221 result
= poll(fds
, n_fds
, -1);
228 struct ustcomm_connection
*newconn
;
231 result
= newfd
= accept(server
->listen_fd
, NULL
, NULL
);
237 newconn
= (struct ustcomm_connection
*) malloc(sizeof(struct ustcomm_connection
));
238 if(newconn
== NULL
) {
239 ERR("malloc returned NULL");
245 list_add(&newconn
->list
, &server
->connections
);
248 for(idx
=1; idx
<n_fds
; idx
++) {
249 if(fds
[idx
].revents
) {
250 retval
= recv_message_fd(fds
[idx
].fd
, msg
, src
);
252 /* connection finished */
255 list_for_each_entry(conn
, &server
->connections
, list
) {
256 if(conn
->fd
== fds
[idx
].fd
) {
257 list_del(&conn
->list
);
263 goto free_fds_return
;
276 int ustcomm_ustd_recv_message(struct ustcomm_ustd
*ustd
, char **msg
, struct ustcomm_source
*src
)
278 return ustcomm_recv_message(&ustd
->server
, msg
, src
);
281 int ustcomm_app_recv_message(struct ustcomm_app
*app
, char **msg
, struct ustcomm_source
*src
)
283 return ustcomm_recv_message(&app
->server
, msg
, src
);
286 static int init_named_socket(char *name
, char **path_out
)
291 struct sockaddr_un addr
;
293 result
= fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
299 addr
.sun_family
= AF_UNIX
;
301 strncpy(addr
.sun_path
, name
, UNIX_PATH_MAX
);
302 addr
.sun_path
[UNIX_PATH_MAX
-1] = '\0';
304 result
= access(name
, F_OK
);
307 result
= unlink(name
);
309 PERROR("unlink of socket file");
312 WARN("socket already exists; overwriting");
315 result
= bind(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));
321 result
= listen(fd
, 1);
329 *path_out
= strdupa(addr
.sun_path
);
340 int ustcomm_init_app(pid_t pid
, struct ustcomm_app
*handle
)
345 result
= asprintf(&name
, "%s/%d", SOCK_DIR
, (int)pid
);
346 if(result
>= UNIX_PATH_MAX
) {
347 ERR("string overflow allocating socket name");
351 handle
->server
.listen_fd
= init_named_socket(name
, &(handle
->server
.socketpath
));
352 if(handle
->server
.listen_fd
< 0) {
353 ERR("error initializing named socket");
358 INIT_LIST_HEAD(&handle
->server
.connections
);
367 int ustcomm_init_ustd(struct ustcomm_ustd
*handle
)
372 result
= asprintf(&name
, "%s/%s", SOCK_DIR
, "ustd");
373 if(result
>= UNIX_PATH_MAX
) {
374 ERR("string overflow allocating socket name");
378 handle
->server
.listen_fd
= init_named_socket(name
, &handle
->server
.socketpath
);
379 if(handle
->server
.listen_fd
< 0) {
380 ERR("error initializing named socket");
385 INIT_LIST_HEAD(&handle
->server
.connections
);
394 static char *find_tok(char *str
)
406 static char *find_sep(char *str
)
418 int nth_token_is(char *str
, char *token
, int tok_no
)
424 for(i
=0; i
<=tok_no
; i
++) {
438 if(end
-start
!= strlen(token
))
441 if(strncmp(start
, token
, end
-start
))
447 char *nth_token(char *str
, int tok_no
)
449 static char *retval
= NULL
;
454 for(i
=0; i
<=tok_no
; i
++) {
473 asprintf(&retval
, "%.*s", (int)(end
-start
), start
);
This page took 0.039171 seconds and 4 git commands to generate.