justincormack / ljsyscall

LuaJIT Unix syscall FFI
http://www.myriabit.com/ljsyscall/
Other
441 stars 54 forks source link

How to create directory with sticky tag? #184

Open eugeneia opened 9 years ago

eugeneia commented 9 years ago

How can I create a directory with the sticky tag using ljsyscall? I tried the following without success:

S.mkdir("/tmp/foo", "1777")
S.mkdir("/tmp/foo", 1023)
S.mkdir("/tmp/foo", "rwxrwxrwt")
justincormack commented 9 years ago

Hi, the octal syntax for mode flags requires that the number be preceded by a zero, so

S.mkdir("/tmp/foo", "01777")

seems ok for me. It looks like I missed the last form, will add it and also add some tests for sticky bits as there arent any right now...

eugeneia commented 9 years ago

Thanks for the blazing fast reply as always. I think there is a bug though:

mkdir -m 01777 /tmp/foo
ls -ld /tmp/foo
drwxrwxrwt 2 root root 4096 Jul 17 17:17 /tmp/foo

S.mkdir("/tmp/bar", "01777")
ls -ld /tmp/bar
drwxr-xr-t 2 root root 4096 Jul 17 17:17 /tmp/bar
justincormack commented 9 years ago

Hmm, I get

drwxrwxr-t  2 justin justin    4096 Jul 17 16:10 foo

which is different. But if I strace it I see:

strace luajit -e 'S=require "syscall";S.mkdir("/tmp/foo", "01777")'
mkdir("/tmp/foo", 01777)

So it is doing what it is told, but oddly stracing the mkdir:

strace mkdir -m 01777 /tmp/baz
umask(0)                                = 02
umask(02)                               = 0
mkdir("/tmp/baz", 01755)                = 0

So the standard strace doesnt actually do what it is told to, but it does do the right thing! I need to look into libc and see if it justifies this behaviour. In the meantime you may be able to get the result you want by setting the umask with ljsyscall I guess...

Thats really odd, I need some coffee!

eugeneia commented 9 years ago

@justincormack I found that it works for me if I do an umask to 0 on advance:

S.umask("0")
S.mkdir("/tmp/test", "01777")
ls -ld /tmp/test/
drwxrwxrwt 2 root root 4096 Jul 22 09:42 /tmp/test/

E.g. we both already had an umask?

justincormack commented 9 years ago

I think the coreutils mkdir(1) program basically wraps this clearing of the umask, but the system call/glibc do not and behave like ljsyscall.

eugeneia commented 9 years ago

@justincormack Is there a way I can get the current umask so I can set it back to its original state after changing it? I fear setting the process umask somewhere might have unintended side effects.

justincormack commented 9 years ago

Its kind of stupid, the umask syscall returns the current value, but you have to change it too before you know what it was, so

mask = S.umask(0)
chmod here
S.umask(mask)

should work (untested).