/* * PAM utility vector library test suite. * * The canonical version of this file is maintained in the rra-c-util package, * which can be found at . * * Written by Russ Allbery * Copyright 2014, 2016, 2018-2019 Russ Allbery * Copyright 2010-2011, 2013 * The Board of Trustees of the Leland Stanford Junior University * * Copying and distribution of this file, with or without modification, are * permitted in any medium without royalty provided the copyright notice and * this notice are preserved. This file is offered as-is, without any * warranty. * * SPDX-License-Identifier: FSFAP */ #include #include #include #include #include #include int main(void) { struct vector *vector, *ovector, *copy; char *command, *string; const char *env[2]; pid_t child; size_t i; const char cstring[] = "This is a\ttest. "; plan(60); vector = vector_new(); ok(vector != NULL, "vector_new returns non-NULL"); if (vector == NULL) bail("vector_new returned NULL"); ok(vector_add(vector, cstring), "vector_add succeeds"); is_int(1, vector->count, "vector_add increases count"); ok(vector->strings[0] != cstring, "...and allocated new memory"); ok(vector_resize(vector, 4), "vector_resize succeeds"); is_int(4, vector->allocated, "vector_resize works"); ok(vector_add(vector, cstring), "vector_add #2"); ok(vector_add(vector, cstring), "vector_add #3"); ok(vector_add(vector, cstring), "vector_add #4"); is_int(4, vector->allocated, "...and no reallocation when adding strings"); is_int(4, vector->count, "...and the count matches"); is_string(cstring, vector->strings[0], "added the right string"); is_string(cstring, vector->strings[1], "added the right string"); is_string(cstring, vector->strings[2], "added the right string"); is_string(cstring, vector->strings[3], "added the right string"); ok(vector->strings[1] != vector->strings[2], "each pointer is different"); ok(vector->strings[2] != vector->strings[3], "each pointer is different"); ok(vector->strings[3] != vector->strings[0], "each pointer is different"); ok(vector->strings[0] != cstring, "each pointer is different"); copy = vector_copy(vector); ok(copy != NULL, "vector_copy returns non-NULL"); if (copy == NULL) bail("vector_copy returned NULL"); is_int(4, copy->count, "...and has right count"); is_int(4, copy->allocated, "...and has right allocated count"); for (i = 0; i < 4; i++) { is_string(cstring, copy->strings[i], "...and string %lu is right", (unsigned long) i); ok(copy->strings[i] != vector->strings[i], "...and pointer %lu is different", (unsigned long) i); } vector_free(copy); vector_clear(vector); is_int(0, vector->count, "vector_clear works"); is_int(4, vector->allocated, "...but doesn't free the allocation"); string = strdup(cstring); if (string == NULL) sysbail("cannot allocate memory"); ok(vector_add(vector, cstring), "vector_add succeeds"); ok(vector_add(vector, string), "vector_add succeeds"); is_int(2, vector->count, "added two strings to the vector"); ok(vector->strings[1] != string, "...and the pointers are different"); ok(vector_resize(vector, 1), "vector_resize succeeds"); is_int(1, vector->count, "vector_resize shrinks the vector"); ok(vector->strings[0] != cstring, "...and the pointer is different"); vector_free(vector); free(string); vector = vector_split_multi("foo, bar, baz", ", ", NULL); ok(vector != NULL, "vector_split_multi returns non-NULL"); if (vector == NULL) bail("vector_split_multi returned NULL"); is_int(3, vector->count, "vector_split_multi returns right count"); is_string("foo", vector->strings[0], "...first string"); is_string("bar", vector->strings[1], "...second string"); is_string("baz", vector->strings[2], "...third string"); ovector = vector; vector = vector_split_multi("", ", ", vector); ok(vector != NULL, "reuse of vector doesn't return NULL"); ok(vector == ovector, "...and reuses the same vector pointer"); is_int(0, vector->count, "vector_split_multi reuse with empty string"); is_int(3, vector->allocated, "...and doesn't free allocation"); vector = vector_split_multi(",,, foo, ", ", ", vector); ok(vector != NULL, "reuse of vector doesn't return NULL"); is_int(1, vector->count, "vector_split_multi with extra separators"); is_string("foo", vector->strings[0], "...first string"); vector = vector_split_multi(", , ", ", ", vector); is_int(0, vector->count, "vector_split_multi with only separators"); vector_free(vector); vector = vector_new(); ok(vector_add(vector, "/bin/sh"), "vector_add succeeds"); ok(vector_add(vector, "-c"), "vector_add succeeds"); basprintf(&command, "echo ok %lu - vector_exec", testnum++); ok(vector_add(vector, command), "vector_add succeeds"); child = fork(); if (child < 0) sysbail("unable to fork"); else if (child == 0) if (vector_exec("/bin/sh", vector) < 0) sysdiag("unable to exec /bin/sh"); waitpid(child, NULL, 0); vector_free(vector); free(command); vector = vector_new(); ok(vector_add(vector, "/bin/sh"), "vector_add succeeds"); ok(vector_add(vector, "-c"), "vector_add succeeds"); ok(vector_add(vector, "echo ok $NUMBER - vector_exec_env"), "vector_add succeeds"); basprintf(&string, "NUMBER=%lu", testnum++); env[0] = string; env[1] = NULL; child = fork(); if (child < 0) sysbail("unable to fork"); else if (child == 0) if (vector_exec_env("/bin/sh", vector, env) < 0) sysdiag("unable to exec /bin/sh"); waitpid(child, NULL, 0); vector_free(vector); free(string); return 0; }