Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a few things to make $&waiting more flexible. #149

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions doc/es.1
Original file line number Diff line number Diff line change
Expand Up @@ -1856,7 +1856,7 @@ as input to
and executes its contents.
The options are a subset of the invocation options for the shell (see below).
.TP
.Cr "access \fR[\fP-n \fIname\fP\fR]\fP \fR[\fP-1e\fR]\fP \fR[\fP-rwx\fR]\fP \fR[\fP-fdcblsp\fR]\fP \fIpath ...\fP"
.Cr "access \fR[\fP-n \fIname\fP\fR]\fP \fR[\fP-1e\fR]\fP \fR[\fP-rwx\fR]\fP \fR[\fP-fdcblsp\fR]\fP \fIpath ...\fP"
Tests if the named paths are accessible according to the options presented.
Normally,
.Cr access
Expand Down Expand Up @@ -2192,14 +2192,19 @@ are specified,
.Cr \-e
is used.
.TP
.Cr "wait \fI\fR[\fPpid\fR]"
.Cr "wait \fR[\fP-n\fR]\fP \fI\fR[\fPpid\fR]"
Waits for the specified
.IR pid ,
which must have been started by
.IR es .
If no
.I pid
is specified, waits for any child process to exit.
If
.Cr \-n
is specified and the process(es) to be waited for is (are) not ready
at call time, returns immediately instead of blocking or throwing an
error.
.TP
.Cr "whatis \fIprogram ...\fP"
For each named
Expand Down Expand Up @@ -2293,6 +2298,19 @@ copied (via
to file descriptor
.IR newfd .
.TP
.Cr "%echo-status \fIpid did status\fP"
Inspects the exit
.I status
of an exited (and waited-for) process
.IR pid ,
where
.I did
indicates if the process
.Cr exited
or was
.Cr signaled ,
and prints any interesting condition.
.TP
.Cr "%eval-noprint \fIcmd\fP"
Run the command.
(Passed as the argument to
Expand Down Expand Up @@ -2740,7 +2758,7 @@ variable, which signals to the
library how much of the history file should be read into the in-memory
history log.
.PP
Several primitives are not directly associated with other function.
Several primitives are not directly associated with other functions.
They are:
.TP
.Cr "$&collect"
Expand All @@ -2750,7 +2768,7 @@ The garbage collector in
runs rather frequently;
there should be no reason for a user to issue this command.
.TP
.Cr "$&noreturn \fIlambda args ...\fP"
.Cr "$&noreturn \fIlambda args ..."
Call the
.IR lambda ,
but in such a way that it does not catch the
Expand All @@ -2765,6 +2783,11 @@ and
.Cr "&&" )
can be implemented as lambdas rather than primitives.
.TP
.Cr "$&sigmessage"
converts a signal name such as
.Cr sigint
to a short message describing the signal, used for error reporting.
.TP
.Cr "$&primitives"
Returns a list of the names of es primitives.
.TP
Expand Down
6 changes: 3 additions & 3 deletions es.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,12 @@ extern char *checkexecutable(char *file);
/* proc.c */

extern Boolean hasforked;
extern int efork(Boolean parent, Boolean background);
extern int efork(Boolean parent);
extern pid_t spgrp(pid_t pgid);
extern int tctakepgrp(void);
extern void initpgrp(void);
extern int ewait(int pid, Boolean interruptible, void *rusage);
#define ewaitfor(pid) ewait(pid, FALSE, NULL)
extern int ewait(int pid, int opts, void *rusage);
#define ewaitfor(pid) ewait(pid, 0, NULL)

#if JOB_PROTECT
extern void tcreturnpgrp(void);
Expand Down
3 changes: 1 addition & 2 deletions eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ extern List *forkexec(char *file, List *list, Boolean inchild) {
Vector *env;
gcdisable();
env = mkenv();
pid = efork(!inchild, FALSE);
pid = efork(!inchild);
if (pid == 0) {
execve(file, vectorize(list)->vector, env->vector);
failexec(file, list);
Expand All @@ -41,7 +41,6 @@ extern List *forkexec(char *file, List *list, Boolean inchild) {
sigint_newline = TRUE;
} else
SIGCHK();
printstatus(0, status);
return mklist(mkterm(mkstatus(status), NULL), NULL);
}

Expand Down
25 changes: 22 additions & 3 deletions initial.es
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ fn-newpgrp = $&newpgrp
fn-result = $&result
fn-throw = $&throw
fn-umask = $&umask
fn-wait = $&wait

fn-%read = $&read

Expand Down Expand Up @@ -579,6 +578,26 @@ fn %pathsearch name { access -n $name -1e -xf $path }

if {~ <=$&primitives execfailure} {fn-%exec-failure = $&execfailure}

# The %echo-status hook is used to print any potentially interesting
# status from an exec()ed binary.

fn %echo-status pid did status {
if {~ $did signaled && !~ $status (sigint sigpipe)} {
let (msg = <={if {$echo-status-pid} {result $pid^': '} {result ''}}) {
msg = $msg^<={$&sigmessage $status}
if {~ $status *+core} {
msg = $msg^'--core dumped'
}
echo >[1=2] $msg
}
}
}

echo-status-pid = false

fn wait {
local (echo-status-pid = true) $&wait $*
}

#
# Read-eval-print loops
Expand Down Expand Up @@ -642,7 +661,7 @@ fn %interactive-loop {
$fn-%dispatch false
} {~ $e signal} {
if {!~ $type sigint sigterm sigquit} {
echo >[1=2] caught unexpected signal: $type
echo >[1=2] caught unexpected signal: $type: <={$&sigmessage $type}
}
} {
echo >[1=2] uncaught exception: $e $type $msg
Expand Down Expand Up @@ -756,7 +775,7 @@ max-eval-depth = 640
# is does. fn-%dispatch is really only important to the current
# interpreter loop.

noexport = noexport pid signals apid bqstatus fn-%dispatch path home matchexpr
noexport = noexport pid signals apid bqstatus fn-%dispatch path home matchexpr print-status-pid


#
Expand Down
11 changes: 3 additions & 8 deletions mksignal
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ sed -n '
mesg["SIGHUP"] = "hangup"
mesg["SIGILL"] = "illegal instruction"
mesg["SIGINFO"] = "information request"
mesg["SIGINT"] = "interrupt"
mesg["SIGIO"] = "input/output possible"
mesg["SIGIOT"] = "IOT instruction"
mesg["SIGKILL"] = "killed"
mesg["SIGLOST"] = "resource lost"
mesg["SIGLWP"] = "lightweight process library signal"
mesg["SIGMIGRATE"] = "migrate process"
mesg["SIGPIPE"] = "broken pipe"
mesg["SIGPOLL"] = "pollable event occurred"
mesg["SIGPROF"] = "profiling timer alarm"
mesg["SIGPWR"] = "power failure"
Expand Down Expand Up @@ -82,13 +84,6 @@ sed -n '
mesg["SIGVIRT"] = "virtual time alarm"
mesg["SIGWINDOW"] = "window size changed"


# set nomesg["SIGNAME"] to suppress message printing

nomesg["SIGINT"] = 1
nomesg["SIGPIPE"] = 1


# set ignore["SIGNAME"] to explicitly ignore a named signal (usually, this
# is just for things that look like signals but really are not)

Expand Down Expand Up @@ -117,7 +112,7 @@ sed -n '
sig[$1] == 0 && ignore[$1] == 0 {
sig[$1] = ++nsig
signame[nsig] = $1
if (mesg[$1] == "" && nomesg[$1] == 0) {
if (mesg[$1] == "") {
str = $3
for (i = 4; i <= NF; i++)
str = str " " $i
Expand Down
21 changes: 9 additions & 12 deletions prim-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ static int pipefork(int p[2], int *extra) {
registerfd(extra, FALSE);

ExceptionHandler
pid = efork(TRUE, FALSE);
pid = efork(TRUE);
CatchExceptionIf (pid != 0, e)
unregisterfd(&p[0]);
unregisterfd(&p[1]);
Expand Down Expand Up @@ -205,7 +205,7 @@ PRIM(pipe) {
for (;; list = list->next) {
int p[2], pid;

pid = (list->next == NULL) ? efork(TRUE, FALSE) : pipefork(p, &inpipe);
pid = (list->next == NULL) ? efork(TRUE) : pipefork(p, &inpipe);

if (pid == 0) { /* child */
if (inpipe != -1) {
Expand Down Expand Up @@ -234,9 +234,9 @@ PRIM(pipe) {

Ref(List *, result, NULL);
do {
int pid = pids[--n];
Term *t;
int status = ewaitfor(pids[--n]);
printstatus(0, status);
int status = ewaitfor(pid);
t = mkstr(mkstatus(status));
result = mklist(t, result);
} while (0 < n);
Expand All @@ -247,7 +247,7 @@ PRIM(pipe) {

#if HAVE_DEV_FD
PRIM(readfrom) {
int pid, p[2], status;
int pid, p[2];
Push push;

caller = "$&readfrom";
Expand Down Expand Up @@ -279,15 +279,14 @@ PRIM(readfrom) {
EndExceptionHandler

close(p[0]);
status = ewaitfor(pid);
printstatus(0, status);
ewaitfor(pid);
varpop(&push);
RefEnd3(cmd, input, var);
RefReturn(lp);
}

PRIM(writeto) {
int pid, p[2], status;
int pid, p[2];
Push push;

caller = "$&writeto";
Expand Down Expand Up @@ -319,8 +318,7 @@ PRIM(writeto) {
EndExceptionHandler

close(p[1]);
status = ewaitfor(pid);
printstatus(0, status);
ewaitfor(pid);
varpop(&push);
RefEnd3(cmd, output, var);
RefReturn(lp);
Expand Down Expand Up @@ -365,11 +363,10 @@ PRIM(backquote) {
}

close(p[1]);
gcdisable();
lp = bqinput(sep, p[0]);
close(p[0]);
status = ewaitfor(pid);
printstatus(0, status);
gcdisable();
lp = mklist(mkstr(mkstatus(status)), lp);
gcenable();
list = lp;
Expand Down
37 changes: 27 additions & 10 deletions prim-sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ PRIM(newpgrp) {
}

PRIM(background) {
int pid = efork(TRUE, TRUE);
int pid = efork(TRUE);
if (pid == 0) {
#if JOB_PROTECT
/* job control safe version: put it in a new pgroup, if interactive. */
Expand All @@ -51,12 +51,11 @@ PRIM(background) {

PRIM(fork) {
int pid, status;
pid = efork(TRUE, FALSE);
pid = efork(TRUE);
if (pid == 0)
esexit(exitstatus(eval(list, NULL, evalflags | eval_inchild)));
status = ewaitfor(pid);
SIGCHK();
printstatus(0, status);
return mklist(mkstr(mkstatus(status)), NULL);
}

Expand Down Expand Up @@ -128,6 +127,26 @@ PRIM(setsignals) {
return mksiglist();
}

PRIM(sigmessage) {
int sig;
char *s, *p;
if (list == NULL || list->next != NULL)
fail("$&sigmessage", "usage: $&sigmessage signal");
s = getstr(list->term);
if ((p = strchr(s, '+')) != NULL) {
if (streq(p, "+core"))
*p = '\0';
else
p = NULL;
}
sig = signumber(s);
if (p != NULL)
*p = '+';
if (sig < 0)
fail("$&sigmessage", "unknown signal: %s", s);
return mklist(mkstr(sigmessage(sig)), NULL);
}

/*
* limit builtin -- this is too much code for what it gives you
*/
Expand Down Expand Up @@ -300,13 +319,12 @@ PRIM(time) {

gc(); /* do a garbage collection first to ensure reproducible results */
t0 = time(NULL);
pid = efork(TRUE, FALSE);
pid = efork(TRUE);
if (pid == 0)
esexit(exitstatus(eval(lp, NULL, evalflags | eval_inchild)));
status = ewait(pid, FALSE, &r);
status = ewait(pid, 0, &r);
t1 = time(NULL);
SIGCHK();
printstatus(0, status);

eprint(
"%6ldr %5ld.%ldu %5ld.%lds\t%L\n",
Expand All @@ -325,7 +343,7 @@ PRIM(time) {
Ref(List *, lp, list);

gc(); /* do a garbage collection first to ensure reproducible results */
pid = efork(TRUE, FALSE);
pid = efork(TRUE);
if (pid == 0) {
clock_t t0, t1;
struct tms tms;
Expand All @@ -335,14 +353,13 @@ PRIM(time) {
ticks = sysconf(_SC_CLK_TCK);

t0 = times(&tms);
pid = efork(TRUE, FALSE);
pid = efork(TRUE);
if (pid == 0)
esexit(exitstatus(eval(lp, NULL, evalflags | eval_inchild)));

status = ewaitfor(pid);
t1 = times(&tms);
SIGCHK();
printstatus(0, status);

tms.tms_cutime += ticks / 20;
tms.tms_cstime += ticks / 20;
Expand All @@ -358,7 +375,6 @@ PRIM(time) {
}
status = ewaitfor(pid);
SIGCHK();
printstatus(0, status);

RefEnd(lp);
return mklist(mkstr(mkstatus(status)), NULL);
Expand Down Expand Up @@ -439,6 +455,7 @@ extern Dict *initprims_sys(Dict *primdict) {
X(fork);
X(run);
X(setsignals);
X(sigmessage);
#if BSD_LIMITS
X(limit);
#endif
Expand Down
Loading