ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l) { ssize_t r; pa_assert(io); pa_assert(data); pa_assert(l); pa_assert(io->ofd >= 0); r = pa_write(io->ofd, data, l, &io->ofd_type); if ((size_t) r == l) return r; /* Fast path - we almost always successfully write everything */ if (r < 0) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) r = 0; else return r; } /* Partial write - let's get a notification when we can write more */ io->writable = io->hungup = false; enable_events(io); return r; }
static void callback(pa_mainloop_api* m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) { pa_iochannel *io = userdata; bool changed = false; pa_assert(m); pa_assert(e); pa_assert(fd >= 0); pa_assert(userdata); if ((f & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) && !io->hungup) { io->hungup = true; changed = true; } if ((f & PA_IO_EVENT_INPUT) && !io->readable) { io->readable = true; changed = true; pa_assert(e == io->input_event); } if ((f & PA_IO_EVENT_OUTPUT) && !io->writable) { io->writable = true; changed = true; pa_assert(e == io->output_event); } if (changed) { enable_events(io); if (io->callback) io->callback(io, io->userdata); } }
int create_live_local_session(char **session_path, char **session_name, int print) { int ret; char *name; int sudo = 0; ret = check_requirements(&sudo); name = random_session_name(); if (!name) { ret = -1; goto end; } ret = check_session_name(name, sudo); if (ret < 0) { goto end_free; } ret = live_local_session(name, sudo); if (ret < 0) { goto end_free; } ret = enable_events(name, sudo); if (ret < 0) { goto end_free; } ret = add_contexts(name, sudo); if (ret < 0) { goto end_free; } ret = start(name, sudo, 0, print); if (ret < 0) { goto end_free; } if (session_path) *session_path = live_path(name); if (session_name) { *session_name = name; goto end; } end_free: free(name); end: return ret; }
/* For more details on FD passing, check the cmsg(3) manpage * and IETF RFC #2292: "Advanced Sockets API for IPv6" */ ssize_t pa_iochannel_write_with_fds(pa_iochannel*io, const void*data, size_t l, int nfd, const int *fds) { ssize_t r; int *msgdata; struct msghdr mh; struct iovec iov; union { struct cmsghdr hdr; uint8_t data[CMSG_SPACE(sizeof(int) * MAX_ANCIL_DATA_FDS)]; } cmsg; pa_assert(io); pa_assert(data); pa_assert(l); pa_assert(io->ofd >= 0); pa_assert(fds); pa_assert(nfd > 0); pa_assert(nfd <= MAX_ANCIL_DATA_FDS); pa_zero(iov); iov.iov_base = (void*) data; iov.iov_len = l; pa_zero(cmsg); cmsg.hdr.cmsg_level = SOL_SOCKET; cmsg.hdr.cmsg_type = SCM_RIGHTS; msgdata = (int*) CMSG_DATA(&cmsg.hdr); memcpy(msgdata, fds, nfd * sizeof(int)); cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(int) * nfd); pa_zero(mh); mh.msg_iov = &iov; mh.msg_iovlen = 1; mh.msg_control = &cmsg; /* If we followed the example on the cmsg man page, we'd use * sizeof(cmsg.data) here, but if nfd < MAX_ANCIL_DATA_FDS, then the data * buffer is larger than needed, and the kernel doesn't like it if we set * msg_controllen to a larger than necessary value. The commit message for * commit 451d1d6762 contains a longer explanation. */ mh.msg_controllen = CMSG_SPACE(sizeof(int) * nfd); if ((r = sendmsg(io->ofd, &mh, MSG_NOSIGNAL)) >= 0) { io->writable = io->hungup = false; enable_events(io); } return r; }
ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l, const pa_creds *ucred) { ssize_t r; struct msghdr mh; struct iovec iov; union { struct cmsghdr hdr; uint8_t data[CMSG_SPACE(sizeof(struct ucred))]; } cmsg; struct ucred *u; pa_assert(io); pa_assert(data); pa_assert(l); pa_assert(io->ofd >= 0); pa_zero(iov); iov.iov_base = (void*) data; iov.iov_len = l; pa_zero(cmsg); cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(struct ucred)); cmsg.hdr.cmsg_level = SOL_SOCKET; cmsg.hdr.cmsg_type = SCM_CREDENTIALS; u = (struct ucred*) CMSG_DATA(&cmsg.hdr); u->pid = getpid(); if (ucred) { u->uid = ucred->uid; u->gid = ucred->gid; } else { u->uid = getuid(); u->gid = getgid(); } pa_zero(mh); mh.msg_iov = &iov; mh.msg_iovlen = 1; mh.msg_control = &cmsg; mh.msg_controllen = sizeof(cmsg); if ((r = sendmsg(io->ofd, &mh, MSG_NOSIGNAL)) >= 0) { io->writable = io->hungup = false; enable_events(io); } return r; }
ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) { ssize_t r; pa_assert(io); pa_assert(data); pa_assert(io->ifd >= 0); if ((r = pa_read(io->ifd, data, l, &io->ifd_type)) >= 0) { /* We also reset the hangup flag here to ensure that another * IO callback is triggered so that we will again call into * user code */ io->readable = io->hungup = false; enable_events(io); } return r; }
int create_local_session() { int ret; char *name; int sudo = 0; ret = check_requirements(&sudo); name = random_session_name(); if (!name) { ret = -1; goto end; } ret = check_session_name(name, sudo); if (ret < 0) { goto end_free; } ret = local_session(name, sudo); if (ret < 0) { goto end_free; } ret = enable_events(name, sudo); if (ret < 0) { goto end_free; } ret = add_contexts(name, sudo); if (ret < 0) { goto end_free; } ret = start(name, sudo, 1, 1); if (ret < 0) { goto end_free; } end_free: free(name); end: return ret; }
pa_iochannel* pa_iochannel_new(pa_mainloop_api*m, int ifd, int ofd) { pa_iochannel *io; pa_assert(m); pa_assert(ifd >= 0 || ofd >= 0); io = pa_xnew0(pa_iochannel, 1); io->ifd = ifd; io->ofd = ofd; io->mainloop = m; if (io->ifd >= 0) pa_make_fd_nonblock(io->ifd); if (io->ofd >= 0 && io->ofd != io->ifd) pa_make_fd_nonblock(io->ofd); enable_events(io); return io; }
scroll_bar:: scroll_bar( drawable_window& w, bar_orientation orientation ) : drawable(w), width_(16), b1(w,arrow_button::UP), b2(w,arrow_button::DOWN), slider(w,*this,&scroll_bar::on_slider_drag), ori(orientation), top_filler(w,*this,&scroll_bar::top_filler_down,&scroll_bar::top_filler_up), bottom_filler(w,*this,&scroll_bar::bottom_filler_down,&scroll_bar::bottom_filler_up), pos(0), max_pos(0), js(10), b1_timer(*this,&scroll_bar::b1_down_t), b2_timer(*this,&scroll_bar::b2_down_t), top_filler_timer(*this,&scroll_bar::top_filler_down_t), bottom_filler_timer(*this,&scroll_bar::bottom_filler_down_t) { if (ori == HORIZONTAL) { b1.set_direction(arrow_button::LEFT); b2.set_direction(arrow_button::RIGHT); } // don't show the slider when there is no place it can move. slider.hide(); set_length(100); b1.set_button_down_handler(*this,&scroll_bar::b1_down); b2.set_button_down_handler(*this,&scroll_bar::b2_down); b1.set_button_up_handler(*this,&scroll_bar::b1_up); b2.set_button_up_handler(*this,&scroll_bar::b2_up); b1.disable(); b2.disable(); enable_events(); }
/* * Add event to trace session */ int cmd_enable_events(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; char *session_name = NULL; const char *leftover = NULL; int event_type = -1; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); /* Default event type */ opt_event_type = LTTNG_EVENT_ALL; while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: SHOW_HELP(); goto end; case OPT_TRACEPOINT: opt_event_type = LTTNG_EVENT_TRACEPOINT; break; case OPT_PROBE: opt_event_type = LTTNG_EVENT_PROBE; break; case OPT_USERSPACE_PROBE: opt_event_type = LTTNG_EVENT_USERSPACE_PROBE; break; case OPT_FUNCTION: opt_event_type = LTTNG_EVENT_FUNCTION; break; case OPT_SYSCALL: opt_event_type = LTTNG_EVENT_SYSCALL; break; case OPT_USERSPACE: opt_userspace = 1; break; case OPT_LOGLEVEL: opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE; opt_loglevel = poptGetOptArg(pc); break; case OPT_LOGLEVEL_ONLY: opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE; opt_loglevel = poptGetOptArg(pc); break; case OPT_LIST_OPTIONS: list_cmd_options(stdout, long_options); goto end; case OPT_FILTER: break; case OPT_EXCLUDE: break; default: ret = CMD_UNDEFINED; goto end; } /* Validate event type. Multiple event type are not supported. */ if (event_type == -1) { event_type = opt_event_type; } else { if (event_type != opt_event_type) { ERR("Multiple event type not supported."); ret = CMD_ERROR; goto end; } } } ret = print_missing_or_multiple_domains( opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_python); if (ret) { ret = CMD_ERROR; goto end; } /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); if (!writer) { ret = -LTTNG_ERR_NOMEM; goto end; } /* Open command element */ ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_enable_event); if (ret) { ret = CMD_ERROR; goto end; } /* Open output element */ ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output); if (ret) { ret = CMD_ERROR; goto end; } } opt_event_list = (char*) poptGetArg(pc); if (opt_event_list == NULL && opt_enable_all == 0) { ERR("Missing event name(s).\n"); ret = CMD_ERROR; goto end; } leftover = poptGetArg(pc); if (leftover) { ERR("Unknown argument: %s", leftover); ret = CMD_ERROR; goto end; } if (!opt_session_name) { session_name = get_session_name(); if (session_name == NULL) { command_ret = CMD_ERROR; success = 0; goto mi_closing; } } else { session_name = opt_session_name; } command_ret = enable_events(session_name); if (command_ret) { success = 0; goto mi_closing; } mi_closing: /* Mi closing */ if (lttng_opt_mi) { /* Close output element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto end; } ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto end; } /* Command element close */ ret = mi_lttng_writer_command_close(writer); if (ret) { ret = CMD_ERROR; goto end; } } end: /* Mi clean-up */ if (writer && mi_lttng_writer_destroy(writer)) { /* Preserve original error code */ ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL; } if (opt_session_name == NULL) { free(session_name); } /* Overwrite ret if an error occurred in enable_events */ ret = command_ret ? command_ret : ret; poptFreeContext(pc); return ret; }
ssize_t pa_iochannel_read_with_ancil_data(pa_iochannel*io, void*data, size_t l, pa_cmsg_ancil_data *ancil_data) { ssize_t r; struct msghdr mh; struct iovec iov; union { struct cmsghdr hdr; uint8_t data[CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int) * MAX_ANCIL_DATA_FDS)]; } cmsg; pa_assert(io); pa_assert(data); pa_assert(l); pa_assert(io->ifd >= 0); pa_assert(ancil_data); if (io->ifd_type > 0) { ancil_data->creds_valid = false; ancil_data->nfd = 0; return pa_iochannel_read(io, data, l); } iov.iov_base = data; iov.iov_len = l; pa_zero(mh); mh.msg_iov = &iov; mh.msg_iovlen = 1; mh.msg_control = &cmsg; mh.msg_controllen = sizeof(cmsg); if ((r = recvmsg(io->ifd, &mh, 0)) >= 0) { struct cmsghdr *cmh; ancil_data->creds_valid = false; ancil_data->nfd = 0; for (cmh = CMSG_FIRSTHDR(&mh); cmh; cmh = CMSG_NXTHDR(&mh, cmh)) { if (cmh->cmsg_level != SOL_SOCKET) continue; if (cmh->cmsg_type == SCM_CREDENTIALS) { struct ucred u; pa_assert(cmh->cmsg_len == CMSG_LEN(sizeof(struct ucred))); memcpy(&u, CMSG_DATA(cmh), sizeof(struct ucred)); ancil_data->creds.gid = u.gid; ancil_data->creds.uid = u.uid; ancil_data->creds_valid = true; } else if (cmh->cmsg_type == SCM_RIGHTS) { int nfd = (cmh->cmsg_len - CMSG_LEN(0)) / sizeof(int); if (nfd > MAX_ANCIL_DATA_FDS) { int i; pa_log("Trying to receive too many file descriptors!"); for (i = 0; i < nfd; i++) pa_close(((int*) CMSG_DATA(cmh))[i]); continue; } memcpy(ancil_data->fds, CMSG_DATA(cmh), nfd * sizeof(int)); ancil_data->nfd = nfd; ancil_data->close_fds_on_cleanup = true; } } io->readable = io->hungup = false; enable_events(io); } if (r == -1 && errno == ENOTSOCK) { io->ifd_type = 1; return pa_iochannel_read_with_ancil_data(io, data, l, ancil_data); } return r; }