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.
|
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;
|
||||||
|
|
26
src/uxncli.c
26
src/uxncli.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ¶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 )
|
|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
|
||||||
|
|
Loading…
Reference in New Issue