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 ;
							 |