more complete make example
This commit is contained in:
parent
d11768a256
commit
8360ee899b
|
@ -32,6 +32,8 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|||
WITH REGARD TO THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define CONSOLE_DEBUG 0
|
||||
|
||||
static UxnSubprocess children[CONSOLE_MAX_CHILDREN];
|
||||
static char *fork_args[4] = {"/bin/sh", "-c", "", NULL};
|
||||
static int to_child_fd[2], from_child_fd[2];
|
||||
|
@ -41,7 +43,6 @@ static UxnSubprocess*
|
|||
find_child_by_pid(pid_t pid)
|
||||
{
|
||||
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)
|
||||
return &children[n];
|
||||
}
|
||||
|
@ -60,11 +61,11 @@ handle_sigchld(int sig)
|
|||
pid_t pid;
|
||||
int n, wstatus;
|
||||
while((pid = waitpid(-1, &wstatus, WNOHANG)) > 0) {
|
||||
//fprintf(stderr, "waitpid got something: %d\n", pid);
|
||||
UxnSubprocess *child = find_child_by_pid(pid);
|
||||
if (child != NULL) {
|
||||
fprintf(stderr, "handle_sigchld: child %d (%d)\n", child->id, pid);
|
||||
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))
|
||||
close(child->pty);
|
||||
else {
|
||||
|
@ -76,7 +77,8 @@ handle_sigchld(int sig)
|
|||
return;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "handle_sigchld: no child found", sig);
|
||||
if(CONSOLE_DEBUG)
|
||||
fprintf(stderr, "handle_sigchld: no child found", sig);
|
||||
}
|
||||
|
||||
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->pty = -1;
|
||||
} 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_writes(mode)) close(from_child_fd[1]);
|
||||
}
|
||||
|
@ -176,9 +179,11 @@ host_execute(Uxn *u, Uint8 *d)
|
|||
UxnSubprocess *child = &children[opts & 0x3];
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -272,9 +277,12 @@ UxnSubprocess
|
|||
void
|
||||
console_monitor(Uxn *u)
|
||||
{
|
||||
fflush(stdout);
|
||||
for(int n = 0; n < CONSOLE_MAX_CHILDREN; n++) {
|
||||
UxnSubprocess *child = &children[n];
|
||||
if(child->running < 0) {
|
||||
/* printf("child ready for clean up: %d\n", n); */
|
||||
/* fflush(stdout); */
|
||||
Uint8 status = child->running + 256;
|
||||
child->running = 0;
|
||||
console_input(u, status, CONSOLE_CHILD_EXIT | n);
|
||||
|
@ -304,8 +312,6 @@ console_listen(Uxn *u, int i, int argc, char **argv)
|
|||
Uint8
|
||||
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];
|
||||
return d[port];
|
||||
}
|
||||
|
@ -313,8 +319,6 @@ console_dei(Uxn *u, Uint8 addr)
|
|||
void
|
||||
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) {
|
||||
case 0x8: std_put(d[port], stdout); break;
|
||||
case 0x9: std_put(d[port], stderr); break;
|
||||
|
|
26
src/uxncli.c
26
src/uxncli.c
|
@ -64,11 +64,11 @@ init_rfds(fd_set *rfds)
|
|||
FD_ZERO(rfds);
|
||||
FD_SET(0, rfds);
|
||||
nfds = 1;
|
||||
/* for(i = 0; i < 4; i++) { */
|
||||
/* int fd = get_child(i)->fd_out; */
|
||||
/* FD_SET(fd, rfds); */
|
||||
/* if (fd >= nfds) nfds = fd + 1; */
|
||||
/* } */
|
||||
for(i = 0; i < 4; i++) {
|
||||
int fd = get_child(i)->fd_out;
|
||||
FD_SET(fd, rfds);
|
||||
if (fd >= nfds) nfds = fd + 1;
|
||||
}
|
||||
return nfds;
|
||||
}
|
||||
|
||||
|
@ -84,14 +84,14 @@ emu_run(Uxn *u)
|
|||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1000;
|
||||
int retval = select(nfds, &rfds, NULL, NULL, &tv);
|
||||
if(retval <= 0)
|
||||
continue;
|
||||
if (FD_ISSET(0, &rfds))
|
||||
handle_input(u, 0, CONSOLE_STDIN, CONSOLE_STDIN_END);
|
||||
for(i = 0; i < 4; i++) {
|
||||
int fd = get_child(i)->fd_out;
|
||||
if (fd > 2 && FD_ISSET(fd, &rfds))
|
||||
handle_input(u, fd, CONSOLE_CHILD_DATA | i, CONSOLE_CHILD_END | i);
|
||||
if(retval > 0) {
|
||||
if (FD_ISSET(0, &rfds))
|
||||
handle_input(u, 0, CONSOLE_STDIN, CONSOLE_STDIN_END);
|
||||
for(i = 0; i < 4; i++) {
|
||||
int fd = get_child(i)->fd_out;
|
||||
if (fd > 2 && FD_ISSET(fd, &rfds))
|
||||
handle_input(u, fd, CONSOLE_CHILD_DATA | i, CONSOLE_CHILD_END | i);
|
||||
}
|
||||
}
|
||||
console_monitor(u);
|
||||
}
|
||||
|
|
|
@ -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 [
|
||||
&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 ¶m $2 &opts $1 &host-put $1
|
||||
]
|
||||
&stdout $1 &stderr $1 &proc-put $1 &pad3 $1 ¶m $2 &opts $1 &host-put $1 ]
|
||||
|
||||
|0100 ( -- BRK )
|
||||
;on-console .Console/vector DEO2 ( ; set up console vector callback )
|
||||
BRK ( ; do other initialization )
|
||||
|
||||
@on-console ( -- BRK )
|
||||
LIT "? .Console/stdout DEO
|
||||
.Console/type DEI #81 EQU ?on-exit ( ; 0x41 signals child 1's exit )
|
||||
.Console/type DEI #01 EQU ?on-stdin ( ; handle stdin )
|
||||
BRK ( ; handle other console input )
|
||||
|
||||
@on-stdin
|
||||
.Console/stdin DEI #0a NEQ
|
||||
?{ run-make } BRK
|
||||
|
||||
@on-exit ( -- BRK )
|
||||
.Console/host-get DEI ( ; read child 1's exit code )
|
||||
?{ display-success-msg BRK } ( ; zero exit code means success )
|
||||
display-failure-msg BRK ( ; non-zero exit code means failure )
|
||||
|
||||
@run-make ( -- )
|
||||
;make-cmd .Console/param DEO2 ( ; set up make to run )
|
||||
#01 .Console/opts DEO ( ; use child without pipelines )
|
||||
#01 .Console/host-put DEO JMP2r ( ; run the command now and return )
|
||||
@on-stdin
|
||||
.Console/stdin DEI DUP #0a NEQ ?parse ( c^ ; parse input char if not newline )
|
||||
POP LIT [ &q $1 ] ?exit ( ; exit if last char was 'q' )
|
||||
;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
|
||||
LIT ". .Console/stdout DEO
|
||||
|
|
Loading…
Reference in New Issue