/** Set pathname of the program to load. * * Sets the name of the program file to load. The name can be relative * to the current working directory (it will be absolutized before * sending to the loader). * * @param ldr Loader connection structure. * @param path Pathname of the program file. * * @return Zero on success or negative error code. * */ int loader_set_pathname(loader_t *ldr, const char *path) { size_t pa_len; char *pa = absolutize(path, &pa_len); if (!pa) return ENOMEM; /* Send program pathname */ async_exch_t *exch = async_exchange_begin(ldr->sess); ipc_call_t answer; aid_t req = async_send_0(exch, LOADER_SET_PATHNAME, &answer); sysarg_t rc = async_data_write_start(exch, (void *) pa, pa_len); async_exchange_end(exch); free(pa); if (rc != EOK) { async_forget(req); return (int) rc; } async_wait_for(req, &rc); return (int) rc; }
/** Get information about the next received message from UDP service. * * @param udp UDP client * @param rmsg Place to store message information * * @return EOK on success or negative error code */ static int udp_rmsg_info(udp_t *udp, udp_rmsg_t *rmsg) { async_exch_t *exch; inet_ep_t ep; ipc_call_t answer; exch = async_exchange_begin(udp->sess); aid_t req = async_send_0(exch, UDP_RMSG_INFO, &answer); int rc = async_data_read_start(exch, &ep, sizeof(inet_ep_t)); async_exchange_end(exch); if (rc != EOK) { async_forget(req); return rc; } sysarg_t retval; async_wait_for(req, &retval); if (retval != EOK) return retval; rmsg->udp = udp; rmsg->assoc_id = IPC_GET_ARG1(answer); rmsg->size = IPC_GET_ARG2(answer); rmsg->remote_ep = ep; return EOK; }
/** Set current working directory for the loaded task. * * Sets the current working directory for the loaded task. * * @param ldr Loader connection structure. * * @return Zero on success or negative error code. * */ int loader_set_cwd(loader_t *ldr) { char *cwd = (char *) malloc(MAX_PATH_LEN + 1); if (!cwd) return ENOMEM; if (!getcwd(cwd, MAX_PATH_LEN + 1)) str_cpy(cwd, MAX_PATH_LEN + 1, "/"); size_t len = str_length(cwd); async_exch_t *exch = async_exchange_begin(ldr->sess); ipc_call_t answer; aid_t req = async_send_0(exch, LOADER_SET_CWD, &answer); sysarg_t rc = async_data_write_start(exch, cwd, len); async_exchange_end(exch); free(cwd); if (rc != EOK) { async_forget(req); return (int) rc; } async_wait_for(req, &rc); return (int) rc; }
size_t loc_get_namespaces(loc_sdesc_t **data) { /* Loop until read is succesful */ while (true) { async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER); size_t count = loc_count_namespaces_internal(exch); loc_exchange_end(exch); if (count == 0) return 0; loc_sdesc_t *devs = (loc_sdesc_t *) calloc(count, sizeof(loc_sdesc_t)); if (devs == NULL) return 0; exch = loc_exchange_begin(LOC_PORT_CONSUMER); ipc_call_t answer; aid_t req = async_send_0(exch, LOC_GET_NAMESPACES, &answer); int rc = async_data_read_start(exch, devs, count * sizeof(loc_sdesc_t)); loc_exchange_end(exch); if (rc == EOVERFLOW) { /* * Number of namespaces has changed since * the last call of LOC_GET_NAMESPACE_COUNT */ free(devs); continue; } if (rc != EOK) { async_forget(req); free(devs); return 0; } sysarg_t retval; async_wait_for(req, &retval); if (retval != EOK) return 0; *data = devs; return count; } }
static int inet_callback_create(void) { async_exch_t *exch = async_exchange_begin(inet_sess); ipc_call_t answer; aid_t req = async_send_0(exch, INET_CALLBACK_CREATE, &answer); int rc = async_connect_to_me(exch, 0, 0, 0, inet_cb_conn, NULL); async_exchange_end(exch); if (rc != EOK) return rc; sysarg_t retval; async_wait_for(req, &retval); return retval; }
/** Set command-line arguments for the program. * * Sets the vector of command-line arguments to be passed to the loaded * program. By convention, the very first argument is typically the same as * the command used to execute the program. * * @param ldr Loader connection structure. * @param argv NULL-terminated array of pointers to arguments. * * @return Zero on success or negative error code. * */ int loader_set_args(loader_t *ldr, const char *const argv[]) { /* * Serialize the arguments into a single array. First * compute size of the buffer needed. */ const char *const *ap = argv; size_t buffer_size = 0; while (*ap != NULL) { buffer_size += str_size(*ap) + 1; ap++; } char *arg_buf = malloc(buffer_size); if (arg_buf == NULL) return ENOMEM; /* Now fill the buffer with null-terminated argument strings */ ap = argv; char *dp = arg_buf; while (*ap != NULL) { str_cpy(dp, buffer_size - (dp - arg_buf), *ap); dp += str_size(*ap) + 1; ap++; } /* Send serialized arguments to the loader */ async_exch_t *exch = async_exchange_begin(ldr->sess); ipc_call_t answer; aid_t req = async_send_0(exch, LOADER_SET_ARGS, &answer); sysarg_t rc = async_data_write_start(exch, (void *) arg_buf, buffer_size); async_exchange_end(exch); free(arg_buf); if (rc != EOK) { async_forget(req); return (int) rc; } async_wait_for(req, &rc); return (int) rc; }
/** * Destroy an existing connection between a source and a sink. * @param sess Valid audio session. * @param source Source name, valid string. * @param sink Sink name, valid string. * @return Error code. */ int hound_service_disconnect_source_sink(hound_sess_t *sess, const char *source, const char *sink) { assert(sess); async_exch_t *exch = async_exchange_begin(sess); if (!exch) return ENOMEM; ipc_call_t call; aid_t id = async_send_0(exch, IPC_M_HOUND_DISCONNECT, &call); int ret = id ? EOK : EPARTY; if (ret == EOK) ret = async_data_write_start(exch, source, str_size(source)); if (ret == EOK) ret = async_data_write_start(exch, sink, str_size(sink)); async_wait_for(id, (sysarg_t*)&ret); async_exchange_end(exch); return ENOTSUP; }
imagemap_handle_t fb_imagemap_create(async_sess_t *sess, imgmap_t *imgmap) { async_exch_t *exch = async_exchange_begin(sess); ipc_call_t answer; aid_t req = async_send_0(exch, FB_IMAGEMAP_CREATE, &answer); int rc = async_share_out_start(exch, imgmap, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE); async_exchange_end(exch); sysarg_t ret; async_wait_for(req, &ret); if ((rc != EOK) || (ret != EOK)) return 0; return (imagemap_handle_t) IPC_GET_ARG1(answer); }
/** Get ID of the new task. * * Retrieves the ID of the new task from the loader. * * @param ldr Loader connection structure. * @param task_id Points to a variable where the ID should be stored. * * @return Zero on success or negative error code. * */ int loader_get_task_id(loader_t *ldr, task_id_t *task_id) { /* Get task ID. */ async_exch_t *exch = async_exchange_begin(ldr->sess); ipc_call_t answer; aid_t req = async_send_0(exch, LOADER_GET_TASKID, &answer); sysarg_t rc = async_data_read_start(exch, task_id, sizeof(task_id_t)); async_exchange_end(exch); if (rc != EOK) { async_forget(req); return (int) rc; } async_wait_for(req, &rc); return (int) rc; }
/** Create new UDP association. * * Create a UDP association that allows sending and receiving messages. * * @a epp may specify remote address and port, in which case only messages * from that remote endpoint will be received. Also, that remote endpoint * is used as default when @c NULL is passed as destination to * udp_assoc_send_msg. * * @a epp may specify a local link or address. If it does not, the association * will listen on all local links/addresses. If @a epp does not specify * a local port number, a free dynamic port number will be allocated. * * The caller is informed about incoming data by invoking @a cb->recv_msg * * @param udp UDP client * @param epp Internet endpoint pair * @param cb Callbacks * @param arg Argument to callbacks * @param rassoc Place to store pointer to new association * * @return EOK on success or negative error code. */ int udp_assoc_create(udp_t *udp, inet_ep2_t *epp, udp_cb_t *cb, void *arg, udp_assoc_t **rassoc) { async_exch_t *exch; udp_assoc_t *assoc; ipc_call_t answer; assoc = calloc(1, sizeof(udp_assoc_t)); if (assoc == NULL) return ENOMEM; exch = async_exchange_begin(udp->sess); aid_t req = async_send_0(exch, UDP_ASSOC_CREATE, &answer); sysarg_t rc = async_data_write_start(exch, (void *)epp, sizeof(inet_ep2_t)); async_exchange_end(exch); if (rc != EOK) { sysarg_t rc_orig; async_wait_for(req, &rc_orig); if (rc_orig != EOK) rc = rc_orig; goto error; } async_wait_for(req, &rc); if (rc != EOK) goto error; assoc->udp = udp; assoc->id = IPC_GET_ARG1(answer); assoc->cb = cb; assoc->cb_arg = arg; list_append(&assoc->ludp, &udp->assoc); *rassoc = assoc; return EOK; error: free(assoc); return (int) rc; }
frontbuf_handle_t fb_frontbuf_create(async_sess_t *sess, screenbuffer_t *frontbuf) { async_exch_t *exch = async_exchange_begin(sess); ipc_call_t answer; aid_t req = async_send_0(exch, FB_FRONTBUF_CREATE, &answer); int rc = async_share_out_start(exch, frontbuf, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE); async_exchange_end(exch); sysarg_t ret; async_wait_for(req, &ret); if ((rc != EOK) || (ret != EOK)) return 0; return (frontbuf_handle_t) IPC_GET_ARG1(answer); }
/** Create callback connection from UDP service. * * @param udp UDP service * @return EOK on success or negative error code */ static int udp_callback_create(udp_t *udp) { async_exch_t *exch = async_exchange_begin(udp->sess); aid_t req = async_send_0(exch, UDP_CALLBACK_CREATE, NULL); port_id_t port; int rc = async_create_callback_port(exch, INTERFACE_UDP_CB, 0, 0, udp_cb_conn, udp, &port); async_exchange_end(exch); if (rc != EOK) return rc; sysarg_t retval; async_wait_for(req, &retval); return retval; }
int win_get_event(async_sess_t *sess, window_event_t *event) { async_exch_t *exch = async_exchange_begin(sess); ipc_call_t answer; aid_t req = async_send_0(exch, WINDOW_GET_EVENT, &answer); int rc = async_data_read_start(exch, event, sizeof(window_event_t)); async_exchange_end(exch); sysarg_t ret; async_wait_for(req, &ret); if (rc != EOK) { return rc; } else if (ret != EOK) { return ret; } else { return EOK; } }
/** Get category ID. * * Provided name of a category, return its ID. * * @param name Category name * @param cat_id Place to store ID * @param flags IPC_FLAG_BLOCKING to wait for location service to start * @return EOK on success or negative error code */ int loc_category_get_id(const char *name, category_id_t *cat_id, unsigned int flags) { async_exch_t *exch; if (flags & IPC_FLAG_BLOCKING) exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER); else { exch = loc_exchange_begin(LOC_PORT_CONSUMER); if (exch == NULL) return errno; } ipc_call_t answer; aid_t req = async_send_0(exch, LOC_CATEGORY_GET_ID, &answer); sysarg_t retval = async_data_write_start(exch, name, str_size(name)); loc_exchange_end(exch); if (retval != EOK) { async_forget(req); return retval; } async_wait_for(req, &retval); if (retval != EOK) { if (cat_id != NULL) *cat_id = (category_id_t) -1; return retval; } if (cat_id != NULL) *cat_id = (category_id_t) IPC_GET_ARG1(answer); return retval; }
/** Create callback * * Must be called with loc_callback_mutex locked. * * @return EOK on success. * */ static int loc_callback_create(void) { if (!loc_callback_created) { async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER); ipc_call_t answer; aid_t req = async_send_0(exch, LOC_CALLBACK_CREATE, &answer); int rc = async_connect_to_me(exch, 0, 0, 0, loc_cb_conn, NULL); loc_exchange_end(exch); if (rc != EOK) return rc; sysarg_t retval; async_wait_for(req, &retval); if (retval != EOK) return retval; loc_callback_created = true; } return EOK; }