static name_info_t * _internal_new_name(notify_state_t *ns, const char *name) { name_info_t *n; size_t namelen; if (ns == NULL) return NULL; if (name == NULL) return NULL; namelen = strlen(name) + 1; n = (name_info_t *)calloc(1, sizeof(name_info_t) + namelen); if (n == NULL) return NULL; n->subscription_table = _nc_table_new(0); if (n->subscription_table == NULL) { free(n); return NULL; } n->name = (char *)n + sizeof(name_info_t); memcpy(n->name, name, namelen); n->name_id = name_id++; n->access = NOTIFY_ACCESS_DEFAULT; n->slot = (uint32_t)-1; n->val = 1; _nc_table_insert_no_copy(ns->name_table, n->name, n); _nc_table_insert_64(ns->name_id_table, n->name_id, n); return n; }
static uint32_t _internal_register_common(notify_state_t *ns, const char *name, pid_t pid, int token, uid_t uid, gid_t gid, client_t **outc) { client_t *c; name_info_t *n; int is_new_name; uint32_t status; if (ns == NULL) return NOTIFY_STATUS_FAILED; if (name == NULL) return NOTIFY_STATUS_INVALID_NAME; if (outc == NULL) return NOTIFY_STATUS_OK; status = _internal_check_access(ns, name, uid, gid, NOTIFY_ACCESS_READ); if (status != NOTIFY_STATUS_OK) return NOTIFY_STATUS_NOT_AUTHORIZED; *outc = NULL; is_new_name = 0; n = (name_info_t *)_nc_table_find(ns->name_table, name); if (n == NULL) { is_new_name = 1; n = _internal_new_name(ns, name); if (n == NULL) return NOTIFY_STATUS_FAILED; } c = _internal_client_new(ns, pid, token); if (c == NULL) { if (is_new_name == 1) { _nc_table_delete(ns->name_table, n->name); _nc_table_free(n->subscription_table); free(n); } return NOTIFY_STATUS_FAILED; } n->refcount++; c->name_info = n; _nc_table_insert_64(n->subscription_table, c->client_id, c); *outc = c; return NOTIFY_STATUS_OK; }
static client_t * _internal_client_new(notify_state_t *ns, pid_t pid, int token) { client_t *c; uint64_t cid = make_client_id(pid, token); if (ns == NULL) return NULL; /* detect duplicates - should never happen, but it would be bad */ c = _nc_table_find_64(ns->client_table, cid); if (c != NULL) return NULL; c = calloc(1, sizeof(client_t)); if (c == NULL) return NULL; c->client_id = cid; c->pid = pid; c->send_val = token; _nc_table_insert_64(ns->client_table, cid, c); return c; }
void _nc_table_insert_n(table_t *tin, uint32_t key, void *datum) { uint64_t n64 = key; _nc_table_insert_64(tin, n64, datum); }