.type = LTTNG_CONSUMER_KERNEL,
.err_unix_sock_path = DEFAULT_KCONSUMERD_ERR_SOCK_PATH,
.cmd_unix_sock_path = DEFAULT_KCONSUMERD_CMD_SOCK_PATH,
+ .err_sock = -1,
+ .cmd_sock = -1,
};
static struct consumer_data ustconsumer64_data = {
.type = LTTNG_CONSUMER64_UST,
.err_unix_sock_path = DEFAULT_USTCONSUMERD64_ERR_SOCK_PATH,
.cmd_unix_sock_path = DEFAULT_USTCONSUMERD64_CMD_SOCK_PATH,
+ .err_sock = -1,
+ .cmd_sock = -1,
};
static struct consumer_data ustconsumer32_data = {
.type = LTTNG_CONSUMER32_UST,
.err_unix_sock_path = DEFAULT_USTCONSUMERD32_ERR_SOCK_PATH,
.cmd_unix_sock_path = DEFAULT_USTCONSUMERD32_CMD_SOCK_PATH,
+ .err_sock = -1,
+ .cmd_sock = -1,
};
static int dispatch_thread_exit;
static char wait_shm_path[PATH_MAX];
/* Sockets and FDs */
-static int client_sock;
-static int apps_sock;
-static int kernel_tracer_fd;
-static int kernel_poll_pipe[2];
+static int client_sock = -1;
+static int apps_sock = -1;
+static int kernel_tracer_fd = -1;
+static int kernel_poll_pipe[2] = { -1, -1 };
/*
* Quit pipe for all threads. This permits a single cancellation point
* for all threads when receiving an event on the pipe.
*/
-static int thread_quit_pipe[2];
+static int thread_quit_pipe[2] = { -1, -1 };
/*
* This pipe is used to inform the thread managing application communication
* that a command is queued and ready to be processed.
*/
-static int apps_cmd_pipe[2];
+static int apps_cmd_pipe[2] = { -1, -1 };
/* Pthread, Mutexes and Semaphores */
static pthread_t apps_thread;
ret = pipe2(thread_quit_pipe, O_CLOEXEC);
if (ret < 0) {
- perror("thread quit pipe");
+ PERROR("thread quit pipe");
goto error;
}
* If a custom kernel consumer was registered, close the socket before
* tearing down the complete kernel session structure
*/
- if (session->kernel_session->consumer_fd != kconsumer_data.cmd_sock) {
+ if (kconsumer_data.cmd_sock >= 0 &&
+ session->kernel_session->consumer_fd != kconsumer_data.cmd_sock) {
lttcomm_close_unix_sock(session->kernel_session->consumer_fd);
}
*/
static void cleanup(void)
{
- int ret;
+ int ret, i;
char *cmd;
struct ltt_session *sess, *stmp;
if (is_root && !opt_no_kernel) {
DBG2("Closing kernel fd");
- close(kernel_tracer_fd);
+ if (kernel_tracer_fd >= 0) {
+ ret = close(kernel_tracer_fd);
+ if (ret) {
+ PERROR("close");
+ }
+ }
DBG("Unloading kernel modules");
modprobe_remove_lttng_all();
}
- close(thread_quit_pipe[0]);
- close(thread_quit_pipe[1]);
+ /*
+ * Closing all pipes used for communication between threads.
+ */
+ for (i = 0; i < 2; i++) {
+ if (kernel_poll_pipe[i] >= 0) {
+ ret = close(kernel_poll_pipe[i]);
+ if (ret) {
+ PERROR("close");
+ }
+
+ }
+ }
+ for (i = 0; i < 2; i++) {
+ if (thread_quit_pipe[i] >= 0) {
+ ret = close(thread_quit_pipe[i]);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ }
+ for (i = 0; i < 2; i++) {
+ if (apps_cmd_pipe[i] >= 0) {
+ ret = close(apps_cmd_pipe[i]);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ }
/* <fun> */
DBG("%c[%d;%dm*** assert failed :-) *** ==> %c[%dm%c[%d;%dm"
DBG("Sending channel %d to consumer", lkm.u.channel.channel_key);
ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm));
if (ret < 0) {
- perror("send consumer channel");
+ PERROR("send consumer channel");
goto error;
}
DBG("Sending stream %d to consumer", lkm.u.stream.stream_key);
ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm));
if (ret < 0) {
- perror("send consumer stream");
+ PERROR("send consumer stream");
goto error;
}
ret = lttcomm_send_fds_unix_sock(sock, &stream->fd, 1);
if (ret < 0) {
- perror("send consumer stream ancillary data");
+ PERROR("send consumer stream ancillary data");
goto error;
}
}
DBG("Sending metadata stream fd");
- /* Extra protection. It's NOT supposed to be set to 0 at this point */
- if (session->consumer_fd == 0) {
+ /* Extra protection. It's NOT supposed to be set to -1 at this point */
+ if (session->consumer_fd < 0) {
session->consumer_fd = consumer_data->cmd_sock;
}
- if (session->metadata_stream_fd != 0) {
+ if (session->metadata_stream_fd >= 0) {
/* Send metadata channel fd */
lkm.cmd_type = LTTNG_CONSUMER_ADD_CHANNEL;
lkm.u.channel.channel_key = session->metadata->fd;
DBG("Sending metadata channel %d to consumer", lkm.u.stream.stream_key);
ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm));
if (ret < 0) {
- perror("send consumer channel");
+ PERROR("send consumer channel");
goto error;
}
DBG("Sending metadata stream %d to consumer", lkm.u.stream.stream_key);
ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm));
if (ret < 0) {
- perror("send consumer stream");
+ PERROR("send consumer stream");
goto error;
}
ret = lttcomm_send_fds_unix_sock(sock, &session->metadata_stream_fd, 1);
if (ret < 0) {
- perror("send consumer stream");
+ PERROR("send consumer stream");
goto error;
}
}
cmd_ctx->llm = zmalloc(sizeof(struct lttcomm_lttng_msg) + buf_size);
if (cmd_ctx->llm == NULL) {
- perror("zmalloc");
+ PERROR("zmalloc");
ret = -ENOMEM;
goto error;
}
continue;
}
- /* This is not suppose to be 0 but this is an extra security check */
- if (session->kernel_session->consumer_fd == 0) {
+ /* This is not suppose to be -1 but this is an extra security check */
+ if (session->kernel_session->consumer_fd < 0) {
session->kernel_session->consumer_fd = consumer_data->cmd_sock;
}
{
struct ltt_session *sess, *stmp;
+ session_lock_list();
+
/* For all tracing session(s) */
cds_list_for_each_entry_safe(sess, stmp, &session_list_ptr->head, list) {
+ session_lock(sess);
if (sess->ust_session) {
ust_app_global_update(sess->ust_session, app_sock);
}
+ session_unlock(sess);
}
+
+ session_unlock_list();
}
/*
ret = create_thread_poll_set(&events, 2);
if (ret < 0) {
- goto error;
+ goto error_poll_create;
}
ret = lttng_poll_add(&events, kernel_poll_pipe[0], LPOLLIN);
lttng_poll_reset(&events);
/* Poll infinite value of time */
+ restart:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
goto error;
} else if (ret == 0) {
/* Should not happen since timeout is infinite */
}
error:
- DBG("Kernel thread dying");
- close(kernel_poll_pipe[0]);
- close(kernel_poll_pipe[1]);
-
lttng_poll_clean(&events);
-
+error_poll_create:
+ DBG("Kernel thread dying");
return NULL;
}
*/
static void *thread_manage_consumer(void *data)
{
- int sock = 0, i, ret, pollfd;
+ int sock = -1, i, ret, pollfd;
uint32_t revents, nb_fd;
enum lttcomm_return_code code;
struct lttng_poll_event events;
ret = lttcomm_listen_unix_sock(consumer_data->err_sock);
if (ret < 0) {
- goto error;
+ goto error_listen;
}
/*
*/
ret = create_thread_poll_set(&events, 2);
if (ret < 0) {
- goto error;
+ goto error_poll;
}
ret = lttng_poll_add(&events, consumer_data->err_sock, LPOLLIN | LPOLLRDHUP);
nb_fd = LTTNG_POLL_GETNB(&events);
/* Inifinite blocking call, waiting for transmission */
+restart:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
goto error;
}
nb_fd = LTTNG_POLL_GETNB(&events);
/* Inifinite blocking call, waiting for transmission */
+restart_poll:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart_poll;
+ }
goto error;
}
ERR("consumer return code : %s", lttcomm_get_readable_code(-code));
error:
- DBG("consumer thread dying");
- close(consumer_data->err_sock);
- close(consumer_data->cmd_sock);
- close(sock);
+ if (consumer_data->err_sock >= 0) {
+ ret = close(consumer_data->err_sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ if (consumer_data->cmd_sock >= 0) {
+ ret = close(consumer_data->cmd_sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ if (sock >= 0) {
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
unlink(consumer_data->err_unix_sock_path);
unlink(consumer_data->cmd_unix_sock_path);
consumer_data->pid = 0;
lttng_poll_clean(&events);
+error_poll:
+error_listen:
+ DBG("consumer thread cleanup completed");
return NULL;
}
ret = create_thread_poll_set(&events, 2);
if (ret < 0) {
- goto error;
+ goto error_poll_create;
}
ret = lttng_poll_add(&events, apps_cmd_pipe[0], LPOLLIN | LPOLLRDHUP);
DBG("Apps thread polling on %d fds", nb_fd);
/* Inifinite blocking call, waiting for transmission */
+ restart:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
goto error;
}
/* Empty pipe */
ret = read(apps_cmd_pipe[0], &ust_cmd, sizeof(ust_cmd));
if (ret < 0 || ret < sizeof(ust_cmd)) {
- perror("read apps cmd pipe");
+ PERROR("read apps cmd pipe");
goto error;
}
/*
* We just need here to monitor the close of the UST
* socket and poll set monitor those by default.
+ * Listen on POLLIN (even if we never expect any
+ * data) to ensure that hangup wakes us.
*/
- ret = lttng_poll_add(&events, ust_cmd.sock, 0);
+ ret = lttng_poll_add(&events, ust_cmd.sock, LPOLLIN);
if (ret < 0) {
goto error;
}
}
error:
- DBG("Application communication apps dying");
- close(apps_cmd_pipe[0]);
- close(apps_cmd_pipe[1]);
-
lttng_poll_clean(&events);
-
+error_poll_create:
+ DBG("Application communication apps thread cleanup complete");
rcu_thread_offline();
rcu_unregister_thread();
return NULL;
ret = write(apps_cmd_pipe[1], ust_cmd,
sizeof(struct ust_command));
if (ret < 0) {
- perror("write apps cmd pipe");
+ PERROR("write apps cmd pipe");
if (errno == EBADF) {
/*
* We can't inform the application thread to process
*/
static void *thread_registration_apps(void *data)
{
- int sock = 0, i, ret, pollfd;
+ int sock = -1, i, ret, pollfd;
uint32_t revents, nb_fd;
struct lttng_poll_event events;
/*
ret = lttcomm_listen_unix_sock(apps_sock);
if (ret < 0) {
- goto error;
+ goto error_listen;
}
/*
*/
ret = create_thread_poll_set(&events, 2);
if (ret < 0) {
- goto error;
+ goto error_create_poll;
}
/* Add the application registration socket */
ret = lttng_poll_add(&events, apps_sock, LPOLLIN | LPOLLRDHUP);
if (ret < 0) {
- goto error;
+ goto error_poll_add;
}
/* Notify all applications to register */
nb_fd = LTTNG_POLL_GETNB(&events);
/* Inifinite blocking call, waiting for transmission */
+ restart:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
goto error;
}
/* Create UST registration command for enqueuing */
ust_cmd = zmalloc(sizeof(struct ust_command));
if (ust_cmd == NULL) {
- perror("ust command zmalloc");
+ PERROR("ust command zmalloc");
goto error;
}
sizeof(struct ust_register_msg));
if (ret < 0 || ret < sizeof(struct ust_register_msg)) {
if (ret < 0) {
- perror("lttcomm_recv_unix_sock register apps");
+ PERROR("lttcomm_recv_unix_sock register apps");
} else {
ERR("Wrong size received on apps register");
}
free(ust_cmd);
- close(sock);
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ sock = -1;
continue;
}
ust_cmd->sock = sock;
+ sock = -1;
DBG("UST registration received with pid:%d ppid:%d uid:%d"
" gid:%d sock:%d name:%s (version %d.%d)",
}
error:
- DBG("UST Registration thread dying");
-
/* Notify that the registration thread is gone */
notify_ust_apps(0);
- close(apps_sock);
- close(sock);
+ if (apps_sock >= 0) {
+ ret = close(apps_sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ if (sock >= 0) {
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
unlink(apps_unix_sock_path);
+error_poll_add:
lttng_poll_clean(&events);
+error_listen:
+error_create_poll:
+ DBG("UST Registration thread cleanup complete");
return NULL;
}
break;
}
default:
- perror("unknown consumer type");
+ PERROR("unknown consumer type");
exit(EXIT_FAILURE);
}
if (errno != 0) {
- perror("kernel start consumer exec");
+ PERROR("kernel start consumer exec");
}
exit(EXIT_FAILURE);
} else if (pid > 0) {
ret = pid;
} else {
- perror("start consumer fork");
+ PERROR("start consumer fork");
ret = -errno;
}
error:
error_version:
modprobe_remove_lttng_control();
- close(kernel_tracer_fd);
- kernel_tracer_fd = 0;
+ ret = close(kernel_tracer_fd);
+ if (ret) {
+ PERROR("close");
+ }
+ kernel_tracer_fd = -1;
return LTTCOMM_KERN_VERSION;
error_modules:
- close(kernel_tracer_fd);
+ ret = close(kernel_tracer_fd);
+ if (ret) {
+ PERROR("close");
+ }
error_open:
modprobe_remove_lttng_control();
error:
WARN("No kernel tracer available");
- kernel_tracer_fd = 0;
+ kernel_tracer_fd = -1;
return LTTCOMM_KERN_NA;
}
if (session->consumer_fds_sent == 0) {
/*
* Assign default kernel consumer socket if no consumer assigned to the
- * kernel session. At this point, it's NOT suppose to be 0 but this is
+ * kernel session. At this point, it's NOT supposed to be -1 but this is
* an extra security check.
*/
- if (session->consumer_fd == 0) {
+ if (session->consumer_fd < 0) {
session->consumer_fd = kconsumer_data.cmd_sock;
}
}
/* Set kernel consumer socket fd */
- if (kconsumer_data.cmd_sock) {
+ if (kconsumer_data.cmd_sock >= 0) {
session->kernel_session->consumer_fd = kconsumer_data.cmd_sock;
}
}
/* Open kernel metadata stream */
- if (ksession->metadata_stream_fd == 0) {
+ if (ksession->metadata_stream_fd < 0) {
ret = kernel_open_metadata_stream(ksession);
if (ret < 0) {
ERR("Kernel create metadata stream failed");
*/
ret = notify_thread_pipe(kernel_poll_pipe[1]);
if (ret < 0) {
- perror("write kernel poll pipe");
+ PERROR("write kernel poll pipe");
}
ret = session_destroy(session);
{
int ret = LTTCOMM_OK;
int need_tracing_session = 1;
+ int need_domain;
DBG("Processing client command %d", cmd_ctx->lsm->cmd_type);
- if (opt_no_kernel && cmd_ctx->lsm->domain.type == LTTNG_DOMAIN_KERNEL) {
+ switch (cmd_ctx->lsm->cmd_type) {
+ case LTTNG_CREATE_SESSION:
+ case LTTNG_DESTROY_SESSION:
+ case LTTNG_LIST_SESSIONS:
+ case LTTNG_LIST_DOMAINS:
+ case LTTNG_START_TRACE:
+ case LTTNG_STOP_TRACE:
+ need_domain = 0;
+ break;
+ default:
+ need_domain = 1;
+ }
+
+ if (opt_no_kernel && need_domain
+ && cmd_ctx->lsm->domain.type == LTTNG_DOMAIN_KERNEL) {
ret = LTTCOMM_KERN_NA;
goto error;
}
/* Commands that DO NOT need a session. */
switch (cmd_ctx->lsm->cmd_type) {
- case LTTNG_CALIBRATE:
case LTTNG_CREATE_SESSION:
+ case LTTNG_CALIBRATE:
case LTTNG_LIST_SESSIONS:
case LTTNG_LIST_TRACEPOINTS:
need_tracing_session = 0;
break;
}
+ if (!need_domain) {
+ goto skip_domain;
+ }
/*
* Check domain type for specific "pre-action".
*/
}
/* Kernel tracer check */
- if (kernel_tracer_fd == 0) {
+ if (kernel_tracer_fd == -1) {
/* Basically, load kernel tracer modules */
ret = init_kernel_tracer();
if (ret != 0) {
default:
break;
}
+skip_domain:
/*
* Check that the UID or GID match that of the tracing session.
session_lock_list();
nr_sessions = lttng_sessions_count(cmd_ctx->creds.uid, cmd_ctx->creds.gid);
- if (nr_sessions == 0) {
- ret = LTTCOMM_NO_SESSION;
- session_unlock_list();
- goto error;
- }
+
ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_session) * nr_sessions);
if (ret < 0) {
session_unlock_list();
*/
static void *thread_manage_clients(void *data)
{
- int sock = 0, ret, i, pollfd;
+ int sock = -1, ret, i, pollfd;
uint32_t revents, nb_fd;
struct command_ctx *cmd_ctx = NULL;
struct lttng_poll_event events;
nb_fd = LTTNG_POLL_GETNB(&events);
/* Inifinite blocking call, waiting for transmission */
+ restart:
ret = lttng_poll_wait(&events, -1);
if (ret < 0) {
+ /*
+ * Restart interrupted system call.
+ */
+ if (errno == EINTR) {
+ goto restart;
+ }
goto error;
}
/* Allocate context command to process the client request */
cmd_ctx = zmalloc(sizeof(struct command_ctx));
if (cmd_ctx == NULL) {
- perror("zmalloc cmd_ctx");
+ PERROR("zmalloc cmd_ctx");
goto error;
}
/* Allocate data buffer for reception */
cmd_ctx->lsm = zmalloc(sizeof(struct lttcomm_session_msg));
if (cmd_ctx->lsm == NULL) {
- perror("zmalloc cmd_ctx->lsm");
+ PERROR("zmalloc cmd_ctx->lsm");
goto error;
}
sizeof(struct lttcomm_session_msg), &cmd_ctx->creds);
if (ret <= 0) {
DBG("Nothing recv() from client... continuing");
- close(sock);
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ sock = -1;
free(cmd_ctx);
continue;
}
}
/* End of transmission */
- close(sock);
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ sock = -1;
clean_command_ctx(&cmd_ctx);
}
error:
DBG("Client thread dying");
unlink(client_unix_sock_path);
- close(client_sock);
- close(sock);
+ if (client_sock >= 0) {
+ ret = close(client_sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
+ if (sock >= 0) {
+ ret = close(sock);
+ if (ret) {
+ PERROR("close");
+ }
+ }
lttng_poll_clean(&events);
clean_command_ctx(&cmd_ctx);
ret = chmod(client_unix_sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (ret < 0) {
ERR("Set file permissions failed: %s", client_unix_sock_path);
- perror("chmod");
+ PERROR("chmod");
goto end;
}
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (ret < 0) {
ERR("Set file permissions failed: %s", apps_unix_sock_path);
- perror("chmod");
+ PERROR("chmod");
goto end;
}
* Set the tracing group gid onto the client socket.
*
* Race window between mkdir and chown is OK because we are going from more
- * permissive (root.root) to les permissive (root.tracing).
+ * permissive (root.root) to less permissive (root.tracing).
*/
static int set_permissions(char *rundir)
{
ret = chown(rundir, 0, gid);
if (ret < 0) {
ERR("Unable to set group on %s", rundir);
- perror("chown");
+ PERROR("chown");
+ }
+
+ /* Ensure tracing group can search the run dir */
+ ret = chmod(rundir, S_IRWXU | S_IXGRP | S_IXOTH);
+ if (ret < 0) {
+ ERR("Unable to set permissions on %s", rundir);
+ PERROR("chmod");
}
/* lttng client socket path */
ret = chown(client_unix_sock_path, 0, gid);
if (ret < 0) {
ERR("Unable to set group on %s", client_unix_sock_path);
- perror("chown");
+ PERROR("chown");
}
/* kconsumer error socket path */
ret = chown(kconsumer_data.err_unix_sock_path, 0, gid);
if (ret < 0) {
ERR("Unable to set group on %s", kconsumer_data.err_unix_sock_path);
- perror("chown");
+ PERROR("chown");
}
/* 64-bit ustconsumer error socket path */
ret = chown(ustconsumer64_data.err_unix_sock_path, 0, gid);
if (ret < 0) {
ERR("Unable to set group on %s", ustconsumer64_data.err_unix_sock_path);
- perror("chown");
+ PERROR("chown");
}
/* 32-bit ustconsumer compat32 error socket path */
ret = chown(ustconsumer32_data.err_unix_sock_path, 0, gid);
if (ret < 0) {
ERR("Unable to set group on %s", ustconsumer32_data.err_unix_sock_path);
- perror("chown");
+ PERROR("chown");
}
DBG("All permissions are set");
/*
* Create the pipe used to wake up the kernel thread.
+ * Closed in cleanup().
*/
static int create_kernel_poll_pipe(void)
{
/*
* Create the application command pipe to wake thread_manage_apps.
+ * Closed in cleanup().
*/
static int create_apps_cmd_pipe(void)
{
DBG3("Creating LTTng run directory: %s", rundir);
- ret = mkdir(rundir, S_IRWXU | S_IRWXG );
+ ret = mkdir(rundir, S_IRWXU);
if (ret < 0) {
if (errno != EEXIST) {
ERR("Unable to create %s", rundir);
DBG2("Creating consumer directory: %s", path);
- ret = mkdir(path, S_IRWXU | S_IRWXG);
+ ret = mkdir(path, S_IRWXU);
if (ret < 0) {
if (errno != EEXIST) {
ERR("Failed to create %s", path);
sigset_t sigset;
if ((ret = sigemptyset(&sigset)) < 0) {
- perror("sigemptyset");
+ PERROR("sigemptyset");
return ret;
}
sa.sa_mask = sigset;
sa.sa_flags = 0;
if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) {
- perror("sigaction");
+ PERROR("sigaction");
return ret;
}
if ((ret = sigaction(SIGINT, &sa, NULL)) < 0) {
- perror("sigaction");
+ PERROR("sigaction");
return ret;
}
if ((ret = sigaction(SIGPIPE, &sa, NULL)) < 0) {
- perror("sigaction");
+ PERROR("sigaction");
return ret;
}
ret = setrlimit(RLIMIT_NOFILE, &lim);
if (ret < 0) {
- perror("failed to set open files limit");
+ PERROR("failed to set open files limit");
}
}
if (opt_daemon) {
ret = daemon(0, 0);
if (ret < 0) {
- perror("daemon");
+ PERROR("daemon");
goto error;
}
}
ret = pthread_create(&client_thread, NULL,
thread_manage_clients, (void *) NULL);
if (ret != 0) {
- perror("pthread_create clients");
+ PERROR("pthread_create clients");
goto exit_client;
}
ret = pthread_create(&dispatch_thread, NULL,
thread_dispatch_ust_registration, (void *) NULL);
if (ret != 0) {
- perror("pthread_create dispatch");
+ PERROR("pthread_create dispatch");
goto exit_dispatch;
}
ret = pthread_create(®_apps_thread, NULL,
thread_registration_apps, (void *) NULL);
if (ret != 0) {
- perror("pthread_create registration");
+ PERROR("pthread_create registration");
goto exit_reg_apps;
}
ret = pthread_create(&apps_thread, NULL,
thread_manage_apps, (void *) NULL);
if (ret != 0) {
- perror("pthread_create apps");
+ PERROR("pthread_create apps");
goto exit_apps;
}
ret = pthread_create(&kernel_thread, NULL,
thread_manage_kernel, (void *) NULL);
if (ret != 0) {
- perror("pthread_create kernel");
+ PERROR("pthread_create kernel");
goto exit_kernel;
}
ret = pthread_join(kernel_thread, &status);
if (ret != 0) {
- perror("pthread_join");
+ PERROR("pthread_join");
goto error; /* join error, exit without cleanup */
}
exit_kernel:
ret = pthread_join(apps_thread, &status);
if (ret != 0) {
- perror("pthread_join");
+ PERROR("pthread_join");
goto error; /* join error, exit without cleanup */
}
exit_apps:
ret = pthread_join(reg_apps_thread, &status);
if (ret != 0) {
- perror("pthread_join");
+ PERROR("pthread_join");
goto error; /* join error, exit without cleanup */
}
exit_reg_apps:
ret = pthread_join(dispatch_thread, &status);
if (ret != 0) {
- perror("pthread_join");
+ PERROR("pthread_join");
goto error; /* join error, exit without cleanup */
}
exit_dispatch:
ret = pthread_join(client_thread, &status);
if (ret != 0) {
- perror("pthread_join");
+ PERROR("pthread_join");
goto error; /* join error, exit without cleanup */
}
ret = join_consumer_thread(&kconsumer_data);
if (ret != 0) {
- perror("join_consumer");
+ PERROR("join_consumer");
goto error; /* join error, exit without cleanup */
}