/** Send message via UDP association. * * @param assoc Association * @param dest Destination endpoint or @c NULL to use association's remote ep. * @param data Message data * @param bytes Message size in bytes * * @return EOK on success or negative error code */ int udp_assoc_send_msg(udp_assoc_t *assoc, inet_ep_t *dest, void *data, size_t bytes) { async_exch_t *exch; exch = async_exchange_begin(assoc->udp->sess); aid_t req = async_send_1(exch, UDP_ASSOC_SEND_MSG, assoc->id, NULL); sysarg_t rc = async_data_write_start(exch, (void *)dest, sizeof(inet_ep_t)); if (rc != EOK) { async_exchange_end(exch); async_forget(req); return rc; } rc = async_data_write_start(exch, data, bytes); if (rc != EOK) { async_forget(req); return rc; } async_exchange_end(exch); if (rc != EOK) { async_forget(req); return rc; } async_wait_for(req, &rc); return rc; }
/** 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; }
static int loc_category_get_ids_once(sysarg_t method, sysarg_t arg1, sysarg_t *id_buf, size_t buf_size, size_t *act_size) { async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER); ipc_call_t answer; aid_t req = async_send_1(exch, method, arg1, &answer); int rc = async_data_read_start(exch, id_buf, buf_size); loc_exchange_end(exch); if (rc != EOK) { async_forget(req); return rc; } sysarg_t retval; async_wait_for(req, &retval); if (retval != EOK) { return retval; } *act_size = IPC_GET_ARG1(answer); return EOK; }
/** 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; }
/** Set preset files for the program. * * Sets the vector of preset files to be passed to the loaded * program. By convention, the first three files represent stdin, * stdout and stderr respectively. * * @param ldr Loader connection structure. * @param files NULL-terminated array of pointers to files. * * @return Zero on success or negative error code. * */ int loader_set_files(loader_t *ldr, int * const files[]) { /* Send serialized files to the loader */ async_exch_t *exch = async_exchange_begin(ldr->sess); async_exch_t *vfs_exch = vfs_exchange_begin(); int i; for (i = 0; files[i]; i++); ipc_call_t answer; aid_t req = async_send_1(exch, LOADER_SET_FILES, i, &answer); sysarg_t rc = EOK; for (i = 0; files[i]; i++) { rc = async_state_change_start(exch, VFS_PASS_HANDLE, *files[i], 0, vfs_exch); if (rc != EOK) break; } vfs_exchange_end(vfs_exch); async_exchange_end(exch); if (rc != EOK) { async_forget(req); return (int) rc; } async_wait_for(req, &rc); return (int) rc; }
/** Get list of IDs into a buffer of fixed size. * * @param vbd Virtual Block Device * @param method IPC method * @param arg1 First argument * @param id_buf Buffer to store IDs * @param buf_size Buffer size * @param act_size Place to store actual size of complete data. * * @return EOK on success or negative error code. */ static int vbd_get_ids_once(vbd_t *vbd, sysarg_t method, sysarg_t arg1, sysarg_t *id_buf, size_t buf_size, size_t *act_size) { async_exch_t *exch = async_exchange_begin(vbd->sess); ipc_call_t answer; aid_t req = async_send_1(exch, method, arg1, &answer); int rc = async_data_read_start(exch, id_buf, buf_size); 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; } *act_size = IPC_GET_ARG1(answer); return EOK; }
int vbd_part_create(vbd_t *vbd, service_id_t disk, vbd_part_spec_t *pspec, vbd_part_id_t *rpart) { async_exch_t *exch; sysarg_t retval; ipc_call_t answer; exch = async_exchange_begin(vbd->sess); aid_t req = async_send_1(exch, VBD_PART_CREATE, disk, &answer); int rc = async_data_write_start(exch, pspec, sizeof(vbd_part_spec_t)); async_exchange_end(exch); if (rc != EOK) { async_forget(req); return EIO; } async_wait_for(req, &retval); if (retval != EOK) return EIO; *rpart = (vbd_part_id_t)IPC_GET_ARG1(answer); return EOK; }
/** Register new service. * * The @p interface is used when forwarding connection to the server. * If not 0, the first argument is the interface and the second argument * is the service ID. * * When the interface is zero (default), the first argument is directly * the handle (to ensure backward compatibility). * * @param fqsn Fully qualified service name * @param[out] sid Service ID of new service * @param interface Interface when forwarding * */ int loc_service_register_with_iface(const char *fqsn, service_id_t *sid, sysarg_t interface) { async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_SUPPLIER); ipc_call_t answer; aid_t req = async_send_2(exch, LOC_SERVICE_REGISTER, interface, 0, &answer); sysarg_t retval = async_data_write_start(exch, fqsn, str_size(fqsn)); loc_exchange_end(exch); if (retval != EOK) { async_forget(req); return retval; } async_wait_for(req, &retval); if (retval != EOK) { if (sid != NULL) *sid = -1; return retval; } if (sid != NULL) *sid = (service_id_t) IPC_GET_ARG1(answer); return retval; }
/** 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; }
int iplink_ev_recv(iplink_srv_t *srv, iplink_srv_sdu_t *sdu) { if (srv->client_sess == NULL) return EIO; async_exch_t *exch = async_exchange_begin(srv->client_sess); ipc_call_t answer; aid_t req = async_send_2(exch, IPLINK_EV_RECV, sdu->lsrc.ipv4, sdu->ldest.ipv4, &answer); int rc = async_data_write_start(exch, sdu->data, sdu->size); 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; return EOK; }
size_t loc_get_services(service_id_t ns_handle, 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_services_internal(exch, ns_handle); 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_1(exch, LOC_GET_SERVICES, ns_handle, &answer); int rc = async_data_read_start(exch, devs, count * sizeof(loc_sdesc_t)); loc_exchange_end(exch); if (rc == EOVERFLOW) { /* * Number of services has changed since * the last call of LOC_GET_SERVICE_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; } }
/** 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; }
/** Send frame from NIC * * @param[in] dev_sess * @param[in] data Frame data * @param[in] size Frame size in bytes * * @return EOK If the operation was successfully completed * */ int nic_send_frame(async_sess_t *dev_sess, void *data, size_t size) { async_exch_t *exch = async_exchange_begin(dev_sess); ipc_call_t answer; aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_SEND_MESSAGE, &answer); sysarg_t retval = async_data_write_start(exch, data, size); async_exchange_end(exch); if (retval != EOK) { async_forget(req); return retval; } async_wait_for(req, &retval); return retval; }
/** 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 callback connection from NIC service * * @param[in] dev_sess * @param[in] device_id * * @return EOK If the operation was successfully completed * */ int nic_callback_create(async_sess_t *dev_sess, async_client_conn_t cfun, void *carg) { ipc_call_t answer; int rc; sysarg_t retval; async_exch_t *exch = async_exchange_begin(dev_sess); aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_CALLBACK_CREATE, &answer); rc = async_connect_to_me(exch, 0, 0, 0, cfun, carg); if (rc != EOK) { async_forget(req); return rc; } async_exchange_end(exch); async_wait_for(req, &retval); return (int) retval; }
/** Get object name. * * Provided ID of an object, return its name. * * @param method IPC method * @param id Object ID * @param name Place to store pointer to new string. Caller should * free it using free(). * @return EOK on success or negative error code */ static int loc_get_name_internal(sysarg_t method, sysarg_t id, char **name) { async_exch_t *exch; char name_buf[LOC_NAME_MAXLEN + 1]; ipc_call_t dreply; size_t act_size; sysarg_t dretval; *name = NULL; exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER); ipc_call_t answer; aid_t req = async_send_1(exch, method, id, &answer); aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply); async_wait_for(dreq, &dretval); loc_exchange_end(exch); if (dretval != EOK) { async_forget(req); return dretval; } sysarg_t retval; async_wait_for(req, &retval); if (retval != EOK) return retval; act_size = IPC_GET_ARG2(dreply); assert(act_size <= LOC_NAME_MAXLEN); name_buf[act_size] = '\0'; *name = str_dup(name_buf); if (*name == NULL) return ENOMEM; return EOK; }
int bd_read_toc(bd_t *bd, uint8_t session, void *buf, size_t size) { async_exch_t *exch = async_exchange_begin(bd->sess); ipc_call_t answer; aid_t req = async_send_1(exch, BD_READ_TOC, session, &answer); int rc = async_data_read_start(exch, buf, size); 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; return EOK; }
/** * Register a named application context to the audio server. * @param sess Valid audio session. * @param name Valid string identifier * @param record True if the application context wishes to receive data. * @return Valid ID on success, Error code on failure. */ hound_context_id_t hound_service_register_context(hound_sess_t *sess, const char *name, bool record) { assert(sess); assert(name); ipc_call_t call; async_exch_t *exch = async_exchange_begin(sess); aid_t mid = async_send_1(exch, IPC_M_HOUND_CONTEXT_REGISTER, record, &call); int ret = mid ? EOK : EPARTY; if (ret == EOK) ret = async_data_write_start(exch, name, str_size(name)); else async_forget(mid); if (ret == EOK) async_wait_for(mid, (sysarg_t *)&ret); async_exchange_end(exch); return ret == EOK ? (hound_context_id_t)IPC_GET_ARG1(call) : ret; }
int inet_send(inet_dgram_t *dgram, uint8_t ttl, inet_df_t df) { async_exch_t *exch = async_exchange_begin(inet_sess); ipc_call_t answer; aid_t req = async_send_5(exch, INET_SEND, dgram->src.ipv4, dgram->dest.ipv4, dgram->tos, ttl, df, &answer); int rc = async_data_write_start(exch, dgram->data, dgram->size); 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; return EOK; }
int vbd_part_get_info(vbd_t *vbd, vbd_part_id_t part, vbd_part_info_t *pinfo) { async_exch_t *exch; sysarg_t retval; ipc_call_t answer; exch = async_exchange_begin(vbd->sess); aid_t req = async_send_1(exch, VBD_PART_GET_INFO, part, &answer); int rc = async_data_read_start(exch, pinfo, sizeof(vbd_part_info_t)); async_exchange_end(exch); if (rc != EOK) { async_forget(req); return EIO; } async_wait_for(req, &retval); if (retval != EOK) return EIO; return EOK; }
int loc_namespace_get_id(const char *name, service_id_t *handle, 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_2(exch, LOC_NAMESPACE_GET_ID, flags, 0, &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 (handle != NULL) *handle = (service_id_t) -1; return retval; } if (handle != NULL) *handle = (service_id_t) IPC_GET_ARG1(answer); return retval; }
/** Get disk information. */ int vbd_disk_info(vbd_t *vbd, service_id_t sid, vbd_disk_info_t *vinfo) { async_exch_t *exch; sysarg_t retval; ipc_call_t answer; exch = async_exchange_begin(vbd->sess); aid_t req = async_send_1(exch, VBD_DISK_INFO, sid, &answer); int rc = async_data_read_start(exch, vinfo, sizeof(vbd_disk_info_t)); async_exchange_end(exch); if (rc != EOK) { async_forget(req); return EIO; } async_wait_for(req, &retval); if (retval != EOK) return EIO; 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; }
/** Register new driver with loc. */ int loc_server_register(const char *name) { async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_SUPPLIER); ipc_call_t answer; aid_t req = async_send_2(exch, LOC_SERVER_REGISTER, 0, 0, &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; } exch = loc_exchange_begin(LOC_PORT_SUPPLIER); async_connect_to_me(exch, 0, 0, 0, NULL, NULL); loc_exchange_end(exch); async_wait_for(req, &retval); return retval; }
int bd_read_blocks(bd_t *bd, aoff64_t ba, size_t cnt, void *data, size_t size) { async_exch_t *exch = async_exchange_begin(bd->sess); ipc_call_t answer; aid_t req = async_send_3(exch, BD_READ_BLOCKS, LOWER32(ba), UPPER32(ba), cnt, &answer); int rc = async_data_read_start(exch, data, size); 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; return EOK; }
/** Suggest partition type based on partition content. * * @param vbd Virtual Block Device * @param disk Disk on which the partition will be created * @param pcnt Partition content * @param ptype Place to store suggested partition type * * @return EOK on success or negative error code */ int vbd_suggest_ptype(vbd_t *vbd, service_id_t disk, label_pcnt_t pcnt, label_ptype_t *ptype) { async_exch_t *exch; sysarg_t retval; ipc_call_t answer; exch = async_exchange_begin(vbd->sess); aid_t req = async_send_2(exch, VBD_SUGGEST_PTYPE, disk, pcnt, &answer); int rc = async_data_read_start(exch, ptype, sizeof(label_ptype_t)); async_exchange_end(exch); if (rc != EOK) { async_forget(req); return EIO; } async_wait_for(req, &retval); if (retval != EOK) return EIO; return EOK; }
/** Set the current time * * @param sess Session of the device * @param t The current time that will be written to the device * * @return EOK on success or a negative error code */ int clock_dev_time_set(async_sess_t *sess, struct tm *t) { aid_t req; int ret; async_exch_t *exch = async_exchange_begin(sess); req = async_send_1(exch, DEV_IFACE_ID(CLOCK_DEV_IFACE), CLOCK_DEV_TIME_SET, NULL); ret = async_data_write_start(exch, t, sizeof(*t)); async_exchange_end(exch); sysarg_t rc; if (ret != EOK) { async_forget(req); return ret; } async_wait_for(req, &rc); return (int)rc; }
/** Read part of received message. * * @param rmsg Received message * @param off Start offset * @param buf Buffer for storing data * @param bsize Buffer size * * @return EOK on success or negative error code. */ int udp_rmsg_read(udp_rmsg_t *rmsg, size_t off, void *buf, size_t bsize) { async_exch_t *exch; ipc_call_t answer; exch = async_exchange_begin(rmsg->udp->sess); aid_t req = async_send_1(exch, UDP_RMSG_READ, off, &answer); int rc = async_data_read_start(exch, buf, bsize); 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; } return EOK; }