# System Interaction The `unix:` namespace contains words for interacting with the host operating system on Unix style systems. ~~~ {{ 'io:UnixSyscall var :identify @io:UnixSyscall n:zero? [ #8 io:scan-for dup n:negative? [ drop 'IO_DEVICE_TYPE_0008_NOT_FOUND s:put nl ] [ !io:UnixSyscall ] choose ] if ; ---reveal--- :io:unix-syscall identify @io:UnixSyscall 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:get-cwd (-s) 'pwd file:R unix:popen dup file:read-line s:trim swap unix:pclose '/ s:append ; ~~~ ~~~ :unix:count-files-in-cwd (-n) 'ls_-1_|_wc_-l file:R unix:popen dup file:read-line s:trim s:to-number swap unix:pclose ; ~~~ ~~~ :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 ; }} ~~~ The clock device provides access to an interface specific timestamp as well as the current date and time in both local and UTC. This is currently grouped with the `unix:` words, but will be a fully separate device in the future. ~~~ :clock:timestamp (-n) #19 io:unix-syscall ; :clock:day (-s) #20 io:unix-syscall ; :clock:month (-s) #21 io:unix-syscall ; :clock:year (-s) #22 io:unix-syscall ; :clock:hour (-s) #23 io:unix-syscall ; :clock:minute (-n) #24 io:unix-syscall ; :clock:second (-s) #25 io:unix-syscall ; :clock:utc:day (-s) #26 io:unix-syscall ; :clock:utc:month (-s) #27 io:unix-syscall ; :clock:utc:year (-s) #28 io:unix-syscall ; :clock:utc:hour (-s) #29 io:unix-syscall ; :clock:utc:minute (-n) #30 io:unix-syscall ; :clock:utc:second (-s) #31 io:unix-syscall ; ~~~