#include <sys/stat.h>
#include <sys/wait.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#define UV_SHOULD_SUCCEED(A, B) do { \
if (A) { \
err(1, "%s:%d - %s", __FILE__, __LINE__, B); \
} \
} while (0)
#define UV_SHOULD_ENOENT(A, B) do { \
if (A) { \
if (do_uv && errno != ENOENT) \
err(1, "%s:%d - %s", __FILE__, __LINE__, B); \
} else { \
if (do_uv) \
errx(1, "%s:%d - %s worked when it should not " \
"have", __FILE__, __LINE__, B); \
} \
} while(0)
#define UV_SHOULD_EACCES(A, B) do { \
if (A) { \
if (do_uv && errno != EACCES) \
err(1, "%s:%d - %s", __FILE__, __LINE__, B); \
} else { \
if (do_uv) \
errx(1, "%s:%d - %s worked when it should not " \
"have", __FILE__, __LINE__, B); \
} \
} while(0)
#define UV_SHOULD_EPERM(A, B) do { \
if (A) { \
if (do_uv && errno != EPERM) \
err(1, "%s:%d - %s", __FILE__, __LINE__, B); \
} else { \
if (do_uv) \
errx(1, "%s:%d - %s worked when it should not " \
"have", __FILE__, __LINE__, B); \
} \
} while(0)
static char uv_dir1[] = "/tmp/uvdir1.XXXXXX";
static char uv_dir2[] = "/tmp/uvdir2.XXXXXX";
static char uv_file1[] = "/tmp/uvfile1.XXXXXX";
static char uv_file2[] = "/tmp/uvfile2.XXXXXX";
static int
runcompare_internal(int (*func)(int), int fail_ok)
{
int unveil = 0, nonunveil = 0;
int status;
pid_t pid = fork();
if (pid == 0)
exit(func(0));
status = 0;
waitpid(pid, &status, 0);
if (WIFEXITED(status))
nonunveil = WEXITSTATUS(status);
if (WIFSIGNALED(status)) {
printf("[FAIL] nonunveil exited with signal %d\n",
WTERMSIG(status));
goto fail;
}
pid = fork();
if (pid == 0)
exit(func(1));
status = 0;
waitpid(pid, &status, 0);
if (WIFEXITED(status))
unveil = WEXITSTATUS(status);
if (WIFSIGNALED(status)) {
printf("[FAIL] nonunveil exited with signal %d\n",
WTERMSIG(status));
goto fail;
}
if (!fail_ok && (unveil || nonunveil)) {
printf("[FAIL] unveil = %d, nonunveil = %d\n", unveil,
nonunveil);
goto fail;
}
if (unveil == nonunveil)
return 0;
printf("[FAIL] unveil = %d, nonunveil = %d\n", unveil, nonunveil);
fail:
return 1;
}
static int
runcompare(int (*func)(int))
{
return runcompare_internal(func, 1);
}
static void
test_setup(void)
{
int fd1, fd2;
char filename[256];
UV_SHOULD_SUCCEED((mkdtemp(uv_dir1) == NULL), "mkdtmp");
UV_SHOULD_SUCCEED((mkdtemp(uv_dir2) == NULL), "mkdtmp");
UV_SHOULD_SUCCEED(((fd1 = mkstemp(uv_file1)) == -1), "mkstemp");
close(fd1);
UV_SHOULD_SUCCEED((chmod(uv_file1, S_IRWXU) == -1), "chmod");
UV_SHOULD_SUCCEED(((fd2 = mkstemp(uv_file2)) == -1), "mkstemp");
(void)snprintf(filename, sizeof(filename), "/%s/subdir", uv_dir1);
UV_SHOULD_SUCCEED((mkdir(filename, 0777) == -1), "mkdir");
(void)snprintf(filename, sizeof(filename), "/%s/subdir", uv_dir2);
UV_SHOULD_SUCCEED((mkdir(filename, 0777) == -1), "mkdir");
close(fd2);
}