238 lines
7.6 KiB
Factor
238 lines
7.6 KiB
Factor
! Copyright (C) 2007 Doug Coleman.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
USING: alien arrays calendar errors io io-internals kernel
|
|
math nonblocking-io sequences unix-internals unix-io ;
|
|
IN: libs-io
|
|
|
|
: O_APPEND HEX: 100 ; inline
|
|
: O_EXCL HEX: 800 ; inline
|
|
: SEEK_SET 0 ; inline
|
|
: SEEK_CUR 1 ; inline
|
|
: SEEK_END 2 ; inline
|
|
: EEXIST 17 ; inline
|
|
|
|
FUNCTION: off_t lseek ( int fildes, off_t offset, int whence ) ;
|
|
: append-mode
|
|
O_WRONLY O_APPEND O_CREAT bitor bitor ; foldable
|
|
|
|
: open-append ( path -- fd )
|
|
append-mode file-mode open dup io-error
|
|
[ 0 SEEK_END lseek io-error ] keep ;
|
|
|
|
: touch-mode
|
|
O_WRONLY O_APPEND O_CREAT O_EXCL bitor bitor bitor ; foldable
|
|
|
|
: open-touch ( path -- fd )
|
|
touch-mode file-mode open
|
|
[ io-error close t ]
|
|
[ 2drop err_no EEXIST = [ err_no io-error ] unless -1 ] recover ;
|
|
|
|
: <file-appender> ( path -- stream ) open-append <writer> ;
|
|
|
|
FUNCTION: int unlink ( char* path ) ;
|
|
: delete-file ( path -- )
|
|
unlink io-error ;
|
|
|
|
FUNCTION: int mkdir ( char* path, mode_t mode ) ;
|
|
|
|
: (create-directory) ( path mode -- )
|
|
mkdir io-error ;
|
|
|
|
: create-directory ( path -- )
|
|
0 (create-directory) ;
|
|
|
|
FUNCTION: int rmdir ( char* path ) ;
|
|
|
|
: delete-directory ( path -- )
|
|
rmdir io-error ;
|
|
|
|
FUNCTION: int chroot ( char* path ) ;
|
|
FUNCTION: int chdir ( char* path ) ;
|
|
FUNCTION: int fchdir ( int fd ) ;
|
|
|
|
FUNCTION: int utimes ( char* path, timeval[2] times ) ;
|
|
FUNCTION: int futimes ( int id, timeval[2] times ) ;
|
|
|
|
TYPEDEF: longlong blkcnt_t
|
|
TYPEDEF: int blksize_t
|
|
TYPEDEF: int dev_t
|
|
TYPEDEF: uint ino_t
|
|
TYPEDEF: ushort mode_t
|
|
TYPEDEF: ushort nlink_t
|
|
TYPEDEF: uint uid_t
|
|
TYPEDEF: uint gid_t
|
|
TYPEDEF: longlong quad_t
|
|
TYPEDEF: ulong u_long
|
|
|
|
FUNCTION: int stat ( char* path, stat* sb ) ;
|
|
|
|
C-STRUCT: stat
|
|
{ "dev_t" "dev" } ! device inode resides on
|
|
{ "ino_t" "ino" } ! inode's number
|
|
{ "mode_t" "mode" } ! inode protection mode
|
|
{ "nlink_t" "nlink" } ! number or hard links to the file
|
|
{ "uid_t" "uid" } ! user-id of owner
|
|
{ "gid_t" "gid" } ! group-id of owner
|
|
{ "dev_t" "rdev" } ! device type, for special file inode
|
|
{ "timespec" "atime" } ! time of last access
|
|
{ "timespec" "mtime" } ! time of last data modification
|
|
{ "timespec" "ctime" } ! time of last file status change
|
|
{ "off_t" "size" } ! file size, in bytes
|
|
{ "blkcnt_t" "blocks" } ! blocks allocated for file
|
|
{ "blksize_t" "blksize" } ! optimal file sys I/O ops blocksize
|
|
{ "u_long" "flags" } ! user defined flags for file
|
|
{ "u_long" "gen" } ; ! file generation number
|
|
|
|
: stat* ( path -- byte-array )
|
|
"stat" <c-object> [ stat io-error ] keep ;
|
|
|
|
: make-timeval-array ( array -- byte-array )
|
|
[ length "timeval" <c-array> ] keep
|
|
dup length [ over [ pick set-timeval-nth ] [ 2drop ] if ] 2each ;
|
|
|
|
: (set-file-times) ( timestamp timestamp -- alien )
|
|
[ [ timestamp>timeval ] [ f ] if* ] 2apply 2array
|
|
make-timeval-array ;
|
|
|
|
: set-file-times ( path timestamp timestamp -- )
|
|
#! set access, write
|
|
(set-file-times) utimes io-error ;
|
|
|
|
: set-file-times* ( fd timestamp timestamp -- )
|
|
(set-file-times) futimes io-error ;
|
|
|
|
|
|
: set-file-access-time ( path timestamp -- )
|
|
f set-file-times ;
|
|
|
|
: set-file-write-time ( path timestamp -- )
|
|
>r f r> set-file-times ;
|
|
|
|
|
|
: file-write-time ( path -- timestamp )
|
|
stat* stat-mtime timespec>timestamp ;
|
|
|
|
: file-access-time ( path -- timestamp )
|
|
stat* stat-atime timespec>timestamp ;
|
|
|
|
! File type
|
|
: S_IFMT OCT: 0170000 ; inline ! type of file
|
|
: S_IFIFO OCT: 0010000 ; inline ! named pipe (fifo)
|
|
: S_IFCHR OCT: 0020000 ; inline ! character special
|
|
: S_IFDIR OCT: 0040000 ; inline ! directory
|
|
: S_IFBLK OCT: 0060000 ; inline ! block special
|
|
: S_IFREG OCT: 0100000 ; inline ! regular
|
|
: S_IFLNK OCT: 0120000 ; inline ! symbolic link
|
|
: S_IFSOCK OCT: 0140000 ; inline ! socket
|
|
: S_IFWHT OCT: 0160000 ; inline ! whiteout
|
|
: S_IFXATTR OCT: 0200000 ; inline ! extended attribute
|
|
|
|
! File mode
|
|
! Read, write, execute/search by owner
|
|
: S_IRWXU OCT: 0000700 ; inline ! rwx mask owner
|
|
: S_IRUSR OCT: 0000400 ; inline ! r owner
|
|
: S_IWUSR OCT: 0000200 ; inline ! w owner
|
|
: S_IXUSR OCT: 0000100 ; inline ! x owner
|
|
! Read, write, execute/search by group
|
|
: S_IRWXG OCT: 0000070 ; inline ! rwx mask group
|
|
: S_IRGRP OCT: 0000040 ; inline ! r group
|
|
: S_IWGRP OCT: 0000020 ; inline ! w group
|
|
: S_IXGRP OCT: 0000010 ; inline ! x group
|
|
! Read, write, execute/search by others
|
|
: S_IRWXO OCT: 0000007 ; inline ! rwx mask other
|
|
: S_IROTH OCT: 0000004 ; inline ! r other
|
|
: S_IWOTH OCT: 0000002 ; inline ! w other
|
|
: S_IXOTH OCT: 0000001 ; inline ! x other
|
|
|
|
: S_ISUID OCT: 0004000 ; inline ! set user id on execution
|
|
: S_ISGID OCT: 0002000 ; inline ! set group id on execution
|
|
: S_ISVTX OCT: 0001000 ; inline ! sticky bit
|
|
|
|
FUNCTION: uid_t getuid ;
|
|
FUNCTION: uid_t geteuid ;
|
|
|
|
FUNCTION: gid_t getgid ;
|
|
FUNCTION: gid_t getegid ;
|
|
|
|
FUNCTION: int setuid ( uid_t uid ) ;
|
|
FUNCTION: int seteuid ( uid_t euid ) ;
|
|
FUNCTION: int setreuid ( uid_t ruid, uid_t euid ) ;
|
|
|
|
FUNCTION: int setgid ( gid_t gid ) ;
|
|
FUNCTION: int setegid ( gid_t egid ) ;
|
|
FUNCTION: int setregid ( gid_t rgid, gid_t egid ) ;
|
|
|
|
FUNCTION: int issetugid ;
|
|
|
|
FUNCTION: int chmod ( char* path, mode_t mode ) ;
|
|
FUNCTION: int fchmod ( int fd, mode_t mode ) ;
|
|
|
|
FUNCTION: int chown ( char* path, uid_t owner, gid_t group ) ;
|
|
FUNCTION: int fchown ( int fd, uid_t owner, gid_t group ) ;
|
|
#! lchown does not follow symbolic links
|
|
FUNCTION: int lchown ( char* path, uid_t owner, gid_t group ) ;
|
|
|
|
FUNCTION: int getgroups ( int gidsetlen, gid_t* gidset ) ;
|
|
FUNCTION: int setgroups ( int ngroups, gid_t* gidset ) ;
|
|
|
|
FUNCTION: int flock ( int fd, int operation ) ;
|
|
! FUNCTION: int dup ( int oldd ) ;
|
|
! FUNCTION: int dup2 ( int oldd, int newd ) ;
|
|
|
|
FUNCTION: int fcntl ( int fd, int cmd, int arg ) ;
|
|
FUNCTION: int getdtablesize ;
|
|
|
|
: file-mode? ( path mask -- ? )
|
|
>r stat* stat-mode r> bit-set? ;
|
|
|
|
: user-read? ( path -- ? ) S_IRUSR file-mode? ;
|
|
: user-write? ( path -- ? ) S_IWUSR file-mode? ;
|
|
: user-execute? ( path -- ? ) S_IXUSR file-mode? ;
|
|
|
|
: group-read? ( path -- ? ) S_IRGRP file-mode? ;
|
|
: group-write? ( path -- ? ) S_IWGRP file-mode? ;
|
|
: group-execute? ( path -- ? ) S_IXGRP file-mode? ;
|
|
|
|
: other-read? ( path -- ? ) S_IROTH file-mode? ;
|
|
: other-write? ( path -- ? ) S_IWOTH file-mode? ;
|
|
: other-execute? ( path -- ? ) S_IXOTH file-mode? ;
|
|
|
|
: set-uid? ( path -- ? ) S_ISUID bit-set? ;
|
|
: set-gid? ( path -- ? ) S_ISGID bit-set? ;
|
|
: set-sticky? ( path -- ? ) S_ISVTX bit-set? ;
|
|
|
|
: chmod* ( path mask ? -- )
|
|
>r >r dup stat* stat-mode r> r> [
|
|
set-bit
|
|
] [
|
|
clear-bit
|
|
] if chmod io-error ;
|
|
|
|
: set-user-read ( path ? -- ) >r S_IRUSR r> chmod* ;
|
|
: set-user-write ( path ? -- ) >r S_IWUSR r> chmod* ;
|
|
: set-user-execute ( path ? -- ) >r S_IXUSR r> chmod* ;
|
|
|
|
: set-group-read ( path ? -- ) >r S_IRGRP r> chmod* ;
|
|
: set-group-write ( path ? -- ) >r S_IWGRP r> chmod* ;
|
|
: set-group-execute ( path ? -- ) >r S_IXGRP r> chmod* ;
|
|
|
|
: set-other-read ( path ? -- ) >r S_IROTH r> chmod* ;
|
|
: set-other-write ( path ? -- ) >r S_IWOTH r> chmod* ;
|
|
: set-other-execute ( path ? -- ) >r S_IXOTH r> chmod* ;
|
|
|
|
: set-uid ( path ? -- ) >r S_ISUID r> chmod* ;
|
|
: set-gid ( path ? -- ) >r S_ISGID r> chmod* ;
|
|
: set-sticky ( path ? -- ) >r S_ISVTX r> chmod* ;
|
|
|
|
: mode>symbol ( mode -- ch )
|
|
S_IFMT bitand
|
|
{
|
|
{ [ dup S_IFDIR = ] [ drop "/" ] }
|
|
{ [ dup S_IFIFO = ] [ drop "|" ] }
|
|
{ [ dup S_IXUSR = ] [ drop "*" ] }
|
|
{ [ dup S_IFLNK = ] [ drop "@" ] }
|
|
{ [ dup S_IFWHT = ] [ drop "%" ] }
|
|
{ [ dup S_IFSOCK = ] [ drop "=" ] }
|
|
{ [ t ] [ drop "" ] }
|
|
} cond ;
|