include "osfiles.s7i";
include "cc_conf.s7i";
include "stdio.s7i";
const type: process is newtype;
IN_PARAM_IS_REFERENCE(process);
const proc: (ref process: dest) ::= (in process: source) is action "PCS_CREATE";
const proc: destroy (ref process: aValue) is action "PCS_DESTR";
const proc: (inout process: dest) := (in process: source) is action "PCS_CPY";
const func process: _GENERATE_EMPTY_PROCESS is action "PCS_EMPTY";
const process: (attr process) . EMPTY is _GENERATE_EMPTY_PROCESS;
const process: (attr process) . value is _GENERATE_EMPTY_PROCESS;
const func boolean: (in process: process1) = (in process: process2) is action "PCS_EQ";
const func boolean: (in process: process1) <> (in process: process2) is action "PCS_NE";
const func integer: compare (in process: process1, in process: process2) is action "PCS_CMP";
const func integer: hashCode (in process: aProcess) is action "PCS_HASHCODE";
const func string: str (in process: aProcess) is action "PCS_STR";
const func boolean: isAlive (in process: process1) is action "PCS_IS_ALIVE";
const func process: startProcess (in string: command, in array string: parameters,
inout clib_file: stdin, inout clib_file: stdout, inout clib_file: stderr) is action "PCS_START";
const func process: startProcess (in string: command, in array string: parameters,
inout file: stdin, inout file: stdout, inout file: stderr) is func
result
var process: aProcess is process.value;
local
var clib_file: stdinFile is CLIB_NULL_FILE;
var clib_file: stdoutFile is CLIB_NULL_FILE;
var clib_file: stderrFile is CLIB_NULL_FILE;
var external_file: aFile is external_file.value;
begin
if stdin <> STD_NULL then
aFile := external_file conv stdin;
stdinFile := aFile.ext_file;
end if;
if stdout <> STD_NULL then
aFile := external_file conv stdout;
stdoutFile := aFile.ext_file;
end if;
if stderr <> STD_NULL then
aFile := external_file conv stderr;
stderrFile := aFile.ext_file;
end if;
aProcess := startProcess(command, parameters, stdinFile, stdoutFile, stderrFile);
end func;
const func process: startProcess (in string: command, in array string: parameters) is
return startProcess(command, parameters, STD_IN.ext_file, STD_OUT.ext_file,
STD_ERR.ext_file);
const func process: startProcess (in var string: cmdAndParams) is func
result
var process: childProcess is process.value;
local
var string: command is "";
var string: parameter is "";
var array string: parameters is 0 times "";
begin
command := getCommandLineWord(cmdAndParams);
parameter := getCommandLineWord(cmdAndParams);
while parameter <> "" do
parameters &:= parameter;
parameter := getCommandLineWord(cmdAndParams);
end while;
childProcess := startProcess(command, parameters);
end func;
const func clib_file: childStdInClibFile (in process: aProcess) is action "PCS_CHILD_STDIN";
const func clib_file: childStdOutClibFile (in process: aProcess) is action "PCS_CHILD_STDOUT";
const func clib_file: childStdErrClibFile (in process: aProcess) is action "PCS_CHILD_STDERR";
const func file: childStdIn (in process: aProcess) is func
result
var file: stdIn is STD_NULL;
local
var clib_file: stdinClibFile is CLIB_NULL_FILE;
var external_file: new_file is external_file.value;
begin
stdinClibFile := childStdInClibFile(aProcess);
if stdinClibFile <> CLIB_NULL_FILE then
new_file.ext_file := stdinClibFile;
stdIn:= toInterface(new_file);
end if;
end func;
const func file: childStdOut (in process: aProcess) is func
result
var file: stdOut is STD_NULL;
local
var clib_file: stdoutClibFile is CLIB_NULL_FILE;
var external_file: new_file is external_file.value;
begin
stdoutClibFile := childStdOutClibFile(aProcess);
if stdoutClibFile <> CLIB_NULL_FILE then
new_file.ext_file := stdoutClibFile;
stdOut:= toInterface(new_file);
end if;
end func;
const func file: childStdErr (in process: aProcess) is func
result
var file: stdErr is STD_NULL;
local
var clib_file: stderrClibFile is CLIB_NULL_FILE;
var external_file: new_file is external_file.value;
begin
stderrClibFile := childStdErrClibFile(aProcess);
if stderrClibFile <> CLIB_NULL_FILE then
new_file.ext_file := stderrClibFile;
stdErr:= toInterface(new_file);
end if;
end func;
const proc: kill (in process: aProcess) is action "PCS_KILL";
const proc: waitFor (in process: aProcess) is action "PCS_WAIT_FOR";
const func integer: exitValue (in process: aProcess) is action "PCS_EXIT_VALUE";
const func array string: getSearchPath is action "CMD_GET_SEARCH_PATH";
const proc: setSearchPath (in array string: searchPath) is action "CMD_SET_SEARCH_PATH";
const func string: commandPath (in string: command) is func
result
var string: cmdPath is "";
local
var string: path is "";
var string: filePath is "";
var boolean: searching is TRUE;
begin
if pos(command, '/') = 0 then
for path range getSearchPath do
filePath := path & "/" & command & ccConf.EXECUTABLE_FILE_EXTENSION;
if searching and fileType(filePath) = FILE_REGULAR and
getFileMode(filePath) & {EXEC_USER, EXEC_GROUP, EXEC_OTHER} <> fileMode.value then
searching := FALSE;
cmdPath := filePath;
end if;
end for;
else
if startsWith(command, "/") then
cmdPath := command & ccConf.EXECUTABLE_FILE_EXTENSION;
else
cmdPath := getcwd;
if cmdPath = "/" then
cmdPath &:= command & ccConf.EXECUTABLE_FILE_EXTENSION;
else
cmdPath &:= "/" & command & ccConf.EXECUTABLE_FILE_EXTENSION;
end if;
end if;
if fileType(cmdPath) <> FILE_REGULAR or
getFileMode(cmdPath) & {EXEC_USER, EXEC_GROUP, EXEC_OTHER} = fileMode.value then
cmdPath := "";
end if;
end if;
end func;
const func string: commandDir (in string: command) is func
result
var string: cmdDir is "";
local
var string: path is "";
var string: filePath is "";
var boolean: searching is TRUE;
var integer: lastSlashPos is 0;
begin
if pos(command, '/') = 0 then
for path range getSearchPath do
filePath := path & "/" & command & ccConf.EXECUTABLE_FILE_EXTENSION;
if searching and fileType(filePath) = FILE_REGULAR and
getFileMode(filePath) & {EXEC_USER, EXEC_GROUP, EXEC_OTHER} <> fileMode.value then
searching := FALSE;
cmdDir := path;
end if;
end for;
elsif startsWith(command, "/") then
lastSlashPos := rpos(command, '/');
if lastSlashPos = 1 then
cmdDir := "/";
else
cmdDir := command[.. pred(lastSlashPos)];
end if;
else
cmdDir := getcwd;
end if;
end func;
const proc: pipe2 (in string: command, in array string: parameters,
inout clib_file: primitiveChildStdin,
inout clib_file: primitiveChildStdout) is action "PCS_PIPE2";
const proc: pipe2 (in string: command, in array string: parameters,
inout file: childStdin, inout file: childStdout) is func
local
var clib_file: primitiveChildStdin is CLIB_NULL_FILE;
var clib_file: primitiveChildStdout is CLIB_NULL_FILE;
var external_file: new_ChildStdin is external_file.value;
var external_file: new_ChildStdout is external_file.value;
begin
pipe2(command, parameters, primitiveChildStdin, primitiveChildStdout);
if primitiveChildStdin <> CLIB_NULL_FILE then
new_ChildStdin.ext_file := primitiveChildStdin;
childStdin := toInterface(new_ChildStdin);
end if;
if primitiveChildStdout <> CLIB_NULL_FILE then
new_ChildStdout.ext_file := primitiveChildStdout;
childStdout := toInterface(new_ChildStdout);
end if;
end func;
const proc: pty (in string: command, in array string: parameters,
inout clib_file: primitiveChildStdin,
inout clib_file: primitiveChildStdout) is action "PCS_PTY";
const proc: pty (in string: command, in array string: parameters,
inout file: childStdin, inout file: childStdout) is func
local
var clib_file: primitiveChildStdin is CLIB_NULL_FILE;
var clib_file: primitiveChildStdout is CLIB_NULL_FILE;
var external_file: new_ChildStdin is external_file.value;
var external_file: new_ChildStdout is external_file.value;
begin
pty(command, parameters, primitiveChildStdin, primitiveChildStdout);
if primitiveChildStdin <> CLIB_NULL_FILE then
new_ChildStdin.ext_file := primitiveChildStdin;
childStdin := toInterface(new_ChildStdin);
end if;
if primitiveChildStdout <> CLIB_NULL_FILE then
new_ChildStdout.ext_file := primitiveChildStdout;
childStdout := toInterface(new_ChildStdout);
end if;
end func;