Browse Source

proper waitpid status values

K. Lange 4 years ago
parent
commit
7a20e11aea
9 changed files with 66 additions and 1685 deletions
  1. 0 1671
      apps/esh.c
  2. 1 1
      apps/kdebug.c
  3. 7 0
      apps/qemu-fwcfg.c
  4. 52 8
      apps/sh.c
  5. 1 1
      base/usr/include/kernel/process.h
  6. 2 0
      base/usr/include/sys/wait.h
  7. 1 2
      kernel/sys/panic.c
  8. 1 1
      kernel/sys/signal.c
  9. 1 1
      kernel/sys/syscall.c

File diff suppressed because it is too large
+ 0 - 1671
apps/esh.c


+ 1 - 1
apps/kdebug.c

@@ -12,5 +12,5 @@ int main(int argc, char * argv[]) {
 	syscall_system_function(7, NULL);
 	int status;
 	wait(&status);
-	return status;
+	return WEXITSTATUS(status);
 }

+ 7 - 0
apps/qemu-fwcfg.c

@@ -17,6 +17,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <signal.h>
 
 #define FW_CFG_PORT_OUT 0x510
 #define FW_CFG_PORT_IN  0x511
@@ -68,6 +69,10 @@ static int usage(char * argv[]) {
 	return 1;
 }
 
