esh: report status of backgrounded apps when they finish
This commit is contained in:
parent
7fe9c841d4
commit
9a6a5ce9c1
98
apps/sh.c
98
apps/sh.c
@ -722,49 +722,55 @@ int is_number(const char * c) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char * _strsignal(int sig) {
|
||||
static char str[256];
|
||||
memset(str, 0, sizeof(str));
|
||||
switch (sig) {
|
||||
case SIGILL:
|
||||
sprintf(str, "Illegal instruction");
|
||||
break;
|
||||
case SIGSEGV:
|
||||
sprintf(str, "Segmentation fault");
|
||||
break;
|
||||
case SIGTERM:
|
||||
sprintf(str, "Terminated");
|
||||
break;
|
||||
case SIGQUIT:
|
||||
sprintf(str, "Quit");
|
||||
break;
|
||||
case SIGKILL:
|
||||
sprintf(str, "Killed");
|
||||
break;
|
||||
case SIGHUP:
|
||||
sprintf(str, "Hangup");
|
||||
break;
|
||||
case SIGUSR1:
|
||||
sprintf(str, "User defined signal 1");
|
||||
break;
|
||||
case SIGUSR2:
|
||||
sprintf(str, "User defined signal 2");
|
||||
break;
|
||||
case SIGINT:
|
||||
sprintf(str, "Interrupt");
|
||||
break;
|
||||
case SIGPIPE:
|
||||
sprintf(str, "Broken pipe");
|
||||
break;
|
||||
default:
|
||||
sprintf(str, "Killed by unhandled signal %d",sig);
|
||||
break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints "Segmentation fault", etc.
|
||||
*/
|
||||
static void handle_status(int ret_code) {
|
||||
if (WIFSIGNALED(ret_code)) {
|
||||
char str[256] = {0};
|
||||
|
||||
switch (WTERMSIG(ret_code)) {
|
||||
case SIGILL:
|
||||
sprintf(str, "Illegal instruction");
|
||||
break;
|
||||
case SIGSEGV:
|
||||
sprintf(str, "Segmentation fault");
|
||||
break;
|
||||
case SIGTERM:
|
||||
sprintf(str, "Terminated");
|
||||
break;
|
||||
case SIGQUIT:
|
||||
sprintf(str, "Quit");
|
||||
break;
|
||||
case SIGKILL:
|
||||
sprintf(str, "Killed");
|
||||
break;
|
||||
case SIGHUP:
|
||||
sprintf(str, "Hangup");
|
||||
break;
|
||||
case SIGUSR1:
|
||||
sprintf(str, "User defined signal 1");
|
||||
break;
|
||||
case SIGUSR2:
|
||||
sprintf(str, "User defined signal 2");
|
||||
break;
|
||||
case SIGINT:
|
||||
/* sprintf(str, "Interrupt"); */
|
||||
return;
|
||||
case SIGPIPE:
|
||||
/* sprintf(str, "Broken pipe"); */
|
||||
return;
|
||||
default:
|
||||
sprintf(str, "Killed by unhandled signal %d",WTERMSIG(ret_code));
|
||||
break;
|
||||
}
|
||||
|
||||
int sig = WTERMSIG(ret_code);
|
||||
if (sig == SIGINT || sig == SIGPIPE) return;
|
||||
char * str = _strsignal(sig);
|
||||
if (shell_interactive == 1) {
|
||||
fprintf(stderr, "%s\n", str);
|
||||
} else if (shell_interactive == 2) {
|
||||
@ -1495,6 +1501,22 @@ int main(int argc, char ** argv) {
|
||||
while (1) {
|
||||
char buffer[LINE_LEN] = {0};
|
||||
|
||||
list_t * keys = hashmap_keys(job_hash);
|
||||
foreach(node, keys) {
|
||||
int pid = (int)node->value;
|
||||
int status = 0;
|
||||
if (waitpid(-pid, &status, WNOHANG | WEXITED) > 0) {
|
||||
char * desc = "Done";
|
||||
if (WTERMSIG(status) != 0) {
|
||||
desc = _strsignal(WTERMSIG(status));
|
||||
}
|
||||
fprintf(stderr, "[%d] %s\t\t%s\n", pid, desc, (char*)hashmap_get(job_hash, (void*)pid));
|
||||
hashmap_remove(job_hash, (void*)pid);
|
||||
}
|
||||
}
|
||||
list_free(keys);
|
||||
free(keys);
|
||||
|
||||
read_entry(buffer);
|
||||
|
||||
char * history = malloc(strlen(buffer) + 1);
|
||||
|
@ -7,6 +7,7 @@ _Begin_C_Header
|
||||
|
||||
#define WNOHANG 0x0001
|
||||
#define WUNTRACED 0x0002
|
||||
#define WEXITED 0x0004
|
||||
#define WNOKERN 0x0010
|
||||
|
||||
/* This were taken from newlib, but they remain true */
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include <kernel/shm.h>
|
||||
#include <kernel/printf.h>
|
||||
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <toaru/list.h>
|
||||
#include <toaru/tree.h>
|
||||
|
||||
@ -781,7 +783,7 @@ void reap_process(process_t * proc) {
|
||||
static int wait_candidate(process_t * parent, int pid, int options, process_t * proc) {
|
||||
if (!proc) return 0;
|
||||
|
||||
if (options & 0x10) {
|
||||
if (options & WNOKERN) {
|
||||
/* Skip kernel processes */
|
||||
if (proc->is_tasklet) return 0;
|
||||
}
|
||||
@ -821,7 +823,11 @@ int waitpid(int pid, int * status, int options) {
|
||||
|
||||
if (wait_candidate(proc, pid, options, child)) {
|
||||
has_children = 1;
|
||||
if (child->finished || child->suspended) {
|
||||
if (child->finished) {
|
||||
candidate = child;
|
||||
break;
|
||||
}
|
||||
if (!(options & WEXITED) && child->suspended) {
|
||||
candidate = child;
|
||||
break;
|
||||
}
|
||||
@ -845,7 +851,7 @@ int waitpid(int pid, int * status, int options) {
|
||||
}
|
||||
return pid;
|
||||
} else {
|
||||
if (options & 1) {
|
||||
if (options & WNOHANG) {
|
||||
return 0;
|
||||
}
|
||||
debug_print(INFO, "Sleeping until queue is done.");
|
||||
|
Loading…
Reference in New Issue
Block a user