File: FSPosixExtras.m3

package info (click to toggle)
pm3 1.1.13-11
  • links: PTS
  • area: main
  • in suites: potato
  • size: 174,164 kB
  • ctags: 133,819
  • sloc: ansic: 982,617; modula3: 548,483; cpp: 57,119; exp: 21,673; sh: 17,053; lisp: 13,693; makefile: 13,492; asm: 11,795; yacc: 8,575; sed: 1,100; objc: 476; csh: 254; awk: 223; pascal: 95; fortran: 5
file content (69 lines) | stat: -rw-r--r-- 2,387 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
(* Copyright (C) 1994, Digital Equipment Corporation               *)
(* All rights reserved.                                            *)
(* See the file COPYRIGHT for a full description.                  *)
(* Last modified on Tue Aug 30 09:45:18 PDT 1994 by mcjones        *)

(* POSIX-specific extensions to FS. *)

UNSAFE MODULE FSPosixExtras EXPORTS FSPosix;

IMPORT Atom, File, FS, M3toC, OSError, OSErrorPosix, Pathname, Pipe,
  RegularFile, Terminal, Unix, Ustat, Word;

PROCEDURE LinkStatus(p: Pathname.T): File.Status RAISES {OSError.E} = 
  VAR status: File.Status; statBuf: Ustat.struct_stat;
  BEGIN
    IF Ustat.lstat(M3toC.TtoS(p), ADR(statBuf)) < 0 THEN OSErrorPosix.Raise() END;
    (* StatBufToStatus(statBuf, status); *)
      status.type := (*FilePosix.*)FileTypeFromStatbuf(statBuf);
      status.modificationTime := FLOAT(statBuf.st_mtime, LONGREAL);
      status.size := statBuf.st_size;
    RETURN status
  END LinkStatus;

(* Copied from os/src/POSIX/FilePosix.i3, with one extra case added: *)
PROCEDURE FileTypeFromStatbuf(READONLY statbuf: Ustat.struct_stat)
  : File.Type =
  BEGIN
    CASE Word.And(statbuf.st_mode, Ustat.S_IFMT) OF
    | Ustat.S_IFCHR =>
        IF IsDevNull(statbuf)
          THEN RETURN RegularFile.FileType
          ELSE RETURN Terminal.FileType
        END
    | Ustat.S_IFPIPE, Ustat.S_IFPORT, Ustat.S_IFSOCK =>
        RETURN Pipe.FileType
    | Ustat.S_IFREG =>
        RETURN RegularFile.FileType
    | Ustat.S_IFDIR =>
        RETURN FS.DirectoryFileType
    | Ustat.S_IFLNK =>
        RETURN (*FSPosix.*)SymbolicLinkFileType
    ELSE
        RETURN RegularFile.FileType
    END
  END FileTypeFromStatbuf;

(* Copied from os/src/POSIX/FilePosix.i3: *)
VAR
  null_done := FALSE;
  null_stat: Ustat.struct_stat;
  null_fd: INTEGER;
PROCEDURE IsDevNull(READONLY statbuf: Ustat.struct_stat): BOOLEAN RAISES {} =
  VAR result: INTEGER;
  BEGIN
    IF NOT null_done THEN
      null_done := TRUE;
      null_fd := Unix.open(
        M3toC.TtoS("/dev/null"), Unix.O_RDONLY, Unix.Mrwrwrw);
      IF null_fd < 0 THEN RETURN FALSE END;
      result := Ustat.fstat(null_fd, ADR(null_stat));
      EVAL Unix.close(null_fd);
      IF result # 0 THEN null_fd := -1 END
    END;
    RETURN null_fd >= 0 AND statbuf.st_rdev = null_stat.st_rdev
  END IsDevNull;

BEGIN
  SymbolicLinkFileType := Atom.FromText("SymbolicLink")
END FSPosixExtras.