Files
RedBear-OS/tests/spawn.c
T
2026-06-15 17:08:11 +05:30

96 lines
3.2 KiB
C

#include "./test_helpers.h"
#include <assert.h>
#include <dirent.h>
#include <fcntl.h>
#include <limits.h>
#include <sched.h>
#include <spawn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
static const char buf[] = "#include <unistd.h>\nint main()\n{\nwrite(900, "
"\"hello_spawn REDOX\\n\", 18);\n}";
#define OPTIONALLY_ERROR(function, args, cond) \
{ \
int x = function args; \
if (!(x cond)) { \
printf("%s failed with error: %s\n", #function, strerror(x)); \
exit(EXIT_FAILURE); \
} \
}
extern char **environ;
int main() {
pid_t pid = 0;
char cwd[PATH_MAX];
int status = 0;
char *__cwd = getcwd(cwd, PATH_MAX);
ERROR_IF(getcwd, __cwd, == NULL);
char target[PATH_MAX];
strcpy(target, cwd);
strcat(target, "/hello_spawn");
// TEST: chdir and open
char *argv1[] = {"ls", target, NULL};
posix_spawn_file_actions_t fa;
posix_spawn_file_actions_init(&fa);
status = mkdir("./hello_spawn", S_IRUSR | S_IWUSR);
ERROR_IF(mkdir, status, != 0);
OPTIONALLY_ERROR(posix_spawn_file_actions_addchdir, (&fa, "./hello_spawn"),
== 0);
OPTIONALLY_ERROR(
posix_spawn_file_actions_addopen,
(&fa, 2, "./hello_spawn.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR), == 0);
OPTIONALLY_ERROR(posix_spawnp, (&pid, "ls", &fa, NULL, argv1, environ), == 0);
assert(pid != 0);
waitpid(pid, NULL, 0);
OPTIONALLY_ERROR(posix_spawn_file_actions_destroy, (&fa), == 0);
pid = 0;
// TEST: close
argv1[0] = "/usr/bin/ls";
OPTIONALLY_ERROR(posix_spawn_file_actions_init, (&fa), == 0);
OPTIONALLY_ERROR(posix_spawn_file_actions_addclose, (&fa, 1), == 0);
OPTIONALLY_ERROR(posix_spawn,
(&pid, "/usr/bin/ls", &fa, NULL, argv1, environ), == 0);
assert(pid != 0);
waitpid(pid, NULL, 0);
OPTIONALLY_ERROR(posix_spawn_file_actions_destroy, (&fa), == 0);
status = unlink("./hello_spawn/hello_spawn.txt");
ERROR_IF(unlink, status, != 0);
status = rmdir("./hello_spawn");
ERROR_IF(rmdir, status, != 0);
// TEST: dup2
pid = 0;
posix_spawn_file_actions_init(&fa);
posix_spawn_file_actions_adddup2(&fa, 1, 900);
FILE *f = fopen("./dup2_check.c", "w");
if (!f) {
printf("Failed to create dup2_check.c\n");
exit(EXIT_FAILURE);
}
OPTIONALLY_ERROR(fwrite, (buf, sizeof(char), 74, f), == 74);
fclose(f);
char *argv2[] = {"gcc", "./dup2_check.c", "-o", "d.out", NULL};
OPTIONALLY_ERROR(posix_spawnp, (&pid, "gcc", NULL, NULL, argv2, environ),
== 0);
waitpid(pid, NULL, 0);
assert(pid != 0);
pid = 0;
char *argv3[] = {"./d.out", NULL};
OPTIONALLY_ERROR(posix_spawnp, (&pid, "./d.out", &fa, NULL, argv3, environ),
== 0);
assert(pid != 0);
waitpid(pid, NULL, 0);
posix_spawn_file_actions_destroy(&fa);
}