/* * Function implementations */ cs_error_t cmap_initialize (cmap_handle_t *handle) { cs_error_t error; struct cmap_inst *cmap_inst; error = hdb_error_to_cs(hdb_handle_create(&cmap_handle_t_db, sizeof(*cmap_inst), handle)); if (error != CS_OK) { goto error_no_destroy; } error = hdb_error_to_cs(hdb_handle_get(&cmap_handle_t_db, *handle, (void *)&cmap_inst)); if (error != CS_OK) { goto error_destroy; } error = CS_OK; cmap_inst->finalize = 0; cmap_inst->c = qb_ipcc_connect("cmap", IPC_REQUEST_SIZE); if (cmap_inst->c == NULL) { error = qb_to_cs_error(-errno); goto error_put_destroy; } (void)hdb_handle_put(&cmap_handle_t_db, *handle); return (CS_OK); error_put_destroy: (void)hdb_handle_put(&cmap_handle_t_db, *handle); error_destroy: (void)hdb_handle_destroy(&cmap_handle_t_db, *handle); error_no_destroy: return (error); }
/** * test * @param handle The handle of pload initialize * @param callbacks The callbacks for pload_initialize * @returns PLOAD_OK */ unsigned int pload_initialize ( pload_handle_t *handle, pload_callbacks_t *callbacks) { cs_error_t error; struct pload_inst *pload_inst; error = hdb_error_to_cs(hdb_handle_create (&pload_handle_t_db, sizeof (struct pload_inst), handle)); if (error != CS_OK) { goto error_no_destroy; } error = hdb_error_to_cs(hdb_handle_get (&pload_handle_t_db, *handle, (void *)&pload_inst)); if (error != CS_OK) { goto error_destroy; } pload_inst->c = qb_ipcc_connect ("pload", IPC_REQUEST_SIZE); if (pload_inst->c == NULL) { error = qb_to_cs_error(-errno); goto error_put_destroy; } (void)hdb_handle_put (&pload_handle_t_db, *handle); return (CS_OK); error_put_destroy: (void)hdb_handle_put (&pload_handle_t_db, *handle); error_destroy: (void)hdb_handle_destroy (&pload_handle_t_db, *handle); error_no_destroy: return (error); }
/* * object db reading */ static int object_find_create ( hdb_handle_t object_handle, const void *object_name, size_t object_len, hdb_handle_t *object_find_handle) { unsigned int res; struct object_instance *object_instance; struct object_find_instance *object_find_instance; objdb_rdlock(); res = hdb_handle_get (&object_instance_database, object_handle, (void *)&object_instance); if (res != 0) { goto error_exit; } res = hdb_handle_create (&object_find_instance_database, sizeof (struct object_find_instance), object_find_handle); if (res != 0) { goto error_put; } res = hdb_handle_get (&object_find_instance_database, *object_find_handle, (void *)&object_find_instance); if (res != 0) { goto error_destroy; } object_find_instance->find_child_list = &object_instance->child_head; object_find_instance->child_head = &object_instance->child_head; object_find_instance->object_name = (char *)object_name; object_find_instance->object_len = object_len; hdb_handle_put (&object_instance_database, object_handle); hdb_handle_put (&object_find_instance_database, *object_find_handle); objdb_rdunlock(); return (0); error_destroy: hdb_handle_destroy (&object_instance_database, *object_find_handle); error_put: hdb_handle_put (&object_instance_database, object_handle); error_exit: objdb_rdunlock(); return (-1); }
SaAisErrorT saAmfInitialize ( SaAmfHandleT *amfHandle, const SaAmfCallbacksT *amfCallbacks, SaVersionT *version) { struct amfInstance *amfInstance; SaAisErrorT error = SA_AIS_OK; error = saVersionVerify (&amfVersionDatabase, (SaVersionT *)version); if (error != SA_AIS_OK) { goto error_no_destroy; } error = hdb_error_to_sa(hdb_handle_create (&amfHandleDatabase, sizeof (struct amfInstance), amfHandle)); if (error != SA_AIS_OK) { goto error_no_destroy; } error = hdb_error_to_sa(hdb_handle_get (&amfHandleDatabase, *amfHandle, (void *)&amfInstance)); if (error != SA_AIS_OK) { goto error_destroy; } error = coroipcc_service_connect ( COROSYNC_SOCKET_NAME, CPG_SERVICE, IPC_REQUEST_SIZE, IPC_RESPONSE_SIZE, IPC_DISPATCH_SIZE, &amfInstance->handle); if (error != SA_AIS_OK) { goto error_put_destroy; } memcpy (&amfInstance->callbacks, amfCallbacks, sizeof (SaAmfCallbacksT)); hdb_handle_put (&amfHandleDatabase, *amfHandle); return (SA_AIS_OK); error_put_destroy: hdb_handle_put (&amfHandleDatabase, *amfHandle); error_destroy: hdb_handle_destroy (&amfHandleDatabase, *amfHandle); error_no_destroy: return (error); }
static int objdb_init (void) { hdb_handle_t handle; struct object_instance *instance; unsigned int res; res = hdb_handle_create (&object_instance_database, sizeof (struct object_instance), &handle); if (res != 0) { goto error_exit; } res = hdb_handle_get (&object_instance_database, handle, (void *)&instance); if (res != 0) { goto error_destroy; } instance->find_child_list = &instance->child_head; instance->object_name = (char *)"parent"; instance->object_name_len = strlen ("parent"); instance->object_handle = handle; instance->parent_handle = OBJECT_PARENT_HANDLE; instance->priv = NULL; instance->object_valid_list = NULL; instance->object_valid_list_entries = 0; list_init (&instance->key_head); list_init (&instance->child_head); list_init (&instance->child_list); list_init (&instance->track_head); list_init (&objdb_trackers_head); pthread_mutexattr_init(&objdb_mutex_attr); pthread_mutexattr_settype(&objdb_mutex_attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&objdb_mutex, &objdb_mutex_attr); hdb_handle_put (&object_instance_database, handle); return (0); error_destroy: hdb_handle_destroy (&object_instance_database, handle); error_exit: return (-1); }
/** * test * @param handle The handle of evs initialize * @param callbacks The callbacks for evs_initialize * @returns EVS_OK */ evs_error_t evs_initialize ( evs_handle_t *handle, evs_callbacks_t *callbacks) { cs_error_t error; struct evs_inst *evs_inst; error = hdb_error_to_cs(hdb_handle_create (&evs_handle_t_db, sizeof (struct evs_inst), handle)); if (error != CS_OK) { goto error_no_destroy; } error = hdb_error_to_cs(hdb_handle_get (&evs_handle_t_db, *handle, (void *)&evs_inst)); if (error != CS_OK) { goto error_destroy; } error = coroipcc_service_connect ( COROSYNC_SOCKET_NAME, EVS_SERVICE, IPC_REQUEST_SIZE, IPC_RESPONSE_SIZE, IPC_DISPATCH_SIZE, &evs_inst->handle); if (error != EVS_OK) { goto error_put_destroy; } if (callbacks) { memcpy (&evs_inst->callbacks, callbacks, sizeof (evs_callbacks_t)); } hdb_handle_put (&evs_handle_t_db, *handle); return (CS_OK); error_put_destroy: hdb_handle_put (&evs_handle_t_db, *handle); error_destroy: hdb_handle_destroy (&evs_handle_t_db, *handle); error_no_destroy: return (error); }
cs_error_t corosync_cfg_initialize ( corosync_cfg_handle_t *cfg_handle, const corosync_cfg_callbacks_t *cfg_callbacks) { struct cfg_inst *cfg_inst; cs_error_t error = CS_OK; error = hdb_error_to_cs (hdb_handle_create (&cfg_hdb, sizeof (struct cfg_inst), cfg_handle)); if (error != CS_OK) { goto error_no_destroy; } error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, *cfg_handle, (void *)&cfg_inst)); if (error != CS_OK) { goto error_destroy; } cfg_inst->finalize = 0; cfg_inst->c = qb_ipcc_connect ("cfg", IPC_REQUEST_SIZE); if (cfg_inst->c == NULL) { error = qb_to_cs_error(-errno); goto error_put_destroy; } if (cfg_callbacks) { memcpy (&cfg_inst->callbacks, cfg_callbacks, sizeof (corosync_cfg_callbacks_t)); } (void)hdb_handle_put (&cfg_hdb, *cfg_handle); return (CS_OK); error_put_destroy: (void)hdb_handle_put (&cfg_hdb, *cfg_handle); error_destroy: (void)hdb_handle_destroy (&cfg_hdb, *cfg_handle); error_no_destroy: return (error); }
cs_error_t votequorum_initialize ( votequorum_handle_t *handle, votequorum_callbacks_t *callbacks) { cs_error_t error; struct votequorum_inst *votequorum_inst; error = hdb_error_to_cs(hdb_handle_create (&votequorum_handle_t_db, sizeof (struct votequorum_inst), handle)); if (error != CS_OK) { goto error_no_destroy; } error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, *handle, (void *)&votequorum_inst)); if (error != CS_OK) { goto error_destroy; } votequorum_inst->finalize = 0; votequorum_inst->c = qb_ipcc_connect ("votequorum", IPC_REQUEST_SIZE); if (votequorum_inst->c == NULL) { error = qb_to_cs_error(-errno); goto error_put_destroy; } if (callbacks) memcpy(&votequorum_inst->callbacks, callbacks, sizeof (*callbacks)); else memset(&votequorum_inst->callbacks, 0, sizeof (*callbacks)); hdb_handle_put (&votequorum_handle_t_db, *handle); return (CS_OK); error_put_destroy: hdb_handle_put (&votequorum_handle_t_db, *handle); error_destroy: hdb_handle_destroy (&votequorum_handle_t_db, *handle); error_no_destroy: return (error); }
/* * object db create/destroy/set */ static int object_create ( hdb_handle_t parent_object_handle, hdb_handle_t *object_handle, const void *object_name, size_t object_name_len) { struct object_instance *object_instance; struct object_instance *parent_instance; unsigned int res; int found = 0; int i; objdb_rdlock(); res = hdb_handle_get (&object_instance_database, parent_object_handle, (void *)&parent_instance); if (res != 0) { goto error_exit; } /* * Do validation check if validation is configured for the parent object */ if (parent_instance->object_valid_list_entries) { for (i = 0; i < parent_instance->object_valid_list_entries; i++) { if ((object_name_len == parent_instance->object_valid_list[i].object_len) && (memcmp (object_name, parent_instance->object_valid_list[i].object_name, object_name_len) == 0)) { found = 1; break; } } /* * Item not found in validation list */ if (found == 0) { goto error_object_put; } } res = hdb_handle_create (&object_instance_database, sizeof (struct object_instance), object_handle); if (res != 0) { goto error_object_put; } res = hdb_handle_get (&object_instance_database, *object_handle, (void *)&object_instance); if (res != 0) { goto error_destroy; } list_init (&object_instance->key_head); list_init (&object_instance->child_head); list_init (&object_instance->child_list); list_init (&object_instance->track_head); object_instance->object_name = malloc (object_name_len); if (object_instance->object_name == 0) { goto error_put_destroy; } memcpy (object_instance->object_name, object_name, object_name_len); object_instance->object_name_len = object_name_len; list_add_tail (&object_instance->child_list, &parent_instance->child_head); object_instance->object_handle = *object_handle; object_instance->find_child_list = &object_instance->child_head; object_instance->iter_key_list = &object_instance->key_head; object_instance->iter_list = &object_instance->child_head; object_instance->priv = NULL; object_instance->object_valid_list = NULL; object_instance->object_valid_list_entries = 0; object_instance->parent_handle = parent_object_handle; hdb_handle_put (&object_instance_database, *object_handle); hdb_handle_put (&object_instance_database, parent_object_handle); object_created_notification(object_instance->object_handle, object_instance->parent_handle, object_instance->object_name, object_instance->object_name_len); objdb_rdunlock(); return (0); error_put_destroy: hdb_handle_put (&object_instance_database, *object_handle); error_destroy: hdb_handle_destroy (&object_instance_database, *object_handle); error_object_put: hdb_handle_put (&object_instance_database, parent_object_handle); error_exit: objdb_rdunlock(); return (-1); }
cs_error_t cmap_track_add( cmap_handle_t handle, const char *key_name, int32_t track_type, cmap_notify_fn_t notify_fn, void *user_data, cmap_track_handle_t *cmap_track_handle) { cs_error_t error; struct iovec iov; struct cmap_inst *cmap_inst; struct req_lib_cmap_track_add req_lib_cmap_track_add; struct res_lib_cmap_track_add res_lib_cmap_track_add; struct cmap_track_inst *cmap_track_inst; cmap_track_handle_t cmap_track_inst_handle; if (cmap_track_handle == NULL || notify_fn == NULL) { return (CS_ERR_INVALID_PARAM); } error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst)); if (error != CS_OK) { return (error); } error = hdb_error_to_cs(hdb_handle_create(&cmap_track_handle_t_db, sizeof(*cmap_track_inst), &cmap_track_inst_handle)); if (error != CS_OK) { goto error_put; } error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db, cmap_track_inst_handle, (void *)&cmap_track_inst)); if (error != CS_OK) { goto error_put_destroy; } cmap_track_inst->user_data = user_data; cmap_track_inst->notify_fn = notify_fn; cmap_track_inst->c = cmap_inst->c; memset(&req_lib_cmap_track_add, 0, sizeof(req_lib_cmap_track_add)); req_lib_cmap_track_add.header.size = sizeof(req_lib_cmap_track_add); req_lib_cmap_track_add.header.id = MESSAGE_REQ_CMAP_TRACK_ADD; if (key_name) { if (strlen(key_name) >= CS_MAX_NAME_LENGTH) { return (CS_ERR_NAME_TOO_LONG); } memcpy(req_lib_cmap_track_add.key_name.value, key_name, strlen(key_name)); req_lib_cmap_track_add.key_name.length = strlen(key_name); } req_lib_cmap_track_add.track_type = track_type; req_lib_cmap_track_add.track_inst_handle = cmap_track_inst_handle; iov.iov_base = (char *)&req_lib_cmap_track_add; iov.iov_len = sizeof(req_lib_cmap_track_add); error = qb_to_cs_error(qb_ipcc_sendv_recv( cmap_inst->c, &iov, 1, &res_lib_cmap_track_add, sizeof (struct res_lib_cmap_track_add), CS_IPC_TIMEOUT_MS)); if (error == CS_OK) { error = res_lib_cmap_track_add.header.error; } if (error == CS_OK) { *cmap_track_handle = res_lib_cmap_track_add.track_handle; cmap_track_inst->track_handle = *cmap_track_handle; } (void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle); (void)hdb_handle_put (&cmap_handle_t_db, handle); return (error); error_put_destroy: (void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle); (void)hdb_handle_destroy (&cmap_track_handle_t_db, cmap_track_inst_handle); error_put: (void)hdb_handle_put (&cmap_handle_t_db, handle); return (error); }
/* * object db reading */ static int object_find_create ( hdb_handle_t object_handle, const void *object_name, size_t object_len, hdb_handle_t *object_find_handle) { unsigned int res; struct object_instance *iter_obj_inst; struct object_instance *object_instance; struct object_find_instance *object_find_instance; struct list_head *list; hdb_handle_t *handles_array, *handles_array_realloc; size_t ha_len; size_t ha_used; objdb_lock(); res = hdb_handle_get (&object_instance_database, object_handle, (void *)&object_instance); if (res != 0) { goto error_exit; } res = hdb_handle_create (&object_find_instance_database, sizeof (struct object_find_instance), object_find_handle); if (res != 0) { goto error_put; } res = hdb_handle_get (&object_find_instance_database, *object_find_handle, (void *)&object_find_instance); if (res != 0) { goto error_destroy; } object_find_instance->object_name = (char *)object_name; object_find_instance->object_len = object_len; ha_len = ha_used = 0; handles_array = NULL; for (list = object_instance->child_head.next; list != &object_instance->child_head; list = list->next) { iter_obj_inst = list_entry (list, struct object_instance, child_list); if (object_find_instance->object_len == 0 || ((iter_obj_inst->object_name_len == object_find_instance->object_len) && (memcmp (iter_obj_inst->object_name, object_find_instance->object_name, object_find_instance->object_len) == 0))) { /* * Add handle to list */ if (ha_used + 1 > ha_len) { ha_len = ha_len * 2 + 1; if ((handles_array_realloc = realloc (handles_array, ha_len * sizeof (hdb_handle_t))) == NULL) { goto error_ha_free; } handles_array = handles_array_realloc; } handles_array[ha_used] = iter_obj_inst->object_handle; ha_used++; } } object_find_instance->handles_array_size = ha_used; object_find_instance->handles_array_pos = 0; object_find_instance->handles_array = handles_array; hdb_handle_put (&object_instance_database, object_handle); hdb_handle_put (&object_find_instance_database, *object_find_handle); objdb_unlock(); return (0); error_ha_free: free(handles_array); error_destroy: hdb_handle_destroy (&object_instance_database, *object_find_handle); error_put: hdb_handle_put (&object_instance_database, object_handle); error_exit: objdb_unlock(); return (-1); }
cs_error_t quorum_initialize ( quorum_handle_t *handle, quorum_callbacks_t *callbacks, uint32_t *quorum_type) { cs_error_t error; struct quorum_inst *quorum_inst; struct iovec iov; struct qb_ipc_request_header req; struct res_lib_quorum_gettype res_lib_quorum_gettype; error = hdb_error_to_cs(hdb_handle_create (&quorum_handle_t_db, sizeof (struct quorum_inst), handle)); if (error != CS_OK) { goto error_no_destroy; } error = hdb_error_to_cs(hdb_handle_get (&quorum_handle_t_db, *handle, (void *)&quorum_inst)); if (error != CS_OK) { goto error_destroy; } error = CS_OK; quorum_inst->c = qb_ipcc_connect ("quorum", IPC_REQUEST_SIZE); if (quorum_inst->c == NULL) { error = qb_to_cs_error(-errno); goto error_put_destroy; } req.size = sizeof (req); req.id = MESSAGE_REQ_QUORUM_GETTYPE; iov.iov_base = (char *)&req; iov.iov_len = sizeof (req); error = qb_to_cs_error(qb_ipcc_sendv_recv ( quorum_inst->c, &iov, 1, &res_lib_quorum_gettype, sizeof (struct res_lib_quorum_gettype), -1)); if (error != CS_OK) { goto error_put_destroy; } error = res_lib_quorum_gettype.header.error; *quorum_type = res_lib_quorum_gettype.quorum_type; if (callbacks) memcpy(&quorum_inst->callbacks, callbacks, sizeof (*callbacks)); else memset(&quorum_inst->callbacks, 0, sizeof (*callbacks)); (void)hdb_handle_put (&quorum_handle_t_db, *handle); return (CS_OK); error_put_destroy: (void)hdb_handle_put (&quorum_handle_t_db, *handle); error_destroy: (void)hdb_handle_destroy (&quorum_handle_t_db, *handle); error_no_destroy: return (error); }
/* * External API */ cs_error_t coroipcc_service_connect ( const char *socket_name, unsigned int service, size_t request_size, size_t response_size, size_t dispatch_size, hdb_handle_t *handle) { int request_fd; struct sockaddr_un address; cs_error_t res; struct ipc_instance *ipc_instance; #if _POSIX_THREAD_PROCESS_SHARED < 1 key_t semkey = 0; union semun semun; #endif int sys_res; mar_req_setup_t req_setup; mar_res_setup_t res_setup; char control_map_path[PATH_MAX]; char request_map_path[PATH_MAX]; char response_map_path[PATH_MAX]; char dispatch_map_path[PATH_MAX]; res = hdb_error_to_cs (hdb_handle_create (&ipc_hdb, sizeof (struct ipc_instance), handle)); if (res != CS_OK) { return (res); } res = hdb_error_to_cs (hdb_handle_get (&ipc_hdb, *handle, (void **)&ipc_instance)); if (res != CS_OK) { return (res); } res_setup.error = CS_ERR_LIBRARY; #if defined(COROSYNC_SOLARIS) request_fd = socket (PF_UNIX, SOCK_STREAM, 0); #else request_fd = socket (PF_LOCAL, SOCK_STREAM, 0); #endif if (request_fd == -1) { return (CS_ERR_LIBRARY); } #ifdef SO_NOSIGPIPE socket_nosigpipe (request_fd); #endif memset (&address, 0, sizeof (struct sockaddr_un)); address.sun_family = AF_UNIX; #if defined(COROSYNC_BSD) || defined(COROSYNC_DARWIN) address.sun_len = SUN_LEN(&address); #endif #if defined(COROSYNC_LINUX) sprintf (address.sun_path + 1, "%s", socket_name); #else sprintf (address.sun_path, "%s/%s", SOCKETDIR, socket_name); #endif sys_res = connect (request_fd, (struct sockaddr *)&address, COROSYNC_SUN_LEN(&address)); if (sys_res == -1) { res = CS_ERR_TRY_AGAIN; goto error_connect; } sys_res = memory_map ( control_map_path, "control_buffer-XXXXXX", (void *)&ipc_instance->control_buffer, 8192); if (sys_res == -1) { res = CS_ERR_LIBRARY; goto error_connect; } sys_res = memory_map ( request_map_path, "request_buffer-XXXXXX", (void *)&ipc_instance->request_buffer, request_size); if (sys_res == -1) { res = CS_ERR_LIBRARY; goto error_request_buffer; } sys_res = memory_map ( response_map_path, "response_buffer-XXXXXX", (void *)&ipc_instance->response_buffer, response_size); if (sys_res == -1) { res = CS_ERR_LIBRARY; goto error_response_buffer; } sys_res = circular_memory_map ( dispatch_map_path, "dispatch_buffer-XXXXXX", (void *)&ipc_instance->dispatch_buffer, dispatch_size); if (sys_res == -1) { res = CS_ERR_LIBRARY; goto error_dispatch_buffer; } #if _POSIX_THREAD_PROCESS_SHARED > 0 sem_init (&ipc_instance->control_buffer->sem_request_or_flush_or_exit, 1, 0); sem_init (&ipc_instance->control_buffer->sem_request, 1, 0); sem_init (&ipc_instance->control_buffer->sem_response, 1, 0); sem_init (&ipc_instance->control_buffer->sem_dispatch, 1, 0); #else { int i; /* * Allocate a semaphore segment */ while (1) { semkey = random(); ipc_instance->euid = geteuid (); if ((ipc_instance->control_buffer->semid = semget (semkey, 4, IPC_CREAT|IPC_EXCL|0600)) != -1) { break; } /* * EACCESS can be returned as non root user when opening a different * users semaphore. * * EEXIST can happen when we are a root or nonroot user opening * an existing shared memory segment for which we have access */ if (errno != EEXIST && errno != EACCES) { res = CS_ERR_LIBRARY; goto error_exit; } } for (i = 0; i < 4; i++) { semun.val = 0; sys_res = semctl (ipc_instance->control_buffer->semid, i, SETVAL, semun); if (sys_res != 0) { res = CS_ERR_LIBRARY; goto error_exit; } } } #endif /* * Initialize IPC setup message */ req_setup.service = service; strcpy (req_setup.control_file, control_map_path); strcpy (req_setup.request_file, request_map_path); strcpy (req_setup.response_file, response_map_path); strcpy (req_setup.dispatch_file, dispatch_map_path); req_setup.control_size = 8192; req_setup.request_size = request_size; req_setup.response_size = response_size; req_setup.dispatch_size = dispatch_size; #if _POSIX_THREAD_PROCESS_SHARED < 1 req_setup.semkey = semkey; #endif res = socket_send (request_fd, &req_setup, sizeof (mar_req_setup_t)); if (res != CS_OK) { goto error_exit; } res = socket_recv (request_fd, &res_setup, sizeof (mar_res_setup_t)); if (res != CS_OK) { goto error_exit; } ipc_instance->fd = request_fd; if (res_setup.error == CS_ERR_TRY_AGAIN) { res = res_setup.error; goto error_exit; } ipc_instance->control_size = 8192; ipc_instance->request_size = request_size; ipc_instance->response_size = response_size; ipc_instance->dispatch_size = dispatch_size; pthread_mutex_init (&ipc_instance->mutex, NULL); hdb_handle_put (&ipc_hdb, *handle); return (res_setup.error); error_exit: #if _POSIX_THREAD_PROCESS_SHARED < 1 if (ipc_instance->control_buffer->semid > 0) semctl (ipc_instance->control_buffer->semid, 0, IPC_RMID); #endif memory_unmap (ipc_instance->dispatch_buffer, dispatch_size); error_dispatch_buffer: memory_unmap (ipc_instance->response_buffer, response_size); error_response_buffer: memory_unmap (ipc_instance->request_buffer, request_size); error_request_buffer: memory_unmap (ipc_instance->control_buffer, 8192); error_connect: close (request_fd); hdb_handle_destroy (&ipc_hdb, *handle); hdb_handle_put (&ipc_hdb, *handle); return (res); }