factor/basis/io/files/info/unix/unix.factor

277 lines
8.3 KiB
Factor
Raw Normal View History

! Copyright (C) 2008 Doug Coleman.
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: accessors kernel system math math.bitwise strings arrays
sequences combinators combinators.short-circuit alien.c-types
vocabs.loader calendar calendar.unix io.files.info
io.files.types io.backend unix unix.stat unix.time unix.users
unix.groups ;
IN: io.files.info.unix
2008-02-29 00:46:27 -05:00
TUPLE: unix-file-system-info < file-system-info
block-size preferred-block-size
blocks blocks-free blocks-available
files files-free files-available
2008-12-03 01:19:52 -05:00
name-max flags id ;
2008-02-29 00:46:27 -05:00
HOOK: new-file-system-info os ( -- file-system-info )
M: unix new-file-system-info ( -- ) unix-file-system-info new ;
HOOK: file-system-statfs os ( path -- statfs )
M: unix file-system-statfs drop f ;
HOOK: file-system-statvfs os ( path -- statvfs )
M: unix file-system-statvfs drop f ;
HOOK: statfs>file-system-info os ( file-system-info statfs -- file-system-info' )
M: unix statfs>file-system-info drop ;
HOOK: statvfs>file-system-info os ( file-system-info statvfs -- file-system-info' )
2008-10-06 18:17:14 -04:00
M: unix statvfs>file-system-info drop ;
: file-system-calculations ( file-system-info -- file-system-info' )
dup [ blocks-available>> ] [ block-size>> ] bi * >>available-space
dup [ blocks-free>> ] [ block-size>> ] bi * >>free-space
dup [ blocks>> ] [ block-size>> ] bi * >>total-space
dup [ total-space>> ] [ free-space>> ] bi - >>used-space ;
M: unix file-system-info
normalize-path
[ new-file-system-info ] dip
[ file-system-statfs statfs>file-system-info ]
[ file-system-statvfs statvfs>file-system-info ] bi
file-system-calculations ;
2008-10-06 18:17:14 -04:00
TUPLE: unix-file-info < file-info uid gid dev ino
nlink rdev blocks blocksize ;
HOOK: new-file-info os ( -- file-info )
HOOK: stat>file-info os ( stat -- file-info )
HOOK: stat>type os ( stat -- file-info )
2008-04-02 21:09:56 -04:00
M: unix file-info ( path -- info )
2008-05-13 14:37:25 -04:00
normalize-path file-status stat>file-info ;
2008-03-13 23:08:57 -04:00
2008-04-02 21:09:56 -04:00
M: unix link-info ( path -- info )
2008-05-13 14:37:25 -04:00
normalize-path link-status stat>file-info ;
2008-10-06 18:17:14 -04:00
M: unix new-file-info ( -- class ) unix-file-info new ;
2009-04-20 18:44:12 -04:00
CONSTANT: standard-unix-block-size 512
2008-10-06 18:17:14 -04:00
M: unix stat>file-info ( stat -- file-info )
[ new-file-info ] dip
{
[ stat>type >>type ]
[ stat-st_size >>size ]
[ stat-st_mode >>permissions ]
[ stat-st_ctimespec timespec>unix-time >>created ]
[ stat-st_mtimespec timespec>unix-time >>modified ]
[ stat-st_atimespec timespec>unix-time >>accessed ]
2008-10-06 18:17:14 -04:00
[ stat-st_uid >>uid ]
[ stat-st_gid >>gid ]
[ stat-st_dev >>dev ]
[ stat-st_ino >>ino ]
[ stat-st_nlink >>nlink ]
[ stat-st_rdev >>rdev ]
[ stat-st_blocks >>blocks ]
[ stat-st_blksize >>blocksize ]
2009-04-20 18:44:12 -04:00
[ drop dup blocks>> standard-unix-block-size * >>size-on-disk ]
2008-10-06 18:17:14 -04:00
} cleave ;
: n>file-type ( n -- type )
S_IFMT bitand {
2008-10-06 18:17:14 -04:00
{ S_IFREG [ +regular-file+ ] }
{ S_IFDIR [ +directory+ ] }
{ S_IFCHR [ +character-device+ ] }
{ S_IFBLK [ +block-device+ ] }
{ S_IFIFO [ +fifo+ ] }
{ S_IFLNK [ +symbolic-link+ ] }
{ S_IFSOCK [ +socket+ ] }
[ drop +unknown+ ]
} case ;
M: unix stat>type ( stat -- type )
stat-st_mode n>file-type ;
2008-10-07 20:25:22 -04:00
<PRIVATE
: stat-mode ( path -- mode )
normalize-path file-status stat-st_mode ;
2008-11-30 20:13:42 -05:00
: chmod-set-bit ( path mask ? -- )
[ dup stat-mode ] 2dip
[ bitor ] [ unmask ] if chmod io-error ;
2008-10-07 20:25:22 -04:00
2008-11-30 20:13:42 -05:00
GENERIC# file-mode? 1 ( obj mask -- ? )
M: integer file-mode? mask? ;
M: string file-mode? [ stat-mode ] dip mask? ;
M: file-info file-mode? [ permissions>> ] dip mask? ;
2008-10-07 20:25:22 -04:00
PRIVATE>
2009-02-22 20:13:08 -05:00
CONSTANT: UID OCT: 0004000
CONSTANT: GID OCT: 0002000
CONSTANT: STICKY OCT: 0001000
CONSTANT: USER-ALL OCT: 0000700
CONSTANT: USER-READ OCT: 0000400
CONSTANT: USER-WRITE OCT: 0000200
CONSTANT: USER-EXECUTE OCT: 0000100
CONSTANT: GROUP-ALL OCT: 0000070
CONSTANT: GROUP-READ OCT: 0000040
CONSTANT: GROUP-WRITE OCT: 0000020
CONSTANT: GROUP-EXECUTE OCT: 0000010
CONSTANT: OTHER-ALL OCT: 0000007
CONSTANT: OTHER-READ OCT: 0000004
CONSTANT: OTHER-WRITE OCT: 0000002
CONSTANT: OTHER-EXECUTE OCT: 0000001
2008-11-30 20:13:42 -05:00
: uid? ( obj -- ? ) UID file-mode? ;
: gid? ( obj -- ? ) GID file-mode? ;
: sticky? ( obj -- ? ) STICKY file-mode? ;
: user-read? ( obj -- ? ) USER-READ file-mode? ;
: user-write? ( obj -- ? ) USER-WRITE file-mode? ;
: user-execute? ( obj -- ? ) USER-EXECUTE file-mode? ;
: group-read? ( obj -- ? ) GROUP-READ file-mode? ;
: group-write? ( obj -- ? ) GROUP-WRITE file-mode? ;
: group-execute? ( obj -- ? ) GROUP-EXECUTE file-mode? ;
: other-read? ( obj -- ? ) OTHER-READ file-mode? ;
: other-write? ( obj -- ? ) OTHER-WRITE file-mode? ;
: other-execute? ( obj -- ? ) OTHER-EXECUTE file-mode? ;
: any-read? ( obj -- ? )
{ [ user-read? ] [ group-read? ] [ other-read? ] } 1|| ;
: any-write? ( obj -- ? )
{ [ user-write? ] [ group-write? ] [ other-write? ] } 1|| ;
: any-execute? ( obj -- ? )
{ [ user-execute? ] [ group-execute? ] [ other-execute? ] } 1|| ;
2008-10-07 20:25:22 -04:00
: set-uid ( path ? -- ) UID swap chmod-set-bit ;
: set-gid ( path ? -- ) GID swap chmod-set-bit ;
: set-sticky ( path ? -- ) STICKY swap chmod-set-bit ;
: set-user-read ( path ? -- ) USER-READ swap chmod-set-bit ;
2008-11-30 20:13:42 -05:00
: set-user-write ( path ? -- ) USER-WRITE swap chmod-set-bit ;
2008-10-07 20:25:22 -04:00
: set-user-execute ( path ? -- ) USER-EXECUTE swap chmod-set-bit ;
: set-group-read ( path ? -- ) GROUP-READ swap chmod-set-bit ;
2008-11-30 20:13:42 -05:00
: set-group-write ( path ? -- ) GROUP-WRITE swap chmod-set-bit ;
2008-10-07 20:25:22 -04:00
: set-group-execute ( path ? -- ) GROUP-EXECUTE swap chmod-set-bit ;
: set-other-read ( path ? -- ) OTHER-READ swap chmod-set-bit ;
2008-11-30 20:13:42 -05:00
: set-other-write ( path ? -- ) OTHER-WRITE swap chmod-set-bit ;
2008-10-07 20:25:22 -04:00
: set-other-execute ( path ? -- ) OTHER-EXECUTE swap chmod-set-bit ;
: set-file-permissions ( path n -- )
2008-10-07 20:25:22 -04:00
[ normalize-path ] dip chmod io-error ;
: file-permissions ( path -- n )
normalize-path file-info permissions>> ;
2008-10-07 20:25:22 -04:00
<PRIVATE
: make-timeval-array ( array -- byte-array )
[ [ "timeval" <c-object> ] unless* ] map concat ;
2008-10-07 20:25:22 -04:00
: timestamp>timeval ( timestamp -- timeval )
unix-1970 time- duration>microseconds make-timeval ;
2008-10-07 20:25:22 -04:00
: timestamps>byte-array ( timestamps -- byte-array )
[ dup [ timestamp>timeval ] when ] map make-timeval-array ;
PRIVATE>
: set-file-times ( path timestamps -- )
#! set access, write
[ normalize-path ] dip
timestamps>byte-array utimes io-error ;
: set-file-access-time ( path timestamp -- )
f 2array set-file-times ;
: set-file-modified-time ( path timestamp -- )
2008-10-07 20:25:22 -04:00
f swap 2array set-file-times ;
: set-file-ids ( path uid gid -- )
[ normalize-path ] 2dip
[ [ -1 ] unless* ] bi@ chown io-error ;
GENERIC: set-file-user ( path string/id -- )
2008-10-07 20:25:22 -04:00
GENERIC: set-file-group ( path string/id -- )
M: integer set-file-user ( path uid -- )
2008-10-07 20:25:22 -04:00
f set-file-ids ;
M: string set-file-user ( path string -- )
user-id f set-file-ids ;
2008-11-30 20:13:42 -05:00
2008-10-07 20:25:22 -04:00
M: integer set-file-group ( path gid -- )
f swap set-file-ids ;
2008-11-30 20:13:42 -05:00
2008-10-07 20:25:22 -04:00
M: string set-file-group ( path string -- )
group-id
f swap set-file-ids ;
: file-user-id ( path -- uid )
normalize-path file-info uid>> ;
2008-10-07 20:25:22 -04:00
2009-01-08 18:56:03 -05:00
: file-user-name ( path -- string )
file-user-id user-name ;
2008-10-07 20:25:22 -04:00
: file-group-id ( path -- gid )
normalize-path file-info gid>> ;
2008-10-07 20:25:22 -04:00
: file-group-name ( path -- string )
file-group-id group-name ;
: ch>file-type ( ch -- type )
{
{ CHAR: b [ +block-device+ ] }
{ CHAR: c [ +character-device+ ] }
{ CHAR: d [ +directory+ ] }
{ CHAR: l [ +symbolic-link+ ] }
{ CHAR: s [ +socket+ ] }
{ CHAR: p [ +fifo+ ] }
{ CHAR: - [ +regular-file+ ] }
[ drop +unknown+ ]
} case ;
: file-type>ch ( type -- ch )
{
{ +block-device+ [ CHAR: b ] }
{ +character-device+ [ CHAR: c ] }
{ +directory+ [ CHAR: d ] }
{ +symbolic-link+ [ CHAR: l ] }
{ +socket+ [ CHAR: s ] }
{ +fifo+ [ CHAR: p ] }
{ +regular-file+ [ CHAR: - ] }
[ drop CHAR: - ]
} case ;
<PRIVATE
: file-type>executable ( directory-entry -- string )
name>> any-execute? "*" "" ? ;
PRIVATE>
: file-type>trailing ( directory-entry -- string )
dup type>>
{
{ +directory+ [ drop "/" ] }
{ +symbolic-link+ [ drop "@" ] }
{ +fifo+ [ drop "|" ] }
{ +socket+ [ drop "=" ] }
{ +whiteout+ [ drop "%" ] }
{ +unknown+ [ file-type>executable ] }
{ +regular-file+ [ file-type>executable ] }
[ drop file-type>executable ]
} case ;