Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 91 additions & 43 deletions sp.h

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions spn.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ source = [
"test/test/axis.c", "test/test/filter.c", "test/test/matrix.c",
"test/test/resolve.c", "test/test/sweep.c", "test/test/tracking.c",
"test/sys/sys.c", "test/sys/open.c", "test/sys/path.c", "test/sys/iter.c", "test/sys/futex.c",
"test/sys/fd.c", "test/sys/nanosleep.c", "test/sys/timestamps.c", "test/sys/self_path.c",
"test/sys/fd.c", "test/sys/nanosleep.c", "test/sys/timestamps.c", "test/sys/perms.c", "test/sys/self_path.c",
"test/sys/pipe/data.c", "test/sys/pipe/blocking.c", "test/sys/transfer.c", "test/sys/readlink.c",
"test/sys/socket/data.c", "test/sys/socket/listen.c", "test/sys/socket/desc.c",
"test/sys/tty/contract.c", "test/sys/tty/mode.c", "test/sys/vtable.c",
Expand All @@ -39,7 +39,7 @@ name = "sys"
source = [
"test/main.c",
"test/sys/sys.c", "test/sys/open.c", "test/sys/path.c", "test/sys/iter.c", "test/sys/futex.c",
"test/sys/fd.c", "test/sys/nanosleep.c", "test/sys/timestamps.c", "test/sys/self_path.c",
"test/sys/fd.c", "test/sys/nanosleep.c", "test/sys/timestamps.c", "test/sys/perms.c", "test/sys/self_path.c",
"test/sys/pipe/data.c", "test/sys/pipe/blocking.c", "test/sys/transfer.c", "test/sys/readlink.c",
"test/sys/socket/data.c", "test/sys/socket/listen.c", "test/sys/socket/desc.c",
"test/sys/tty/contract.c", "test/sys/tty/mode.c", "test/sys/vtable.c",
Expand Down
7 changes: 3 additions & 4 deletions test/sys/path.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ static sp_err_t run(sp_test_t* t, test_t* c) {
switch (c->op) {
case OP_UNLINK: err = sp_sys_unlink_s(sandbox_fd, path); break;
case OP_RMDIR: err = sp_sys_rmdir_s(sandbox_fd, path); break;
case OP_MKDIR: err = sp_sys_mkdir_s(sandbox_fd, path, 0755); break;
case OP_MKDIR: err = sp_sys_mkdir_s(sandbox_fd, path, sp_sys_default_dir_perms); break;
case OP_STAT: err = sp_sys_get_path_metadata_s(sandbox_fd, path, &meta); break;
case OP_LSTAT: err = sp_sys_get_link_metadata_s(sandbox_fd, path, &meta); break;
}
Expand Down Expand Up @@ -489,9 +489,8 @@ sp_test(sys, canonicalize_ignores_read_permission) {
if (geteuid() == 0) return sp_test_skip(t, "running as root");
#endif

sp_sys_file_meta_t meta = sp_zero;
sp_err_t err = sp_sys_chmod_s(sp_sys_get_root(0), path, &meta);
if (err == SP_ERR_SYS_UNSUPPORTED) return sp_test_skip(t, "chmod not supported");
sp_err_t err = sp_sys_set_file_perms_s(sp_sys_get_root(0), path, sp_zero_s(sp_sys_file_perms_t));
if (err == SP_ERR_SYS_UNSUPPORTED) return sp_test_skip(t, "set_file_perms not supported");
sp_try(err);

c8 buf [SP_PATH_MAX] = sp_zero;
Expand Down
105 changes: 105 additions & 0 deletions test/sys/perms.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include "sp.h"
#include "sp/sp_test.h"

#define PERMS_TEST_MAX_OPS 2

typedef enum {
OP_NONE,
OP_READ_ONLY,
OP_EXECUTABLE,
} op_kind_t;

typedef struct {
op_kind_t kind;
bool value;
} op_t;

typedef struct {
bool read_only;
bool executable;
} expect_t;

typedef struct {
const c8* name;
op_t ops [PERMS_TEST_MAX_OPS];
expect_t expect;
} test_t;

static const test_t tests [] = {
{ .name = "fresh_file_is_writable" },
{ .name = "set_read_only", .ops = { { OP_READ_ONLY, true } }, .expect = { .read_only = true } },
{ .name = "clear_read_only", .ops = { { OP_READ_ONLY, true }, { OP_READ_ONLY, false } } },
{ .name = "set_executable", .ops = { { OP_EXECUTABLE, true } }, .expect = { .executable = true } },
{ .name = "clear_executable", .ops = { { OP_EXECUTABLE, true }, { OP_EXECUTABLE, false } } },
{ .name = "read_only_keeps_executable", .ops = { { OP_EXECUTABLE, true }, { OP_READ_ONLY, true } }, .expect = { .read_only = true, .executable = true } },
};

static sp_err_t run(sp_test_t* t, test_t* it) {
sp_str_t path = sp_fs_join_path(sp_test_arena(t), sp_test_dir(t), sp_str_lit("A"));
sp_fs_create_file(path);
sp_sys_fd_t root = sp_sys_get_root(0);

sp_sys_file_meta_t meta = sp_zero;
sp_err_t err = sp_sys_get_path_metadata_s(root, path, &meta);
if (err == SP_ERR_SYS_UNSUPPORTED) return sp_test_skip(t, "metadata not supported");
sp_try(err);

sp_carr_for_until(it->ops, i, it->ops[i].kind != OP_NONE) {
op_t op = it->ops[i];
switch (op.kind) {
case OP_NONE: break;
case OP_READ_ONLY: sp_sys_set_read_only(&meta.perms, op.value); break;
case OP_EXECUTABLE: sp_sys_set_executable(&meta.perms, op.value); break;
}
}
sp_must_ok(t, sp_sys_set_file_perms_s(root, path, meta.perms));

sp_sys_file_meta_t after = sp_zero;
sp_must_ok(t, sp_sys_get_path_metadata_s(root, path, &after));
sp_expect_eq(t, sp_sys_is_read_only(after.perms), it->expect.read_only);
#if !defined(SP_WIN32)
sp_expect_eq(t, (after.perms.value & 0111) != 0, it->expect.executable);
#endif
return SP_OK;
}

sp_test_each_fn(sys, perms, test_t, tests, run);

sp_test(sys, default_perms_then_read_only) {
sp_str_t path = sp_fs_join_path(sp_test_arena(t), sp_test_dir(t), sp_str_lit("A"));
sp_fs_create_file(path);
sp_sys_fd_t root = sp_sys_get_root(0);

sp_err_t err = sp_sys_set_file_perms_s(root, path, sp_sys_default_file_perms);
if (err == SP_ERR_SYS_UNSUPPORTED) return sp_test_skip(t, "set_file_perms not supported");
sp_try(err);

sp_sys_file_meta_t meta = sp_zero;
sp_must_ok(t, sp_sys_get_path_metadata_s(root, path, &meta));
sp_expect(t, !sp_sys_is_read_only(meta.perms));

sp_sys_set_read_only(&meta.perms, true);
sp_must_ok(t, sp_sys_set_file_perms_s(root, path, meta.perms));

sp_sys_file_meta_t after = sp_zero;
sp_must_ok(t, sp_sys_get_path_metadata_s(root, path, &after));
sp_expect(t, sp_sys_is_read_only(after.perms));
return SP_OK;
}

sp_test(sys, mkdir_applies_perms) {
sp_test_skip_on_win32();
sp_str_t path = sp_fs_join_path(sp_test_arena(t), sp_test_dir(t), sp_str_lit("D"));
sp_sys_fd_t root = sp_sys_get_root(0);

sp_sys_file_perms_t perms = sp_sys_default_dir_perms;
sp_sys_set_read_only(&perms, true);
sp_err_t err = sp_sys_mkdir_s(root, path, perms);
if (err == SP_ERR_SYS_UNSUPPORTED) return sp_test_skip(t, "mkdir not supported");
sp_try(err);

sp_sys_file_meta_t meta = sp_zero;
sp_must_ok(t, sp_sys_get_path_metadata_s(root, path, &meta));
sp_expect(t, sp_sys_is_read_only(meta.perms));
return SP_OK;
}
12 changes: 4 additions & 8 deletions test/sys/sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,9 @@ static bool sys_apply_setup(s32* utest_result, sp_test_file_manager_t* fm, sp_st
SP_FAIL();
return false;
}
#if defined(SP_WIN32)
meta.raw_attrs |= FILE_ATTRIBUTE_READONLY;
#else
meta.raw_attrs &= ~(u32)0222;
#endif
if (sp_sys_chmod_s(sp_sys_get_root(0), path, &meta)) {
SP_TEST_REPORT("failed to chmod {}", sp_fmt_str(path));
sp_sys_set_read_only(&meta.perms, true);
if (sp_sys_set_file_perms_s(sp_sys_get_root(0), path, meta.perms)) {
SP_TEST_REPORT("failed to set perms on {}", sp_fmt_str(path));
SP_FAIL();
return false;
}
Expand Down Expand Up @@ -376,7 +372,7 @@ static void run_sys_test(s32* utest_result, sys_test_t t) {
break;
}
case SYS_STEP_MKDIR: {
sp_err_t err = sp_sys_mkdir_s(sandbox_fd, sp_cstr_as_str(step->mkdir.path), 0755);
sp_err_t err = sp_sys_mkdir_s(sandbox_fd, sp_cstr_as_str(step->mkdir.path), sp_sys_default_dir_perms);
sys_expect_err(utest_result, "mkdir", err, step->mkdir.err);
break;
}
Expand Down
13 changes: 7 additions & 6 deletions test/sys/timestamps.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ typedef enum {

typedef enum {
OP_WRITE,
OP_CHMOD,
OP_SET_PERMS,
} op_t;

typedef struct {
Expand All @@ -20,9 +20,9 @@ typedef struct {

static const test_t tests [] = {
{ .name = "write_moves_mtime", .field = FIELD_MTIME, .op = OP_WRITE, .moves = true },
{ .name = "chmod_keeps_mtime", .field = FIELD_MTIME, .op = OP_CHMOD },
{ .name = "set_perms_keeps_mtime", .field = FIELD_MTIME, .op = OP_SET_PERMS },
{ .name = "write_keeps_btime", .field = FIELD_BTIME, .op = OP_WRITE },
{ .name = "chmod_keeps_btime", .field = FIELD_BTIME, .op = OP_CHMOD },
{ .name = "set_perms_keeps_btime", .field = FIELD_BTIME, .op = OP_SET_PERMS },
};

static s64 field_ns(const sp_sys_file_meta_t* meta, field_t field) {
Expand Down Expand Up @@ -52,9 +52,10 @@ static sp_err_t run(sp_test_t* t, test_t* c) {
sp_sys_close(fd);
break;
}
case OP_CHMOD: {
sp_sys_file_meta_t meta = sp_zero;
sp_must_ok(t, sp_sys_chmod_s(root, path, &meta));
case OP_SET_PERMS: {
sp_sys_file_perms_t perms = before.perms;
sp_sys_set_read_only(&perms, true);
sp_must_ok(t, sp_sys_set_file_perms_s(root, path, perms));
break;
}
}
Expand Down
14 changes: 7 additions & 7 deletions test/sys/vtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static sp_err_t mock_pipe_ready(sp_sys_fd_t fd, u8* ready) {
return (sp_err_t)69;
}

static sp_err_t mock_mkdir(sp_sys_fd_t fd, const c8* path, u32 len, s32 mode) {
static sp_err_t mock_mkdir(sp_sys_fd_t fd, const c8* path, u32 len, sp_sys_file_perms_t perms) {
return (sp_err_t)69;
}

Expand Down Expand Up @@ -115,7 +115,7 @@ static sp_err_t mock_get_file_metadata(sp_sys_fd_t fd, sp_sys_file_meta_t* st) {
return (sp_err_t)69;
}

static sp_err_t mock_chmod(sp_sys_fd_t fd, const c8* path, u32 len, const sp_sys_file_meta_t* st) {
static sp_err_t mock_set_file_perms(sp_sys_fd_t fd, const c8* path, u32 len, sp_sys_file_perms_t perms) {
return (sp_err_t)69;
}

Expand Down Expand Up @@ -326,7 +326,7 @@ static const sp_sys_vtable_t mock = {
.get_path_metadata = mock_get_path_metadata,
.get_link_metadata = mock_get_link_metadata,
.get_file_metadata = mock_get_file_metadata,
.chmod = mock_chmod,
.set_file_perms = mock_set_file_perms,
.clock_gettime = mock_clock_gettime,
.nanosleep = mock_nanosleep,
.futex_wait = mock_futex_wait,
Expand Down Expand Up @@ -444,7 +444,7 @@ static s64 call_pipe_ready(void) {
}

static s64 call_mkdir(void) {
return (s64)sp_sys_mkdir(0, SP_NULLPTR, 0, 0);
return (s64)sp_sys_mkdir(0, SP_NULLPTR, 0, sp_zero_s(sp_sys_file_perms_t));
}

static s64 call_rmdir(void) {
Expand Down Expand Up @@ -484,8 +484,8 @@ static s64 call_get_file_metadata(void) {
return (s64)sp_sys_get_file_metadata(0, SP_NULLPTR);
}

static s64 call_chmod(void) {
return (s64)sp_sys_chmod(0, SP_NULLPTR, 0, SP_NULLPTR);
static s64 call_set_file_perms(void) {
return (s64)sp_sys_set_file_perms(0, SP_NULLPTR, 0, sp_zero_s(sp_sys_file_perms_t));
}

static s64 call_clock_gettime(void) {
Expand Down Expand Up @@ -709,7 +709,7 @@ static const test_t tests [] = {
{ "get_path_metadata", call_get_path_metadata, 69 },
{ "get_link_metadata", call_get_link_metadata, 69 },
{ "get_file_metadata", call_get_file_metadata, 69 },
{ "chmod", call_chmod, 69 },
{ "set_file_perms", call_set_file_perms, 69 },
{ "clock_gettime", call_clock_gettime, 69 },
{ "nanosleep", call_nanosleep, 69 },
{ "futex_wait", call_futex_wait, 1 },
Expand Down
Loading