X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=libtracectl%2Ftracectl.c;h=46874d4ad4d56d15c2e6217906ebac8d898f719e;hb=98963de4a2dfae12d8aafa0f9a6d97cf4a44e12d;hp=aca3abc207ae81ad60067778e717a7c11b3ebe92;hpb=9c67dc50afb2eaa1c3966ee73fac3ce55935556c;p=ust.git diff --git a/libtracectl/tracectl.c b/libtracectl/tracectl.c index aca3abc..46874d4 100644 --- a/libtracectl/tracectl.c +++ b/libtracectl/tracectl.c @@ -4,6 +4,7 @@ #include #include #include +#include #define UNIX_PATH_MAX 108 //#define SOCKETDIR "/var/run/ust/socks" @@ -16,14 +17,32 @@ #define ERR(fmt, args...) fprintf(stderr, "usertrace: ERROR: " fmt "\n", ## args) #define PERROR(call) perror("usertrace: ERROR: " call) +#define MAX_MSG_SIZE (100) +#define MSG_NOTIF 1 +#define MSG_REGISTER_NOTIF 2 + struct tracecmd { /* no padding */ uint32_t size; uint16_t command; }; +//struct listener_arg { +// int pipe_fd; +//}; + +struct trctl_msg { + /* size: the size of all the fields except size itself */ + uint32_t size; + uint16_t type; + /* Only the necessary part of the payload is transferred. It + * may even be none of it. + */ + char payload[94]; +}; pid_t mypid; char mysocketfile[UNIX_PATH_MAX] = ""; +int pfd = -1; void do_command(struct tracecmd *cmd) { @@ -33,6 +52,94 @@ void receive_commands() { } +int fd_notif = -1; +void notif_cb(void) +{ + int result; + struct trctl_msg msg; + + /* FIXME: fd_notif should probably be protected by a spinlock */ + + if(fd_notif == -1) + return; + + msg.type = MSG_NOTIF; + msg.size = sizeof(msg.type); + + /* FIXME: don't block here */ + result = write(fd_notif, &msg, msg.size+sizeof(msg.size)); + if(result == -1) { + PERROR("write"); + return; + } +} + +int listener_main(void *p) +{ + int result; + + /* Allowing only 1 connection for now. */ + result = listen(pfd, 1); + if(result == -1) { + PERROR("listen"); + return 1; + } + + for(;;) { + + uint32_t size; + int fd; + struct sockaddr_un addr; + socklen_t addrlen = sizeof(addr); + + result = fd = accept(pfd, (struct sockaddr *)&addr, &addrlen); + if(result == -1) { + PERROR("accept"); + continue; + } + + for(;;) { + struct trctl_msg msg; + unsigned char dontclose=0; + + result = read(fd, &msg.size, sizeof(msg.size)); + if(result == -1) { + PERROR("read"); + continue; + } + + if(size > MAX_MSG_SIZE) { + ERR("trctl message too big"); + break; + } + + result = read(fd, &msg.type, sizeof(msg.type)); + if(result == -1) { + PERROR("read"); + continue; + } + + switch(msg.type) { + case MSG_REGISTER_NOTIF: + /* TODO: put it in notif mode */ + goto next_conn; + }; + } + next_conn:; + } +} + +void create_listener(void) +{ + int result; + static char listener_stack[16384]; + + result = clone(listener_main, listener_stack+sizeof(listener_stack)-1, CLONE_FS | CLONE_FILES | CLONE_VM, NULL); + if(result == -1) { + perror("clone"); + } +} + /* The signal handler itself. */ void sighandler(int sig) @@ -43,12 +150,12 @@ void sighandler(int sig) /* Called by the app signal handler to chain it to us. */ -void chain_signal() +void chain_signal(void) { sighandler(USTSIGNAL); } -int init_socket() +static int init_socket(void) { int result; int fd; @@ -80,13 +187,16 @@ int init_socket() strcpy(mysocketfile, addr.sun_path); + pfd = fd; + return 0; + close_sock: close(fd); return -1; } -void destroy_socket() +static void destroy_socket(void) { int result; @@ -99,7 +209,7 @@ void destroy_socket() } } -int init_signal_handler(void) +static int init_signal_handler(void) { /* Attempt to handler SIGIO. If the main program wants to * handle it, fine, it'll override us. They it'll have to @@ -130,15 +240,25 @@ int init_signal_handler(void) return 0; } -void __attribute__((constructor)) init() +static void __attribute__((constructor)) init() { int result; mypid = getpid(); - /* if using instead seperate thread, then should create thread */ - result = init_signal_handler(); + /* Must create socket before signal handler to prevent races + * on pfd variable. + */ result = init_socket(); + if(result == -1) { + ERR("init_socket error"); + return; + } + result = init_signal_handler(); + if(result == -1) { + ERR("init_signal_handler error"); + return; + } return; @@ -149,7 +269,7 @@ void __attribute__((constructor)) init() /* This is only called if we terminate normally, not with an unhandled signal, * so we cannot rely on it. */ -void __attribute__((destructor)) fini() +static void __attribute__((destructor)) fini() { destroy_socket(); }