Remove a silly print out in ust_trace.h
[ust.git] / libustd / libustd.c
CommitLineData
d159ac37
AH
1/* Copyright (C) 2009 Pierre-Marc Fournier
2 * 2010 Alexis Halle
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#define _GNU_SOURCE
20
4723ca09 21#include <sys/epoll.h>
d159ac37 22#include <sys/shm.h>
4723ca09
NC
23#include <sys/types.h>
24#include <sys/stat.h>
d159ac37
AH
25#include <unistd.h>
26#include <pthread.h>
27#include <signal.h>
28
29#include <stdlib.h>
30#include <stdio.h>
31#include <string.h>
32#include <errno.h>
33#include <assert.h>
34
d6c9f207
AH
35#include <ust/ustd.h>
36#include "lowlevel.h"
d159ac37
AH
37#include "usterr.h"
38#include "ustcomm.h"
39
40/* return value: 0 = subbuffer is finished, it won't produce data anymore
41 * 1 = got subbuffer successfully
42 * <0 = error
43 */
44
45#define GET_SUBBUF_OK 1
46#define GET_SUBBUF_DONE 0
47#define GET_SUBBUF_DIED 2
48
49#define PUT_SUBBUF_OK 1
50#define PUT_SUBBUF_DIED 0
51#define PUT_SUBBUF_PUSHED 2
52#define PUT_SUBBUF_DONE 3
53
54#define UNIX_PATH_MAX 108
55
56int get_subbuffer(struct buffer_info *buf)
57{
58 char *send_msg=NULL;
59 char *received_msg=NULL;
60 char *rep_code=NULL;
61 int retval;
62 int result;
63
08b8805e
DG
64 if (asprintf(&send_msg, "get_subbuffer %s", buf->name) < 0) {
65 ERR("get_subbuffer : asprintf failed (%s)",
66 buf->name);
67 retval = -1;
68 goto end;
69 }
4723ca09
NC
70
71 result = ustcomm_send_request(buf->app_sock, send_msg, &received_msg);
d159ac37
AH
72 if((result == -1 && (errno == ECONNRESET || errno == EPIPE)) || result == 0) {
73 DBG("app died while being traced");
74 retval = GET_SUBBUF_DIED;
75 goto end;
76 }
77 else if(result < 0) {
78 ERR("get_subbuffer: ustcomm_send_request failed");
79 retval = -1;
80 goto end;
81 }
82
83 result = sscanf(received_msg, "%as %ld", &rep_code, &buf->consumed_old);
84 if(result != 2 && result != 1) {
85 ERR("unable to parse response to get_subbuffer");
86 retval = -1;
87 free(received_msg);
88 goto end_rep;
89 }
90
4723ca09 91 if (!strcmp(rep_code, "OK")) {
d159ac37
AH
92 DBG("got subbuffer %s", buf->name);
93 retval = GET_SUBBUF_OK;
4723ca09 94 } else if(!strcmp(received_msg, "NOTFOUND")) {
d159ac37
AH
95 DBG("For buffer %s, the trace was not found. This likely means it was destroyed by the user.", buf->name);
96 retval = GET_SUBBUF_DIED;
97 goto end_rep;
4723ca09 98 } else {
d159ac37
AH
99 DBG("error getting subbuffer %s", buf->name);
100 retval = -1;
101 }
102
103 /* FIXME: free correctly the stuff */
104end_rep:
105 if(rep_code)
106 free(rep_code);
107end:
108 if(send_msg)
109 free(send_msg);
110 if(received_msg)
111 free(received_msg);
112
113 return retval;
114}
115
116int put_subbuffer(struct buffer_info *buf)
117{
118 char *send_msg=NULL;
119 char *received_msg=NULL;
120 char *rep_code=NULL;
121 int retval;
122 int result;
123
08b8805e
DG
124 if (asprintf(&send_msg, "put_subbuffer %s %ld", buf->name, buf->consumed_old) < 0) {
125 ERR("put_subbuffer : asprintf failed (%s %ld)",
126 buf->name, buf->consumed_old);
127 retval = -1;
128 goto end;
129 }
4723ca09 130 result = ustcomm_send_request(buf->app_sock, send_msg, &received_msg);
d159ac37
AH
131 if(result < 0 && (errno == ECONNRESET || errno == EPIPE)) {
132 retval = PUT_SUBBUF_DIED;
133 goto end;
134 }
135 else if(result < 0) {
136 ERR("put_subbuffer: send_message failed");
137 retval = -1;
138 goto end;
139 }
140 else if(result == 0) {
141 /* Program seems finished. However this might not be
142 * the last subbuffer that has to be collected.
143 */
144 retval = PUT_SUBBUF_DIED;
145 goto end;
146 }
147
148 result = sscanf(received_msg, "%as", &rep_code);
149 if(result != 1) {
150 ERR("unable to parse response to put_subbuffer");
151 retval = -1;
152 goto end_rep;
153 }
154
155 if(!strcmp(rep_code, "OK")) {
156 DBG("subbuffer put %s", buf->name);
157 retval = PUT_SUBBUF_OK;
158 }
159 else if(!strcmp(received_msg, "NOTFOUND")) {
160 DBG("For buffer %s, the trace was not found. This likely means it was destroyed by the user.", buf->name);
161 /* However, maybe this was not the last subbuffer. So
162 * we return the program died.
163 */
164 retval = PUT_SUBBUF_DIED;
165 goto end_rep;
166 }
167 else {
168 DBG("put_subbuffer: received error, we were pushed");
169 retval = PUT_SUBBUF_PUSHED;
170 goto end_rep;
171 }
172
173end_rep:
174 if(rep_code)
175 free(rep_code);
176
177end:
178 if(send_msg)
179 free(send_msg);
180 if(received_msg)
181 free(received_msg);
182
183 return retval;
184}
185
186void decrement_active_buffers(void *arg)
187{
188 struct libustd_instance *instance = arg;
189 pthread_mutex_lock(&instance->mutex);
190 instance->active_buffers--;
191 pthread_mutex_unlock(&instance->mutex);
192}
193
194struct buffer_info *connect_buffer(struct libustd_instance *instance, pid_t pid, const char *bufname)
195{
196 struct buffer_info *buf;
197 char *send_msg;
198 char *received_msg;
199 int result;
d159ac37 200 struct shmid_ds shmds;
4723ca09 201 struct ustcomm_header header;
d159ac37 202
7032c7d3 203 buf = (struct buffer_info *) zmalloc(sizeof(struct buffer_info));
d159ac37
AH
204 if(buf == NULL) {
205 ERR("add_buffer: insufficient memory");
206 return NULL;
207 }
208
209 buf->name = bufname;
210 buf->pid = pid;
211
4723ca09 212 /* FIXME: Fix all the freeing and exit sequence from this functions */
d159ac37 213 /* connect to app */
4723ca09 214 result = ustcomm_connect_app(buf->pid, &buf->app_sock);
d159ac37
AH
215 if(result) {
216 WARN("unable to connect to process, it probably died before we were able to connect");
217 return NULL;
218 }
219
220 /* get pidunique */
08b8805e
DG
221 if (asprintf(&send_msg, "get_pidunique") < 0) {
222 ERR("connect_buffer : asprintf failed (get_pidunique)");
223 return NULL;
224 }
4723ca09 225 result = ustcomm_send_request(buf->app_sock, send_msg, &received_msg);
d159ac37
AH
226 free(send_msg);
227 if(result == -1) {
228 ERR("problem in ustcomm_send_request(get_pidunique)");
229 return NULL;
230 }
231 if(result == 0) {
232 goto error;
233 }
234
235 result = sscanf(received_msg, "%lld", &buf->pidunique);
236 if(result != 1) {
237 ERR("unable to parse response to get_pidunique");
238 return NULL;
239 }
240 free(received_msg);
241 DBG("got pidunique %lld", buf->pidunique);
242
243 /* get shmid */
08b8805e
DG
244 if (asprintf(&send_msg, "get_shmid %s", buf->name) < 0) {
245 ERR("connect_buffer : asprintf failed (get_schmid %s)",
246 buf->name);
247 return NULL;
248 }
4723ca09 249 result = ustcomm_send_request(buf->app_sock, send_msg, &received_msg);
d159ac37
AH
250 free(send_msg);
251 if(result == -1) {
252 ERR("problem in ustcomm_send_request(get_shmid)");
253 return NULL;
254 }
255 if(result == 0) {
256 goto error;
257 }
258
259 result = sscanf(received_msg, "%d %d", &buf->shmid, &buf->bufstruct_shmid);
260 if(result != 2) {
261 ERR("unable to parse response to get_shmid (\"%s\")", received_msg);
262 return NULL;
263 }
264 free(received_msg);
265 DBG("got shmids %d %d", buf->shmid, buf->bufstruct_shmid);
266
267 /* get n_subbufs */
08b8805e
DG
268 if (asprintf(&send_msg, "get_n_subbufs %s", buf->name) < 0) {
269 ERR("connect_buffer : asprintf failed (get_n_subbufs %s)",
270 buf->name);
271 return NULL;
272 }
4723ca09 273 result = ustcomm_send_request(buf->app_sock, send_msg, &received_msg);
d159ac37
AH
274 free(send_msg);
275 if(result == -1) {
276 ERR("problem in ustcomm_send_request(g_n_subbufs)");
277 return NULL;
278 }
279 if(result == 0) {
280 goto error;
281 }
282
283 result = sscanf(received_msg, "%d", &buf->n_subbufs);
284 if(result != 1) {
285 ERR("unable to parse response to get_n_subbufs");
286 return NULL;
287 }
288 free(received_msg);
289 DBG("got n_subbufs %d", buf->n_subbufs);
290
291 /* get subbuf size */
08b8805e
DG
292 if (asprintf(&send_msg, "get_subbuf_size %s", buf->name) < 0) {
293 ERR("connect_buffer : asprintf failed (get_subbuf_size %s)",
294 buf->name);
295 return NULL;
296 }
4723ca09 297 result = ustcomm_send_request(buf->app_sock, send_msg, &received_msg);
d159ac37
AH
298 free(send_msg);
299 if(result == -1) {
300 ERR("problem in ustcomm_send_request(get_subbuf_size)");
301 return NULL;
302 }
303 if(result == 0) {
304 goto error;
305 }
306
307 result = sscanf(received_msg, "%d", &buf->subbuf_size);
308 if(result != 1) {
309 ERR("unable to parse response to get_subbuf_size");
310 return NULL;
311 }
312 free(received_msg);
313 DBG("got subbuf_size %d", buf->subbuf_size);
314
315 /* attach memory */
316 buf->mem = shmat(buf->shmid, NULL, 0);
317 if(buf->mem == (void *) 0) {
318 PERROR("shmat");
319 return NULL;
320 }
321 DBG("successfully attached buffer memory");
322
323 buf->bufstruct_mem = shmat(buf->bufstruct_shmid, NULL, 0);
324 if(buf->bufstruct_mem == (void *) 0) {
325 PERROR("shmat");
326 return NULL;
327 }
328 DBG("successfully attached buffer bufstruct memory");
329
330 /* obtain info on the memory segment */
331 result = shmctl(buf->shmid, IPC_STAT, &shmds);
332 if(result == -1) {
333 PERROR("shmctl");
334 return NULL;
335 }
336 buf->memlen = shmds.shm_segsz;
337
4723ca09
NC
338 /* get buffer pipe fd */
339 memset(&header, 0, sizeof(header));
340 if (asprintf(&send_msg, "get_buffer_fd %s", buf->name) < 0) {
341 ERR("connect_buffer : asprintf failed (get_buffer_fd %s)",
342 buf->name);
343 return NULL;
344 }
345 header.size = strlen(send_msg) + 1;
346 result = ustcomm_send(buf->app_sock, &header, send_msg);
347 free(send_msg);
348 if (result <= 0) {
349 ERR("ustcomm_send failed.");
350 return NULL;
351 }
352 result = ustcomm_recv_fd(buf->app_sock, &header, NULL, &buf->pipe_fd);
353 if (result <= 0) {
354 ERR("ustcomm_recv_fd failed");
355 return NULL;
356 } else {
357 struct stat temp;
358 fstat(buf->pipe_fd, &temp);
359 if (!S_ISFIFO(temp.st_mode)) {
360 ERR("Didn't receive a fifo from the app");
361 return NULL;
362 }
363 }
d159ac37
AH
364 if(instance->callbacks->on_open_buffer)
365 instance->callbacks->on_open_buffer(instance->callbacks, buf);
366
367 pthread_mutex_lock(&instance->mutex);
368 instance->active_buffers++;
369 pthread_mutex_unlock(&instance->mutex);
370
371 return buf;
372
373error:
374 free(buf);
375 return NULL;
376}
377
378static void destroy_buffer(struct libustd_callbacks *callbacks,
379 struct buffer_info *buf)
380{
381 int result;
382
4723ca09 383 result = close(buf->app_sock);
d159ac37
AH
384 if(result == -1) {
385 WARN("problem calling ustcomm_close_app");
386 }
387
388 result = shmdt(buf->mem);
389 if(result == -1) {
390 PERROR("shmdt");
391 }
392
393 result = shmdt(buf->bufstruct_mem);
394 if(result == -1) {
395 PERROR("shmdt");
396 }
397
398 if(callbacks->on_close_buffer)
399 callbacks->on_close_buffer(callbacks, buf);
400
401 free(buf);
402}
403
404int consumer_loop(struct libustd_instance *instance, struct buffer_info *buf)
405{
4723ca09
NC
406 int result, read_result;
407 char read_buf;
d159ac37
AH
408
409 pthread_cleanup_push(decrement_active_buffers, instance);
410
411 for(;;) {
4723ca09 412 read_result = read(buf->pipe_fd, &read_buf, 1);
d159ac37 413 /* get the subbuffer */
4723ca09
NC
414 if (read_result == 1) {
415 result = get_subbuffer(buf);
416 if(result == -1) {
417 ERR("error getting subbuffer");
418 continue;
419 } else if (result == GET_SUBBUF_DIED) {
420 finish_consuming_dead_subbuffer(instance->callbacks, buf);
421 break;
422 }
423 } else if ((read_result == -1 && (errno == ECONNRESET || errno == EPIPE)) ||
424 result == 0) {
425 DBG("App died while being traced");
d159ac37
AH
426 finish_consuming_dead_subbuffer(instance->callbacks, buf);
427 break;
428 }
429
430 if(instance->callbacks->on_read_subbuffer)
431 instance->callbacks->on_read_subbuffer(instance->callbacks, buf);
432
433 /* put the subbuffer */
434 result = put_subbuffer(buf);
435 if(result == -1) {
436 ERR("unknown error putting subbuffer (channel=%s)", buf->name);
437 break;
438 }
439 else if(result == PUT_SUBBUF_PUSHED) {
440 ERR("Buffer overflow (channel=%s), reader pushed. This channel will not be usable passed this point.", buf->name);
441 break;
442 }
443 else if(result == PUT_SUBBUF_DIED) {
444 DBG("application died while putting subbuffer");
445 /* Skip the first subbuffer. We are not sure it is trustable
446 * because the put_subbuffer() did not complete.
447 */
448 if(instance->callbacks->on_put_error)
449 instance->callbacks->on_put_error(instance->callbacks, buf);
450
451 finish_consuming_dead_subbuffer(instance->callbacks, buf);
452 break;
453 }
454 else if(result == PUT_SUBBUF_DONE) {
455 /* Done with this subbuffer */
456 /* FIXME: add a case where this branch is used? Upon
457 * normal trace termination, at put_subbuf time, a
458 * special last-subbuffer code could be returned by
459 * the listener.
460 */
461 break;
462 }
463 else if(result == PUT_SUBBUF_OK) {
464 }
465 }
466
467 DBG("thread for buffer %s is stopping", buf->name);
468
469 /* FIXME: destroy, unalloc... */
470
471 pthread_cleanup_pop(1);
472
473 return 0;
474}
475
476struct consumer_thread_args {
477 pid_t pid;
478 const char *bufname;
479 struct libustd_instance *instance;
480};
481
482void *consumer_thread(void *arg)
483{
484 struct buffer_info *buf;
485 struct consumer_thread_args *args = (struct consumer_thread_args *) arg;
486 int result;
487 sigset_t sigset;
488
489 DBG("GOT ARGS: pid %d bufname %s", args->pid, args->bufname);
490
491 if(args->instance->callbacks->on_new_thread)
492 args->instance->callbacks->on_new_thread(args->instance->callbacks);
493
494 /* Block signals that should be handled by the main thread. */
495 result = sigemptyset(&sigset);
496 if(result == -1) {
497 PERROR("sigemptyset");
498 goto end;
499 }
500 result = sigaddset(&sigset, SIGTERM);
501 if(result == -1) {
502 PERROR("sigaddset");
503 goto end;
504 }
505 result = sigaddset(&sigset, SIGINT);
506 if(result == -1) {
507 PERROR("sigaddset");
508 goto end;
509 }
510 result = sigprocmask(SIG_BLOCK, &sigset, NULL);
511 if(result == -1) {
512 PERROR("sigprocmask");
513 goto end;
514 }
515
516 buf = connect_buffer(args->instance, args->pid, args->bufname);
517 if(buf == NULL) {
518 ERR("failed to connect to buffer");
519 goto end;
520 }
521
522 consumer_loop(args->instance, buf);
523
524 destroy_buffer(args->instance->callbacks, buf);
525
526 end:
527
528 if(args->instance->callbacks->on_close_thread)
529 args->instance->callbacks->on_close_thread(args->instance->callbacks);
530
531 free((void *)args->bufname);
532 free(args);
533 return NULL;
534}
535
536int start_consuming_buffer(
537 struct libustd_instance *instance, pid_t pid, const char *bufname)
538{
539 pthread_t thr;
540 struct consumer_thread_args *args;
541 int result;
542
543 DBG("beginning of start_consuming_buffer: args: pid %d bufname %s", pid, bufname);
544
7032c7d3 545 args = (struct consumer_thread_args *) zmalloc(sizeof(struct consumer_thread_args));
d159ac37
AH
546
547 args->pid = pid;
548 args->bufname = strdup(bufname);
549 args->instance = instance;
550 DBG("beginning2 of start_consuming_buffer: args: pid %d bufname %s", args->pid, args->bufname);
551
552 result = pthread_create(&thr, NULL, consumer_thread, args);
553 if(result == -1) {
554 ERR("pthread_create failed");
555 return -1;
556 }
557 result = pthread_detach(thr);
558 if(result == -1) {
559 ERR("pthread_detach failed");
560 return -1;
561 }
562 DBG("end of start_consuming_buffer: args: pid %d bufname %s", args->pid, args->bufname);
563
564 return 0;
565}
4723ca09
NC
566static void process_client_cmd(char *recvbuf, struct libustd_instance *instance)
567{
568 if(!strncmp(recvbuf, "collect", 7)) {
569 pid_t pid;
570 char *bufname = NULL;
571 int result;
572
573 result = sscanf(recvbuf, "%*s %d %50as", &pid, &bufname);
574 if (result != 2) {
575 ERR("parsing error: %s", recvbuf);
576 goto free_bufname;
577 }
578
579 result = start_consuming_buffer(instance, pid, bufname);
580 if (result < 0) {
581 ERR("error in add_buffer");
582 goto free_bufname;
583 }
584
585 free_bufname:
586 if (bufname) {
587 free(bufname);
588 }
589 } else if(!strncmp(recvbuf, "exit", 4)) {
590 /* Only there to force poll to return */
591 } else {
592 WARN("unknown command: %s", recvbuf);
593 }
594}
595
596#define MAX_EVENTS 10
d159ac37
AH
597
598int libustd_start_instance(struct libustd_instance *instance)
599{
4723ca09
NC
600 struct ustcomm_sock *epoll_sock;
601 struct epoll_event events[MAX_EVENTS];
602 struct sockaddr addr;
603 int result, epoll_fd, accept_fd, nfds, i, addr_size, timeout;
d159ac37
AH
604
605 if(!instance->is_init) {
606 ERR("libustd instance not initialized");
607 return 1;
608 }
4723ca09
NC
609 epoll_fd = instance->epoll_fd;
610
611 timeout = -1;
d159ac37
AH
612
613 /* app loop */
614 for(;;) {
4723ca09
NC
615 nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, timeout);
616 if (nfds == -1 && errno == EINTR) {
d159ac37 617 /* Caught signal */
4723ca09
NC
618 } else if (nfds == -1) {
619 PERROR("libustd_start_instance: epoll_wait failed");
620 continue;
d159ac37 621 }
d159ac37 622
4723ca09
NC
623 for (i = 0; i < nfds; ++i) {
624 epoll_sock = (struct ustcomm_sock *)events[i].data.ptr;
625 if (epoll_sock == instance->listen_sock) {
626 addr_size = sizeof(struct sockaddr);
627 accept_fd = accept(epoll_sock->fd,
628 &addr,
629 (socklen_t *)&addr_size);
630 if (accept_fd == -1) {
631 PERROR("libustd_start_instance: "
632 "accept failed");
633 continue;
634 }
635 ustcomm_init_sock(accept_fd, epoll_fd,
636 &instance->connections);
637 } else {
638 char *msg = NULL;
639 result = recv_message_conn(epoll_sock->fd, &msg);
640 if (result == 0) {
641 ustcomm_del_sock(epoll_sock, 0);
642 } else if (msg) {
643 process_client_cmd(msg, instance);
644 free(msg);
d159ac37
AH
645 }
646
d159ac37 647 }
d159ac37
AH
648 }
649
4723ca09 650 if (instance->quit_program) {
d159ac37
AH
651 pthread_mutex_lock(&instance->mutex);
652 if(instance->active_buffers == 0) {
653 pthread_mutex_unlock(&instance->mutex);
654 break;
655 }
656 pthread_mutex_unlock(&instance->mutex);
657 timeout = 100;
658 }
659 }
660
661 if(instance->callbacks->on_trace_end)
662 instance->callbacks->on_trace_end(instance);
663
664 libustd_delete_instance(instance);
665
666 return 0;
667}
668
4723ca09 669/* FIXME: threads and connections !? */
d159ac37
AH
670void libustd_delete_instance(struct libustd_instance *instance)
671{
4723ca09
NC
672 if (instance->is_init) {
673 ustcomm_del_named_sock(instance->listen_sock, 0);
674 close(instance->epoll_fd);
675 }
d159ac37
AH
676
677 pthread_mutex_destroy(&instance->mutex);
678 free(instance->sock_path);
679 free(instance);
680}
681
682int libustd_stop_instance(struct libustd_instance *instance, int send_msg)
683{
684 int result;
685 int fd;
686 int bytes = 0;
687
688 char msg[] = "exit";
689
690 instance->quit_program = 1;
691
692 if(!send_msg)
693 return 0;
694
695 /* Send a message through the socket to force poll to return */
696
697 struct sockaddr_un addr;
698
699 result = fd = socket(PF_UNIX, SOCK_STREAM, 0);
700 if(result == -1) {
701 PERROR("socket");
702 return 1;
703 }
704
705 addr.sun_family = AF_UNIX;
706
707 strncpy(addr.sun_path, instance->sock_path, UNIX_PATH_MAX);
708 addr.sun_path[UNIX_PATH_MAX-1] = '\0';
709
710 result = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
711 if(result == -1) {
712 PERROR("connect");
713 }
714
715 while(bytes != sizeof(msg))
716 bytes += send(fd, msg, sizeof(msg), 0);
717
718 close(fd);
719
720 return 0;
721}
722
4723ca09
NC
723struct libustd_instance
724*libustd_new_instance(struct libustd_callbacks *callbacks,
725 char *sock_path)
d159ac37
AH
726{
727 struct libustd_instance *instance =
7032c7d3 728 zmalloc(sizeof(struct libustd_instance));
4723ca09 729 if(!instance) {
f3f8cc91
AH
730 return NULL;
731 }
732
d159ac37
AH
733 instance->callbacks = callbacks;
734 instance->quit_program = 0;
735 instance->is_init = 0;
736 instance->active_buffers = 0;
737 pthread_mutex_init(&instance->mutex, NULL);
738
4723ca09 739 if (sock_path) {
d159ac37 740 instance->sock_path = strdup(sock_path);
4723ca09 741 } else {
d159ac37 742 instance->sock_path = NULL;
4723ca09 743 }
d159ac37
AH
744
745 return instance;
746}
747
4723ca09
NC
748static int init_ustd_socket(struct libustd_instance *instance)
749{
750 char *name;
751
752 if (instance->sock_path) {
753 if (asprintf(&name, "%s", instance->sock_path) < 0) {
754 ERR("ustcomm_init_ustd : asprintf failed (sock_path %s)",
755 instance->sock_path);
756 return -1;
757 }
758 } else {
759 int result;
760
761 /* Only check if socket dir exists if we are using the default directory */
762 result = ensure_dir_exists(SOCK_DIR);
763 if (result == -1) {
764 ERR("Unable to create socket directory %s", SOCK_DIR);
765 return -1;
766 }
767
768 if (asprintf(&name, "%s/%s", SOCK_DIR, "ustd") < 0) {
769 ERR("ustcomm_init_ustd : asprintf failed (%s/ustd)",
770 SOCK_DIR);
771 return -1;
772 }
773 }
774
775 /* Set up epoll */
776 instance->epoll_fd = epoll_create(MAX_EVENTS);
777 if (instance->epoll_fd == -1) {
778 ERR("epoll_create failed, start instance bailing");
779 goto free_name;
780 }
781
782 /* Create the named socket */
783 instance->listen_sock = ustcomm_init_named_socket(name,
784 instance->epoll_fd);
785 if(!instance->listen_sock) {
786 ERR("error initializing named socket at %s", name);
787 goto close_epoll;
788 }
789
790 INIT_LIST_HEAD(&instance->connections);
791
792 free(name);
793
794 return 0;
795
796close_epoll:
797 close(instance->epoll_fd);
798free_name:
799 free(name);
800
801 return -1;
802}
803
d159ac37
AH
804int libustd_init_instance(struct libustd_instance *instance)
805{
806 int result;
4723ca09 807 result = init_ustd_socket(instance);
d159ac37
AH
808 if(result == -1) {
809 ERR("failed to initialize socket");
810 return 1;
811 }
812 instance->is_init = 1;
813 return 0;
814}
815
This page took 0.055136 seconds and 4 git commands to generate.