X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=libustcomm%2Fustcomm.c;h=dcf8cd88d7a1694d2831267fe343da7df5d2449c;hb=f446d1cbf3f3b2e722b68b6bcbee2359d0f3d8e5;hp=fe8fea2d66c2c46b8fd30252c3357fba443cb95e;hpb=7200aa31f2b51c2f6051df61eeab2f471636cd27;p=ust.git diff --git a/libustcomm/ustcomm.c b/libustcomm/ustcomm.c index fe8fea2..dcf8cd8 100644 --- a/libustcomm/ustcomm.c +++ b/libustcomm/ustcomm.c @@ -18,6 +18,7 @@ /* API used by UST components to communicate with each other via sockets. */ #define _GNU_SOURCE +#include #include #include #include @@ -113,7 +114,7 @@ static struct sockaddr_un * create_sock_addr(const char *name, } struct ustcomm_sock * ustcomm_init_sock(int fd, int epoll_fd, - struct list_head *list) + struct cds_list_head *list) { struct epoll_event ev; struct ustcomm_sock *sock; @@ -136,9 +137,9 @@ struct ustcomm_sock * ustcomm_init_sock(int fd, int epoll_fd, sock->epoll_fd = epoll_fd; if (list) { - list_add(&sock->list, list); + cds_list_add(&sock->list, list); } else { - INIT_LIST_HEAD(&sock->list); + CDS_INIT_LIST_HEAD(&sock->list); } return sock; @@ -146,7 +147,7 @@ struct ustcomm_sock * ustcomm_init_sock(int fd, int epoll_fd, void ustcomm_del_sock(struct ustcomm_sock *sock, int keep_in_epoll) { - list_del(&sock->list); + cds_list_del(&sock->list); if (!keep_in_epoll) { if (epoll_ctl(sock->epoll_fd, EPOLL_CTL_DEL, sock->fd, NULL) == -1) { PERROR("epoll_ctl: failed to delete socket"); @@ -371,7 +372,7 @@ int ustcomm_recv_fd(int sock, if (peek_header.size && data) { if (peek_header.size < 0 || peek_header.size > USTCOMM_DATA_SIZE) { - ERR("big peek header! %d", peek_header.size); + ERR("big peek header! %ld", peek_header.size); return 0; } @@ -533,6 +534,21 @@ close_sock: return -1; } +/* Returns the current users socket directory, must be freed */ +char *ustcomm_user_sock_dir(void) +{ + int result; + char *sock_dir = NULL; + + result = asprintf(&sock_dir, "%s%s", USER_SOCK_DIR, + cuserid(NULL)); + if (result < 0) { + ERR("string overflow allocating directory name"); + return NULL; + } + + return sock_dir; +} /* Open a connection to a traceable app. * @@ -541,51 +557,117 @@ close_sock: * -1: error */ -int ustcomm_connect_app(pid_t pid, int *app_fd) +static int connect_app_non_root(pid_t pid, int *app_fd) { int result; int retval = 0; - char *name; + char *dir_name, *sock_name; + + dir_name = ustcomm_user_sock_dir(); + if (!dir_name) + return -ENOMEM; - result = asprintf(&name, "%s/%d", SOCK_DIR, pid); + result = asprintf(&sock_name, "%s/%d", dir_name, pid); if (result < 0) { ERR("failed to allocate socket name"); - return -1; + retval = -1; + goto free_dir_name; } - result = ustcomm_connect_path(name, app_fd); + result = ustcomm_connect_path(sock_name, app_fd); if (result < 0) { ERR("failed to connect to app"); retval = -1; + goto free_sock_name; } - free(name); +free_sock_name: + free(sock_name); +free_dir_name: + free(dir_name); return retval; } -int ensure_dir_exists(const char *dir) + + +static int connect_app_root(pid_t pid, int *app_fd) +{ + DIR *tmp_dir; + struct dirent *dirent; + char *sock_name; + int result; + + tmp_dir = opendir(USER_TMP_DIR); + if (!tmp_dir) { + return -1; + } + + while ((dirent = readdir(tmp_dir))) { + if (!strncmp(dirent->d_name, USER_SOCK_DIR_BASE, + strlen(USER_SOCK_DIR_BASE))) { + + if (asprintf(&sock_name, USER_TMP_DIR "/%s/%u", + dirent->d_name, pid) < 0) { + goto close_tmp_dir; + } + + result = ustcomm_connect_path(sock_name, app_fd); + + free(sock_name); + + if (result == 0) { + goto close_tmp_dir; + } + } + } + +close_tmp_dir: + closedir(tmp_dir); + + return result; +} + +int ustcomm_connect_app(pid_t pid, int *app_fd) +{ + *app_fd = 0; + + if (geteuid()) { + return connect_app_non_root(pid, app_fd); + } else { + return connect_app_root(pid, app_fd); + } + +} + +int ensure_dir_exists(const char *dir, mode_t mode) { struct stat st; int result; - if(!strcmp(dir, "")) + if (!strcmp(dir, "")) return -1; result = stat(dir, &st); - if(result == -1 && errno != ENOENT) { + if (result < 0 && errno != ENOENT) { return -1; - } - else if(result == -1) { + } else if (result < 0) { /* ENOENT */ int result; - /* mkdir mode to 0777 */ - result = mkdir_p(dir, S_IRWXU | S_IRWXG | S_IRWXO); + result = mkdir_p(dir, mode); if(result != 0) { ERR("executing in recursive creation of directory %s", dir); return -1; } + } else { + if (st.st_mode != mode) { + result = chmod(dir, mode); + if (result < 0) { + ERR("couldn't set directory mode on %s", dir); + return -1; + } + } } return 0; @@ -621,13 +703,54 @@ char * ustcomm_restore_ptr(char *ptr, char *data_field, int data_field_size) return data_field + (long)ptr; } +int ustcomm_pack_single_field(struct ustcomm_header *header, + struct ustcomm_single_field *single_field, + const char *string) +{ + int offset = 0; + + single_field->field = ustcomm_print_data(single_field->data, + sizeof(single_field->data), + &offset, + string); + + if (single_field->field == USTCOMM_POISON_PTR) { + return -ENOMEM; + } + + header->size = COMPUTE_MSG_SIZE(single_field, offset); + + return 0; +} + +int ustcomm_unpack_single_field(struct ustcomm_single_field *single_field) +{ + single_field->field = ustcomm_restore_ptr(single_field->field, + single_field->data, + sizeof(single_field->data)); + if (!single_field->field) { + return -EINVAL; + } + + return 0; +} int ustcomm_pack_channel_info(struct ustcomm_header *header, struct ustcomm_channel_info *ch_inf, + const char *trace, const char *channel) { int offset = 0; + ch_inf->trace = ustcomm_print_data(ch_inf->data, + sizeof(ch_inf->data), + &offset, + trace); + + if (ch_inf->trace == USTCOMM_POISON_PTR) { + return -ENOMEM; + } + ch_inf->channel = ustcomm_print_data(ch_inf->data, sizeof(ch_inf->data), &offset, @@ -645,6 +768,13 @@ int ustcomm_pack_channel_info(struct ustcomm_header *header, int ustcomm_unpack_channel_info(struct ustcomm_channel_info *ch_inf) { + ch_inf->trace = ustcomm_restore_ptr(ch_inf->trace, + ch_inf->data, + sizeof(ch_inf->data)); + if (!ch_inf->trace) { + return -EINVAL; + } + ch_inf->channel = ustcomm_restore_ptr(ch_inf->channel, ch_inf->data, sizeof(ch_inf->data)); @@ -657,11 +787,21 @@ int ustcomm_unpack_channel_info(struct ustcomm_channel_info *ch_inf) int ustcomm_pack_buffer_info(struct ustcomm_header *header, struct ustcomm_buffer_info *buf_inf, + const char *trace, const char *channel, int channel_cpu) { int offset = 0; + buf_inf->trace = ustcomm_print_data(buf_inf->data, + sizeof(buf_inf->data), + &offset, + trace); + + if (buf_inf->trace == USTCOMM_POISON_PTR) { + return -ENOMEM; + } + buf_inf->channel = ustcomm_print_data(buf_inf->data, sizeof(buf_inf->data), &offset, @@ -681,6 +821,13 @@ int ustcomm_pack_buffer_info(struct ustcomm_header *header, int ustcomm_unpack_buffer_info(struct ustcomm_buffer_info *buf_inf) { + buf_inf->trace = ustcomm_restore_ptr(buf_inf->trace, + buf_inf->data, + sizeof(buf_inf->data)); + if (!buf_inf->trace) { + return -EINVAL; + } + buf_inf->channel = ustcomm_restore_ptr(buf_inf->channel, buf_inf->data, sizeof(buf_inf->data)); @@ -693,11 +840,22 @@ int ustcomm_unpack_buffer_info(struct ustcomm_buffer_info *buf_inf) int ustcomm_pack_marker_info(struct ustcomm_header *header, struct ustcomm_marker_info *marker_inf, + const char *trace, const char *channel, const char *marker) { int offset = 0; + marker_inf->trace = ustcomm_print_data(marker_inf->data, + sizeof(marker_inf->data), + &offset, + trace); + + if (marker_inf->trace == USTCOMM_POISON_PTR) { + return -ENOMEM; + } + + marker_inf->channel = ustcomm_print_data(marker_inf->data, sizeof(marker_inf->data), &offset, @@ -724,6 +882,13 @@ int ustcomm_pack_marker_info(struct ustcomm_header *header, int ustcomm_unpack_marker_info(struct ustcomm_marker_info *marker_inf) { + marker_inf->trace = ustcomm_restore_ptr(marker_inf->trace, + marker_inf->data, + sizeof(marker_inf->data)); + if (!marker_inf->trace) { + return -EINVAL; + } + marker_inf->channel = ustcomm_restore_ptr(marker_inf->channel, marker_inf->data, sizeof(marker_inf->data)); @@ -741,37 +906,3 @@ int ustcomm_unpack_marker_info(struct ustcomm_marker_info *marker_inf) return 0; } -int ustcomm_pack_sock_path(struct ustcomm_header *header, - struct ustcomm_sock_path *sock_path_inf, - const char *socket_path) -{ - int offset = 0; - - sock_path_inf->sock_path = - ustcomm_print_data(sock_path_inf->data, - sizeof(sock_path_inf->data), - &offset, - socket_path); - - if (sock_path_inf->sock_path == USTCOMM_POISON_PTR) { - return -ENOMEM; - } - - header->size = COMPUTE_MSG_SIZE(sock_path_inf, offset); - - return 0; -} - -int ustcomm_unpack_sock_path(struct ustcomm_sock_path *sock_path_inf) -{ - sock_path_inf->sock_path = - ustcomm_restore_ptr(sock_path_inf->sock_path, - sock_path_inf->data, - sizeof(sock_path_inf->data)); - if (!sock_path_inf->sock_path) { - return -EINVAL; - } - - return 0; -} -