specify posix.sys.stat: - before: st = require "posix.sys.stat" S_IRWXU, S_IRWXG, S_IRWXO = st.S_IRWXU, st.S_IRWXG, st.S_IRWXO S_ISBLK, S_ISCHR, S_ISDIR, S_ISFIFO, S_ISREG, S_ISLNK, S_ISSOCK = st.S_ISBLK, st.S_ISCHR, st.S_ISDIR, st.S_ISFIFO, st.S_ISREG, st.S_ISLNK, st.S_ISSOCK RWXALL = bor (S_IRWXU, S_IRWXG, S_IRWXO) dir = posix.mkdtemp (template) posix.mkdir (dir .. "/subdir") posix.link ("subdir", dir .. "/soft", true) touch (dir .. "/file") posix.link (dir .. "/file", dir .. "/hard") posix.link ("no such destination", dir .. "/dangling", true) posix.mkfifo (dir .. "/fifo") - after: rmtmp (dir) - describe chmod: - before: chmod, lstat = st.chmod, st.lstat chmod (dir .. "/file", bor (st.S_IRWXU, st.S_IRGRP, st.S_IXGRP)) - context with bad arguments: | badargs.diagnose (chmod, "(string, int)") examples { ["it diagnoses non-existent files"] = function () expect (Emsg (chmod (dir .. "/not existing file", st.S_IRWXU))). to_contain "No such file or directory" end } - it sets file mode: mode = bor (st.S_IRUSR, st.S_IWUSR, st.S_IXGRP, st.S_IROTH) chmod (dir .. "/file", mode) expect (band (lstat (dir .. "/file").st_mode, RWXALL)).to_be (mode) - describe lstat: - before: # choose a format without seconds, that won't cause a race condition fmt = "%b %d %H:%M" now = os.date (fmt) getegid, geteuid = posix.getegid, posix.geteuid lstat = st.lstat - context with bad arguments: badargs.diagnose (lstat, "(string)") - it returns a PosixStat: expect (prototype (lstat (dir .. "/file"))).to_be "PosixStat" - it fetches the device id: dev = lstat (dir .. "/file").st_dev expect (type (dev)).to_be "number" expect (dev >= 0).to_be (true) expect (dev).to_be (lstat (dir).st_dev) - it fetches the file inode: ino = lstat (dir .. "/file").st_ino expect (type (ino)).to_be "number" expect (ino >= 0).to_be (true) expect (ino).to_be (lstat (dir .. "/hard").st_ino) expect (ino).not_to_be (lstat (dir .. "/soft").st_ino) - context with file mode: - it fetches the file access mode: mode = lstat (dir).st_mode expect (type (mode)).to_be "number" expect (band (mode, S_IRWXU)).to_be (S_IRWXU) - it recognises directories: expect (S_ISBLK (lstat (dir).st_mode)).to_be (0) expect (S_ISCHR (lstat (dir).st_mode)).to_be (0) expect (S_ISDIR (lstat (dir).st_mode)).not_to_be (0) expect (S_ISFIFO (lstat (dir).st_mode)).to_be (0) expect (S_ISREG (lstat (dir).st_mode)).to_be (0) expect (S_ISLNK (lstat (dir).st_mode)).to_be (0) expect (S_ISSOCK (lstat (dir).st_mode)).to_be (0) - it recognises fifos: expect (S_ISBLK (lstat (dir .. "/fifo").st_mode)).to_be (0) expect (S_ISCHR (lstat (dir .. "/fifo").st_mode)).to_be (0) expect (S_ISDIR (lstat (dir .. "/fifo").st_mode)).to_be (0) expect (S_ISFIFO (lstat (dir .. "/fifo").st_mode)).not_to_be (0) expect (S_ISREG (lstat (dir .. "/fifo").st_mode)).to_be (0) expect (S_ISLNK (lstat (dir .. "/fifo").st_mode)).to_be (0) expect (S_ISSOCK (lstat (dir .. "/fifo").st_mode)).to_be (0) - it recognises regular files: expect (S_ISBLK (lstat (dir .. "/file").st_mode)).to_be (0) expect (S_ISCHR (lstat (dir .. "/file").st_mode)).to_be (0) expect (S_ISDIR (lstat (dir .. "/file").st_mode)).to_be (0) expect (S_ISFIFO (lstat (dir .. "/file").st_mode)).to_be (0) expect (S_ISREG (lstat (dir .. "/file").st_mode)).not_to_be (0) expect (S_ISLNK (lstat (dir .. "/file").st_mode)).to_be (0) expect (S_ISSOCK (lstat (dir .. "/file").st_mode)).to_be (0) - it recognises soft links: expect (S_ISBLK (lstat (dir .. "/soft").st_mode)).to_be (0) expect (S_ISCHR (lstat (dir .. "/soft").st_mode)).to_be (0) expect (S_ISDIR (lstat (dir .. "/soft").st_mode)).to_be (0) expect (S_ISFIFO (lstat (dir .. "/soft").st_mode)).to_be (0) expect (S_ISREG (lstat (dir .. "/soft").st_mode)).to_be (0) expect (S_ISLNK (lstat (dir .. "/soft").st_mode)).not_to_be (0) expect (S_ISSOCK (lstat (dir .. "/soft").st_mode)).to_be (0) - it fetches the number of links: expect (lstat (dir .. "/file").st_nlink).to_be (2) expect (lstat (dir .. "/soft").st_nlink).to_be (1) expect (lstat (dir .. "/hard").st_nlink). to_be (lstat (dir .. "/file").st_nlink) expect (lstat (dir .. "/subdir").st_nlink).to_be (2) - it fetches the owner id: expect (lstat (dir .. "/file").st_uid).to_be (geteuid ()) expect (lstat (dir .. "/subdir").st_uid).to_be (geteuid ()) - it fetches the owner group id: expect (lstat (dir .. "/file").st_gid).to_be (getegid ()) expect (lstat (dir .. "/subdir").st_gid).to_be (getegid ()) - it fetches the device special file id: pending "mknod not yet bound" - it fetches the file size: # skip directory size, which is system dependent expect (lstat (dir .. "/file").st_size).to_be (0) expect (lstat (dir .. "/soft").st_size).to_be (string.len ("subdir")) expect (lstat (dir .. "/hard").st_size). to_be (lstat (dir .. "/file").st_size) - it fetches the file access time: expect (os.date (fmt, lstat (dir .. "/file").st_atime)).to_be (os.date (fmt)) - it fetches the file modification time: expect (os.date (fmt, lstat (dir .. "/file").st_mtime)).to_be (now) - it fetches the file change time: expect (os.date (fmt, lstat (dir .. "/file").st_ctime)).to_be (now) - it fetches the device block size: blksize = lstat (dir .. "/file").st_blksize expect (type (blksize)).to_be "number" expect (blksize > 0).to_be (true) expect (blksize).to_be (lstat (dir .. "/hard").st_blksize) - it fetches the number of blocks: blocks = lstat (dir .. "/file").st_blocks expect (type (blocks)).to_be "number" expect (blocks >= 0).to_be (true) expect (blocks).to_be (lstat (dir .. "/hard").st_blocks) - describe mkdir: - before: dir = posix.mkdtemp (template) lstat, mkdir = st.lstat, st.mkdir - after: rmtmp (dir) - context with bad arguments: badargs.diagnose (mkdir, "(string, ?int)") - it creates the named directory: expect (Emsg (mkdir (dir .. "/subdir"))).not_to_contain "exists" mode = lstat (dir .. "/subdir").st_mode expect (st.S_ISDIR (mode)).not_to_be (0) - it sets the new directory permissions: mkdir (dir .. "/subdir", S_IRWXU) mode = lstat (dir .. "/subdir").st_mode expect (band (mode, RWXALL)).to_be (S_IRWXU) - it diagnoses already existing directory: expect (Emsg (mkdir (dir, RWXALL))).to_contain "exists" - describe mkfifo: - before: dir = posix.mkdtemp (template) lstat, mkfifo = st.lstat, st.mkfifo - after: rmtmp (dir) - context with bad arguments: badargs.diagnose (mkfifo, "(string, ?int)") - it creates the named fifo: expect (Emsg (mkfifo (dir .. "/fifo"))).not_to_contain "exists" mode = lstat (dir .. "/fifo").st_mode expect (st.S_ISFIFO (mode)).not_to_be (0) - it sets the new fifo permissions: mkfifo (dir .. "/fifo", S_IRWXU) mode = lstat (dir .. "/fifo").st_mode expect (band (mode, RWXALL)).to_be (S_IRWXU) - it diagnoses already existing fifo: expect (Emsg (mkfifo (dir, RWXALL))).to_contain "exists" - describe stat: - before: # choose a format without seconds, that won't cause a race condition fmt = "%b %d %H:%M" now = os.date (fmt) getegid, geteuid = posix.getegid, posix.geteuid stat = st.stat - context with bad arguments: badargs.diagnose (stat, "(string)") - it returns a PosixStat: expect (prototype (stat (dir .. "/file"))).to_be "PosixStat" - it fetches the device id: dev = stat (dir .. "/file").st_dev expect (type (dev)).to_be "number" expect (dev >= 0).to_be (true) expect (dev).to_be (stat (dir).st_dev) - it fetches the file inode: ino = stat (dir .. "/file").st_ino expect (type (ino)).to_be "number" expect (ino >= 0).to_be (true) expect (ino).to_be (stat (dir .. "/hard").st_ino) expect (ino).not_to_be (stat (dir .. "/soft").st_ino) - context with file mode: - it fetches the file access mode: mode = stat (dir).st_mode expect (type (mode)).to_be "number" expect (band (mode, S_IRWXU)).to_be (S_IRWXU) - it recognises directories: expect (S_ISBLK (stat (dir).st_mode)).to_be (0) expect (S_ISCHR (stat (dir).st_mode)).to_be (0) expect (S_ISDIR (stat (dir).st_mode)).not_to_be (0) expect (S_ISFIFO (stat (dir).st_mode)).to_be (0) expect (S_ISREG (stat (dir).st_mode)).to_be (0) expect (S_ISLNK (stat (dir).st_mode)).to_be (0) expect (S_ISSOCK (stat (dir).st_mode)).to_be (0) - it recognises fifos: expect (S_ISBLK (stat (dir .. "/fifo").st_mode)).to_be (0) expect (S_ISCHR (stat (dir .. "/fifo").st_mode)).to_be (0) expect (S_ISDIR (stat (dir .. "/fifo").st_mode)).to_be (0) expect (S_ISFIFO (stat (dir .. "/fifo").st_mode)).not_to_be (0) expect (S_ISREG (stat (dir .. "/fifo").st_mode)).to_be (0) expect (S_ISLNK (stat (dir .. "/fifo").st_mode)).to_be (0) expect (S_ISSOCK (stat (dir .. "/fifo").st_mode)).to_be (0) - it recognises regular files: expect (S_ISBLK (stat (dir .. "/file").st_mode)).to_be (0) expect (S_ISCHR (stat (dir .. "/file").st_mode)).to_be (0) expect (S_ISDIR (stat (dir .. "/file").st_mode)).to_be (0) expect (S_ISFIFO (stat (dir .. "/file").st_mode)).to_be (0) expect (S_ISREG (stat (dir .. "/file").st_mode)).not_to_be (0) expect (S_ISLNK (stat (dir .. "/file").st_mode)).to_be (0) expect (S_ISSOCK (stat (dir .. "/file").st_mode)).to_be (0) - it recognises soft links: expect (S_ISBLK (stat (dir .. "/soft").st_mode)).to_be (0) expect (S_ISCHR (stat (dir .. "/soft").st_mode)).to_be (0) expect (S_ISDIR (stat (dir .. "/soft").st_mode)).not_to_be (0) expect (S_ISFIFO (stat (dir .. "/soft").st_mode)).to_be (0) expect (S_ISREG (stat (dir .. "/soft").st_mode)).to_be (0) expect (S_ISLNK (stat (dir .. "/soft").st_mode)).to_be (0) expect (S_ISSOCK (stat (dir .. "/soft").st_mode)).to_be (0) - it fetches the number of links: expect (stat (dir .. "/file").st_nlink).to_be (2) expect (stat (dir .. "/soft").st_nlink). to_be (stat (dir .. "/subdir").st_nlink) expect (stat (dir .. "/hard").st_nlink). to_be (stat (dir .. "/file").st_nlink) expect (stat (dir .. "/subdir").st_nlink).to_be (2) - it fetches the owner id: expect (stat (dir .. "/file").st_uid).to_be (geteuid ()) expect (stat (dir .. "/subdir").st_uid).to_be (geteuid ()) - it fetches the owner group id: expect (stat (dir .. "/file").st_gid).to_be (getegid ()) expect (stat (dir .. "/subdir").st_gid).to_be (getegid ()) - it fetches the device special file id: pending "mknod not yet bound" - it fetches the file size: # skip directory size, which is system dependent expect (stat (dir .. "/file").st_size).to_be (0) expect (stat (dir .. "/soft").st_size).not_to_be (string.len ("subdir")) expect (stat (dir .. "/hard").st_size). to_be (stat (dir .. "/file").st_size) - it fetches the file access time: expect (os.date (fmt, stat (dir .. "/file").st_atime)).to_be (os.date (fmt)) - it fetches the file modification time: expect (os.date (fmt, stat (dir .. "/file").st_mtime)).to_be (now) - it fetches the file change time: expect (os.date (fmt, stat (dir .. "/file").st_ctime)).to_be (now) - it fetches the device block size: blksize = stat (dir .. "/file").st_blksize expect (type (blksize)).to_be "number" expect (blksize > 0).to_be (true) expect (blksize).to_be (stat (dir .. "/hard").st_blksize) - it fetches the number of blocks: blocks = stat (dir .. "/file").st_blocks expect (type (blocks)).to_be "number" expect (blocks >= 0).to_be (true) expect (blocks).to_be (stat (dir .. "/hard").st_blocks) - describe umask: - before: lstat, umask = st.lstat, st.umask newmask = band (st.S_IWGRP, st.S_IRWXO) origmask = umask (newmask) - after: umask (origmask) - context with bad arguments: badargs.diagnose (umask, "(int)") - it returns current umask: expect (umask (0)).to_be (newmask) expect (umask (newmask)).to_be (0) - it controls the mode of newly created files: all = bor (st.S_IRWXU, st.S_IRWXG, st.S_IRWXO) xxx, mask = dir .. "/xxx", bor (st.S_IRWXO, st.S_IWGRP, st.S_IXGRP) umask (mask) touch (xxx) expect (band (lstat (xxx).st_mode, all)).to_be (bor (st.S_IRUSR, st.S_IWUSR, st.S_IRGRP)) os.remove (xxx)