sys_obey_linerep 
Author Message
 sys_obey_linerep

My previous message referred to a utility for running a unix command
and providing a line repeater that would return the output of the
unix command a line at a time.

For example here I run the command 'who' on sun5, using 'rsh' (=remsh on
HP machines) and then get a line repeater for the output. I use that
to print out the output a line at a time.

-----------------------------------------------------------------------
vars repeater = sys_obey_linerep('rsh sun5 who');

vars string;

until (repeater() ->> string) == termin do

    string =>

enduntil;

** cxfa      ttypc   May  4 12:25       (ncd2a:0.0)
** abwa      ttyq2   Apr 25 21:17       (mancer:0.0)
** aksr      ttyq5   May  5 10:21       (apron)
** jdmp      ttyr7   May  4 16:49       (ncd5a:0.0)
** jxh2      ttyrc   May  4 20:16       (garden:0.0)

(Actually I've slightly distorted the output for security reasons).
-----------------------------------------------------------------------

This capability is useful for writing system management scripts and
other things that need to use the output of unix utilities.

The code for sys_obey_linerep follows.
Aaron

/*              --- University of Birmingham 1993.  ------
 > File:            $poplocal/local/auto/sys_obey_linerep.p
 > Purpose:                  Run a Unix command
 >                                   and produce a line repeater for the output
 > Author:          Aaron Sloman, May  5 1993
 > Documentation:   Below
 */

/*
HELP SYS_OBEY_LINEREP

sys_obey_linerep(string) -> repeater;
sys_obey_linerep(string, shell) -> repeater;

The first form takes a string which is a unix command and runs
it returning a repeater for the output lines.

The second form takes an optional extra argument which is one of
the characters `$`, `%`, `!` and determines which shell should be used,
exactly as with * sysobey.

*/

lconstant
        arglist = [0 '-ce' 0];

define lconstant sub_repeater(dev, buffer, lim, pid) -> line;
                ;;; This will be partially applied to its arguments, to create
                ;;; a repeater. "dev" is a file device record.

                lvars len, buffer, dev, lim, line, pid;

                fast_sysread(dev, 1, buffer, lim) -> len;
                if len == 0 then termin
                else substring(1, len fi_- 1, buffer)
                endif -> line;
                if line == termin then
                        ;;; wait for child to finish
                        until syswait() == pid do enduntil;
                endif;
enddefine;

define sys_obey_linerep(string, /*shell*/) -> repeater;
        lvars shell, string, pipe_device, repeater;

        if isinteger(string) then
                ;;; extra argument on stack
                string -> (string, shell)
        else
                false -> shell
        endif;

        if      shell == `$` or not(shell) then '/bin/sh'
        elseif shell == `%`     then '/bin/csh'
        elseif shell == `!` then systranslate('SHELL')
        else shell
        endif -> shell;

        unless isstring(shell) then
                mishap(shell,1,'SHELL PATH NAME NEEDED')
        endunless;

        shell -> arglist(1);
        string -> arglist(3);

        pipein(shell, arglist, false) -> pipe_device;

        ;;; make a string repeater from the device
        sub_repeater(%pipe_device,
                                        copy(sysstring),
                                        sysstringlen,
                                        pipein_child_pid%) -> repeater;

enddefine;
--
Aaron Sloman,
School of Computer Science, The University of Birmingham, B15 2TT, England

Phone: +44-(0)21-414-3711       Fax:   +44-(0)21-414-4281



Wed, 25 Oct 1995 08:41:55 GMT  
 
 [ 1 post ] 

 Relevant Pages 
 

 
Powered by phpBB® Forum Software