Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
	}
}
Beispiel #5
0
/**
 * 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);
}
Beispiel #6
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);
    }
}
Beispiel #7
0
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);
}
Beispiel #8
0
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");
}
Beispiel #9
0
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);
}
Beispiel #10
0
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);
}
Beispiel #11
0
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);
    }
}
Beispiel #12
0
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);
}
Beispiel #13
0
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);
	}
}