#include "marker.h"
#include "tracer.h"
-#include "usterr.h"
+#include "localerr.h"
+#include "ustcomm.h"
#define UNIX_PATH_MAX 108
-//#define SOCKETDIR "/var/run/ust/socks"
#define SOCKETDIR "/tmp/socks"
#define SOCKETDIRLEN sizeof(SOCKETDIR)
#define USTSIGNAL SIGIO
char consumer_stack[10000];
+static struct ustcomm_app ustcomm_app;
+
struct tracecmd { /* no padding */
uint32_t size;
uint16_t command;
pid_t mypid;
char mysocketfile[UNIX_PATH_MAX] = "";
-int pfd = -1;
+//int pfd = -1;
struct consumer_channel {
int fd;
{
struct marker_iter iter;
+ lock_markers();
marker_iter_reset(&iter);
marker_iter_start(&iter);
fprintf(stderr, "marker: %s_%s \"%s\"\n", iter.marker->channel, iter.marker->name, iter.marker->format);
marker_iter_next(&iter);
}
+ unlock_markers();
}
void do_command(struct tracecmd *cmd)
}
}
-char recvbuf[10000];
+#define CONSUMER_DAEMON_SOCK SOCKETDIR "/ustd"
+
+static int inform_consumer_daemon(void)
+{
+}
int listener_main(void *p)
{
socklen_t addrlen = sizeof(addr);
char trace_name[] = "auto";
char trace_type[] = "ustrelay";
+ char *recvbuf;
+ int len;
- for(;;) {
- struct trctl_msg msg;
- int len;
-
- result = len = recvfrom(pfd, recvbuf, sizeof(recvbuf-1), 0, &addr, &addrlen);
- if(result == -1) {
- PERROR("recvfrom");
- continue;
- }
-
- if(recvbuf[len-1] == '\n')
- recvbuf[len-1] = '\0';
- else
- recvbuf[len] = 0;
+ result = ustcomm_app_recv_message(&ustcomm_app, &recvbuf);
+ if(result) {
+ WARN("error in ustcomm_app_recv_message");
+ continue;
+ }
- fprintf(stderr, "received a message! it's: %s\n", recvbuf);
+ DBG("received a message! it's: %s\n", recvbuf);
+ len = strlen(recvbuf);
+ if(len && recvbuf[len-1] == '\n') {
+ recvbuf[len-1] = '\0';
+ }
+ if(!strcmp(recvbuf, "print_markers")) {
+ print_markers();
+ }
+ else if(!strcmp(recvbuf, "trace_setup")) {
+ DBG("trace setup");
- if(!strcmp(recvbuf, "print_markers")) {
- print_markers();
+ result = ltt_trace_setup(trace_name);
+ if(result < 0) {
+ ERR("ltt_trace_setup failed");
+ return;
}
- else if(!strcmp(recvbuf, "trace_setup")) {
- DBG("trace setup");
-
- result = ltt_trace_setup(trace_name);
- if(result < 0) {
- ERR("ltt_trace_setup failed");
- return;
- }
-
- result = ltt_trace_set_type(trace_name, trace_type);
- if(result < 0) {
- ERR("ltt_trace_set_type failed");
- return;
- }
+
+ result = ltt_trace_set_type(trace_name, trace_type);
+ if(result < 0) {
+ ERR("ltt_trace_set_type failed");
+ return;
}
- else if(!strcmp(recvbuf, "trace_alloc")) {
- DBG("trace alloc");
-
- result = ltt_trace_alloc(trace_name);
- if(result < 0) {
- ERR("ltt_trace_alloc failed");
- return;
- }
+ }
+ else if(!strcmp(recvbuf, "trace_alloc")) {
+ DBG("trace alloc");
+
+ result = ltt_trace_alloc(trace_name);
+ if(result < 0) {
+ ERR("ltt_trace_alloc failed");
+ return;
}
- else if(!strcmp(recvbuf, "trace_start")) {
- DBG("trace start");
-
- result = ltt_trace_start(trace_name);
- if(result < 0) {
- ERR("ltt_trace_start failed");
- return;
- }
+ }
+ else if(!strcmp(recvbuf, "trace_start")) {
+ DBG("trace start");
+
+ result = ltt_trace_start(trace_name);
+ if(result < 0) {
+ ERR("ltt_trace_start failed");
+ continue;
}
- else if(!strcmp(recvbuf, "trace_stop")) {
- DBG("trace stop");
-
- result = ltt_trace_stop(trace_name);
- if(result < 0) {
- ERR("ltt_trace_stop failed");
- return;
- }
+ }
+ else if(!strcmp(recvbuf, "trace_stop")) {
+ DBG("trace stop");
+
+ result = ltt_trace_stop(trace_name);
+ if(result < 0) {
+ ERR("ltt_trace_stop failed");
+ return;
}
- else if(!strcmp(recvbuf, "trace_destroy")) {
+ }
+ else if(!strcmp(recvbuf, "trace_destroy")) {
- DBG("trace destroy");
+ DBG("trace destroy");
- result = ltt_trace_destroy(trace_name);
- if(result < 0) {
- ERR("ltt_trace_destroy failed");
- return;
- }
+ result = ltt_trace_destroy(trace_name);
+ if(result < 0) {
+ ERR("ltt_trace_destroy failed");
+ return;
}
}
- next_conn:;
+
+ free(recvbuf);
}
}
}
}
-/* The signal handler itself. */
+/* The signal handler itself. Signals must be setup so there cannot be
+ nested signals. */
void sighandler(int sig)
{
+ static char have_listener = 0;
DBG("sighandler");
- create_listener();
+
+ if(!have_listener) {
+ create_listener();
+ have_listener = 1;
+ }
}
/* Called by the app signal handler to chain it to us. */
static int init_socket(void)
{
- int result;
- int fd;
- char pidstr[6];
- int pidlen;
-
- struct sockaddr_un addr;
-
- result = fd = socket(PF_UNIX, SOCK_DGRAM, 0);
- if(result == -1) {
- PERROR("socket");
- return -1;
- }
-
- addr.sun_family = AF_UNIX;
-
- result = snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%d", SOCKETDIR, mypid);
- if(result >= UNIX_PATH_MAX) {
- ERR("string overflow allocating socket name");
- goto close_sock;
- }
- //DBG("opening socket at %s", addr.sun_path);
-
- result = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
- if(result == -1) {
- PERROR("bind");
- goto close_sock;
- }
-
- strcpy(mysocketfile, addr.sun_path);
-
- pfd = fd;
- return 0;
-
- close_sock:
- close(fd);
-
- return -1;
+ return ustcomm_init_app(getpid(), &ustcomm_app);
}
static void destroy_socket(void)
}
/* FIXME: wait for the consumer to be done */
- sleep(3);
+ sleep(1);
destroy_socket();
}
+#define _GNU_SOURCE
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+
+#include "ustcomm.h"
+#include "localerr.h"
#define UNIX_PATH_MAX 108
#define SOCK_DIR "/tmp/socks"
#define UST_SIGNAL SIGIO
+#define MSG_MAX 1000
+
static void signal_process(pid_t pid)
{
int result;
sleep(1);
}
-int send_message(pid_t pid, const char *msg, const char *reply)
+/* pid: the pid of the trace process that must receive the msg
+ msg: pointer to a null-terminated message to send
+ reply: location where to put the null-terminated string of the reply;
+ it must be free'd after usage
+ */
+
+int send_message(pid_t pid, const char *msg, char **reply)
{
int fd;
int result;
struct sockaddr_un addr;
- char *buf;
result = fd = socket(PF_UNIX, SOCK_DGRAM, 0);
if(result == -1) {
perror("socket");
- return 1;
+ return -1;
}
addr.sun_family = AF_UNIX;
result = snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%d", SOCK_DIR, pid);
if(result >= UNIX_PATH_MAX) {
fprintf(stderr, "string overflow allocating socket name");
- return 1;
+ return -1;
}
- asprintf(&buf, "%s\n", msg);
-
signal_process(pid);
- result = sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&addr, sizeof(addr));
+ result = sendto(fd, msg, strlen(msg), 0, (struct sockaddr *)&addr, sizeof(addr));
if(result == -1) {
perror("sendto");
- return 1;
+ return -1;
}
- free(buf);
+ if(!reply)
+ return 0;
+
+ *reply = (char *) malloc(MSG_MAX+1);
+ result = recvfrom(fd, *reply, MSG_MAX, 0, NULL, NULL);
+ if(result == -1) {
+ perror("recvfrom");
+ return -1;
+ }
+
+ (*reply)[result] = '\0';
return 0;
}
+int ustcomm_app_recv_message(struct ustcomm_app *app, char **msg)
+{
+ int fd;
+ int result;
+ struct sockaddr_un addr;
+
+ *msg = (char *) malloc(MSG_MAX+1);
+ result = recvfrom(app->fd, *msg, MSG_MAX, 0, NULL, NULL);
+ if(result == -1) {
+ PERROR("recvfrom");
+ return -1;
+ }
+
+ DBG("ustcomm_app_recv_message: result is %d, message[1] is %hhd", result, (*msg)[1]);
+ (*msg)[result] = '\0';
+ return 0;
+}
+
+static int init_named_socket(char *name, char **path_out)
+{
+ int result;
+ int fd;
+
+ struct sockaddr_un addr;
+
+ result = fd = socket(PF_UNIX, SOCK_DGRAM, 0);
+ if(result == -1) {
+ PERROR("socket");
+ return -1;
+ }
+
+ addr.sun_family = AF_UNIX;
+
+ strncpy(addr.sun_path, name, UNIX_PATH_MAX);
+ addr.sun_path[UNIX_PATH_MAX-1] = '\0';
+
+ result = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
+ if(result == -1) {
+ PERROR("bind");
+ goto close_sock;
+ }
+
+ if(path_out)
+ *path_out = strdupa(addr.sun_path);
+
+ return fd;
+
+ close_sock:
+ close(fd);
+
+ return -1;
+}
+
+int ustcomm_init_app(pid_t pid, struct ustcomm_app *handle)
+{
+ int result;
+ char *name;
+
+ result = asprintf(&name, "%s/%d", SOCK_DIR, (int)pid);
+ if(result >= UNIX_PATH_MAX) {
+ ERR("string overflow allocating socket name");
+ return -1;
+ }
+
+ handle->fd = init_named_socket(name, &handle->socketpath);
+ if(handle->fd < 0) {
+ goto free_name;
+ }
+ free(name);
+
+ return 0;
+
+free_name:
+ free(name);
+ return -1;
+}
+
+int ustcomm_init_ustd(struct ustcomm_ustd *handle)
+{
+ handle->fd = init_named_socket("ustd", &handle->socketpath);
+ if(handle->fd < 0)
+ return handle->fd;
+
+ return 0;
+}