1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
/* -*-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
*
*/
|