void test_array_addn (void) { char **array, **ret; size_t len; /* Check that we can append strings to a NULL-terminated array. */ TEST_FUNCTION ("nih_str_array_addn"); array = nih_str_array_new (NULL); len = 0; TEST_ALLOC_FAIL { ret = nih_str_array_addn (&array, NULL, &len, "testing", 4); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 1); TEST_EQ_STR (array[0], "test"); TEST_EQ_P (array[1], NULL); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_ALLOC_PARENT (array[0], array); TEST_ALLOC_SIZE (array[0], 5); TEST_EQ_STR (array[0], "test"); TEST_EQ_P (array[1], NULL); } nih_free (array); }
void test_all_valid (void) { char **env; int valid; TEST_FUNCTION ("environ_all_valid"); /* Check that a valid environment table returns TRUE. */ TEST_FEATURE ("with valid table"); env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, NULL, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, NULL, "BAR=BAZ")); valid = environ_all_valid (env); TEST_TRUE (valid); nih_free (env); /* Check that an empty environment table is valid. */ TEST_FEATURE ("with empty table"); env = nih_str_array_new (NULL); valid = environ_all_valid (env); TEST_TRUE (valid); nih_free (env); /* Check that an entry without an equals means the table is not * valid. */ TEST_FEATURE ("with missing equals"); env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, NULL, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, NULL, "BAR")); assert (nih_str_array_add (&env, NULL, NULL, "WIBBLE=woo")); valid = environ_all_valid (env); TEST_FALSE (valid); nih_free (env); }
void test_getn (void) { char **env = NULL; size_t len = 0; const char *ret; TEST_FUNCTION ("environ_getn"); len = 0; env = nih_str_array_new (NULL); /* Check that an empty table always returns NULL. */ TEST_FEATURE ("with empty table"); ret = environ_getn (env, "FOO", 3); TEST_EQ_P (ret, NULL); assert (nih_str_array_add (&env, NULL, &len, "FOOLISH=no")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); /* Check that a key that is present is returned. */ TEST_FEATURE ("with key to be found"); ret = environ_getn (env, "BAR", 3); TEST_EQ_STR (ret, "BAZ"); /* Check that a key that doesn't exist returns NULL. */ TEST_FEATURE ("with key not found"); ret = environ_getn (env, "MEEP", 4); TEST_EQ_P (ret, NULL); /* Check that the key is not prefix-matched. */ TEST_FEATURE ("with key that is prefix of another"); ret = environ_getn (env, "FOO", 3); TEST_EQ_P (ret, NULL); /* Check that the length is honoured. */ TEST_FEATURE ("with longer key"); ret = environ_getn (env, "FOOLISH", 3); TEST_EQ_P (ret, NULL); nih_free (env); }
void test_set (void) { char **env = NULL, **ret; size_t len = 0; TEST_FUNCTION ("environ_set"); /* Check that an environment variable can be set from a format * string. */ TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); } ret = environ_set (&env, NULL, &len, TRUE, "FOO=%d", 1234); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (env[0], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_ALLOC_PARENT (env[0], env); TEST_ALLOC_SIZE (env[0], 9); TEST_EQ_STR (env[0], "FOO=1234"); TEST_EQ_P (env[1], NULL); nih_free (env); } }
/** * shutdown_now: * * Send a signal to init to shut down the machine. * * This does not return. **/ static void shutdown_now (void) { nih_local char **extra_env = NULL; NihDBusError * dbus_err; if (init_halt) { char *e; e = NIH_MUST (nih_sprintf (NULL, "INIT_HALT=%s", init_halt)); extra_env = NIH_MUST (nih_str_array_new (NULL)); NIH_MUST (nih_str_array_addp (&extra_env, NULL, NULL, e)); } if (sysv_change_runlevel (runlevel, extra_env, NULL, NULL) < 0) { dbus_err = (NihDBusError *)nih_error_get (); if ((dbus_err->number != NIH_DBUS_ERROR) || strcmp (dbus_err->name, DBUS_ERROR_NO_SERVER)) { nih_fatal ("%s", dbus_err->message); nih_free (dbus_err); exit (1); } nih_free (dbus_err); /* Connection Refused means that init isn't running, this * might mean we've just upgraded to upstart and haven't * yet rebooted ... so try /dev/initctl */ sysvinit_shutdown (); } unlink (ETC_NOLOGIN); nih_main_unlink_pidfile (); exit (0); }
void test_array_new (void) { char **array; /* Check that we can allocate a NULL-terminated array of strings using * nih_alloc(). */ TEST_FUNCTION ("nih_str_array_new"); TEST_ALLOC_FAIL { array = nih_str_array_new (NULL); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_ALLOC_SIZE (array, sizeof (char *)); TEST_EQ_P (array[0], NULL); nih_free (array); } }
void test_append (void) { char **env = NULL, **new_env, **ret; size_t len = 0; TEST_FUNCTION ("environ_append"); /* Check that we can append all new entries onto the end of an * existing environment table, without modifying the entries passed. */ TEST_FEATURE ("with new entries"); new_env = nih_str_array_new (NULL); assert (environ_add (&new_env, NULL, NULL, TRUE, "MILK=white")); assert (environ_add (&new_env, NULL, NULL, TRUE, "TEA=green")); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (environ_add (&env, NULL, &len, TRUE, "FOO=BAR")); assert (environ_add (&env, NULL, &len, TRUE, "BAR=BAZ")); } ret = environ_append (&env, NULL, &len, TRUE, new_env); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); nih_free (env); continue; } TEST_EQ_P (ret, env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "MILK=white"); TEST_EQ_STR (env[3], "TEA=green"); TEST_EQ_P (env[4], NULL); nih_free (env); } nih_free (new_env); /* Check that if entries are being replaced, those values from the * new table replace the values in the old table. */ TEST_FEATURE ("with replacement entries"); new_env = nih_str_array_new (NULL); assert (environ_add (&new_env, NULL, NULL, TRUE, "MILK=white")); assert (environ_add (&new_env, NULL, NULL, TRUE, "TEA=green")); assert (environ_add (&new_env, NULL, NULL, TRUE, "FOO=apricot")); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (environ_add (&env, NULL, &len, TRUE, "FOO=BAR")); assert (environ_add (&env, NULL, &len, TRUE, "BAR=BAZ")); } ret = environ_append (&env, NULL, &len, TRUE, new_env); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); nih_free (env); continue; } TEST_EQ_P (ret, env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=apricot"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "MILK=white"); TEST_EQ_STR (env[3], "TEA=green"); TEST_EQ_P (env[4], NULL); nih_free (env); } nih_free (new_env); /* Check that if entries are being preserved, those values from the * new table are ignored. */ TEST_FEATURE ("with preserve existing entries"); new_env = nih_str_array_new (NULL); assert (environ_add (&new_env, NULL, NULL, TRUE, "MILK=white")); assert (environ_add (&new_env, NULL, NULL, TRUE, "TEA=green")); assert (environ_add (&new_env, NULL, NULL, TRUE, "FOO=apricot")); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (environ_add (&env, NULL, &len, TRUE, "FOO=BAR")); assert (environ_add (&env, NULL, &len, TRUE, "BAR=BAZ")); } ret = environ_append (&env, NULL, &len, FALSE, new_env); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); nih_free (env); continue; } TEST_EQ_P (ret, env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "MILK=white"); TEST_EQ_STR (env[3], "TEA=green"); TEST_EQ_P (env[4], NULL); nih_free (env); } nih_free (new_env); }
void test_add (void) { char **env = NULL, **ret; size_t len = 0; TEST_FUNCTION ("environ_add"); /* Check that we can add a variable to a new environment table * and that it is appended to the array. */ TEST_FEATURE ("with empty table"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); } ret = environ_add (&env, NULL, &len, TRUE, "FOO=BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (env[0], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_ALLOC_PARENT (env[0], env); TEST_ALLOC_SIZE (env[0], 8); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_P (env[1], NULL); nih_free (env); } /* Check that we can add a variable to an environment table with * existing different entries and that it is appended to the array. */ TEST_FEATURE ("with new variable"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, TRUE, "FRODO=BAGGINS"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_ALLOC_PARENT (env[2], env); TEST_ALLOC_SIZE (env[2], 14); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that we can add a variable from the environment to the table * and that it is appended to the array. */ TEST_FEATURE ("with new variable from environment"); putenv ("FRODO=BAGGINS"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, TRUE, "FRODO"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_ALLOC_PARENT (env[2], env); TEST_ALLOC_SIZE (env[2], 14); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } unsetenv ("FRODO"); /* Check that when we attempt to add a variable that's not in the * environment, the table is not extended. */ TEST_FEATURE ("with new variable unset in environment"); unsetenv ("FRODO"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, TRUE, "FRODO"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); } /* Check that we can replace a variable in the environment table * when one already exists with the same or different value. */ TEST_FEATURE ("with replacement variable"); TEST_ALLOC_FAIL { char *old_env; TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); } old_env = env[1]; TEST_FREE_TAG (old_env); ret = environ_add (&env, NULL, &len, TRUE, "BAR=WIBBLE"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_NOT_FREE (old_env); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); continue; } TEST_FREE (old_env); TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_ALLOC_PARENT (env[1], env); TEST_ALLOC_SIZE (env[1], 11); TEST_EQ_STR (env[1], "BAR=WIBBLE"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that we can replace a variable from the environment in the * environment table when one already exists with the same or * different value. */ TEST_FEATURE ("with replacement variable from environment"); putenv ("BAR=WIBBLE"); TEST_ALLOC_FAIL { char *old_env; TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } old_env = env[1]; TEST_FREE_TAG (old_env); ret = environ_add (&env, NULL, &len, TRUE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_NOT_FREE (old_env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_FREE (old_env); TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_ALLOC_PARENT (env[1], env); TEST_ALLOC_SIZE (env[1], 11); TEST_EQ_STR (env[1], "BAR=WIBBLE"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); } unsetenv ("BAR"); /* Check that when we attempt to replace a variable that's unset * in the environment, the existing variable is removed from the * table. */ TEST_FEATURE ("with replacement variable unset in environment"); unsetenv ("BAR"); TEST_ALLOC_FAIL { char *old_env; TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } old_env = env[1]; TEST_FREE_TAG (old_env); ret = environ_add (&env, NULL, &len, TRUE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_NOT_FREE (old_env); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_FREE (old_env); TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "FRODO=BAGGINS"); TEST_EQ_STR (env[2], "BILBO=TOOK"); TEST_EQ_P (env[3], NULL); nih_free (env); } unsetenv ("BAR"); /* Check that we can add a variable to an environment table with * existing different entries and that it is appended to the array, * even if replace is FALSE. */ TEST_FEATURE ("with new variable but no replace"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); } ret = environ_add (&env, NULL, &len, FALSE, "FRODO=BAGGINS"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_P (env[2], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_ALLOC_PARENT (env[2], env); TEST_ALLOC_SIZE (env[2], 14); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that when a variable already exists in the environment * table, and we're not replacing, the original value is left * untouched. */ TEST_FEATURE ("with existing variable"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); } ret = environ_add (&env, NULL, &len, FALSE, "BAR=WIBBLE"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 3); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_P (env[3], NULL); nih_free (env); } /* Check that when a variable from the environment already exists in * the environment table, and we're not replacing, the original value * is left untouched. */ TEST_FEATURE ("with existing variable from environment"); putenv ("BAR=WIBBLE"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } ret = environ_add (&env, NULL, &len, FALSE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); } unsetenv ("BAR"); /* Check that when a variable from the environment is unset it * does not remove an existing variable in the environment table * if we're not replacing. */ TEST_FEATURE ("with existing variable unset in environment"); unsetenv ("BAR"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { len = 0; env = nih_str_array_new (NULL); assert (nih_str_array_add (&env, NULL, &len, "FOO=BAR")); assert (nih_str_array_add (&env, NULL, &len, "BAR=BAZ")); assert (nih_str_array_add (&env, NULL, &len, "FRODO=BAGGINS")); assert (nih_str_array_add (&env, NULL, &len, "BILBO=TOOK")); } ret = environ_add (&env, NULL, &len, FALSE, "BAR"); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (env[0], "FOO=BAR"); TEST_EQ_STR (env[1], "BAR=BAZ"); TEST_EQ_STR (env[2], "FRODO=BAGGINS"); TEST_EQ_STR (env[3], "BILBO=TOOK"); TEST_EQ_P (env[4], NULL); nih_free (env); } unsetenv ("BAR"); }
void test_array_append (void) { char **array, **args, **ret; size_t len; TEST_FUNCTION ("nih_str_array_append"); args = NIH_MUST (nih_str_array_new (NULL)); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "this")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "is")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "a")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "test")); /* Check that we can append one array onto the end of the other, * and that the array is extended and each new element copied * into the new array. */ TEST_FEATURE ("with length given"); TEST_ALLOC_FAIL { len = 0; TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); NIH_MUST (nih_str_array_add (&array, NULL, &len, "foo")); NIH_MUST (nih_str_array_add (&array, NULL, &len, "bar")); } ret = nih_str_array_append (&array, NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 2); TEST_EQ_STR (array[0], "foo"); TEST_EQ_STR (array[1], "bar"); TEST_EQ_P (array[2], NULL); nih_free (array); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 6); TEST_EQ_STR (array[0], "foo"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "bar"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "this"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "is"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_STR (array[4], "a"); TEST_ALLOC_PARENT (array[4], array); TEST_EQ_STR (array[5], "test"); TEST_ALLOC_PARENT (array[5], array); TEST_EQ_P (array[6], NULL); nih_free (array); } /* Check that we can omit the length, and have it calculated. */ TEST_FEATURE ("with no length given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); NIH_MUST (nih_str_array_add (&array, NULL, NULL, "foo")); NIH_MUST (nih_str_array_add (&array, NULL, NULL, "bar")); } ret = nih_str_array_append (&array, NULL, NULL, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_STR (array[0], "foo"); TEST_EQ_STR (array[1], "bar"); TEST_EQ_P (array[2], NULL); nih_free (array); continue; } TEST_NE_P (ret, NULL); TEST_EQ_STR (array[0], "foo"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "bar"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "this"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "is"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_STR (array[4], "a"); TEST_ALLOC_PARENT (array[4], array); TEST_EQ_STR (array[5], "test"); TEST_ALLOC_PARENT (array[5], array); TEST_EQ_P (array[6], NULL); nih_free (array); } /* Check that we can pass a NULL array to get a copy of it, with * the returned length containing the new length. */ TEST_FEATURE ("with NULL array and length"); TEST_ALLOC_FAIL { len = 0; array = NULL; ret = nih_str_array_append (&array, NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (array, NULL); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 4); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } /* Check that we can pass a NULL array to get a copy of it, without * passing the length in. */ TEST_FEATURE ("with NULL array and no length"); TEST_ALLOC_FAIL { array = NULL; ret = nih_str_array_append (&array, NULL, NULL, args); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (array, NULL); continue; } TEST_NE_P (ret, NULL); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } nih_free (args); }
void test_array_copy (void) { char **array, **args; size_t len; TEST_FUNCTION ("nih_str_array_copy"); args = NIH_MUST (nih_str_array_new (NULL)); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "this")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "is")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "a")); NIH_MUST (nih_str_array_add (&args, NULL, NULL, "test")); /* Check that we can make a copy of an array, with each element * a copy of the last. */ TEST_FEATURE ("with length given"); TEST_ALLOC_FAIL { len = 0; array = nih_str_array_copy (NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_NE_P (array, NULL); TEST_EQ (len, 4); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } /* Check that we can omit the length, and have it calculated. */ TEST_FEATURE ("with no length given"); TEST_ALLOC_FAIL { array = nih_str_array_copy (NULL, NULL, args); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_NE_P (array, NULL); TEST_EQ_STR (array[0], "this"); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_STR (array[1], "is"); TEST_ALLOC_PARENT (array[1], array); TEST_EQ_STR (array[2], "a"); TEST_ALLOC_PARENT (array[2], array); TEST_EQ_STR (array[3], "test"); TEST_ALLOC_PARENT (array[3], array); TEST_EQ_P (array[4], NULL); nih_free (array); } nih_free (args); /* Check that we can make a copy of an array with a single NULL * element and have the same returned. */ TEST_FEATURE ("with zero-length array"); args = NIH_MUST (nih_str_array_new (NULL)); TEST_ALLOC_FAIL { len = 0; array = nih_str_array_copy (NULL, &len, args); if (test_alloc_failed) { TEST_EQ_P (array, NULL); continue; } TEST_NE_P (array, NULL); TEST_EQ (len, 0); TEST_EQ_P (array[0], NULL); nih_free (array); } nih_free (args); }
void test_array_addp (void) { char **array, **ret; char *ptr1 = NULL; char *ptr2 = NULL; size_t len; TEST_FUNCTION ("nih_str_array_addn"); /* Check that we can call the function with a NULL array pointer, * and get one allocated automatically. */ TEST_FEATURE ("with no array given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { ptr1 = nih_alloc (NULL, 1024); memset (ptr1, ' ', 1024); } array = NULL; len = 0; ret = nih_str_array_addp (&array, NULL, &len, ptr1); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (array, NULL); TEST_EQ (len, 0); nih_free (ptr1); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_EQ_P (array[0], ptr1); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[1], NULL); nih_free (array); nih_free (ptr1); } /* Check that we can append allocated blocks to a * NULL-terminated array, and that the blocks are automatically * reparented. */ TEST_FEATURE ("with length given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); len = 0; ptr1 = nih_alloc (NULL, 1024); memset (ptr1, ' ', 1024); } ret = nih_str_array_addp (&array, NULL, &len, ptr1); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ (len, 0); TEST_EQ_P (array[0], NULL); nih_free (array); nih_free (ptr1); continue; } TEST_NE_P (ret, NULL); TEST_EQ (len, 1); TEST_EQ_P (array[0], ptr1); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[1], NULL); nih_free (array); nih_free (ptr1); } /* Check that we can omit the length, and have it calculated. */ TEST_FEATURE ("with no length given"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { array = nih_str_array_new (NULL); len = 0; ptr1 = nih_alloc (NULL, 1024); memset (ptr1, ' ', 1024); assert (nih_str_array_addp (&array, NULL, NULL, ptr1)); ptr2 = nih_alloc (NULL, 512); memset (ptr2, ' ', 512); } ret = nih_str_array_addp (&array, NULL, NULL, ptr2); if (test_alloc_failed) { TEST_EQ_P (ret, NULL); TEST_EQ_P (array[0], ptr1); TEST_EQ_P (array[1], NULL); nih_free (array); nih_free (ptr1); nih_free (ptr2); continue; } TEST_NE_P (ret, NULL); TEST_EQ_P (array[0], ptr1); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[1], ptr2); TEST_ALLOC_PARENT (array[0], array); TEST_EQ_P (array[2], NULL); nih_free (array); nih_free (ptr1); nih_free (ptr2); } }
static void udev_monitor_watcher (struct udev_monitor *udev_monitor, NihIoWatch * watch, NihIoEvents events) { struct udev_device * udev_device; nih_local char * subsystem = NULL; nih_local char * action = NULL; nih_local char * kernel = NULL; nih_local char * devpath = NULL; nih_local char * devname = NULL; nih_local char * name = NULL; nih_local char ** env = NULL; const char * value = NULL; size_t env_len = 0; DBusPendingCall * pending_call; char *(*copy_string)(const void *, const char *) = NULL; udev_device = udev_monitor_receive_device (udev_monitor); if (! udev_device) return; copy_string = no_strip_udev_data ? nih_strdup : make_safe_string; value = udev_device_get_subsystem (udev_device); subsystem = value ? copy_string (NULL, value) : NULL; value = udev_device_get_action (udev_device); action = value ? copy_string (NULL, value) : NULL; value = udev_device_get_sysname (udev_device); kernel = value ? copy_string (NULL, value) : NULL; value = udev_device_get_devpath (udev_device); devpath = value ? copy_string (NULL, value) : NULL; value = udev_device_get_devnode (udev_device); devname = value ? copy_string (NULL, value) : NULL; /* Protect against the "impossible" */ if (! action) goto out; if (! strcmp (action, "add")) { name = NIH_MUST (nih_sprintf (NULL, "%s-device-added", subsystem)); } else if (! strcmp (action, "change")) { name = NIH_MUST (nih_sprintf (NULL, "%s-device-changed", subsystem)); } else if (! strcmp (action, "remove")) { name = NIH_MUST (nih_sprintf (NULL, "%s-device-removed", subsystem)); } else { name = NIH_MUST (nih_sprintf (NULL, "%s-device-%s", subsystem, action)); } env = NIH_MUST (nih_str_array_new (NULL)); if (kernel) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "KERNEL=%s", kernel)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (devpath) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "DEVPATH=%s", devpath)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (devname) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "DEVNAME=%s", devname)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (subsystem) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "SUBSYSTEM=%s", subsystem)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (action) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "ACTION=%s", action)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } for (struct udev_list_entry *list_entry = udev_device_get_properties_list_entry (udev_device); list_entry != NULL; list_entry = udev_list_entry_get_next (list_entry)) { nih_local char *udev_name = NULL; nih_local char *udev_value = NULL; nih_local char *var = NULL; udev_name = copy_string (NULL, udev_list_entry_get_name (list_entry)); if (! strcmp (udev_name, "DEVPATH")) continue; if (! strcmp (udev_name, "DEVNAME")) continue; if (! strcmp (udev_name, "SUBSYSTEM")) continue; if (! strcmp (udev_name, "ACTION")) continue; udev_value = copy_string (NULL, udev_list_entry_get_value (list_entry)); var = NIH_MUST (nih_sprintf (NULL, "%s=%s", udev_name, udev_value)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } nih_debug ("%s %s", name, devname ? devname : ""); pending_call = upstart_emit_event (upstart, name, env, FALSE, NULL, emit_event_error, NULL, NIH_DBUS_TIMEOUT_NEVER); if (! pending_call) { NihError *err; int saved = errno; err = nih_error_get (); nih_warn ("%s", err->message); if (saved != ENOMEM && subsystem) nih_warn ("Likely that udev '%s' event contains binary garbage", subsystem); nih_free (err); } dbus_pending_call_unref (pending_call); out: udev_device_unref (udev_device); }
void test_operator_new (void) { EventOperator *oper; char **env; TEST_FUNCTION ("event_operator_new"); /* Check that we can create a new EventOperator structure to match * an event, and have the details filled in and returned. It * should not be placed into any tree structure. */ TEST_FEATURE ("with EVENT_MATCH"); TEST_ALLOC_FAIL { oper = event_operator_new (NULL, EVENT_MATCH, "test", NULL); if (test_alloc_failed) { TEST_EQ_P (oper, NULL); continue; } TEST_ALLOC_SIZE (oper, sizeof (EventOperator)); TEST_EQ_P (oper->node.parent, NULL); TEST_EQ_P (oper->node.left, NULL); TEST_EQ_P (oper->node.right, NULL); TEST_EQ (oper->value, FALSE); TEST_EQ_STR (oper->name, "test"); TEST_ALLOC_PARENT (oper->name, oper); TEST_EQ_P (oper->env, NULL); TEST_EQ_P (oper->event, NULL); nih_free (oper); } /* Check that environment passed to event_operator_new is reparented * to belong to the structure itself. */ TEST_FEATURE ("with EVENT_MATCH and environment"); TEST_ALLOC_FAIL { TEST_ALLOC_SAFE { env = nih_str_array_new (NULL); NIH_MUST (nih_str_array_add (&env, NULL, NULL, "foo")); NIH_MUST (nih_str_array_add (&env, NULL, NULL, "BAR=frodo")); } oper = event_operator_new (NULL, EVENT_MATCH, "test", env); if (test_alloc_failed) { TEST_EQ_P (oper, NULL); TEST_ALLOC_PARENT (env, NULL); nih_free (env); continue; } nih_discard (env); TEST_ALLOC_SIZE (oper, sizeof (EventOperator)); TEST_EQ_P (oper->node.parent, NULL); TEST_EQ_P (oper->node.left, NULL); TEST_EQ_P (oper->node.right, NULL); TEST_EQ (oper->value, FALSE); TEST_EQ_STR (oper->name, "test"); TEST_ALLOC_PARENT (oper->name, oper); TEST_EQ_P (oper->env, env); TEST_ALLOC_PARENT (oper->env, oper); TEST_EQ_P (oper->event, NULL); nih_free (oper); } /* Check that an ordinary operator needs no name attached. */ TEST_FEATURE ("with EVENT_OR"); TEST_ALLOC_FAIL { oper = event_operator_new (NULL, EVENT_OR, NULL, NULL); if (test_alloc_failed) { TEST_EQ_P (oper, NULL); continue; } TEST_ALLOC_SIZE (oper, sizeof (EventOperator)); TEST_EQ_P (oper->node.parent, NULL); TEST_EQ_P (oper->node.left, NULL); TEST_EQ_P (oper->node.right, NULL); TEST_EQ (oper->value, FALSE); TEST_EQ_P (oper->name, NULL); TEST_EQ_P (oper->env, NULL); TEST_EQ_P (oper->event, NULL); nih_free (oper); } }