"$Header: lam7.c,v 1.9 87/12/14 18:48:02 sklower Exp $";
/* -[Fri Aug 5 12:51:31 1983 by jkf]-
* (c) copyright 1982, Regents of the University of California
register lispval ret
, temp
;
register lispval ret
, temp
;
temp
= inewint(pipes
[0]);
temp
= inewint(pipes
[1]);
register lispval fd
, type
;
if ( (ptr
=fdopen((int)fd
->i
, (char *)type
->a
.pname
))==NULL
)
lispval fname
, arglist
, envlist
, temp
;
char *args
[100], *envs
[100], estrs
[1024];
case 3: envlist
= lbot
[2].val
;
case 2: arglist
= lbot
[1].val
;
case 1: fname
= lbot
[0].val
;
while (TYPE(fname
)!=ATOM
)
fname
= error("exece: non atom function name",TRUE
);
while (TYPE(arglist
)!=DTPR
&& arglist
!=nil
)
arglist
= error("exece: non list arglist",TRUE
);
for (argsp
=args
; arglist
!=nil
; arglist
=arglist
->d
.cdr
) {
error("exece: non atom argument seen",FALSE
);
*argsp
++ = temp
->a
.pname
;
if (TYPE(envlist
)!=DTPR
&& envlist
!=nil
)
for (argsp
=envs
,cp
=estrs
; envlist
!=nil
; envlist
=envlist
->d
.cdr
) {
if (TYPE(temp
)!=DTPR
|| TYPE(temp
->d
.car
)!=ATOM
|| TYPE(temp
->d
.cdr
)!=ATOM
)
error("exece: Bad enviroment list",FALSE
);
for (p
=temp
->d
.car
->a
.pname
; (*cp
++ = *p
++);) ;
for (p
=temp
->d
.cdr
->a
.pname
; (*cp
++ = *p
++);) ;
return(inewint(execve(fname
->a
.pname
, args
, envs
)));
* C code to implement the *process function
* (*process 'st_command ['s_readp ['s_writep]])
* where st_command is the command to execute
* s_readp is non nil if you want a port to read from returned
* s_writep is non nil if you want a port to write to returned
* both flags default to nil
* the exit status of the process if s_readp and s_writep not given
* (in this case the parent waits for the child to finish)
* a list of (readport writeport childpid) if one of s_readp or s_writep
* is given. If only s_readp is non nil, then writeport will be nil,
* If only s_writep is non nil, then readport will be nil
int wflag
, childsi
, childso
, child
;
int (*handler
)(), (*signal())();
FILE *bufs
[2],*obufs
[2], *fpipe();
case 3: if(lbot
[2].val
!= nil
) writep
= TRUE
;
case 2: if(lbot
[1].val
!= nil
) readp
= TRUE
;
case 1: command
= (char *) verify(lbot
[0].val
,
"*process: non atom first arg");
/* if there will be communication between the processes,
* it will be through these pipes:
* parent -> bufs[1] -> bufs[0] -> child if writep
* parent <- obufs[0] <- obufs[1] <- parent if readp
childsi
= fileno(bufs
[0]);
childso
= fileno(obufs
[1]);
handler
= signal(SIGINT
,SIG_IGN
);
if((child
= vfork()) == 0 ) {
/* if we will wait for the child to finish
* and if the process had ignored interrupts before
* we were called, then leave them ignored, else
* set it back the the default (death)
if(wflag
&& handler
!= SIG_IGN
)
if ((p
= (char *)getenv("SHELL")) != (char *)0) {
execlp(p
, p
, "-c",command
,0);
_exit(-1); /* if exec fails, signal problems*/
execlp("csh", "csh", "-c",command
,0);
execlp("sh", "sh", "-c",command
,0);
_exit(-1); /* if exec fails, signal problems*/
/* close the duplicated file descriptors
* e.g. if writep is true then we've created two desriptors,
* bufs[0] and bufs[1], we will write to bufs[1] and the
* child (who has a copy of our bufs[0]) will read from bufs[0]
* We (the parent) close bufs[0] since we will not be reading
if(writep
) fclose(bufs
[0]);
if(readp
) fclose(obufs
[1]);
if(wflag
&& child
!= -1) {
/* we await the death of the child */
while(wait(&status
)!=child
) {}
signal(2,handler
); /* restore the interrupt handler */
return(inewint(itemp
)); /* return its status */
/* we are not waiting for the childs death
* build a list containing the write and read ports
protect(handy
= newdot());
handy
->d
.cdr
->d
.cdr
= newdot();
handy
->d
.car
= P(obufs
[0]);
ioname
[PN(obufs
[0])] = (lispval
) inewstr((char *) "from-process");
handy
->d
.cdr
->d
.car
= P(bufs
[1]);
ioname
[PN(bufs
[1])] = (lispval
) inewstr((char *) "to-process");
handy
->d
.cdr
->d
.cdr
->d
.car
= (lispval
) inewint(child
);
extern int gensymcounter
;
default: argerr("gensym");
if (arg
!= nil
&& TYPE(arg
)==ATOM
)
leader
= arg
->a
.pname
[0];
sprintf(strbuf
, "%c%05d", leader
, gensymcounter
++);
return((lispval
)newatom(0));
type_len
; /* note type_len is in units of int */
register struct argent
*argp
;
register lispval pptr
, ind
, opptr
;
errorh1(Vermisc
, "remprop: Illegal first argument :",
if (TYPE(pptr
->d
.cdr
)!=DTPR
)
errorh1(Vermisc
, "remprop: Bad property list",
if (pptr
->d
.car
== ind
) {
opptr
->d
.cdr
= pptr
->d
.cdr
->d
.cdr
;
atm
->d
.cdr
= pptr
->d
.cdr
->d
.cdr
;
nilplist
= pptr
->d
.cdr
->d
.cdr
;
atm
->a
.plist
= pptr
->d
.cdr
->d
.cdr
;
if ((pptr
->d
.cdr
)->d
.cdr
== nil
) return(nil
);
pptr
= (pptr
->d
.cdr
)->d
.cdr
;
error("ONLY ATOMS HAVE FUNCTION BINDINGS", FALSE
);
if (TYPE(lbot
->val
)==STRNG
)
if (TYPE(lbot
->val
)==ATOM
)
temp
->a
.pname
= (char *)CNIL
;
temp
->a
.clb
=(lispval
)atom_str
.next_free
;
atom_str
.next_free
=(char *) temp
;
register lispval work
, prev
;
char *front
, *temp
; int clean
;
extern unsigned char *ctable
;
sprintf(ctemp
,"%d",a
->i
);
sprintf(ctemp
,"%f",a
->r
);
temp
= front
= a
->a
.pname
;
if (*temp
== '-') temp
++;
clean
= clean
&& (ctable
[*temp
] != VNUM
);
clean
= (!(ctable
[*temp
++] & QUTMASK
));
strncpy(ctemp
, front
, 99);
sprintf(ctemp
,"\"%s\"",front
);
error("prname does not support this type", FALSE
);
protect(ret
= prev
= newdot());
prev
->d
.cdr
= work
= newdot();
work
->d
.car
= getatom(FALSE
);
if(np
-lbot
==0) franzexit(0);
franzexit((int) handy
->i
);
register lispval handy
, work
;
register char *cp
= strbuf
;
extern int atmlen
; /* used by newatom and getatom */
extern char *atomtoolong();
for(handy
= lbot
->val
; handy
!=nil
; handy
= handy
->d
.cdr
)
*cp
++ = work
->a
.pname
[0];
work
= errorh1(Vermisc
,"implode/maknam: Illegal type for this arg:",nil
,FALSE
,44,work
);
if(unintern
) return((lispval
)newatom(FALSE
));
else return((lispval
) getatom(FALSE
));
return(Iimplode(TRUE
)); /* unintern result */
return(Iimplode(FALSE
)); /* intern result */
register lispval handy
,atpr
;
if(TYPE(handy
=lbot
->val
) != ATOM
)
errorh1(Vermisc
,"non atom to intern ",nil
,FALSE
,0,handy
);
/* compute hash of pname of arg */
hash
= hashfcn(handy
->a
.pname
);
/* search for atom with same pname on hash list */
atpr
= (lispval
) hasht
[hash
];
for(atpr
= (lispval
) hasht
[hash
]
; atpr
= (lispval
)atpr
->a
.hshlnk
)
if(strcmp(atpr
->a
.pname
,handy
->a
.pname
) == 0) return(atpr
);
/* not there yet, put the given one on */
handy
->a
.hshlnk
= hasht
[hash
];
hasht
[hash
] = (struct atom
*)handy
;
/*** Ibindvars :: lambda bind values to variables
called with a list of variables and values.
does the special binding and returns a fixnum which represents
the value of bnp before the binding
register lispval vars
,vals
,handy
;
struct nament
*oldbnp
= bnp
;
chkarg(2,"int:bindvars");
if(vars
== nil
) return(inewint(oldbnp
));
errorh1(Vermisc
,"progv (int:bindvars): bad first argument ", nil
,
if((vals
!= nil
) && (TYPE(vals
) != DTPR
))
errorh1(Vermisc
,"progv (int:bindvars): bad second argument ",nil
,
for( ; vars
!= nil
; vars
= vars
->d
.cdr
, vals
=vals
->d
.cdr
)
errorh1(Vermisc
,"progv (int:bindvars): non symbol argument to bind ",
PUSHDOWN(handy
,vals
->d
.car
);
/*** Iunbindvars :: unbind the variable stacked by Ibindvars
called by compiled progv's
chkarg(1,"int:unbindvars");
oldbnp
= (struct nament
*) (lbot
[0].val
->i
);
if((oldbnp
< orgbnp
) || ( oldbnp
> bnp
))
errorh1(Vermisc
,"int:unbindvars: bad bnp value given ",nil
,FALSE
,0,
* (time-string ['x_milliseconds])
* if given no argument, returns the current time as a string
* if given an argument which is a fixnum representing the current time
* as a fixnum, it generates a string from that
* the format of the string returned is that defined in the Unix manual
* except the trailing newline is removed.
case 0: time(&timevalue
);
case 1: while (TYPE(lbot
[0].val
) != INT
)
errorh(Vermisc
,"time-string: non fixnum argument ",
timevalue
= lbot
[0].val
->i
;
retval
= (char *) ctime(&timevalue
);
/* remove newline character */
retval
[strlen(retval
)-1] = '\0';
return((lispval
) inewstr(retval
));