+static void sig_pass(int sig) {
+	exit(1);
+}
+
 int main(int argc, char * argv[]) {
 
 	uint32_t count = 0;
@@ -101,6 +106,8 @@ int main(int argc, char * argv[]) {
 		return usage(argv);
 	}
 
+	signal(SIGILL, sig_pass);
+
 	/* First check for QEMU */
 	outports(FW_CFG_PORT_OUT, FW_CFG_SELECT_QEMU);
 	if (inportb(FW_CFG_PORT_IN) != 'Q' ||

+ 52 - 8
apps/sh.c

@@ -70,6 +70,8 @@ char ** shell_argv = NULL;
 int shell_argc = 0;
 int experimental_rline = 1;
 
+static int current_line = 0;
+static char * current_file = NULL;
 
 int pid; /* Process ID of the shell */
 
@@ -663,6 +665,36 @@ int is_number(const char * c) {
 	return 1;
 }
 
+/**
+ * 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 SIGINT:
+				/* Do nothing */
+				return;
+			default:
+				sprintf(str, "Killed by unhandled signal %d",WTERMSIG(ret_code));
+				break;
+		}
+
+		if (shell_interactive == 1) {
+			fprintf(stderr, "%s\n", str);
+		} else if (shell_interactive == 2) {
+			fprintf(stderr, "%s: line %d: %s\n", current_file, current_line, str);
+		}
+	}
+}
+
 int shell_exec(char * buffer, size_t size, FILE * file, char ** out_buffer) {
 
 	*out_buffer = NULL;
@@ -1122,7 +1154,8 @@ _nope:
 	tcsetpgrp(STDIN_FILENO, getpid());
 	free(cmd);
 
-	return ret_code;
+	handle_status(ret_code);
+	return WEXITSTATUS(ret_code);
 }
 
 void add_path_contents(char * path) {
@@ -1212,6 +1245,7 @@ void add_path(void) {
 }
 
 int run_script(FILE * f) {
+	current_line = 1;
 	while (!feof(f)) {
 		char buf[LINE_LEN] = {0};
 		fgets(buf, LINE_LEN, f);
@@ -1222,6 +1256,7 @@ int run_script(FILE * f) {
 			ret = shell_exec(b, LINE_LEN, f, &out);
 			b = out;
 		} while (b);
+		current_line++;
 		if (ret >= 0) last_ret = ret;
 	}
 
@@ -1241,6 +1276,7 @@ void source_eshrc(void) {
 	FILE * f = fopen(tmp, "r");
 	if (!f) return;
 
+	current_file = tmp;
 	run_script(f);
 }
 
@@ -1296,7 +1332,8 @@ int main(int argc, char ** argv) {
 		}
 
 		shell_argc = argc - 1;
-		shell_argv = &argv[1];
+		shell_argv = &argv[optind];
+		current_file = argv[optind];
 
 		return run_script(f);
 	}
@@ -1450,7 +1487,9 @@ uint32_t shell_cmd_if(int argc, char * argv[]) {
 
 	child = 0;
 
-	if (ret_code == 0) {
+	handle_status(ret_code);
+
+	if (WEXITSTATUS(ret_code) == 0) {
 		shell_command_t func = shell_find(*then_args);
 		if (func) {
 			int argc = 0;
@@ -1470,7 +1509,8 @@ uint32_t shell_cmd_if(int argc, char * argv[]) {
 			} while (pid != -1 || (pid == -1 && errno != ECHILD));
 			child = 0;
 			tcsetpgrp(STDIN_FILENO, getpid());
-			return ret_code;
+			handle_status(ret_code);
+			return WEXITSTATUS(ret_code);
 		}
 	} else if (else_args) {
 		shell_command_t func = shell_find(*else_args);
@@ -1491,7 +1531,8 @@ uint32_t shell_cmd_if(int argc, char * argv[]) {
 				pid = waitpid(-1, &ret_code, 0);
 			} while (pid != -1 || (pid == -1 && errno != ECHILD));
 			child = 0;
-			return ret_code;
+			handle_status(ret_code);
+			return WEXITSTATUS(ret_code);
 		}
 	}
 
@@ -1531,7 +1572,8 @@ uint32_t shell_cmd_while(int argc, char * argv[]) {
 		} while (pid != -1 || (pid == -1 && errno != ECHILD));
 		child = 0;
 
-		if (ret_code == 0) {
+		handle_status(ret_code);
+		if (WEXITSTATUS(ret_code) == 0) {
 			child_pid = fork();
 			if (!child_pid) {
 				run_cmd(do_args);
@@ -1542,7 +1584,7 @@ uint32_t shell_cmd_while(int argc, char * argv[]) {
 			} while (pid != -1 || (pid == -1 && errno != ECHILD));
 			child = 0;
 		} else {
-			return ret_code;
+			return WEXITSTATUS(ret_code);
 		}
 	} while (!break_while);
 
@@ -1625,6 +1667,7 @@ uint32_t shell_cmd_source(int argc, char * argv[]) {
 		fprintf(stderr, "%s: %s: %s", argv[0], argv[1], strerror(errno));
 	}
 
+	current_file = argv[1];
 	return run_script(f);
 }
 
@@ -1650,7 +1693,8 @@ uint32_t shell_cmd_not(int argc, char * argv[]) {
 	} while (pid != -1 || (pid == -1 && errno != ECHILD));
 	child = 0;
 	tcsetpgrp(STDIN_FILENO, getpid());
-	return !ret_code;
+	handle_status(ret_code);
+	return !WEXITSTATUS(ret_code);
 }
 
 uint32_t shell_cmd_unset(int argc, char * argv[]) {

+ 1 - 1
base/usr/include/kernel/process.h

@@ -12,7 +12,7 @@
 
 typedef signed int    pid_t;
 typedef unsigned int  user_t;
-typedef unsigned char status_t;
+typedef unsigned int  status_t;
 
 #define USER_ROOT_UID (user_t)0
 

+ 2 - 0
base/usr/include/sys/wait.h

@@ -15,5 +15,7 @@
 #define WSTOPSIG    WEXITSTATUS
 
 
+#ifndef _KERNEL_
 extern pid_t wait(int*);
 extern pid_t waitpid(pid_t, int *, int);
+#endif

+ 1 - 2
kernel/sys/panic.c

@@ -26,8 +26,7 @@ void halt_and_catch_fire(char * error_message, const char * file, int line, stru
 		debug_print(ERROR, "User ESP:   0x%x",  regs->useresp);
 		debug_print(ERROR, "eip=0x%x",          regs->eip);
 	}
-	debug_print(ERROR, "This process has been descheduled.");
-	kexit(1);
+	send_signal(current_process->id, SIGILL);
 }
 
 char * probable_function_name(uintptr_t ip, uintptr_t * out_addr) {

+ 1 - 1
kernel/sys/signal.c

@@ -97,7 +97,7 @@ void handle_signal(process_t * proc, signal_t * sig) {
 		char dowhat = isdeadly[signum];
 		if (dowhat == 1 || dowhat == 2) {
 			debug_print(WARNING, "Process %d killed by unhandled signal (%d)", proc->id, signum);
-			kexit(128 + signum);
+			kexit(((128 + signum) << 8) | signum);
 			__builtin_unreachable();
 		} else {
 			debug_print(WARNING, "Ignoring signal %d by default in pid %d", signum, proc->id);

+ 1 - 1
kernel/sys/syscall.c

@@ -53,7 +53,7 @@ void validate(void * ptr) {
  */
 static int __attribute__((noreturn)) sys_exit(int retval) {
 	/* Deschedule the current task */
-	task_exit(retval);
+	task_exit((retval & 0xFF) << 8);
 	for (;;) ;
 }