static int my_com_netsplit_Nih_Test_colour_set (NihDBusObject * object, NihDBusMessage * message, DBusMessageIter *iter) { DBusMessageIter variter; const char * value_dbus; char * value; nih_assert (object != NULL); nih_assert (message != NULL); nih_assert (iter != NULL); /* Recurse into the variant */ if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_VARIANT) { nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS, "Invalid arguments to colour property"); return -1; } dbus_message_iter_recurse (iter, &variter); /* Demarshal a char * from the message */ if (dbus_message_iter_get_arg_type (&variter) != DBUS_TYPE_STRING) { nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS, "Invalid arguments to colour property"); return -1; } dbus_message_iter_get_basic (&variter, &value_dbus); value = nih_strdup (message, value_dbus); if (! value) { nih_error_raise_no_memory (); return -1; } dbus_message_iter_next (&variter); dbus_message_iter_next (iter); if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_INVALID) { nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS, "Invalid arguments to colour property"); return -1; } /* Call the handler function */ if (my_test_set_colour (object->data, message, value) < 0) return -1; return 0; }
int get_pid_cgroup_abs_main (void *parent, char *controller, struct ucred p, struct ucred r, struct ucred v, char **output) { DBusMessage *message; DBusMessageIter iter; int sv[2], ret = -1; char s[MAXPATHLEN] = { 0 }; if (memcmp(&p, &r, sizeof(struct ucred)) != 0) { nih_error("%s: proxy != requestor", __func__); return -1; } if (!(message = start_dbus_request("GetPidCgroupAbsScm", sv))) { nih_error("%s: error starting dbus request", __func__); return -1; } dbus_message_iter_init_append(message, &iter); if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &controller)) { dbus_message_unref(message); nih_error("%s: out of memory", __func__); goto out; } if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_UNIX_FD, &sv[1])) { dbus_message_unref(message); nih_error("%s: out of memory", __func__); goto out; } if (!complete_dbus_request(message, sv, &r, &v)) { nih_error("%s: error completing dbus request", __func__); goto out; } if (proxyrecv(sv[0], s, MAXPATHLEN-1) <= 0) nih_error("%s: Error reading result from cgmanager", __func__); else { *output = NIH_MUST( nih_strdup(parent, s) ); ret = 0; } out: close(sv[0]); close(sv[1]); return ret; }
static void get_active_controllers(void) { int i; nih_local char **list = cgm_list_controllers(); if (!list) { mysyslog(LOG_NOTICE, "unable to detect controllers"); ctrl_list = NIH_MUST( nih_strdup(NULL, "all") ); return; } for (i = 0; list[i]; i++) { if (strcmp(list[i], "name=systemd") == 0) continue; NIH_MUST( nih_strcat_sprintf(&ctrl_list, NULL, "%s%s", ctrl_list ? "," : "", list[i]) ); } }
char *get_my_cgroup() { char line[1024], *ret = NULL; FILE *f = fopen("/proc/self/cgroup", "r"); while (fgets(line, 1024, f)) { char *p, *p2; if ((p = strchr(line, ':')) == NULL) continue; p++; if ((p2 = strchr(p, ':')) == NULL) continue; if (strncmp(p, "name=", 5) == 0) continue; ret = NIH_MUST( nih_strdup(NULL, p2+1) ); break; } fclose(f); return ret; }
/** * nih_dbus_error_raise_printf: * @name: D-Bus name for error, * @format: format string for human-readable message. * * Raises an error which includes a D-Bus name so that it may be sent as * a reply to a method call, the error type is fixed to NIH_DBUS_ERROR. * * The human-readable message for the error is parsed according to @format, * and allocated as a child of the error object so that it is freed. * * You may use this in D-Bus handlers and return a negative number to * automatically have this error returned as the method reply. It is also * useful when mixing D-Bus and libnih function calls in your own methods * to return consistent error forms, in which case pass the name and message * members of the DBusError structure before freeing it. **/ void nih_dbus_error_raise_printf (const char *name, const char *format, ...) { NihDBusError *err; va_list args; nih_assert (name != NULL); nih_assert (format != NULL); err = NIH_MUST (nih_new (NULL, NihDBusError)); err->number = NIH_DBUS_ERROR; err->name = NIH_MUST (nih_strdup (err, name)); va_start (args, format); err->message = NIH_MUST (nih_vsprintf (err, format, args)); va_end (args); nih_error_raise_error ((NihError *)err); }
/** * session_new: * @parent: parent, * @chroot: full chroot path, * @user: user id. * * Create a new session. * * Return new Session, or NULL on error. **/ Session * session_new (const void *parent, const char *chroot, uid_t user) { Session *session; nih_assert ((chroot != NULL) || (user != 0)); session_init (); session = nih_new (parent, Session); if (! session) return NULL; nih_list_init (&session->entry); if (chroot) { session->chroot = nih_strdup (session, chroot); if (! session->chroot) { nih_free (session); return NULL; } } else { session->chroot = NULL; } session->user = user; session->conf_path = NULL; nih_alloc_set_destructor (session, nih_list_destroy); nih_list_add (sessions, &session->entry); return session; }
/** * _nih_error_raise_system: * @filename: filename where the error was raised, * @line: line number of @filename where the error was raised, * @function: function name the error was raised within. * * Raises an error with details taken from the current value of errno, * if an unhandled error already exists then an error message is emmitted * through the logging system; you should try to avoid this. * * This function should never be called directly, instead use the * nih_error_raise_system() macro to pass the correct arguments for @filename, * @line and @function. **/ void _nih_error_raise_system (const char *filename, int line, const char *function) { NihError *error; int saved_errno; nih_assert (filename != NULL); nih_assert (line > 0); nih_assert (function != NULL); nih_assert (errno > 0); saved_errno = errno; nih_error_init (); error = NIH_MUST (nih_new (NULL, NihError)); error->number = saved_errno; error->message = NIH_MUST (nih_strdup (error, strerror (saved_errno))); _nih_error_raise_error (filename, line, function, error); errno = saved_errno; }
int my_method_sync (const void * parent, NihDBusProxy * proxy, MyMethodStructure **structure) { DBusMessage * method_call; DBusMessageIter iter; DBusError error; DBusMessage * reply; MyMethodStructure *structure_local; DBusMessageIter structure_local_iter; const char * structure_local_item0_dbus; char * structure_local_item0; uint32_t structure_local_item1; nih_assert (proxy != NULL); nih_assert (structure != NULL); /* Construct the method call message. */ method_call = dbus_message_new_method_call (proxy->name, proxy->path, "com.netsplit.Nih.Test", "Method"); if (! method_call) nih_return_no_memory_error (-1); dbus_message_set_auto_start (method_call, proxy->auto_start); dbus_message_iter_init_append (method_call, &iter); /* Send the message, and wait for the reply. */ dbus_error_init (&error); reply = dbus_connection_send_with_reply_and_block (proxy->connection, method_call, -1, &error); if (! reply) { dbus_message_unref (method_call); if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) { nih_error_raise_no_memory (); } else { nih_dbus_error_raise (error.name, error.message); } dbus_error_free (&error); return -1; } dbus_message_unref (method_call); /* Iterate the arguments of the reply */ dbus_message_iter_init (reply, &iter); do { __label__ enomem; /* Demarshal a structure from the message */ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT) { dbus_message_unref (reply); nih_return_error (-1, NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); } dbus_message_iter_recurse (&iter, &structure_local_iter); structure_local = nih_new (parent, MyMethodStructure); if (! structure_local) { *structure = NULL; goto enomem; } /* Demarshal a char * from the message */ if (dbus_message_iter_get_arg_type (&structure_local_iter) != DBUS_TYPE_STRING) { nih_free (structure_local); dbus_message_unref (reply); nih_return_error (-1, NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); } dbus_message_iter_get_basic (&structure_local_iter, &structure_local_item0_dbus); structure_local_item0 = nih_strdup (structure_local, structure_local_item0_dbus); if (! structure_local_item0) { nih_free (structure_local); *structure = NULL; goto enomem; } dbus_message_iter_next (&structure_local_iter); structure_local->item0 = structure_local_item0; /* Demarshal a uint32_t from the message */ if (dbus_message_iter_get_arg_type (&structure_local_iter) != DBUS_TYPE_UINT32) { nih_free (structure_local); dbus_message_unref (reply); nih_return_error (-1, NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); } dbus_message_iter_get_basic (&structure_local_iter, &structure_local_item1); dbus_message_iter_next (&structure_local_iter); structure_local->item1 = structure_local_item1; if (dbus_message_iter_get_arg_type (&structure_local_iter) != DBUS_TYPE_INVALID) { nih_free (structure_local); dbus_message_unref (reply); nih_return_error (-1, NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); } dbus_message_iter_next (&iter); *structure = structure_local; enomem: __attribute__ ((unused)); } while (! *structure); if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) { nih_free (structure_local); *structure = NULL; dbus_message_unref (reply); nih_return_error (-1, NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); } dbus_message_unref (reply); return 0; }
int list_children_main (void *parent, char *controller, const char *cgroup, struct ucred p, struct ucred r, char ***output) { DBusMessage *message; DBusMessageIter iter; int sv[2], ret = -1; uint32_t len; int32_t nrkids; nih_local char * paths = NULL; char *s; int i; *output = NULL; if (memcmp(&p, &r, sizeof(struct ucred)) != 0) { nih_error("%s: proxy != requestor", __func__); return -1; } if (!sane_cgroup(cgroup)) { nih_error("%s: unsafe cgroup", __func__); return -1; } if (!(message = start_dbus_request("ListChildrenScm", sv))) { nih_error("%s: error starting dbus request", __func__); return -1; } dbus_message_iter_init_append(message, &iter); if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &controller)) { nih_error("%s: out of memory", __func__); dbus_message_unref(message); goto out; } if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &cgroup)) { nih_error("%s: out of memory", __func__); dbus_message_unref(message); goto out; } if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_UNIX_FD, &sv[1])) { nih_error("%s: out of memory", __func__); dbus_message_unref(message); goto out; } if (!complete_dbus_request(message, sv, &r, NULL)) { nih_error("%s: error completing dbus request", __func__); goto out; } if (proxyrecv(sv[0], &nrkids, sizeof(int32_t)) != sizeof(int32_t)) goto out; if (nrkids == 0) { ret = 0; goto out; } if (nrkids < 0) { nih_error("%s: Server encountered an error: bad cgroup?", __func__); ret = -1; goto out; } if (proxyrecv(sv[0], &len, sizeof(uint32_t)) != sizeof(uint32_t)) goto out; paths = nih_alloc(NULL, len+1); paths[len] = '\0'; if (read(sv[0], paths, len) != len) { nih_error("%s: Failed getting paths from server", __func__); goto out; } *output = NIH_MUST( nih_alloc(parent, sizeof( char*)*(nrkids+1)) ); memset(*output, 0, (nrkids + 1) * sizeof(char *)); s = paths; for (i=0; i<nrkids; i++) { if (s > paths + len) { ret = -1; nih_error("%s: corrupted result from cgmanager", __func__); goto out; } (*output)[i] = NIH_MUST( nih_strdup(parent, s) ); s += strlen(s) + 1; } ret = nrkids; out: close(sv[0]); close(sv[1]); return ret; }
int get_value_main (void *parent, char *controller, const char *cgroup, const char *key, struct ucred p, struct ucred r, char **value) { DBusMessage *message; DBusMessageIter iter; int sv[2], ret = -1; char output[MAXPATHLEN] = { 0 }; if (memcmp(&p, &r, sizeof(struct ucred)) != 0) { nih_error("%s: proxy != requestor", __func__); return -1; } if (!sane_cgroup(cgroup)) { nih_error("%s: unsafe cgroup", __func__); return -1; } if (!(message = start_dbus_request("GetValueScm", sv))) { nih_error("%s: error starting dbus request", __func__); return -1; } dbus_message_iter_init_append(message, &iter); if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &controller)) { nih_error("%s: out of memory", __func__); dbus_message_unref(message); goto out; } if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &cgroup)) { nih_error("%s: out of memory", __func__); dbus_message_unref(message); goto out; } if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key)) { nih_error("%s: out of memory", __func__); dbus_message_unref(message); goto out; } if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_UNIX_FD, &sv[1])) { nih_error("%s: out of memory", __func__); dbus_message_unref(message); goto out; } if (!complete_dbus_request(message, sv, &r, NULL)) { nih_error("%s: error completing dbus request", __func__); goto out; } if (proxyrecv(sv[0], output, MAXPATHLEN) <= 0) { nih_error("%s: Failed reading string from cgmanager: %s", __func__, strerror(errno)); } else { *value = NIH_MUST( nih_strdup(parent, output) ); ret = 0; } out: close(sv[0]); close(sv[1]); return ret; }
static DBusHandlerResult my_com_netsplit_Nih_Test_Poke_method (NihDBusObject * object, NihDBusMessage *message) { DBusMessageIter iter; DBusMessage * reply; uint32_t address; char * value; const char * value_dbus; nih_assert (object != NULL); nih_assert (message != NULL); /* Iterate the arguments to the message and demarshal into arguments * for our own function call. */ dbus_message_iter_init (message->message, &iter); /* Demarshal a uint32_t from the message */ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32) { reply = dbus_message_new_error (message->message, DBUS_ERROR_INVALID_ARGS, "Invalid arguments to Poke method"); if (! reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; if (! dbus_connection_send (message->connection, reply, NULL)) { dbus_message_unref (reply); return DBUS_HANDLER_RESULT_NEED_MEMORY; } dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } dbus_message_iter_get_basic (&iter, &address); dbus_message_iter_next (&iter); /* Demarshal a char * from the message */ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) { reply = dbus_message_new_error (message->message, DBUS_ERROR_INVALID_ARGS, "Invalid arguments to Poke method"); if (! reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; if (! dbus_connection_send (message->connection, reply, NULL)) { dbus_message_unref (reply); return DBUS_HANDLER_RESULT_NEED_MEMORY; } dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } dbus_message_iter_get_basic (&iter, &value_dbus); value = nih_strdup (message, value_dbus); if (! value) { return DBUS_HANDLER_RESULT_NEED_MEMORY; } dbus_message_iter_next (&iter); if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) { reply = dbus_message_new_error (message->message, DBUS_ERROR_INVALID_ARGS, "Invalid arguments to Poke method"); if (! reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; if (! dbus_connection_send (message->connection, reply, NULL)) { dbus_message_unref (reply); return DBUS_HANDLER_RESULT_NEED_MEMORY; } dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } /* Call the handler function */ nih_error_push_context (); if (my_test_poke (object->data, message, address, value) < 0) { NihError *err; err = nih_error_get (); if (err->number == ENOMEM) { nih_free (err); nih_error_pop_context (); return DBUS_HANDLER_RESULT_NEED_MEMORY; } else if (err->number == NIH_DBUS_ERROR) { NihDBusError *dbus_err = (NihDBusError *)err; reply = NIH_MUST (dbus_message_new_error (message->message, dbus_err->name, err->message)); nih_free (err); nih_error_pop_context (); NIH_MUST (dbus_connection_send (message->connection, reply, NULL)); dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } else { reply = NIH_MUST (dbus_message_new_error (message->message, DBUS_ERROR_FAILED, err->message)); nih_free (err); nih_error_pop_context (); NIH_MUST (dbus_connection_send (message->connection, reply, NULL)); dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; } } nih_error_pop_context (); /* If the sender doesn't care about a reply, don't bother wasting * effort constructing and sending one. */ if (dbus_message_get_no_reply (message->message)) return DBUS_HANDLER_RESULT_HANDLED; do { __label__ enomem; /* Construct the reply message. */ reply = dbus_message_new_method_return (message->message); if (! reply) goto enomem; dbus_message_iter_init_append (reply, &iter); enomem: __attribute__ ((unused)); } while (! reply); /* Send the reply, appending it to the outgoing queue. */ NIH_MUST (dbus_connection_send (message->connection, reply, NULL)); dbus_message_unref (reply); return DBUS_HANDLER_RESULT_HANDLED; }
int list_keys_main (void *parent, char *controller, const char *cgroup, struct ucred p, struct ucred r, struct keys_return_type ***output) { DBusMessage *message; DBusMessageIter iter; int sv[2], ret = -1; uint32_t len; int32_t nrkeys; nih_local char * results = NULL; char *s; int i; *output = NULL; if (memcmp(&p, &r, sizeof(struct ucred)) != 0) { nih_error("%s: proxy != requestor", __func__); return -1; } if (!sane_cgroup(cgroup)) { nih_error("%s: unsafe cgroup", __func__); return -1; } if (!(message = start_dbus_request("ListKeysScm", sv))) { nih_error("%s: error starting dbus request", __func__); return -1; } dbus_message_iter_init_append(message, &iter); if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &controller)) { nih_error("%s: out of memory", __func__); dbus_message_unref(message); goto out; } if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &cgroup)) { nih_error("%s: out of memory", __func__); dbus_message_unref(message); goto out; } if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_UNIX_FD, &sv[1])) { nih_error("%s: out of memory", __func__); dbus_message_unref(message); goto out; } if (!complete_dbus_request(message, sv, &r, NULL)) { nih_error("%s: error completing dbus request", __func__); goto out; } if (proxyrecv(sv[0], &nrkeys, sizeof(int32_t)) != sizeof(int32_t)) goto out; if (nrkeys == 0) { ret = 0; goto out; } if (nrkeys < 0) { nih_error("%s: Server encountered an error: bad cgroup?", __func__); ret = -1; goto out; } if (proxyrecv(sv[0], &len, sizeof(uint32_t)) != sizeof(uint32_t)) goto out; results = nih_alloc(NULL, len+1); results[len] = '\0'; if (read(sv[0], results, len) != len) { nih_error("%s: Failed getting results from server", __func__); goto out; } *output = NIH_MUST( nih_alloc(parent, sizeof(**output)*(nrkeys+1)) ); memset(*output, 0, (nrkeys + 1) * sizeof(**output)); s = results; for (i=0; i<nrkeys; i++) { struct keys_return_type *tmp; char *s2 = find_eol(s); if (s2 > results + len) goto bad; *s2 = '\0'; (*output)[i] = tmp = NIH_MUST( nih_new(*output, struct keys_return_type) ); tmp->name = NIH_MUST( nih_strdup(tmp, s) ); s = s2 + 1; s2 = find_eol(s); if (s2 > results + len) goto bad; if (sscanf(s, "%u\n", &tmp->uid) != 1) goto bad; s = s2 + 1; s2 = find_eol(s); if (sscanf(s, "%u\n", &tmp->gid) != 1) goto bad; s = s2 + 1; s2 = find_eol(s); if (sscanf(s, "%u\n", &tmp->perms) != 1) goto bad; s = s2 + 1; } ret = nrkeys; out: close(sv[0]); close(sv[1]); return ret; bad: ret = -1; nih_error("%s: corrupted result from cgmanager", __func__); goto out; }
void test_strncat (void) { char *str, *ret; TEST_FUNCTION ("nih_strncat"); /* Check that we can extend a string with the first number of bytes * from another, resulting in the original string being modified and * the new pointer stored in the argument and returned. */ TEST_FEATURE ("with larger string than length"); TEST_ALLOC_FAIL { char *tmp; TEST_ALLOC_SAFE { str = nih_strdup (NULL, "this is a test"); } tmp = str; ret = nih_strncat (&str, NULL, " of strndup", 3); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, tmp); TEST_EQ_STR (str, "this is a test"); nih_free (str); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 18); TEST_EQ_STR (str, "this is a test of"); nih_free (str); } /* Check that if a longer length than the string is given, enough * space is reserved but the string copy stops at the NULL. */ TEST_FEATURE ("with larger length than string"); TEST_ALLOC_FAIL { char *tmp; TEST_ALLOC_SAFE { str = nih_strdup (NULL, "this is a test"); } tmp = str; ret = nih_strncat (&str, NULL, " of strndup", 21); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, tmp); TEST_EQ_STR (str, "this is a test"); nih_free (str); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 36); TEST_EQ_STR (str, "this is a test of strndup"); nih_free (str); } /* Check that when no string is passed, this behaves as strndup. */ TEST_FEATURE ("with NULL"); TEST_ALLOC_FAIL { str = NULL; ret = nih_strncat (&str, NULL, "test of strndup", 12); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, NULL); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 13); TEST_EQ_STR (str, "test of strn"); nih_free (str); } }
void test_cgroup_new (void) { nih_local char *parent = NULL; CGroup *cgroup; TEST_FUNCTION ("cgroup_new"); parent = nih_strdup (NULL, "a parent object"); TEST_NE_P (parent, NULL); TEST_FEATURE ("no parent, controller"); TEST_ALLOC_FAIL { cgroup = cgroup_new (NULL, "cpuset"); if (test_alloc_failed) { TEST_EQ_P (cgroup, NULL); continue; } TEST_NE_P (cgroup, NULL); TEST_ALLOC_SIZE (cgroup, sizeof (CGroup)); TEST_ALLOC_PARENT (cgroup, NULL); TEST_EQ_STR (cgroup->controller, "cpuset"); TEST_ALLOC_SIZE (cgroup->controller, 1+strlen ("cpuset")); TEST_ALLOC_PARENT (cgroup->controller, cgroup); TEST_LIST_EMPTY (&cgroup->names); nih_free (cgroup); } TEST_FEATURE ("parent, controller"); TEST_ALLOC_FAIL { cgroup = cgroup_new (parent, "perf_event"); if (test_alloc_failed) { TEST_EQ_P (cgroup, NULL); continue; } TEST_NE_P (cgroup, NULL); TEST_ALLOC_SIZE (cgroup, sizeof (CGroup)); TEST_ALLOC_PARENT (cgroup, parent); TEST_EQ_STR (cgroup->controller, "perf_event"); TEST_ALLOC_SIZE (cgroup->controller, 1+strlen ("perf_event")); TEST_ALLOC_PARENT (cgroup->controller, cgroup); TEST_LIST_EMPTY (&cgroup->names); nih_free (cgroup); } }
void my_com_netsplit_Nih_Test_property_get_notify (DBusPendingCall * pending_call, NihDBusPendingData *pending_data) { DBusMessage * reply; DBusMessageIter iter; DBusMessageIter variter; NihDBusMessage *message; DBusError error; const char * value_dbus; char * value; nih_assert (pending_call != NULL); nih_assert (pending_data != NULL); nih_assert (dbus_pending_call_get_completed (pending_call)); /* Steal the reply from the pending call. */ reply = dbus_pending_call_steal_reply (pending_call); nih_assert (reply != NULL); /* Handle error replies */ if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { message = NIH_MUST (nih_dbus_message_new (pending_data, pending_data->connection, reply)); dbus_error_init (&error); dbus_set_error_from_message (&error, message->message); nih_error_push_context (); nih_dbus_error_raise (error.name, error.message); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); dbus_error_free (&error); nih_free (message); dbus_message_unref (reply); return; } nih_assert (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN); do { __label__ enomem; /* Create a message context for the reply, and iterate * over and recurse into the arguments. */ message = nih_dbus_message_new (pending_data, pending_data->connection, reply); if (! message) goto enomem; dbus_message_iter_init (message->message, &iter); if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_VARIANT) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } dbus_message_iter_recurse (&iter, &variter); /* Demarshal a char * from the message */ if (dbus_message_iter_get_arg_type (&variter) != DBUS_TYPE_STRING) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } dbus_message_iter_get_basic (&variter, &value_dbus); value = nih_strdup (message, value_dbus); if (! value) { nih_free (message); message = NULL; goto enomem; } dbus_message_iter_next (&variter); dbus_message_iter_next (&iter); if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } enomem: __attribute__ ((unused)); } while (! message); /* Call the handler function */ nih_error_push_context (); ((MyGetPropertyReply)pending_data->handler) (pending_data->data, message, value); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); }
void test_libupstart (void) { nih_local NihDBusProxy *upstart = NULL; nih_local char *version = NULL; int ret; pid_t upstart_pid; pid_t dbus_pid; char xdg_runtime_dir[PATH_MAX]; nih_local char *orig_xdg_runtime_dir = NULL; nih_local char *session_file = NULL; nih_local char *path = NULL; TEST_GROUP ("libupstart"); TEST_FEATURE ("version"); TEST_FILENAME (xdg_runtime_dir); TEST_EQ (mkdir (xdg_runtime_dir, 0755), 0); /* Take care to avoid disrupting users environment by saving and * restoring this variable (assuming the tests all pass...). */ orig_xdg_runtime_dir = getenv ("XDG_RUNTIME_DIR"); if (orig_xdg_runtime_dir) orig_xdg_runtime_dir = NIH_MUST (nih_strdup (NULL, orig_xdg_runtime_dir)); assert0 (setenv ("XDG_RUNTIME_DIR", xdg_runtime_dir, 1)); /*******************************************************************/ /* Create a private Session Init instance to connect to */ TEST_DBUS (dbus_pid); START_UPSTART (upstart_pid, TRUE); upstart = upstart_open (NULL); TEST_NE_P (upstart, NULL); /* Basic test (that does not change the state of the system * running this test) to see if we can query version of running * Upstart instance. */ ret = upstart_get_version_sync (NULL, upstart, &version); TEST_EQ (ret, 0); nih_message ("Running instance version: '%s'", version); assert0 (fnmatch ("init (upstart*)", version, 0x0)); STOP_UPSTART (upstart_pid); TEST_DBUS_END (dbus_pid); /*******************************************************************/ if (orig_xdg_runtime_dir) { /* restore */ setenv ("XDG_RUNTIME_DIR", orig_xdg_runtime_dir, 1); } else { assert0 (unsetenv ("XDG_RUNTIME_DIR")); } session_file = get_session_file (xdg_runtime_dir, upstart_pid); unlink (session_file); /* Remove the directory tree the Session Init created */ path = NIH_MUST (nih_sprintf (NULL, "%s/upstart/sessions", xdg_runtime_dir)); assert0 (rmdir (path)); path = NIH_MUST (nih_sprintf (NULL, "%s/upstart", xdg_runtime_dir)); assert0 (rmdir (path)); assert0 (rmdir (xdg_runtime_dir)); }
/** * warning_message: * @message: user message. * * Prefixes the message with details about how long until the shutdown * completes. * * Returns: newly allocated string. **/ static char * warning_message (const char *message) { nih_local char *banner = NULL; char * msg; nih_assert (message != NULL); if ((runlevel == '0') && init_halt && (! strcmp (init_halt, "POWEROFF"))) { if (delay) { banner = nih_sprintf ( NULL, _n("The system is going down for " "power off in %d minute!", "The system is going down for " "power off in %d minutes!", delay), delay); } else { banner = nih_strdup ( NULL, _("The system is going down for " "power off NOW!")); } } else if (runlevel == '0') { if (delay) { banner = nih_sprintf ( NULL, _n("The system is going down for " "halt in %d minute!", "The system is going down for " "halt in %d minutes!", delay), delay); } else { banner = nih_strdup ( NULL, _("The system is going down for " "halt NOW!")); } } else if (runlevel == '1') { if (delay) { banner = nih_sprintf ( NULL, _n("The system is going down for " "maintenance in %d minute!", "The system is going down for " "maintenance in %d minutes!", delay), delay); } else { banner = nih_strdup ( NULL, _("The system is going down for " "maintenance NOW!")); } } else if (runlevel == '6') { if (delay) { banner = nih_sprintf ( NULL, _n("The system is going down for " "reboot in %d minute!", "The system is going down for " "reboot in %d minutes!", delay), delay); } else { banner = nih_strdup ( NULL, _("The system is going down for " "reboot NOW!")); } } if (! banner) return NULL; msg = nih_sprintf (NULL, "\r%s\r\n%s", banner, message); return msg; }
int main (int argc, char *argv[]) { char ** args; nih_local char *message = NULL; size_t messagelen; nih_local char *msg = NULL; int arg; pid_t pid = 0; nih_main_init (argv[0]); nih_option_set_usage (_("TIME [MESSAGE]")); nih_option_set_synopsis (_("Bring the system down.")); nih_option_set_help ( _("TIME may have different formats, the most common is simply " "the word 'now' which will bring the system down " "immediately. Other valid formats are +m, where m is the " "number of minutes to wait until shutting down and hh:mm " "which specifies the time on the 24hr clock.\n" "\n" "Logged in users are warned by a message sent to their " "terminal, you may include an optional MESSAGE included " "with this. Messages can be sent without actually " "bringing the system down by using the -k option.\n" "\n" "If TIME is given, the command will remain in the " "foreground until the shutdown occurs. It can be cancelled " "by Control-C, or by another user using the -c option.\n" "\n" "The system is brought down into maintenance (single-user) " "mode by default, you can change this with either the -r or " "-h option which specify a reboot or system halt " "respectively. The -h option can be further modified with " "-H or -P to specify whether to halt the system, or to " "power it off afterwards. The default is left up to the " "shutdown scripts.")); args = nih_option_parser (NULL, argc, argv, options, FALSE); if (! args) exit (1); /* If the runlevel wasn't given explicitly, set it to 1 so we go * down into single-user mode. */ if (! runlevel) { runlevel = '1'; init_halt = NULL; } /* When may be specified with -g, or must be first argument */ if (! (cancel || when || args[0])) { fprintf (stderr, _("%s: time expected\n"), program_name); nih_main_suggest_help (); exit (1); } else if (! (cancel || when)) { when = NIH_MUST (nih_strdup (NULL, args[0])); arg = 1; } else { arg = 0; } /* Parse the time argument */ if (when) { if (! strcmp (when, "now")) { /* "now" means, err, now */ delay = 0; } else if (strchr (when, ':')) { /* Clock time */ long hours, mins; char *endptr; struct tm *tm; time_t now; hours = strtoul (when, &endptr, 10); if ((*endptr != ':') || (hours < 0) || (hours > 23)) { fprintf (stderr, _("%s: illegal hour value\n"), program_name); nih_main_suggest_help (); exit (1); } mins = strtoul (endptr + 1, &endptr, 10); if (*endptr || (mins < 0) || (mins > 59)) { fprintf (stderr, _("%s: illegal minute value\n"), program_name); nih_main_suggest_help (); exit (1); } /* Subtract the current time to get the delay. * Add a whole day if we go negative */ now = time (NULL); tm = localtime (&now); delay = (((hours * 60) + mins) - ((tm->tm_hour * 60) + tm->tm_min)); if (delay < 0) delay += 1440; } else { /* Delay in minutes */ char *endptr; delay = strtoul (when, &endptr, 10); if (*endptr || (delay < 0)) { fprintf (stderr, _("%s: illegal time value\n"), program_name); nih_main_suggest_help (); exit (1); } } nih_free (when); } /* The rest of the arguments are a message. * Really this should be just the next argument, but that's not * how this has been traditionally done *sigh* */ message = NIH_MUST (nih_strdup (NULL, "")); messagelen = 0; for (; args[arg]; arg++) { message = NIH_MUST (nih_realloc ( message, NULL, messagelen + strlen(args[arg]) + 4)); strcat (message, args[arg]); strcat (message, " "); messagelen += strlen (args[arg]) + 1; } /* Terminate with \r\n */ if (messagelen) strcat (message, "\r\n"); /* Check we're root, or setuid root */ setuid (geteuid ()); if (getuid ()) { nih_fatal (_("Need to be root")); exit (1); } /* Look for an existing pid file and deal with the existing * process if there is one. */ pid = nih_main_read_pidfile (); if (pid > 0) { if (cancel) { if (kill (pid, SIGINT) < 0) { nih_error (_("Shutdown is not running")); exit (1); } if (messagelen) wall (message); exit (0); } else if (kill (pid, 0) == 0) { nih_error (_("Another shutdown is already running")); exit (1); } } else if (cancel) { nih_error (_("Cannot find pid of running shutdown")); exit (1); } /* Send an initial message */ msg = NIH_MUST (warning_message (message)); wall (msg); if (warn_only) exit (0); /* Give us a sane environment */ if (chdir ("/") < 0) nih_warn ("%s: %s", _("Unable to change directory"), strerror (errno)); umask (022); /* Shutdown now? */ if (! delay) shutdown_now (); /* Save our pid so we can be interrupted later */ if (nih_main_write_pidfile (getpid ()) < 0) { NihError *err; err = nih_error_get (); nih_warn ("%s: %s: %s", nih_main_get_pidfile(), _("Unable to write pid file"), err->message); nih_free (err); } /* Ignore a whole bunch of signals */ nih_signal_set_ignore (SIGCHLD); nih_signal_set_ignore (SIGHUP); nih_signal_set_ignore (SIGTSTP); nih_signal_set_ignore (SIGTTIN); nih_signal_set_ignore (SIGTTOU); /* Catch the usual quit signals */ nih_signal_set_handler (SIGINT, nih_signal_handler); NIH_MUST (nih_signal_add_handler (NULL, SIGINT, cancel_callback, NULL)); nih_signal_set_handler (SIGQUIT, nih_signal_handler); NIH_MUST (nih_signal_add_handler (NULL, SIGQUIT, cancel_callback, NULL)); nih_signal_set_handler (SIGTERM, nih_signal_handler); NIH_MUST (nih_signal_add_handler (NULL, SIGTERM, cancel_callback, NULL)); /* Call a timer every minute until we shutdown */ NIH_MUST (nih_timer_add_periodic (NULL, 60, (NihTimerCb)timer_callback, message)); /* Hang around */ nih_main_loop (); return 0; }
void test_strcat_vsprintf (void) { char *str, *ret; TEST_FUNCTION ("test_strcat_vsprintf"); /* Check that we can extend a string with a formatted string, * resulting in the original string being modified and the new * pointer stored in the argument and returned. */ TEST_FEATURE ("with original string"); TEST_ALLOC_FAIL { char *tmp; TEST_ALLOC_SAFE { str = nih_strdup (NULL, "this"); } tmp = str; ret = my_strcat_vsprintf (&str, NULL, " %s a test %d", "is", 54321); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, tmp); TEST_EQ_STR (str, "this"); nih_free (str); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 21); TEST_EQ_STR (str, "this is a test 54321"); nih_free (str); } /* Check that when no string is passed, this behaves as sprintf. */ TEST_FEATURE ("with NULL"); TEST_ALLOC_FAIL { str = NULL; ret = my_strcat_vsprintf (&str, NULL, "%s a test %d", "is", 54321); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, NULL); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 15); TEST_EQ_STR (str, "is a test 54321"); nih_free (str); } }
int main (int argc, char *argv[]) { NihList prototypes; NihList typedefs; NihList structs; nih_local Interface *interface = NULL; nih_local Property * property = NULL; nih_local char * code = NULL; nih_local char * block = NULL; printf ("#include <dbus/dbus.h>\n" "\n" "#include <nih/macros.h>\n" "#include <nih/alloc.h>\n" "#include <nih/string.h>\n" "#include <nih/logging.h>\n" "#include <nih/error.h>\n" "\n" "#include <nih-dbus/dbus_error.h>\n" "#include <nih-dbus/dbus_message.h>\n" "#include <nih-dbus/dbus_object.h>\n" "#include <nih-dbus/dbus_pending_data.h>\n" "#include <nih-dbus/dbus_proxy.h>\n" "#include <nih-dbus/errors.h>\n" "\n" "#include \"tests/interface_code.h\"\n" "\n" "\n"); interface = interface_new (NULL, "com.netsplit.Nih.Test"); interface->symbol = NULL; property = property_new (interface, "name", "s", NIH_DBUS_READWRITE); property->symbol = nih_strdup (property, "name"); nih_list_add (&interface->properties, &property->entry); property = property_new (interface, "size", "u", NIH_DBUS_READWRITE); property->symbol = nih_strdup (property, "size"); nih_list_add (&interface->properties, &property->entry); nih_list_init (&prototypes); nih_list_init (&structs); interface->name = "com.netsplit.Nih.TestA"; code = interface_proxy_get_all_function (NULL, "my", interface, &prototypes, &structs); printf ("extern void my_com_netsplit_Nih_TestA_get_all_notify (DBusPendingCall *pending_call, " "NihDBusPendingData *pending_data);\n"); printf ("\n"); printf ("%s" "\n", code); nih_list_init (&prototypes); nih_list_init (&typedefs); nih_list_init (&structs); interface->name = "com.netsplit.Nih.Test"; code = interface_proxy_get_all_notify_function (NULL, "my", interface, &prototypes, &typedefs, &structs); printf ("%s", code); printf ("\n" "\n"); nih_list_init (&prototypes); nih_list_init (&structs); code = interface_proxy_get_all_sync_function (NULL, "my", interface, &prototypes, &structs); printf ("%s" "\n", code); return 0; }
/** * type_of: * @parent: parent object for new string, * @iter: D-Bus signature iterator. * * Converts the D-Bus basic type at the current element of the iterator * @iter into an appropriate C type to hold it. * * If @parent is not NULL, it should be a pointer to another object which * will be used as a parent for the returned string. When all parents * of the returned string are freed, the returned string will also be * freed. * * Returns: newly allocated string or NULL if allocation failed. **/ char * type_of (const void * parent, DBusSignatureIter *iter) { int dbus_type; nih_assert (iter != NULL); dbus_type = dbus_signature_iter_get_current_type (iter); switch (dbus_type) { case DBUS_TYPE_BYTE: return nih_strdup (parent, "uint8_t"); case DBUS_TYPE_BOOLEAN: return nih_strdup (parent, "int"); case DBUS_TYPE_INT16: return nih_strdup (parent, "int16_t"); case DBUS_TYPE_UINT16: return nih_strdup (parent, "uint16_t"); case DBUS_TYPE_INT32: return nih_strdup (parent, "int32_t"); case DBUS_TYPE_UINT32: return nih_strdup (parent, "uint32_t"); case DBUS_TYPE_INT64: return nih_strdup (parent, "int64_t"); case DBUS_TYPE_UINT64: return nih_strdup (parent, "uint64_t"); case DBUS_TYPE_DOUBLE: return nih_strdup (parent, "double"); case DBUS_TYPE_STRING: return nih_strdup (parent, "char *"); case DBUS_TYPE_OBJECT_PATH: return nih_strdup (parent, "char *"); case DBUS_TYPE_SIGNATURE: return nih_strdup (parent, "char *"); case DBUS_TYPE_UNIX_FD: return nih_strdup (parent, "int"); default: nih_assert_not_reached (); } }
void test_cgroup_setting_new (void) { CGroupSetting *setting; nih_local char *parent= NULL; parent = nih_strdup (NULL, "a parent object"); TEST_NE_P (parent, NULL); TEST_FUNCTION ("cgroup_setting_new"); TEST_FEATURE ("no parent, key, no value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (NULL, "foo", NULL); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, NULL); TEST_EQ_STR (setting->key, "foo"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("foo")); TEST_ALLOC_PARENT (setting->key, setting); nih_free (setting); } TEST_FEATURE ("parent, key, no value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (parent, "hello world", NULL); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, parent); TEST_EQ_STR (setting->key, "hello world"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world")); TEST_ALLOC_PARENT (setting->key, setting); nih_free (setting); } TEST_FEATURE ("no parent, key, value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (NULL, "hello world", "a value"); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, NULL); TEST_EQ_STR (setting->key, "hello world"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world")); TEST_ALLOC_PARENT (setting->key, setting); TEST_EQ_STR (setting->value, "a value"); TEST_ALLOC_SIZE (setting->value, 1+strlen ("a value")); TEST_ALLOC_PARENT (setting->value, setting); nih_free (setting); } TEST_FEATURE ("parent, key, value"); TEST_ALLOC_FAIL { setting = cgroup_setting_new (parent, "hello world", "a value"); if (test_alloc_failed) { TEST_EQ_P (setting, NULL); continue; } TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting)); TEST_ALLOC_PARENT (setting, parent); TEST_EQ_STR (setting->key, "hello world"); TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world")); TEST_ALLOC_PARENT (setting->key, setting); TEST_EQ_STR (setting->value, "a value"); TEST_ALLOC_SIZE (setting->value, 1+strlen ("a value")); TEST_ALLOC_PARENT (setting->value, setting); nih_free (setting); } }
int list_controllers_main (void *parent, char ***output) { DBusMessage *message = NULL, *reply = NULL; char ** output_local = NULL; DBusError error; DBusMessageIter iter; int ret = -1; DBusMessageIter output_local_iter; size_t output_local_size; *output = NULL; message = dbus_message_new_method_call(dbus_bus_get_unique_name(server_conn), "/org/linuxcontainers/cgmanager", "org.linuxcontainers.cgmanager0_0", "ListControllers"); dbus_error_init (&error); reply = dbus_connection_send_with_reply_and_block (server_conn, message, -1, &error); if (! reply) { dbus_message_unref (message); nih_error("%s: error completing dbus request: %s %s", __func__, error.name, error.message); dbus_error_free (&error); return -1; } dbus_message_unref (message); dbus_message_iter_init (reply, &iter); if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) goto out; dbus_message_iter_recurse (&iter, &output_local_iter); output_local_size = 0; output_local = NULL; output_local = NIH_MUST( nih_alloc (parent, sizeof (char *)) ); output_local[output_local_size] = NULL; while (dbus_message_iter_get_arg_type (&output_local_iter) != DBUS_TYPE_INVALID) { const char *output_local_element_dbus; char ** output_local_tmp; char * output_local_element; if (dbus_message_iter_get_arg_type (&output_local_iter) != DBUS_TYPE_STRING) goto out; dbus_message_iter_get_basic (&output_local_iter, &output_local_element_dbus); output_local_element = NIH_MUST( nih_strdup (output_local, output_local_element_dbus) ); dbus_message_iter_next (&output_local_iter); output_local_tmp = NIH_MUST( nih_realloc (output_local, parent, sizeof (char *) * (output_local_size + 2)) ); output_local = output_local_tmp; output_local[output_local_size] = output_local_element; output_local[output_local_size + 1] = NULL; output_local_size++; } dbus_message_iter_next (&iter); if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) goto out; *output = output_local; ret = 0; out: if (reply) dbus_message_unref (reply); if (ret) nih_free (output_local); return ret; }
max = 0; NIH_LIST_FOREACH (vars, iter) { TypeVar *var = (TypeVar *)iter; size_t this_len; this_len = strlen (var->type); if (! strchr (var->type, '*')) this_len++; if (this_len > max) max = this_len; } /* Allocate a string with each of the variables on each line. */ len = 0; str = nih_strdup (parent, ""); if (! str) return NULL; NIH_LIST_FOREACH (vars, iter) { TypeVar *var = (TypeVar *)iter; char * new_str; new_str = nih_realloc (str, parent, (len + max + strlen (var->name) + (var->array ? 2 : 0) + 3)); if (! new_str) { nih_free (str); return NULL; }
void test_strcat (void) { char *str, *ret; TEST_FUNCTION ("nih_strcat"); /* Check that we can extend a string with another, resulting in the * original string being modified and the new pointer stored in the * argument and returned. */ TEST_FEATURE ("with string"); TEST_ALLOC_FAIL { char *tmp; TEST_ALLOC_SAFE { str = nih_strdup (NULL, "this is a test"); } tmp = str; ret = nih_strcat (&str, NULL, " of strdup"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, tmp); TEST_EQ_STR (str, "this is a test"); nih_free (str); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 25); TEST_EQ_STR (str, "this is a test of strdup"); nih_free (str); } /* Check that when no string is passed, this behaves as strdup. */ TEST_FEATURE ("with NULL"); TEST_ALLOC_FAIL { str = NULL; ret = nih_strcat (&str, NULL, "test of strdup"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (str, NULL); continue; } TEST_NE (ret, NULL); TEST_EQ_P (ret, str); TEST_ALLOC_SIZE (str, 15); TEST_EQ_STR (str, "test of strdup"); nih_free (str); } }
int remove_main(const char *controller, const char *cgroup, struct ucred p, struct ucred r, int recursive, int32_t *existed) { char rcgpath[MAXPATHLEN]; size_t cgroup_len; nih_local char *working = NULL, *copy = NULL, *wcgroup = NULL; char *p1; *existed = 1; if (!sane_cgroup(cgroup)) { nih_error("%s: unsafe cgroup", __func__); return -1; } // Get r's current cgroup in rcgpath if (!compute_pid_cgroup(r.pid, controller, "", rcgpath, NULL)) { nih_error("%s: Could not determine the requested cgroup", __func__); return -1; } cgroup_len = strlen(cgroup); if (strlen(rcgpath) + cgroup_len > MAXPATHLEN) { nih_error("%s: Path name too long", __func__); return -1; } wcgroup = NIH_MUST( nih_strdup(NULL, cgroup) ); if (!normalize_path(wcgroup)) return -1; working = NIH_MUST( nih_strdup(NULL, rcgpath) ); NIH_MUST( nih_strcat(&working, NULL, "/") ); NIH_MUST( nih_strcat(&working, NULL, wcgroup) ); if (!dir_exists(working)) { *existed = -1; return 0; } // must have write access to the parent dir copy = NIH_MUST( nih_strdup(NULL, working) ); if (!(p1 = strrchr(copy, '/'))) return -1; *p1 = '\0'; if (!may_access(r.pid, r.uid, r.gid, copy, O_WRONLY)) { nih_error("%s: pid %d (%u:%u) may not remove %s", __func__, r.pid, r.uid, r.gid, copy); return -1; } if (!recursive) { if (rmdir(working) < 0) { nih_error("%s: Failed to remove %s: %s", __func__, working, strerror(errno)); return -1; } } else if (recursive_rmdir(working) < 0) return -1; nih_info(_("Removed %s for %d (%u:%u)"), working, r.pid, r.uid, r.gid); return 0; }
void my_com_netsplit_Nih_Test_get_all_notify (DBusPendingCall * pending_call, NihDBusPendingData *pending_data) { DBusMessage * reply; DBusMessageIter iter; DBusMessageIter arrayiter; DBusMessageIter dictiter; DBusMessageIter variter; NihDBusMessage *message; DBusError error; const char * property; MyProperties * properties; size_t property_count; char * name; const char * name_dbus; uint32_t size; nih_assert (pending_call != NULL); nih_assert (pending_data != NULL); nih_assert (dbus_pending_call_get_completed (pending_call)); /* Steal the reply from the pending call. */ reply = dbus_pending_call_steal_reply (pending_call); nih_assert (reply != NULL); /* Handle error replies */ if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { message = NIH_MUST (nih_dbus_message_new (pending_data, pending_data->connection, reply)); dbus_error_init (&error); dbus_set_error_from_message (&error, message->message); nih_error_push_context (); nih_dbus_error_raise (error.name, error.message); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); dbus_error_free (&error); nih_free (message); dbus_message_unref (reply); return; } nih_assert (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN); /* Create a message context for the reply, and iterate * over and recurse into the arguments. */ message = NIH_MUST (nih_dbus_message_new (pending_data, pending_data->connection, reply)); /* Iterate the method arguments, recursing into the array */ dbus_message_iter_init (reply, &iter); if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } properties = NIH_MUST (nih_new (message, MyProperties)); property_count = 0; dbus_message_iter_recurse (&iter, &arrayiter); while (dbus_message_iter_get_arg_type (&arrayiter) != DBUS_TYPE_INVALID) { __label__ enomem; if (dbus_message_iter_get_arg_type (&arrayiter) != DBUS_TYPE_DICT_ENTRY) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } dbus_message_iter_recurse (&arrayiter, &dictiter); if (dbus_message_iter_get_arg_type (&dictiter) != DBUS_TYPE_STRING) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } dbus_message_iter_get_basic (&dictiter, &property); dbus_message_iter_next (&dictiter); if (dbus_message_iter_get_arg_type (&dictiter) != DBUS_TYPE_VARIANT) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } dbus_message_iter_recurse (&dictiter, &variter); if (! strcmp (property, "name")) { /* Demarshal a char * from the message */ if (dbus_message_iter_get_arg_type (&variter) != DBUS_TYPE_STRING) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } dbus_message_iter_get_basic (&variter, &name_dbus); name = nih_strdup (properties, name_dbus); if (! name) { goto enomem; } dbus_message_iter_next (&variter); properties->name = name; nih_assert (++property_count); } if (! strcmp (property, "size")) { /* Demarshal a uint32_t from the message */ if (dbus_message_iter_get_arg_type (&variter) != DBUS_TYPE_UINT32) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } dbus_message_iter_get_basic (&variter, &size); dbus_message_iter_next (&variter); properties->size = size; nih_assert (++property_count); } dbus_message_iter_next (&dictiter); if (dbus_message_iter_get_arg_type (&dictiter) != DBUS_TYPE_INVALID) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } dbus_message_iter_next (&arrayiter); enomem: __attribute__ ((unused)); } dbus_message_iter_next (&iter); if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } if (property_count < 2) { nih_error_push_context (); nih_error_raise (NIH_DBUS_INVALID_ARGS, _(NIH_DBUS_INVALID_ARGS_STR)); pending_data->error_handler (pending_data->data, message); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); return; } /* Call the handler function */ nih_error_push_context (); ((MyGetAllReply)pending_data->handler) (pending_data->data, message, properties); nih_error_pop_context (); nih_free (message); dbus_message_unref (reply); }