This REXX program runs
/bin/ls to list files in the
/bin directory,
and sets up a signal that enforces a time limit of 10 seconds for
the program to run:
/* REXX */
address syscall
/* initialize file descriptor map (see note 1) */
fd.0=-1
fd.2=-1
'creat /tmp/dirlist 600'
fd.1=retval
/* initialize parameter stem (see note 2) */
parm.1='/bin/ls'
parm.2='-l'
parm.3='/bin'
parm.0=3
/* spawn new process (see note 3) */
'spawn /bin/ls 3 fd. parm. __environment.'
pid=retval
/* set up signals to wait up to 10 seconds (see note 4) */
call syscalls 'SIGON'
'sigaction' sigalrm sig_cat 0 'oldh oldf'
'sigprocmask' sig_unblock sigaddset(sigsetempty(),sigalrm) 'mask'
'alarm' 10 /* set alarm */
'waitpid (pid) st. 0' /* wait for process term or alarm */
srv=retval
'alarm 0' /* make sure alarm is now off */
if srv=-1 then /* if alarm went off */
do
'kill' pid sigkill /* cancel child process */
'waitpid (pid) st. 0' /* wait for completion */
end
call syscalls 'SIGOFF' /* turn off signals */
/* determine process status code (see note 5) */
select
when st.w_ifexited then
say 'exited with code' st.w_exitstatus
when st.w_ifsignaled then
say 'terminated with signal' st.w_termsig
when st.w_ifstopped then
say 'stopped by signal' st.w_stopsig
end
return
sigsetempty: return copies(0,64)
sigaddset: return overlay(1,arg(1),arg(2))
Note: - The file descriptor map is set up so that the file descriptor
for the new file being created is remapped to file descriptor 1 (standard
output) for the new process. File descriptors 0 and 2 will not be
opened in the new process.
- The first parameter is set to the path name for the file being
spawned. Additional parameters are set in the format the program
expects. In this case, they specify a long directory listing for
the /bin directory.
- The new process is spawned to run /bin/ls. File descriptors
greater than or equal to 3 are not available to the new process. fd.0 to fd.2 are
used in remapping file descriptors from the parent. The current environment
for the parent is passed to the new process.
- The syscalls function is called to enable
signals. If this program were to be exec'd (run from the shell),
this would not be necessary, and, similarly, the call later on to
turn off signals would also be unnecessary.
sigaction is
used to set the action for sigalrm to be
caught. sigprocmask is used to unblock sigalrm.
This call also uses sigaddset and sigsetempty to
create a signal mask with the sigalrm bit.
The
alarm is set by using the alarm service,
and the process waits for completion of the child or the alarm. "ALARM
0" is used just to make sure the alarm is off.
- A SELECT instruction is used on the status stem returned by the waitpid service.
This determines if the process was terminated by a signal, if it
exited, or if the process is stopped. If it exited, the exit status
is available; otherwise, the signal number is available.