more complete make example

This commit is contained in:
~d6 2023-12-01 20:29:21 -05:00
parent d11768a256
commit 8360ee899b
3 changed files with 46 additions and 36 deletions

View File

@ -32,6 +32,8 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE. WITH REGARD TO THIS SOFTWARE.
*/ */
#define CONSOLE_DEBUG 0
static UxnSubprocess children[CONSOLE_MAX_CHILDREN]; static UxnSubprocess children[CONSOLE_MAX_CHILDREN];
static char *fork_args[4] = {"/bin/sh", "-c", "", NULL}; static char *fork_args[4] = {"/bin/sh", "-c", "", NULL};
static int to_child_fd[2], from_child_fd[2]; static int to_child_fd[2], from_child_fd[2];
@ -41,7 +43,6 @@ static UxnSubprocess*
find_child_by_pid(pid_t pid) find_child_by_pid(pid_t pid)
{ {
for(int n = 0; n < CONSOLE_MAX_CHILDREN; n++) { for(int n = 0; n < CONSOLE_MAX_CHILDREN; n++) {
//fprintf(stderr, "child %d has pid %d [%d] (looking for %d)\n", n, children[n].pid, children[n].running, pid);
if(children[n].pid == pid) if(children[n].pid == pid)
return &children[n]; return &children[n];
} }
@ -60,11 +61,11 @@ handle_sigchld(int sig)
pid_t pid; pid_t pid;
int n, wstatus; int n, wstatus;
while((pid = waitpid(-1, &wstatus, WNOHANG)) > 0) { while((pid = waitpid(-1, &wstatus, WNOHANG)) > 0) {
//fprintf(stderr, "waitpid got something: %d\n", pid);
UxnSubprocess *child = find_child_by_pid(pid); UxnSubprocess *child = find_child_by_pid(pid);
if (child != NULL) { if (child != NULL) {
fprintf(stderr, "handle_sigchld: child %d (%d)\n", child->id, pid);
child->running = WEXITSTATUS(wstatus) - 256; child->running = WEXITSTATUS(wstatus) - 256;
if(CONSOLE_DEBUG)
fprintf(stderr, "handle_sigchld: %d -> child %d (%d) -> %d\n", sig, child->id, pid, child->running);
if(child_ptys(child->mode)) if(child_ptys(child->mode))
close(child->pty); close(child->pty);
else { else {
@ -76,7 +77,8 @@ handle_sigchld(int sig)
return; return;
} }
} }
fprintf(stderr, "handle_sigchld: no child found", sig); if(CONSOLE_DEBUG)
fprintf(stderr, "handle_sigchld: no child found", sig);
} }
static void static void
@ -145,7 +147,8 @@ start_fork_pipe(UxnSubprocess *child, int mode)
child->fd_out = child_writes(mode) ? from_child_fd[0] : -1; child->fd_out = child_writes(mode) ? from_child_fd[0] : -1;
child->pty = -1; child->pty = -1;
} while (child->pid != pid); } while (child->pid != pid);
fprintf(stderr, "child has pid %d\n", child->pid); if(CONSOLE_DEBUG)
fprintf(stderr, "child has pid %d\n", child->pid);
if(child_reads(mode)) close(to_child_fd[0]); if(child_reads(mode)) close(to_child_fd[0]);
if(child_writes(mode)) close(from_child_fd[1]); if(child_writes(mode)) close(from_child_fd[1]);
} }
@ -176,9 +179,11 @@ host_execute(Uxn *u, Uint8 *d)
UxnSubprocess *child = &children[opts & 0x3]; UxnSubprocess *child = &children[opts & 0x3];
fork_args[2] = cmd; fork_args[2] = cmd;
fprintf(stderr, "running execute: %s (#%02x)\n", cmd, opts); if(CONSOLE_DEBUG)
fprintf(stderr, "running execute: %s (#%02x)\n", cmd, opts);
if(child->pid) { if(child->pid) {
fprintf(stderr, " killing previous child: %d\n", child->pid); if(CONSOLE_DEBUG)
fprintf(stderr, " killing previous child: %d\n", child->pid);
kill(child->pid, 9); kill(child->pid, 9);
} }
@ -272,9 +277,12 @@ UxnSubprocess
void void
console_monitor(Uxn *u) console_monitor(Uxn *u)
{ {
fflush(stdout);
for(int n = 0; n < CONSOLE_MAX_CHILDREN; n++) { for(int n = 0; n < CONSOLE_MAX_CHILDREN; n++) {
UxnSubprocess *child = &children[n]; UxnSubprocess *child = &children[n];
if(child->running < 0) { if(child->running < 0) {
/* printf("child ready for clean up: %d\n", n); */
/* fflush(stdout); */
Uint8 status = child->running + 256; Uint8 status = child->running + 256;
child->running = 0; child->running = 0;
console_input(u, status, CONSOLE_CHILD_EXIT | n); console_input(u, status, CONSOLE_CHILD_EXIT | n);
@ -304,8 +312,6 @@ console_listen(Uxn *u, int i, int argc, char **argv)
Uint8 Uint8
console_dei(Uxn *u, Uint8 addr) console_dei(Uxn *u, Uint8 addr)
{ {
/* for(int n = 0; n < 3; n++) */
/* fprintf(stderr, "child %d has pid %d (%d)\n", n, children[n].pid, children[n].running); */
Uint8 port = addr & 0x0f, *d = &u->dev[addr & 0xf0]; Uint8 port = addr & 0x0f, *d = &u->dev[addr & 0xf0];
return d[port]; return d[port];
} }
@ -313,8 +319,6 @@ console_dei(Uxn *u, Uint8 addr)
void void
console_deo(Uxn *u, Uint8 *d, Uint8 port) console_deo(Uxn *u, Uint8 *d, Uint8 port)
{ {
/* for(int n = 0; n < 3; n++) */
/* fprintf(stderr, "child %d has pid %d (%d)\n", n, children[n].pid, children[n].running); */
switch(port) { switch(port) {
case 0x8: std_put(d[port], stdout); break; case 0x8: std_put(d[port], stdout); break;
case 0x9: std_put(d[port], stderr); break; case 0x9: std_put(d[port], stderr); break;

View File

@ -64,11 +64,11 @@ init_rfds(fd_set *rfds)
FD_ZERO(rfds); FD_ZERO(rfds);
FD_SET(0, rfds); FD_SET(0, rfds);
nfds = 1; nfds = 1;
/* for(i = 0; i < 4; i++) { */ for(i = 0; i < 4; i++) {
/* int fd = get_child(i)->fd_out; */ int fd = get_child(i)->fd_out;
/* FD_SET(fd, rfds); */ FD_SET(fd, rfds);
/* if (fd >= nfds) nfds = fd + 1; */ if (fd >= nfds) nfds = fd + 1;
/* } */ }
return nfds; return nfds;
} }
@ -84,14 +84,14 @@ emu_run(Uxn *u)
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 1000; tv.tv_usec = 1000;
int retval = select(nfds, &rfds, NULL, NULL, &tv); int retval = select(nfds, &rfds, NULL, NULL, &tv);
if(retval <= 0) if(retval > 0) {
continue; if (FD_ISSET(0, &rfds))
if (FD_ISSET(0, &rfds)) handle_input(u, 0, CONSOLE_STDIN, CONSOLE_STDIN_END);
handle_input(u, 0, CONSOLE_STDIN, CONSOLE_STDIN_END); for(i = 0; i < 4; i++) {
for(i = 0; i < 4; i++) { int fd = get_child(i)->fd_out;
int fd = get_child(i)->fd_out; if (fd > 2 && FD_ISSET(fd, &rfds))
if (fd > 2 && FD_ISSET(fd, &rfds)) handle_input(u, fd, CONSOLE_CHILD_DATA | i, CONSOLE_CHILD_END | i);
handle_input(u, fd, CONSOLE_CHILD_DATA | i, CONSOLE_CHILD_END | i); }
} }
console_monitor(u); console_monitor(u);
} }

View File

@ -1,33 +1,39 @@
|00 @System [
&vector $2 &expansion $2 &title $2 &metadata $2
&red $2 &green $2 &blue $2 &debug $1 &exit $1 ]
|10 @Console [ |10 @Console [
&vector $2 &stdin $1 &pad1 $1 &proc-get $1 &host-get $1 &pad2 $1 &type $1 &vector $2 &stdin $1 &pad1 $1 &proc-get $1 &host-get $1 &pad2 $1 &type $1
&stdout $1 &stderr $1 &proc-put $1 &pad3 $1 &param $2 &opts $1 &host-put $1 &stdout $1 &stderr $1 &proc-put $1 &pad3 $1 &param $2 &opts $1 &host-put $1 ]
]
|0100 ( -- BRK ) |0100 ( -- BRK )
;on-console .Console/vector DEO2 ( ; set up console vector callback ) ;on-console .Console/vector DEO2 ( ; set up console vector callback )
BRK ( ; do other initialization ) BRK ( ; do other initialization )
@on-console ( -- BRK ) @on-console ( -- BRK )
LIT "? .Console/stdout DEO
.Console/type DEI #81 EQU ?on-exit ( ; 0x41 signals child 1's exit ) .Console/type DEI #81 EQU ?on-exit ( ; 0x41 signals child 1's exit )
.Console/type DEI #01 EQU ?on-stdin ( ; handle stdin ) .Console/type DEI #01 EQU ?on-stdin ( ; handle stdin )
BRK ( ; handle other console input ) BRK ( ; handle other console input )
@on-stdin
.Console/stdin DEI #0a NEQ
?{ run-make } BRK
@on-exit ( -- BRK ) @on-exit ( -- BRK )
.Console/host-get DEI ( ; read child 1's exit code ) .Console/host-get DEI ( ; read child 1's exit code )
?{ display-success-msg BRK } ( ; zero exit code means success ) ?{ display-success-msg BRK } ( ; zero exit code means success )
display-failure-msg BRK ( ; non-zero exit code means failure ) display-failure-msg BRK ( ; non-zero exit code means failure )
@run-make ( -- ) @on-stdin
;make-cmd .Console/param DEO2 ( ; set up make to run ) .Console/stdin DEI DUP #0a NEQ ?parse ( c^ ; parse input char if not newline )
#01 .Console/opts DEO ( ; use child without pipelines ) POP LIT [ &q $1 ] ?exit ( ; exit if last char was 'q' )
#01 .Console/host-put DEO JMP2r ( ; run the command now and return ) ;make-cmd .Console/param DEO2 ( ; set up make to run )
#01 .Console/opts DEO ( ; use child 1 without pipelines )
#01 .Console/host-put DEO BRK ( ; run the command now and return )
@make-cmd "pwd 00 ( ; buffer containing cmd to run ) @parse ( c^ -> BRK )
LIT "q EQU ,on-stdin/q STR BRK
@exit ( -> BRK )
#80 .System/exit DEO BRK
@make-cmd "make 00 ( ; buffer containing cmd to run )
@display-success-msg @display-success-msg
LIT ". .Console/stdout DEO LIT ". .Console/stdout DEO