#include <getopt.h>
#include "ustd.h"
-#include "localerr.h"
+#include "usterr.h"
#include "ustcomm.h"
-#include "share.h"
/* return value: 0 = subbuffer is finished, it won't produce data anymore
* 1 = got subbuffer successfully
char *sock_path=NULL;
char *trace_path=NULL;
+int daemon_mode = 0;
+char *pidfile = NULL;
/* Number of active buffers and the mutex to protect it. */
int active_buffers = 0;
result = sscanf(received_msg, "%d %d", &buf->shmid, &buf->bufstruct_shmid);
if(result != 2) {
- ERR("unable to parse response to get_shmid");
+ ERR("unable to parse response to get_shmid (\"%s\")", received_msg);
return NULL;
}
free(received_msg);
}
free(tmp);
- asprintf(&tmp, "%s/%u_%lld/%s_0", trace_path, buf->pid, buf->pidunique, buf->name);
+ asprintf(&tmp, "%s/%u_%lld/%s", trace_path, buf->pid, buf->pidunique, buf->name);
result = fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 00600);
if(result == -1) {
PERROR("open");
return buf;
}
+int write_current_subbuffer(struct buffer_info *buf)
+{
+ int result;
+
+ void *subbuf_mem = buf->mem + (buf->consumed_old & (buf->n_subbufs * buf->subbuf_size-1));
+
+ size_t cur_sb_size = subbuffer_data_size(subbuf_mem);
+
+ result = patient_write(buf->file_fd, subbuf_mem, cur_sb_size);
+ if(result == -1) {
+ PERROR("write");
+ /* FIXME: maybe drop this trace */
+ return 0;
+ }
+
+ return 0;
+}
+
int consumer_loop(struct buffer_info *buf)
{
int result;
}
/* write data to file */
- result = patient_write(buf->file_fd, buf->mem + (buf->consumed_old & (buf->n_subbufs * buf->subbuf_size-1)), buf->subbuf_size);
- if(result == -1) {
- PERROR("write");
- /* FIXME: maybe drop this trace */
- }
+ write_current_subbuffer(buf);
+ /* FIXME: handle return value? */
/* put the subbuffer */
/* FIXME: we actually should unput the buffer before consuming... */
fprintf(stderr, "Usage:\nustd OPTIONS\n\nOptions:\n"
"\t-h\t\tDisplay this usage.\n"
"\t-o DIR\t\tSpecify the directory where to output the traces.\n"
- "\t-s PATH\t\tSpecify the path to use for the daemon socket.\n");
+ "\t-s PATH\t\tSpecify the path to use for the daemon socket.\n"
+ "\t-d\t\tStart as a daemon.\n"
+ "\t--pidfile FILE\tWrite the PID in this file (when using -d).\n");
}
int parse_args(int argc, char **argv)
while (1) {
int option_index = 0;
static struct option long_options[] = {
+ {"pidfile", 1, 0, 'p'},
{"help", 0, 0, 'h'},
{"version", 0, 0, 'V'},
{0, 0, 0, 0}
};
- c = getopt_long(argc, argv, "hs:o:", long_options, &option_index);
+ c = getopt_long(argc, argv, "hs:o:d", long_options, &option_index);
if (c == -1)
break;
return -1;
}
break;
+ case 'd':
+ daemon_mode = 1;
+ break;
+ case 'p':
+ pidfile = strdup(optarg);
+ break;
case 'h':
usage();
exit(0);
terminate_req = 1;
}
-int main(int argc, char **argv)
+static int write_pidfile(const char *file_name, pid_t pid)
+{
+ FILE *pidfp;
+
+ pidfp = fopen(file_name, "w");
+ if(!pidfp) {
+ PERROR("fopen (%s)", pidfile);
+ WARN("killing child process");
+ return -1;
+ }
+
+ fprintf(pidfp, "%d\n", pid);
+
+ fclose(pidfp);
+
+ return 0;
+}
+
+int start_ustd(int fd)
{
struct ustcomm_ustd ustd;
int result;
return 1;
}
- result = parse_args(argc, argv);
- if(result == -1) {
- exit(1);
- }
-
result = ustcomm_init_ustd(&ustd, sock_path);
if(result == -1) {
ERR("failed to initialize socket");
return 1;
}
+ /* Write pidfile */
+ if(pidfile) {
+ result = write_pidfile(pidfile, getpid());
+ if(result == -1) {
+ ERR("failed to write pidfile");
+ return 1;
+ }
+ }
+
+ /* Notify parent that we are successfully started. */
+ if(fd != -1) {
+ /* write any one character */
+ result = write(fd, "!", 1);
+ if(result == -1) {
+ PERROR("write");
+ return -1;
+ }
+ if(result != 1) {
+ ERR("Problem sending confirmation of daemon start to parent");
+ return -1;
+ }
+ result = close(fd);
+ if(result == -1) {
+ PERROR("close");
+ }
+ }
+
/* app loop */
for(;;) {
char *recvbuf;
return 0;
}
+
+int start_ustd_daemon()
+{
+ int result;
+ int fd[2];
+ pid_t child_pid;
+
+ result = pipe(fd);
+
+ result = child_pid = fork();
+ if(result == -1) {
+ PERROR("fork");
+ return -1;
+ }
+ else if(result == 0) {
+ return start_ustd(fd[1]);
+ }
+ else {
+ char buf;
+
+ result = read(fd[0], &buf, 1);
+ if(result == -1) {
+ PERROR("read");
+ return -1;
+ }
+ if(result != 1) {
+ ERR("did not receive valid confirmation that the daemon is started");
+ return -1;
+ }
+
+ result = close(fd[0]);
+ if(result == -1) {
+ PERROR("close");
+ }
+
+ DBG("The daemon is now successfully started");
+ }
+
+ /* Wait for confirmation that the server is ready. */
+
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int result;
+
+ result = parse_args(argc, argv);
+ if(result == -1) {
+ exit(1);
+ }
+
+ if(daemon_mode) {
+ result = start_ustd_daemon();
+ }
+ else {
+ result = start_ustd(-1);
+ }
+
+ return result;
+}