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,14 +722,10 @@ int is_number(const char * c) {
return 1; return 1;
} }
/** static char * _strsignal(int sig) {
* Prints "Segmentation fault", etc. static char str[256];
*/ memset(str, 0, sizeof(str));
static void handle_status(int ret_code) { switch (sig) {
if (WIFSIGNALED(ret_code)) {
char str[256] = {0};
switch (WTERMSIG(ret_code)) {
case SIGILL: case SIGILL:
sprintf(str, "Illegal instruction"); sprintf(str, "Illegal instruction");
break; break;
@ -755,16 +751,26 @@ static void handle_status(int ret_code) {
sprintf(str, "User defined signal 2"); sprintf(str, "User defined signal 2");
break; break;
case SIGINT: case SIGINT:
/* sprintf(str, "Interrupt"); */ sprintf(str, "Interrupt");
return; break;
case SIGPIPE: case SIGPIPE:
/* sprintf(str, "Broken pipe"); */ sprintf(str, "Broken pipe");
return; break;
default: default:
sprintf(str, "Killed by unhandled signal %d",WTERMSIG(ret_code)); sprintf(str, "Killed by unhandled signal %d",sig);
break; break;
} }
return str;
}
/**
* Prints "Segmentation fault", etc.
*/
static void handle_status(int ret_code) {
if (WIFSIGNALED(ret_code)) {
int sig = WTERMSIG(ret_code);
if (sig == SIGINT || sig == SIGPIPE) return;
char * str = _strsignal(sig);
if (shell_interactive == 1) { if (shell_interactive == 1) {
fprintf(stderr, "%s\n", str); fprintf(stderr, "%s\n", str);
} else if (shell_interactive == 2) { } else if (shell_interactive == 2) {
@ -1495,6 +1501,22 @@ int main(int argc, char ** argv) {
while (1) { while (1) {
char buffer[LINE_LEN] = {0}; 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); read_entry(buffer);
char * history = malloc(strlen(buffer) + 1); char * history = malloc(strlen(buffer) + 1);

View File

@ -7,6 +7,7 @@ _Begin_C_Header
#define WNOHANG 0x0001 #define WNOHANG 0x0001
#define WUNTRACED 0x0002 #define WUNTRACED 0x0002
#define WEXITED 0x0004
#define WNOKERN 0x0010 #define WNOKERN 0x0010
/* This were taken from newlib, but they remain true */ /* This were taken from newlib, but they remain true */

View File

@ -17,6 +17,8 @@
#include <kernel/shm.h> #include <kernel/shm.h>
#include <kernel/printf.h> #include <kernel/printf.h>
#include <sys/wait.h>
#include <toaru/list.h> #include <toaru/list.h>
#include <toaru/tree.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) { static int wait_candidate(process_t * parent, int pid, int options, process_t * proc) {
if (!proc) return 0; if (!proc) return 0;
if (options & 0x10) { if (options & WNOKERN) {
/* Skip kernel processes */ /* Skip kernel processes */
if (proc->is_tasklet) return 0; 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)) { if (wait_candidate(proc, pid, options, child)) {
has_children = 1; has_children = 1;
if (child->finished || child->suspended) { if (child->finished) {
candidate = child;
break;
}
if (!(options & WEXITED) && child->suspended) {
candidate = child; candidate = child;
break; break;
} }
@ -845,7 +851,7 @@ int waitpid(int pid, int * status, int options) {
} }
return pid; return pid;
} else { } else {
if (options & 1) { if (options & WNOHANG) {
return 0; return 0;
} }
debug_print(INFO, "Sleeping until queue is done."); debug_print(INFO, "Sleeping until queue is done.");