3 * COPYRIGHT (c
) 1995 AT
&T Bell Laboratories
.
5 * The Posix implementation
of the generic file system interface
.
11 structure P_FSys
= Posix
.FileSys
13 val sysWordToWord
= Word.fromLargeWord
o SysWord
.toLargeWord
15 type dirstream
= P_FSys
.dirstream
17 val openDir
= P_FSys
.opendir
18 val readDir
= P_FSys
.readdir
19 val rewindDir
= P_FSys
.rewinddir
20 val closeDir
= P_FSys
.closedir
22 val chDir
= P_FSys
.chdir
23 val getDir
= P_FSys
.getcwd
25 structure S
= P_FSys
.S
26 val mode777
= S
.flags
[S
.irwxu
, S
.irwxg
, S
.irwxo
]
28 fun mkDir path
= P_FSys
.mkdir(path
, mode777
)
30 val rmDir
= P_FSys
.rmdir
31 val isDir
= P_FSys
.ST
.isDir
o P_FSys
.stat
33 val isLink
= P_FSys
.ST
.isLink
o P_FSys
.lstat
34 val readLink
= P_FSys
.readlink
36 (* the maximum number
of links allowed
*)
37 val maxLinks
: int = 64
41 val isMinGW
= let open Primitive
.MLton
.Platform
.OS
in host
= MinGW
end
43 (* An implementation
of fullPath which works on Unix
and Windows (Cygwin
and MinGW
) *)
47 fun mkPath (pathFromRoot
, vol
) =
48 P
.toString
{arcs
= List.rev pathFromRoot
,
51 fun walkPath (n
, pathFromRoot
, arcs
, vol
) =
53 then raise PosixError
.SysErr ("too many links", NONE
)
56 [] => mkPath (pathFromRoot
, vol
)
58 if arc
= "" orelse arc
= "."
59 then walkPath (n
, pathFromRoot
, al
, vol
)
63 [] => walkPath (n
, [], al
, vol
)
65 (chDir
".."; walkPath (n
, r
, al
, vol
))
68 then expandLink (n
, pathFromRoot
, arc
, al
, vol
)
71 [] => mkPath (arc
:: pathFromRoot
, vol
)
74 ; walkPath (n
, arc
:: pathFromRoot
, al
, vol
))
75 and expandLink (n
, pathFromRoot
, link
, rest
, vol
) =
77 val {isAbs
, arcs
, ...} = P
.fromString (readLink link
)
78 val arcs
= List.@
(arcs
, rest
)
81 then gotoRoot (n
-1, arcs
, vol
)
82 else walkPath (n
-1, pathFromRoot
, arcs
, vol
)
84 (* If the volume is not empty
, chDir to it rather than to
"/" *)
85 and gotoRoot (n
, arcs
, vol
) =
86 (if vol
<> "" andalso vol
<> "/"
87 then chDir (vol ^
(if isMinGW
then "\\" else "/"))
89 ; walkPath (n
, [], arcs
, vol
))
90 fun computeFullPath (arcs
, vol
) =
91 (gotoRoot (maxLinks
, arcs
, vol
) before chDir oldCWD
)
92 handle ex
=> (chDir oldCWD
; raise ex
)
95 of {isAbs
=false, arcs
, vol
} =>
97 val {arcs
=arcs
', vol
=vol
, ...} = P
.fromString(oldCWD
)
99 computeFullPath (List.@
(arcs
', arcs
), vol
)
101 |
{isAbs
=true, arcs
, vol
} => computeFullPath (arcs
, vol
)
107 else P
.mkRelative
{path
= fullPath p
,
108 relativeTo
= fullPath (getDir ())}
110 val fileSize
= P_FSys
.ST
.size
o P_FSys
.stat
112 val modTime
= P_FSys
.ST
.mtime
o P_FSys
.stat
114 fun setTime (path
, t
) =
115 P_FSys
.utime (path
, Option
.map (fn t
=> {actime
= t
, modtime
= t
}) t
)
117 val remove
= P_FSys
.unlink
119 val rename
= P_FSys
.rename
121 datatype access_mode
= datatype Posix
.FileSys
.access_mode
123 fun access (path
, al
) =
125 fun cvt A_READ
= P_FSys
.A_READ
126 | cvt A_WRITE
= P_FSys
.A_WRITE
127 | cvt A_EXEC
= P_FSys
.A_EXEC
129 P_FSys
.access (path
, List.map cvt al
)
132 datatype file_id
= FID
of {dev
: SysWord
.word, ino
: SysWord
.word}
134 fun fileId fname
= let
135 val st
= P_FSys
.stat fname
138 dev
= P_FSys
.devToWord(P_FSys
.ST
.dev st
),
139 ino
= P_FSys
.inoToWord(P_FSys
.ST
.ino st
)
143 fun hash (FID
{dev
, ino
}) = sysWordToWord(SysWord
.+(SysWord
.<<(dev
, 0w16
), ino
))
145 fun compare (FID
{dev
=d1
, ino
=i1
}, FID
{dev
=d2
, ino
=i2
}) =
146 if (SysWord
.<(d1
, d2
))
148 else if (SysWord
.>(d1
, d2
))
150 else if (SysWord
.<(i1
, i2
))
152 else if (SysWord
.>(i1
, i2
))
159 * $Log
: os
-filesys
.sml
, v $
160 * Revision
1.3 1997/06/07 15:27:51 jhr
161 * SML
'97 Basis Library
changes (phase
3; Posix changes
)
163 * Revision
1.2 1997/02/26 21:00:32 george
164 * Defined a new top level Option
structure. All
'a option related
165 * functions have been moved out
of General
.
167 * Revision
1.1.1.1 1997/01/14 01:38:25 george