From 0ab6a8cd0129c066115047c027888658eb508c21 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 4 Jan 2021 17:57:17 +0000 Subject: [PATCH] os: add a `posix_set_permission_bit` function (#7754) --- vlib/os/const.v | 17 -------------- vlib/os/os_c.v | 4 ++-- vlib/os/os_nix.c.v | 36 ++++++++++++++++++++++++++++++ vlib/os/os_test.v | 50 ++++++++++++++++++++++++++++++++++++++++++ vlib/os/os_windows.c.v | 4 ++++ 5 files changed, 92 insertions(+), 19 deletions(-) diff --git a/vlib/os/const.v b/vlib/os/const.v index 85d08f38f0..bcf59cfbe1 100644 --- a/vlib/os/const.v +++ b/vlib/os/const.v @@ -1,18 +1 @@ module os - -// (Must be realized in Syscall) (Must be specified) -// ref: http://www.ccfit.nsu.ru/~deviv/courses/unix/unix/ng7c229.html -const ( - s_ifmt = 0xF000 // type of file - s_ifdir = 0x4000 // directory - s_iflnk = 0xa000 // link - s_ixusr = 0o100 // is executable by the owner - s_ixgrp = 0o010 // is executable by group - s_ixoth = 0o001 // is executable by others -) - -const ( - std_input_handle = -10 - std_output_handle = -11 - std_error_handle = -12 -) diff --git a/vlib/os/os_c.v b/vlib/os/os_c.v index f457b82ae8..8a212d430c 100644 --- a/vlib/os/os_c.v +++ b/vlib/os/os_c.v @@ -472,7 +472,7 @@ pub fn get_raw_line() string { unsafe { max_line_chars := 256 buf := malloc(max_line_chars * 2) - h_input := C.GetStdHandle(std_input_handle) + h_input := C.GetStdHandle(C.STD_INPUT_HANDLE) mut bytes_read := 0 if is_atty(0) > 0 { C.ReadConsole(h_input, buf, max_line_chars * 2, C.LPDWORD(&bytes_read), @@ -514,7 +514,7 @@ pub fn get_raw_stdin() []byte { unsafe { block_bytes := 512 mut buf := malloc(block_bytes) - h_input := C.GetStdHandle(std_input_handle) + h_input := C.GetStdHandle(C.STD_INPUT_HANDLE) mut bytes_read := 0 mut offset := 0 for { diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index c8ac6c056c..91f343ca0e 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -17,6 +17,26 @@ const ( stderr_value = 2 ) +// (Must be realized in Syscall) (Must be specified) +// ref: http://www.ccfit.nsu.ru/~deviv/courses/unix/unix/ng7c229.html +pub const ( + s_ifmt = 0xF000 // type of file + s_ifdir = 0x4000 // directory + s_iflnk = 0xa000 // link + s_isuid = 0o4000 // SUID + s_isgid = 0o2000 // SGID + s_isvtx = 0o1000 // Sticky + s_irusr = 0o0400 // Read by owner + s_iwusr = 0o0200 // Write by owner + s_ixusr = 0o0100 // Execute by owner + s_irgrp = 0o0040 // Read by group + s_iwgrp = 0o0020 // Write by group + s_ixgrp = 0o0010 // Execute by group + s_iroth = 0o0004 // Read by others + s_iwoth = 0o0002 // Write by others + s_ixoth = 0o0001 // Execute by others +) + struct C.utsname { mut: sysname charptr @@ -264,3 +284,19 @@ pub fn is_writable_folder(folder string) ?bool { pub fn getpid() int { return C.getpid() } + +// Turns the given bit on or off, depending on the `enable` parameter +pub fn posix_set_permission_bit(path_s string, mode u32, enable bool) { + mut s := C.stat{} + mut new_mode := u32(0) + path := charptr(path_s.str) + unsafe { + C.stat(path, &s) + new_mode = s.st_mode + } + match enable { + true { new_mode |= mode } + false { new_mode &= (0o7777 - mode) } + } + C.chmod(path, int(new_mode)) +} diff --git a/vlib/os/os_test.v b/vlib/os/os_test.v index c7c66b15e2..660753b6a5 100644 --- a/vlib/os/os_test.v +++ b/vlib/os/os_test.v @@ -465,3 +465,53 @@ for !cmd.eof { cmd.close() */ } + +fn test_posix_set_bit() { + $if windows { + assert true + } $else { + fpath := '/tmp/permtest' + create(fpath) or { panic("Couldn't create file") } + chmod(fpath, 0o7777) + c_fpath := charptr(fpath.str) + mut s := C.stat{} + unsafe { + C.stat(c_fpath, &s) + } + // Take the permissions part of the mode + mut mode := u32(s.st_mode) & 0o7777 + assert mode == 0o7777 + // `chmod u-r` + posix_set_permission_bit(fpath, os.s_irusr, false) + unsafe { + C.stat(c_fpath, &s) + } + mode = u32(s.st_mode) & 0o7777 + assert mode == 0o7377 + // `chmod u+r` + posix_set_permission_bit(fpath, os.s_irusr, true) + unsafe { + C.stat(c_fpath, &s) + } + mode = u32(s.st_mode) & 0o7777 + assert mode == 0o7777 + // `chmod -s -g -t` + posix_set_permission_bit(fpath, os.s_isuid, false) + posix_set_permission_bit(fpath, os.s_isgid, false) + posix_set_permission_bit(fpath, os.s_isvtx, false) + unsafe { + C.stat(c_fpath, &s) + } + mode = u32(s.st_mode) & 0o7777 + assert mode == 0o0777 + // `chmod g-w o-w` + posix_set_permission_bit(fpath, os.s_iwgrp, false) + posix_set_permission_bit(fpath, os.s_iwoth, false) + unsafe { + C.stat(c_fpath, &s) + } + mode = u32(s.st_mode) & 0o7777 + assert mode == 0o0755 + rm(fpath) + } +} diff --git a/vlib/os/os_windows.c.v b/vlib/os/os_windows.c.v index 437e32daae..a2faeea2bd 100644 --- a/vlib/os/os_windows.c.v +++ b/vlib/os/os_windows.c.v @@ -391,3 +391,7 @@ fn C._getpid() int pub fn getpid() int { return C._getpid() } + +pub fn posix_set_permission_bit(path_s string, mode u32, enable bool) { + // windows has no concept of a permission mask, so do nothing +}