retroforth/interface/unix.retro
crc 16d5df0dc8 add source info for i/o words
FossilOrigin-Name: 4e07d2424d6b43867789fe2d25ec1b794ec3511eba5c9beefcfdc2a38344c0c4
2021-08-23 13:23:10 +00:00

166 lines
3.7 KiB
Forth

# System Interaction
The `unix:` namespace contains words for interacting with the
host operating system on Unix style systems.
~~~
:io:unix-syscall
#8 io:scan-for
dup n:negative? [ drop 'Error:_device_(0008)_not_found s:put nl ] if;
io:invoke ;
~~~
`unix:system` runs another application using the system shell
and returns after execution is completed.
~~~
:unix:system (s-) #0 io:unix-syscall ;
~~~
`unix:fork` forks the current process and returns a process
identifier.
~~~
:unix:fork (-n) #1 io:unix-syscall ;
~~~
This group is used to execute a new process in place of the
current one. These take a program and optionally 1-3 arguments.
They map to the execl() system call.
Example:
'/usr/bin/cal '2 '2019 unix:exec2
~~~
:unix:exec0 (s-) #2 io:unix-syscall ;
:unix:exec1 (ss-) #3 io:unix-syscall ;
:unix:exec2 (sss-) #4 io:unix-syscall ;
:unix:exec3 (ssss-) #5 io:unix-syscall ;
~~~
`unix:exit` takes a return code and exits RRE, returning the
specified code.
~~~
:unix:exit (n-) #6 io:unix-syscall ;
~~~
`unix:getpid` returns the current process identifier.
~~~
:unix:getpid (-n) #7 io:unix-syscall ;
~~~
`unix:wait` waits for a child process to complete. This maps to
the wait() system call.
~~~
:unix:wait (-n) #8 io:unix-syscall ;
~~~
`unix:kill` terminates a process. Takes a process and a signal
to send.
~~~
:unix:kill (nn-) #9 io:unix-syscall ;
~~~
The next two words allow opening and closing pipes. The first,
`unix:popen` takes the name of a program and a file mode and
returns a file handle usable with words in the `file:` namespace.
The second, `unix:pclose` closes the pipe.
~~~
:unix:popen (sn-n) #10 io:unix-syscall ;
:unix:pclose (n-) #11 io:unix-syscall ;
~~~
`unix:chdir` changes the current working directory to the
specified one.
~~~
:unix:chdir (s-) #13 io:unix-syscall ;
~~~
~~~
:unix:getenv (sa-) #14 io:unix-syscall ;
:unix:putenv (s-) #15 io:unix-syscall ;
~~~
`unix:sleep` pauses execution for the specified number of
seconds.
~~~
:unix:sleep (n-) #16 io:unix-syscall ;
~~~
~~~
:unix:execute (s-) #17 io:unix-syscall ;
~~~
~~~
(s-s) :unix:pipe
file:R unix:popen &file:read-line &unix:pclose bi ;
~~~
~~~
(-s) :unix:get-cwd
'pwd unix:pipe s:trim '/ s:append ;
~~~
~~~
(-n) :unix:count-files-in-cwd
'ls_-1_|_wc_-l unix:pipe s:trim s:to-number ;
~~~
~~~
(q-) :unix:for-each-file (q-)
'ls_-1_-p file:R unix:popen
unix:count-files-in-cwd
[ [ file:read-line s:temp over call ] sip ] times
unix:pclose drop ;
~~~
~~~
{{
:start swap buffer:set file:R unix:popen ;
:read dup file:read dup buffer:add n:zero? ;
:finish unix:pclose buffer:size ;
---reveal---
:unix:slurp-pipe (as-n)
[ start &read until finish ] buffer:preserve ;
}}
~~~
## d:source
~~~
'interface/unix.retro s:keep
dup 'unix:slurp-pipe d:lookup d:source store
dup 'unix:for-each-file d:lookup d:source store
dup 'unix:count-files-in-cwd d:lookup d:source store
dup 'unix:get-cwd d:lookup d:source store
dup 'unix:pipe d:lookup d:source store
dup 'unix:execute d:lookup d:source store
dup 'unix:sleep d:lookup d:source store
dup 'unix:putenv d:lookup d:source store
dup 'unix:getenv d:lookup d:source store
dup 'unix:chdir d:lookup d:source store
dup 'unix:pclose d:lookup d:source store
dup 'unix:popen d:lookup d:source store
dup 'unix:kill d:lookup d:source store
dup 'unix:wait d:lookup d:source store
dup 'unix:getpid d:lookup d:source store
dup 'unix:exit d:lookup d:source store
dup 'unix:exec3 d:lookup d:source store
dup 'unix:exec2 d:lookup d:source store
dup 'unix:exec1 d:lookup d:source store
dup 'unix:exec0 d:lookup d:source store
dup 'unix:fork d:lookup d:source store
dup 'unix:system d:lookup d:source store
dup 'io:unix-syscall d:lookup d:source store
drop
~~~