esh: report status of backgrounded apps when they finish

This commit is contained in:
K. Lange 2018-10-29 12:45:22 +09:00
parent 7fe9c841d4
commit 9a6a5ce9c1
3 changed files with 70 additions and 41 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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.");