os: add a `posix_set_permission_bit` function (#7754)

pull/7801/head
clubby789 2021-01-04 17:57:17 +00:00 committed by GitHub
parent 46d311dcc4
commit 0ab6a8cd01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 92 additions and 19 deletions

View File

@ -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
)

View File

@ -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 {

View File

@ -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))
}

View File

@ -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)
}
}

View File

@ -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
}