3 IMPORT SYSTEM
, Log
, DswProcs
, HostLang
, unistd
:= PosixCunistd
, stdlib
:= PosixCstdlib
,
4 signal
:= PosixCsignal
, sys_wait
:= PosixCsys_wait
, macro
:= PosixCmacro
,
8 Directory
= POINTER TO RECORD (DswProcs
.Directory
) END;
10 String
= POINTER TO ARRAY OF SHORTCHAR
;
11 SString
= POINTER TO ARRAY OF String
;
13 Process
= POINTER TO RECORD (DswProcs
.Process
)
19 PROCEDURE (d
: Directory
) New
* (): Process
;
22 NEW(p
); p
.argv
:= NIL; p
.pid
:= -1; p
.code
:= 0;
26 PROCEDURE ToHost (IN s
: ARRAY OF CHAR): String
;
27 VAR ss
: String
; res
: INTEGER;
29 NEW(ss
, LEN(s$
) * 3 + 1);
30 ASSERT(ss
# NIL, 100);
31 HostLang
.StringToHost(s
, ss
, HostLang
.pep383x
, res
);
36 PROCEDURE (p
: Process
) Program
* (IN exe
: ARRAY OF CHAR);
39 ASSERT(p
.pid
= -1, 20);
40 NEW(argv
, 1); argv
[0] := ToHost(exe
);
44 PROCEDURE (p
: Process
) PutParam
* (IN par
: ARRAY OF CHAR);
45 VAR i
: INTEGER; argv
: SString
;
47 ASSERT(p
.pid
= -1, 20);
48 ASSERT(p
.argv
# NIL, 21);
49 NEW(argv
, LEN(p
.argv
) + 1);
50 FOR i
:= 0 TO LEN(p
.argv
) - 1 DO
53 argv
[i
] := ToHost(par
);
57 PROCEDURE (p
: Process
) Execute
* (OUT ok
: BOOLEAN);
59 UString
= POINTER [untagged
] TO ARRAY [untagged
] OF SHORTCHAR
;
60 SUString
= POINTER TO ARRAY OF UString
;
62 i
, j
: INTEGER; pid
: unistd
.pid_t
; res
: unistd
.int
; argv
: SUString
;
64 ASSERT(p
.pid
= -1, 20);
65 ASSERT(p
.argv
# NIL, 21);
66 NEW(argv
, LEN(p
.argv
) + 1);
67 FOR i
:= 0 TO LEN(p
.argv
) - 1 DO
68 argv
[i
] := SYSTEM
.VAL(UString
, SYSTEM
.ADR(p
.argv
[i
, 0]))
72 res
:= unistd
.execv(argv
[0], argv
);
73 unistd
._exit(127); (* system() and most utils exit with 126/127 *)
78 p
.argv
:= NIL; (* or save it for debugging and reuse? *)
84 PROCEDURE (p
: Process
) Terminate
* (OUT ok
: BOOLEAN);
85 VAR res
, e
: signal
.int
;
87 ASSERT(p
.pid
> 0, 20);
88 res
:= signal
.kill(p
.pid
, signal
.SIGTERM
);
89 IF res
= 0 THEN p
.Wait
; ok
:= TRUE
93 | errno
.EINVAL
: HALT(100) (* wat *)
94 | errno
.EPERM
: ok
:= FALSE (* process can not be killed *)
95 | errno
.ESRCH
: p
.code
:= 0; p
.pid
:= -1; ok
:= TRUE (* process already killed *)
97 ELSE HALT(101) (* wat *)
101 PROCEDURE (p
: Process
) IsTerminated
* (): BOOLEAN;
102 VAR pid
: unistd
.pid_t
; e
: unistd
.int
;
105 ASSERT(p
.pid
> 0, 100); (* wat *)
106 pid
:= sys_wait
.waitpid(p
.pid
, p
.code
, sys_wait
.WNOHANG
);
107 IF pid
= 0 THEN (* process still executes *)
108 ELSIF pid
= p
.pid
THEN p
.pid
:= -1 (* process returns code *)
112 | errno
.ECHILD
: p
.code
:= 0; p
.pid
:= -1 (* process was killed externally *)
113 | errno
.EINVAL
: HALT(101) (* wat *)
114 | errno
.EINTR
: (* assume that process still executes *)
116 ELSE HALT(102) (* wat *)
122 PROCEDURE (p
: Process
) Wait
*;
123 VAR pid
: unistd
.pid_t
; e
: unistd
.int
;
125 ASSERT(p
.pid
> 0, 20);
127 pid
:= sys_wait
.waitpid(p
.pid
, p
.code
, 0);
128 IF pid
= p
.pid
THEN p
.pid
:= -1 (* was terminated *)
132 | errno
.ECHILD
: p
.code
:= 0; p
.pid
:= -1 (* process was killed externally *)
133 | errno
.EINVAL
: HALT(100) (* wat *)
134 | errno
.EINTR
: (* continue wait for process termination *)
136 ELSE HALT(101) (* wat *)
141 PROCEDURE (p
: Process
) Result (): INTEGER;
143 IF p
.pid
# -1 THEN p
.Wait
END;
144 (* RETURN SYSTEM.CONV(INTEGER, sys_wait.WEXITSTATUS(p.code)) *) (* !!! *)
145 RETURN SYSTEM
.VAL(INTEGER, p
.code
) DIV 256 MOD 128
151 NEW(d
); DswProcs
.SetDir(d
)