/* -*-C-*-
*
******************************************************************************
*
* UNIX primitive additions to XLISP-PLUS.
*
* Originally from:
*
******************************************************************************
*
* WINTERP 1.0 Copyright 1989 Hewlett-Packard Company (by Niels Mayer).
* XLISP version 2.1, Copyright (c) 1989, by David Betz.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Hewlett-Packard and David Betz not be
* used in advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. Hewlett-Packard and David Betz
* make no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
* IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* See ./winterp/COPYRIGHT for information on contacting the authors.
*
* Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
* Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
*
********************************************************************************
*
* Modified for XLISP-PLUS 2.1d by Brian Anderson.
*
*/
#include "xlisp.h"
#include "osdefs.h"
/* Function Prototypes */
LOCAL FILEP ospipeopen _((char *name, char *mode));
LOCAL int ospipeclose _((FILEP f));
#ifdef FILETABLE
/******************************************************************************
* Prim_POPEN - start a process and open a pipe for read/write
* (code stolen from xlfio.c:xopen())
*
* syntax: (popen <command line> :direction <direction>)
* <command line> is a string to be sent to the subshell (sh).
* <direction> is either :input (to read from the pipe) or
* :output (to write to the pipe).
* (:input is the default)
*
* Popen returns a stream, or NIL if files or processes couldn't be created.
* The success of the command execution can be checked by examining the
* return value of pclose.
*
* Added to XLISP by Niels Mayer
******************************************************************************/
LVAL Prim_POPEN()
{
char *name; /* file name string */
int iomode = 0; /* file mode */
FILEP fp; /* opened file pointer */
LVAL dir; /* :direction keyword arg */
LVAL fname; /* file name string LVAL */
/* get the process name */
name = getstring(fname = xlgetfname());
/* get direction */
if (!xlgetkeyarg(k_direction, &dir))
dir = k_input; /* default is :input */
/* set the mode */
if (dir == k_input)
iomode = S_FORREADING;
else if (dir == k_output)
iomode = S_FORWRITING;
else
xlerror("bad direction",dir);
/* try to open the pipe */
if ((fp = ospipeopen (name, (iomode & S_FORWRITING) ? CREATE_WR : OPEN_RO)) == CLOSED)
xlfail("error opening pipe");
/* return the xlisp stream as a Lisp datum*/
return cvfile(fp,iomode);
}
LOCAL FILEP ospipeopen(name, mode)
char *name, *mode;
{
int i=getslot();
char namebuf[FNAMEMAX+1];
FILE *fp;
if (!truename((char *)name, namebuf))
strcpy(namebuf, name); /* should not happen */
if ((filetab[i].tname = (char *)malloc(strlen(namebuf)+1)) == NULL) {
/* free(filetab[i].tname); */
xlfail("insufficient memory");
}
if ((fp = popen(name,mode)) == NULL) {
free(filetab[i].tname);
return CLOSED;
}
filetab[i].fp = fp;
strcpy(filetab[i].tname, namebuf);
return i;
}
/******************************************************************************
* Prim_PCLOSE - close a pipe opened by Prim_POPEN().
* (code stolen from xlfio.c:xclose())
*
* syntax: (pclose <stream>)
* <stream> is a stream created by popen.
* returns T if the command executed successfully, otherwise,
* returns the exit status of the opened command.
*
* Added to XLISP by Niels Mayer
******************************************************************************/
LVAL Prim_PCLOSE()
{
LVAL fptr; /* the pipe stream to close */
FILEP fp;
int result;
/* get stream arg as a Lisp datum */
fptr = xlgetarg();
xllastarg();
/* give error of not file stream */
if (!streamp(fptr)) xlbadtype(fptr);
/* get the stream from the Lisp datum
* make sure the stream exists */
if ((fp = getfile(fptr)) == CLOSED)
return (NIL);
/* close the pipe */
result = ospipeclose(fp);
if (result == -1)
xlfail("<stream> has not been opened with popen");
setsavech(fptr, '\0');
setfile(fptr,CLOSED);
/* return T if success (exit status 0), else return exit status */
return (result ? cvfixnum((FIXTYPE) result) : s_true);
}
LOCAL int ospipeclose (f)
FILEP f;
{
int result;
result = pclose(filetab[f].fp);
free(filetab[f].tname);
filetab[f].tname = NULL;
filetab[f].fp = NULL;
return result;
}
#endif /* FILETABLE */
/*
* others to be converted later from Winterp version:
*
* fscanf-fixnum
* fscanf-string
* fscanf-flonum
* copy-array
* array-insert-pos
* array-delete-pos
*
*/
syntax highlighted by Code2HTML, v. 0.9.1