mirror of
				https://gitlab.com/sortix/sortix.git
				synced 2023-02-13 20:55:38 -05:00 
			
		
		
		
	Initial signal support. Please squash improvements into this commit.
This commit is contained in:
		
							parent
							
								
									7a9afd66fe
								
							
						
					
					
						commit
						2b032b0414
					
				
					 25 changed files with 972 additions and 23 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -5,3 +5,4 @@
 | 
			
		|||
/*.so
 | 
			
		||||
/*.a
 | 
			
		||||
builds
 | 
			
		||||
sysroot
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										9
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,5 +1,11 @@
 | 
			
		|||
ifndef CPU
 | 
			
		||||
    CPU=x86
 | 
			
		||||
    MFLAGS:=CPU=$(CPU)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifndef SYSROOT
 | 
			
		||||
    SYSROOT:=$(shell pwd)/sysroot
 | 
			
		||||
    MFLAGS:=SYSROOT=$(SYSROOT)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
REMOTE=192.168.2.6
 | 
			
		||||
| 
						 | 
				
			
			@ -22,9 +28,10 @@ INITRD=sortix/sortix.initrd
 | 
			
		|||
all: $(INITRD)
 | 
			
		||||
 | 
			
		||||
suball:
 | 
			
		||||
	(for D in $(MODULES); do $(MAKE) all $(MFLAGS) --directory $$D || exit $?; done)
 | 
			
		||||
	(for D in $(MODULES); do ($(MAKE) all $(MFLAGS) --directory $$D && $(MAKE) install $(MFLAGS) --directory $$D) || exit $?; done)
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -rf $(SYSROOT)
 | 
			
		||||
	rm -f $(INITRD)
 | 
			
		||||
	rm -f initrd/*
 | 
			
		||||
	(for D in $(MODULES); do $(MAKE) clean $(MFLAGS) --directory $$D || exit $?; done)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,7 @@ c/h/sys/stat.h \
 | 
			
		|||
c/h/sys/types.h \
 | 
			
		||||
c/h/sys/wait.h \
 | 
			
		||||
c/h/stdio.h \
 | 
			
		||||
c/h/signal.h \
 | 
			
		||||
 | 
			
		||||
COMMONOBJS=c++.o memory.o string.o error.o format.o
 | 
			
		||||
SORTIXOBJS:=$(addprefix sortix/,$(COMMONOBJS))
 | 
			
		||||
| 
						 | 
				
			
			@ -56,10 +57,12 @@ process.o \
 | 
			
		|||
thread.o \
 | 
			
		||||
io.o \
 | 
			
		||||
init.o \
 | 
			
		||||
signal.o \
 | 
			
		||||
$(CPU)/signal.o \
 | 
			
		||||
start.o \
 | 
			
		||||
random.o \
 | 
			
		||||
 | 
			
		||||
HEADERS=\
 | 
			
		||||
MAXSIHEADERS=\
 | 
			
		||||
error.h \
 | 
			
		||||
io.h \
 | 
			
		||||
memory.h \
 | 
			
		||||
| 
						 | 
				
			
			@ -72,6 +75,8 @@ types.h \
 | 
			
		|||
format.h \
 | 
			
		||||
keyboard.h \
 | 
			
		||||
sortedlist.h \
 | 
			
		||||
signal.h \
 | 
			
		||||
signalnum.h \
 | 
			
		||||
sortix-vga.h \
 | 
			
		||||
sortix-keyboard.h \
 | 
			
		||||
sortix-sound.h \
 | 
			
		||||
| 
						 | 
				
			
			@ -100,7 +105,7 @@ ifndef LIBMAXSI_NO_LIBC
 | 
			
		|||
         BINS:=$(BINS) libc.a
 | 
			
		||||
    endif
 | 
			
		||||
 | 
			
		||||
    HEADERS:=$(HEADERS) $(CHEADERS)
 | 
			
		||||
    HEADERS:=$(MAXSIHEADERS) $(CHEADERS)
 | 
			
		||||
 | 
			
		||||
else
 | 
			
		||||
    DEFINES:=$(DEFINES) -DLIBMAXSI_NO_LIBC
 | 
			
		||||
| 
						 | 
				
			
			@ -173,3 +178,18 @@ sortix/%.o: sortix/%.cpp
 | 
			
		|||
clean:
 | 
			
		||||
	rm -f *.o sortix/*.o c/*.o x86/*.o x64/*.o *.a *.so $(CHEADERS) $(HEADERS)
 | 
			
		||||
 | 
			
		||||
# Installation into sysroot
 | 
			
		||||
install:
 | 
			
		||||
	mkdir -p $(SYSROOT)/usr/lib
 | 
			
		||||
	for F in $(BINS); do cp --preserve=links $$F $(SYSROOT)/usr/lib || exit $?; done
 | 
			
		||||
	mkdir -p $(SYSROOT)/usr/include
 | 
			
		||||
	for F in $(CHEADERS); do F=`echo $$F | sed 's/c\/h\///g'`; mkdir -p $(SYSROOT)/usr/include/`dirname $$F`; cp c/h/$$F $(SYSROOT)/usr/include/$$F || exit $?; done
 | 
			
		||||
	mkdir -p $(SYSROOT)/usr/include/libmaxsi
 | 
			
		||||
	for F in $(MAXSIHEADERS); do cp $$F $(SYSROOT)/usr/include/libmaxsi || exit $?; done
 | 
			
		||||
	cp start.o $(SYSROOT)/usr/lib/crt1.o
 | 
			
		||||
	touch deleteme.cpp
 | 
			
		||||
	g++ $(CPUFLAGS) -c deleteme.cpp -o deleteme.o
 | 
			
		||||
	for F in crt0.o crtn.o crtbegin.o crtend.o crtbeginT.o crti.o; do cp deleteme.o $(SYSROOT)/usr/lib/$$F; done
 | 
			
		||||
	for F in libgcc.so libm.so libstdc++.so; do ld $(CPULDFLAGS) -shared deleteme.o -o $(SYSROOT)/usr/lib/$$F; done
 | 
			
		||||
	rm -f deleteme.o deleteme.cpp
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										80
									
								
								libmaxsi/c/hsrc/signal.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								libmaxsi/c/hsrc/signal.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 | 
			
		||||
	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
 | 
			
		||||
 | 
			
		||||
	This file is part of LibMaxsi.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is free software: you can redistribute it and/or modify it under
 | 
			
		||||
	the terms of the GNU Lesser General Public License as published by the Free
 | 
			
		||||
	Software Foundation, either version 3 of the License, or (at your option)
 | 
			
		||||
	any later version.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
	FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
 | 
			
		||||
	more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
	along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
	signal.h
 | 
			
		||||
	Signals.
 | 
			
		||||
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
/* TODO: This does not fully implement POSIX 2008-1 yet! */
 | 
			
		||||
 | 
			
		||||
#ifndef	_SIGNAL_H
 | 
			
		||||
#define	_SIGNAL_H 1
 | 
			
		||||
 | 
			
		||||
#include <features.h>
 | 
			
		||||
 | 
			
		||||
__BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define SIGHUP		1 /* Hangup */
 | 
			
		||||
#define SIGINT		2 /* Interrupt */
 | 
			
		||||
#define SIGQUIT		3 /* Quit */
 | 
			
		||||
#define SIGILL		4 /* Illegal Instruction */
 | 
			
		||||
#define SIGTRAP		5 /* Trace/Breakpoint Trap */
 | 
			
		||||
#define SIGABRT		6 /* Abort */
 | 
			
		||||
#define SIGEMT		7 /* Emulation Trap */
 | 
			
		||||
#define SIGFPE		8 /* Arithmetic Exception */
 | 
			
		||||
#define SIGKILL		9 /* Killed */
 | 
			
		||||
#define SIGBUS		10 /* Bus Error */
 | 
			
		||||
#define SIGSEGV		11 /* Segmentation Fault */
 | 
			
		||||
#define SIGSYS		12 /* Bad System Call */
 | 
			
		||||
#define SIGPIPE		13 /* Broken Pipe */
 | 
			
		||||
#define SIGALRM		14 /* Alarm Clock */
 | 
			
		||||
#define SIGTERM		15 /* Terminated */
 | 
			
		||||
#define SIGUSR1		16 /* User Signal 1 */
 | 
			
		||||
#define SIGUSR2		17 /* User Signal 2 */
 | 
			
		||||
#define SIGCHLD		18 /* Child Status */
 | 
			
		||||
#define SIGPWR		19 /* Power Fail/Restart */
 | 
			
		||||
#define SIGWINCH	20 /* Window Size Change */
 | 
			
		||||
#define SIGURG		21 /* Urgent Socket Condition */
 | 
			
		||||
#define SIGSTOP		23 /* Stopped (signal) */
 | 
			
		||||
#define SIGTSTP		24 /* Stopped (user) */
 | 
			
		||||
#define SIGCONT		25 /* Continued */
 | 
			
		||||
#define SIGTTIN		26 /* Stopped (tty input) */
 | 
			
		||||
#define SIGTTOU		27 /* Stopped (tty output) */
 | 
			
		||||
#define SIGVTALRM	28 /* Virtual Timer Expired */
 | 
			
		||||
#define SIGXCPU		30 /* CPU time limit exceeded */
 | 
			
		||||
#define SIGXFSZ		31 /* File size limit exceeded */
 | 
			
		||||
#define SIGWAITING	32 /* All LWPs blocked */
 | 
			
		||||
#define SIGLWP		33 /* Virtual Interprocessor Interrupt for Threads Library */
 | 
			
		||||
#define SIGAIO		34 /* Asynchronous I/O */
 | 
			
		||||
 | 
			
		||||
@include(pid_t.h);
 | 
			
		||||
 | 
			
		||||
typedef void (*sighandler_t)(int);
 | 
			
		||||
 | 
			
		||||
void SIG_DFL(int signum);
 | 
			
		||||
void SIG_IGN(int signum);
 | 
			
		||||
void SIG_ERR(int signum);
 | 
			
		||||
 | 
			
		||||
sighandler_t signal(int signum, sighandler_t handler);
 | 
			
		||||
int kill(pid_t pid, int sig);
 | 
			
		||||
 | 
			
		||||
__END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -19,5 +19,6 @@
 | 
			
		|||
#define EIO 27
 | 
			
		||||
#define ENOEXEC 28
 | 
			
		||||
#define EACCESS 29
 | 
			
		||||
#define ESRCH 30
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,6 +62,7 @@ namespace Maxsi
 | 
			
		|||
				case EIO: return (char*) "Input/output error";
 | 
			
		||||
				case ENOEXEC: return (char*) "Not executable";
 | 
			
		||||
				case EACCESS: return (char*) "Permission denied";
 | 
			
		||||
				case ESRCH: return (char*) "No such process";
 | 
			
		||||
				default: return (char*) "Unknown error condition";
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										42
									
								
								libmaxsi/hsrc/signal.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								libmaxsi/hsrc/signal.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 | 
			
		||||
	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
 | 
			
		||||
 | 
			
		||||
	This file is part of LibMaxsi.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is free software: you can redistribute it and/or modify it under
 | 
			
		||||
	the terms of the GNU Lesser General Public License as published by the Free
 | 
			
		||||
	Software Foundation, either version 3 of the License, or (at your option)
 | 
			
		||||
	any later version.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
	FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
 | 
			
		||||
	more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
	along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
	signal.h
 | 
			
		||||
	Handles the good old unix signals.
 | 
			
		||||
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef LIBMAXSI_SIGNAL_H
 | 
			
		||||
#define LIBMAXSI_SIGNAL_H
 | 
			
		||||
 | 
			
		||||
#include "signalnum.h"
 | 
			
		||||
 | 
			
		||||
namespace Maxsi
 | 
			
		||||
{
 | 
			
		||||
	namespace Signal
 | 
			
		||||
	{
 | 
			
		||||
		typedef void (*Handler)(int);
 | 
			
		||||
 | 
			
		||||
		void Init();
 | 
			
		||||
		Handler RegisterHandler(int signum, Handler handler);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										71
									
								
								libmaxsi/hsrc/signalnum.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								libmaxsi/hsrc/signalnum.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 | 
			
		||||
	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
 | 
			
		||||
 | 
			
		||||
	This file is part of LibMaxsi.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is free software: you can redistribute it and/or modify it under
 | 
			
		||||
	the terms of the GNU Lesser General Public License as published by the Free
 | 
			
		||||
	Software Foundation, either version 3 of the License, or (at your option)
 | 
			
		||||
	any later version.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
	FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
 | 
			
		||||
	more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
	along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
	signalnum.h
 | 
			
		||||
	Declares the signal-related constants.
 | 
			
		||||
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef LIBMAXSI_SIGNALNUM_H
 | 
			
		||||
#define LIBMAXSI_SIGNALNUM_H
 | 
			
		||||
 | 
			
		||||
namespace Maxsi
 | 
			
		||||
{
 | 
			
		||||
	namespace Signal
 | 
			
		||||
	{
 | 
			
		||||
		const int HUP = 1; /* Hangup */
 | 
			
		||||
		const int INT = 2; /* Interrupt */
 | 
			
		||||
		const int QUIT = 3; /* Quit */
 | 
			
		||||
		const int ILL = 4; /* Illegal Instruction */
 | 
			
		||||
		const int TRAP = 5; /* Trace/Breakpoint Trap */
 | 
			
		||||
		const int ABRT = 6; /* Abort */
 | 
			
		||||
		const int EMT = 7; /* Emulation Trap */
 | 
			
		||||
		const int FPE = 8; /* Arithmetic Exception */
 | 
			
		||||
		const int KILL = 9; /* Killed */
 | 
			
		||||
		const int BUS = 10; /* Bus Error */
 | 
			
		||||
		const int SEGV = 11; /* Segmentation Fault */
 | 
			
		||||
		const int SYS = 12; /* Bad System Call */
 | 
			
		||||
		const int PIPE = 13; /* Broken Pipe */
 | 
			
		||||
		const int ALRM = 14; /* Alarm Clock */
 | 
			
		||||
		const int TERM = 15; /* Terminated */
 | 
			
		||||
		const int USR1 = 16; /* User Signal 1 */
 | 
			
		||||
		const int USR2 = 17; /* User Signal 2 */
 | 
			
		||||
		const int CHLD = 18; /* Child Status */
 | 
			
		||||
		const int PWR = 19; /* Power Fail/Restart */
 | 
			
		||||
		const int WINCH = 20; /* Window Size Change */
 | 
			
		||||
		const int URG = 21; /* Urgent Socket Condition */
 | 
			
		||||
		const int STOP = 23; /* Stopped (signal) */
 | 
			
		||||
		const int TSTP = 24; /* Stopped (user) */
 | 
			
		||||
		const int CONT = 25; /* Continued */
 | 
			
		||||
		const int TTIN = 26; /* Stopped (tty input) */
 | 
			
		||||
		const int TTOU = 27; /* Stopped (tty output) */
 | 
			
		||||
		const int VTALRM = 28; /* Virtual Timer Expired */
 | 
			
		||||
		const int XCPU = 30; /* CPU time limit exceeded */
 | 
			
		||||
		const int XFSZ = 31; /* File size limit exceeded */
 | 
			
		||||
		const int WAITING = 32; /* All LWPs blocked */
 | 
			
		||||
		const int LWP = 33; /* Virtual Interprocessor Interrupt for Threads Library */
 | 
			
		||||
		const int AIO = 34; /* Asynchronous I/O */
 | 
			
		||||
		const int NUMSIGNALS = 35;
 | 
			
		||||
 | 
			
		||||
		typedef void (*Handler)(int);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +24,7 @@
 | 
			
		|||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "signal.h"
 | 
			
		||||
 | 
			
		||||
namespace Maxsi
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -31,6 +32,10 @@ namespace Maxsi
 | 
			
		|||
 | 
			
		||||
	extern "C" void initialize_standard_library()
 | 
			
		||||
	{
 | 
			
		||||
		// Initialize stuff such as errno.
 | 
			
		||||
		init_error_functions();
 | 
			
		||||
 | 
			
		||||
		// It's probably best to initialize the Unix signals early on.
 | 
			
		||||
		Signal::Init();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										127
									
								
								libmaxsi/signal.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								libmaxsi/signal.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,127 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 | 
			
		||||
	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
 | 
			
		||||
 | 
			
		||||
	This file is part of LibMaxsi.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is free software: you can redistribute it and/or modify it under
 | 
			
		||||
	the terms of the GNU Lesser General Public License as published by the Free
 | 
			
		||||
	Software Foundation, either version 3 of the License, or (at your option)
 | 
			
		||||
	any later version.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
	FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
 | 
			
		||||
	more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
	along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
	signal.cpp
 | 
			
		||||
	Handles the good old unix signals.
 | 
			
		||||
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "string.h"
 | 
			
		||||
#include "memory.h"
 | 
			
		||||
#include "syscall.h"
 | 
			
		||||
#include "process.h"
 | 
			
		||||
#include "signal.h"
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
 | 
			
		||||
namespace Maxsi
 | 
			
		||||
{
 | 
			
		||||
	namespace Signal
 | 
			
		||||
	{
 | 
			
		||||
		void Core(int signum)
 | 
			
		||||
		{
 | 
			
		||||
			 Process::Exit(128 + signum);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		extern "C" void SIG_DFL(int signum)
 | 
			
		||||
		{
 | 
			
		||||
			if ( signum == Signal::HUP ) { Process::Exit(128 + signum); } else
 | 
			
		||||
			if ( signum == Signal::INT ) { Process::Exit(128 + signum); } else
 | 
			
		||||
			if ( signum == Signal::QUIT ) { Core(signum); } else
 | 
			
		||||
			if ( signum == Signal::TRAP ) { Core(signum); } else
 | 
			
		||||
			if ( signum == Signal::ABRT ) { Core(signum); } else
 | 
			
		||||
			if ( signum == Signal::EMT ) { Core(signum); } else
 | 
			
		||||
			if ( signum == Signal::FPE ) { Core(signum); } else
 | 
			
		||||
			if ( signum == Signal::KILL ) { Process::Exit(128 + signum); } else
 | 
			
		||||
			if ( signum == Signal::BUS ) { Core(signum); } else
 | 
			
		||||
			if ( signum == Signal::SEGV ) { Core(signum); } else
 | 
			
		||||
			if ( signum == Signal::SYS ) { Core(signum); } else
 | 
			
		||||
			if ( signum == Signal::PIPE ) { Process::Exit(128 + signum); } else
 | 
			
		||||
			if ( signum == Signal::ALRM ) { Process::Exit(128 + signum); } else
 | 
			
		||||
			if ( signum == Signal::TERM ) { Process::Exit(128 + signum); } else
 | 
			
		||||
			if ( signum == Signal::USR1 ) { Process::Exit(128 + signum); } else
 | 
			
		||||
			if ( signum == Signal::USR2 ) { Process::Exit(128 + signum); } else
 | 
			
		||||
			if ( signum == Signal::CHLD ) { /* Ignore this signal. */ } else
 | 
			
		||||
			if ( signum == Signal::PWR ) { /* Ignore this signal. */ } else
 | 
			
		||||
			if ( signum == Signal::WINCH ) { /* Ignore this signal. */ } else
 | 
			
		||||
			if ( signum == Signal::URG ) { /* Ignore this signal. */ } else
 | 
			
		||||
			if ( signum == Signal::CONT ) { /* Ignore this signal. */ } else
 | 
			
		||||
			if ( signum == Signal::VTALRM ) { /* Ignore this signal. */ } else
 | 
			
		||||
			if ( signum == Signal::XCPU ) { Core(signum); } else
 | 
			
		||||
			if ( signum == Signal::XFSZ ) { Core(signum); } else
 | 
			
		||||
			if ( signum == Signal::WAITING ) { /* Ignore this signal. */ } else
 | 
			
		||||
			if ( signum == Signal::LWP ) { /* Ignore this signal. */ } else
 | 
			
		||||
			if ( signum == Signal::AIO ) { /* Ignore this signal. */ } else
 | 
			
		||||
			{ /* Ignore this signal. */ }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		extern "C" void SIG_IGN(int /*signum*/)
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		extern "C" void SIG_ERR(int /*signum*/)
 | 
			
		||||
		{
 | 
			
		||||
			Process::Abort();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const int MAX_SIGNALS = 128;
 | 
			
		||||
		sighandler_t handlers[MAX_SIGNALS];
 | 
			
		||||
 | 
			
		||||
		extern "C" void SignalHandlerAssembly(int signum);
 | 
			
		||||
		extern "C" void SignalHandler(int signum)
 | 
			
		||||
		{
 | 
			
		||||
			if ( 0 <= signum && signum < (int) MAX_SIGNALS )
 | 
			
		||||
			{
 | 
			
		||||
				handlers[signum](signum);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		DEFN_SYSCALL1_VOID(SysRegisterSignalHandler, 29, sighandler_t);
 | 
			
		||||
		DEFN_SYSCALL0_VOID(SysSigReturn, 30);
 | 
			
		||||
		DEFN_SYSCALL2(int, SysKill, 31, pid_t, int);
 | 
			
		||||
 | 
			
		||||
		void Init()
 | 
			
		||||
		{
 | 
			
		||||
			for ( int i = 0; i < MAX_SIGNALS; i++ )
 | 
			
		||||
			{
 | 
			
		||||
				handlers[i] = SIG_DFL;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Tell the kernel which function we want called upon signals.
 | 
			
		||||
			SysRegisterSignalHandler(&SignalHandlerAssembly);
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
		Handler RegisterHandler(int signum, Handler handler)
 | 
			
		||||
		{
 | 
			
		||||
			if ( signum < 0 || MAX_SIGNALS <= signum ) { return SIG_ERR; }
 | 
			
		||||
			return handlers[signum] = handler;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		extern "C" sighandler_t signal(int signum, sighandler_t handler)
 | 
			
		||||
		{
 | 
			
		||||
			return RegisterHandler(signum, handler);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		extern "C" int kill(pid_t pid, int signum)
 | 
			
		||||
		{
 | 
			
		||||
			return SysKill(pid, signum);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								libmaxsi/x64/signal.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								libmaxsi/x64/signal.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 | 
			
		||||
	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
 | 
			
		||||
 | 
			
		||||
	This file is part of LibMaxsi.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is free software: you can redistribute it and/or modify it under
 | 
			
		||||
	the terms of the GNU Lesser General Public License as published by the Free
 | 
			
		||||
	Software Foundation, either version 3 of the License, or (at your option)
 | 
			
		||||
	any later version.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
	FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
 | 
			
		||||
	more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
	along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
	signal.s
 | 
			
		||||
	An assembly stub that for handling unix signals.
 | 
			
		||||
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
.globl SignalHandlerAssembly
 | 
			
		||||
 | 
			
		||||
.section .text
 | 
			
		||||
 | 
			
		||||
.type SignalHandlerAssembly, @function
 | 
			
		||||
SignalHandlerAssembly:
 | 
			
		||||
 | 
			
		||||
	# The kernel put the signal id in edi.
 | 
			
		||||
	call SignalHandler
 | 
			
		||||
 | 
			
		||||
	# Return control to the kernel, so normal computation can resume normally.
 | 
			
		||||
	movl $3, %eax
 | 
			
		||||
	int $0x80
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								libmaxsi/x86/signal.s
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								libmaxsi/x86/signal.s
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 | 
			
		||||
	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
 | 
			
		||||
 | 
			
		||||
	This file is part of LibMaxsi.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is free software: you can redistribute it and/or modify it under
 | 
			
		||||
	the terms of the GNU Lesser General Public License as published by the Free
 | 
			
		||||
	Software Foundation, either version 3 of the License, or (at your option)
 | 
			
		||||
	any later version.
 | 
			
		||||
 | 
			
		||||
	LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
	FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
 | 
			
		||||
	more details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
	along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
	signal.s
 | 
			
		||||
	An assembly stub that for handling unix signals.
 | 
			
		||||
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
.globl SignalHandlerAssembly
 | 
			
		||||
 | 
			
		||||
.section .text
 | 
			
		||||
 | 
			
		||||
.type SignalHandlerAssembly, @function
 | 
			
		||||
SignalHandlerAssembly:
 | 
			
		||||
 | 
			
		||||
	# The kernel put the signal id in edi.
 | 
			
		||||
	pushl %edi
 | 
			
		||||
	call SignalHandler
 | 
			
		||||
 | 
			
		||||
	# Restore the stack as it was.
 | 
			
		||||
	addl $4, %esp
 | 
			
		||||
 | 
			
		||||
	# Now that the stack is intact, return control to the kernel, so normal
 | 
			
		||||
	# computation can resume normally.
 | 
			
		||||
	movl $30, %eax # SysSigReturn
 | 
			
		||||
	int $0x80
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -11,3 +11,5 @@ all: $(BINARIES)
 | 
			
		|||
clean:
 | 
			
		||||
	rm -f $(BINARIES)
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,10 +74,11 @@ pipe.o \
 | 
			
		|||
filesystem.o \
 | 
			
		||||
directory.o \
 | 
			
		||||
mount.o \
 | 
			
		||||
signal.o \
 | 
			
		||||
fs/devfs.o \
 | 
			
		||||
fs/initfs.o \
 | 
			
		||||
fs/ramfs.o \
 | 
			
		||||
../libmaxsi/libmaxsi-sortix.a
 | 
			
		||||
../libmaxsi/libmaxsi-sortix.a \
 | 
			
		||||
 | 
			
		||||
JSOBJS:=$(subst .o,-js.o,$(OBJS))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,20 +128,8 @@ sortix.bin: sortix-$(BUILDID).tmp
 | 
			
		|||
clean:
 | 
			
		||||
	for D in $(DIRS); do rm -fv $$D/*.o $$D/*.bin $$D/*.out $$D/*.tmp; done
 | 
			
		||||
 | 
			
		||||
# Local machine
 | 
			
		||||
# Installation into sysroot
 | 
			
		||||
install:
 | 
			
		||||
	mkdir -p $(SYSROOT)/usr/include/sortix
 | 
			
		||||
	cp $(CPU)/bits.h $(SYSROOT)/usr/include/sortix/bits.h
 | 
			
		||||
 | 
			
		||||
install: sortix.bin
 | 
			
		||||
	cp sortix.bin /boot
 | 
			
		||||
 | 
			
		||||
uninstall:
 | 
			
		||||
	rm -f /boot/sortix.bin
 | 
			
		||||
 | 
			
		||||
# Remote machine
 | 
			
		||||
 | 
			
		||||
install-remote: sortix.bin
 | 
			
		||||
	scp -r ./ 192.168.2.6:/home/sortie/Desktop/sortix	
 | 
			
		||||
	scp sortix.bin root@192.168.2.6:/boot
 | 
			
		||||
	ssh root@192.168.2.6 "init 6"
 | 
			
		||||
 | 
			
		||||
uninstall-remote:
 | 
			
		||||
	ssh root@192.168.2.6 "rm /boot/sortix.bin"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -241,6 +241,9 @@ namespace Sortix
 | 
			
		|||
		// Initialize the process system.
 | 
			
		||||
		Process::Init();
 | 
			
		||||
 | 
			
		||||
		// Initialize the thread system.
 | 
			
		||||
		Thread::Init();
 | 
			
		||||
 | 
			
		||||
		// Initialize the IO system.
 | 
			
		||||
		IO::Init();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -153,7 +153,7 @@ namespace Sortix
 | 
			
		|||
			if ( clonesegments == NULL ) { delete clone; return NULL; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Fork address-space here and copy memory somehow.
 | 
			
		||||
		// Fork address-space here and copy memory.
 | 
			
		||||
		clone->addrspace = Memory::Fork();
 | 
			
		||||
		if ( !clone->addrspace )
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -132,6 +132,8 @@ namespace Sortix
 | 
			
		|||
			Memory::SwitchAddressSpace(newaddrspace);
 | 
			
		||||
			currentthread = nextthread;
 | 
			
		||||
 | 
			
		||||
			nextthread->HandleSignal(regs);
 | 
			
		||||
 | 
			
		||||
			LogEndContextSwitch(currentthread, regs);
 | 
			
		||||
 | 
			
		||||
			if ( currentthread->scfunc ) { Syscall::Resume(regs); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										244
									
								
								sortix/signal.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								sortix/signal.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,244 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 | 
			
		||||
	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
 | 
			
		||||
 | 
			
		||||
	This file is part of Sortix.
 | 
			
		||||
 | 
			
		||||
	Sortix is free software: you can redistribute it and/or modify it under the
 | 
			
		||||
	terms of the GNU General Public License as published by the Free Software
 | 
			
		||||
	Foundation, either version 3 of the License, or (at your option) any later
 | 
			
		||||
	version.
 | 
			
		||||
 | 
			
		||||
	Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 | 
			
		||||
	details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU General Public License along
 | 
			
		||||
	with Sortix. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
	signal.cpp
 | 
			
		||||
	Classes and functions making it easier to handle Unix signals.
 | 
			
		||||
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include <libmaxsi/memory.h>
 | 
			
		||||
#include "panic.h"
 | 
			
		||||
#include "signal.h"
 | 
			
		||||
 | 
			
		||||
using namespace Maxsi;
 | 
			
		||||
 | 
			
		||||
namespace Sortix
 | 
			
		||||
{
 | 
			
		||||
	const int PRIORITY_NORMAL = 0;
 | 
			
		||||
	const int PRIORITY_HIGH = 1;
 | 
			
		||||
	const int PRIORITY_STOP = 2;
 | 
			
		||||
	const int PRIORITY_CORE = 3;
 | 
			
		||||
	const int PRIORITY_KILL = 4;
 | 
			
		||||
 | 
			
		||||
	const int PRIORITIES[Maxsi::Signal::NUMSIGNALS] =
 | 
			
		||||
	{
 | 
			
		||||
		PRIORITY_NORMAL, // unused
 | 
			
		||||
		PRIORITY_NORMAL, // SIGHUP
 | 
			
		||||
		PRIORITY_NORMAL, // SIGINT
 | 
			
		||||
		PRIORITY_NORMAL, // SIGQUIT
 | 
			
		||||
		PRIORITY_CORE, // SIGILL
 | 
			
		||||
		PRIORITY_CORE, // SIGTRAP
 | 
			
		||||
		PRIORITY_CORE, // SIGABRT
 | 
			
		||||
		PRIORITY_CORE, // SIGEMT
 | 
			
		||||
		PRIORITY_CORE, // SIGFPE
 | 
			
		||||
		PRIORITY_KILL, // SIGKILL
 | 
			
		||||
		PRIORITY_CORE, // SIGBUS
 | 
			
		||||
		PRIORITY_CORE, // SIGSEGV
 | 
			
		||||
		PRIORITY_CORE, // SIGSYS
 | 
			
		||||
		PRIORITY_NORMAL, // SIGPIPE
 | 
			
		||||
		PRIORITY_NORMAL, // SIGALRM
 | 
			
		||||
		PRIORITY_NORMAL, // SIGTERM
 | 
			
		||||
		PRIORITY_NORMAL, // SIGUSR1
 | 
			
		||||
		PRIORITY_NORMAL, // SIGUSR2
 | 
			
		||||
		PRIORITY_NORMAL, // SIGCHLD
 | 
			
		||||
		PRIORITY_HIGH, // SIGPWR
 | 
			
		||||
		PRIORITY_NORMAL, // SIGWINCH
 | 
			
		||||
		PRIORITY_NORMAL, // SIGURG
 | 
			
		||||
		PRIORITY_NORMAL, // obsolete
 | 
			
		||||
		PRIORITY_STOP, // SIGSTOP
 | 
			
		||||
		PRIORITY_STOP, // SIGTSTP
 | 
			
		||||
		PRIORITY_STOP, // SIGCONT
 | 
			
		||||
		PRIORITY_STOP, // SIGTTIN
 | 
			
		||||
		PRIORITY_STOP, // SIGTTOU
 | 
			
		||||
		PRIORITY_NORMAL, // SIGVTALRM
 | 
			
		||||
		PRIORITY_NORMAL, // obsolete
 | 
			
		||||
		PRIORITY_CORE, // SIGXCPU
 | 
			
		||||
		PRIORITY_CORE, // SIGXFSZ
 | 
			
		||||
		PRIORITY_NORMAL, // SIGCORE
 | 
			
		||||
		PRIORITY_NORMAL, // SIGLWP
 | 
			
		||||
		PRIORITY_NORMAL, // SIGAIO
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// Returns true of the exact ordering of this signal version others aren't
 | 
			
		||||
	// important - if it returns false, then this signal will be put in the
 | 
			
		||||
	// queue according to priority, instead of being merged into another signal
 | 
			
		||||
	// with the same signum.
 | 
			
		||||
	bool Unifiable(int /*signum*/)
 | 
			
		||||
	{
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Returns whether a specific signal is more important to deliver than
 | 
			
		||||
	// another. This is used to schedule signals.
 | 
			
		||||
	int CompareSignalPriority(int siga, int sigb)
 | 
			
		||||
	{
 | 
			
		||||
		int prioa = PRIORITY_NORMAL;
 | 
			
		||||
		int priob = PRIORITY_NORMAL;
 | 
			
		||||
 | 
			
		||||
		if ( siga < Maxsi::Signal::NUMSIGNALS ) { prioa = PRIORITIES[siga]; }
 | 
			
		||||
		if ( sigb < Maxsi::Signal::NUMSIGNALS ) { priob = PRIORITIES[sigb]; }
 | 
			
		||||
 | 
			
		||||
		if ( prioa < priob ) { return -1; } else
 | 
			
		||||
		if ( prioa > priob ) { return 1; }
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SignalQueue::SignalQueue()
 | 
			
		||||
	{
 | 
			
		||||
		queue = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SignalQueue::~SignalQueue()
 | 
			
		||||
	{
 | 
			
		||||
		while ( queue )
 | 
			
		||||
		{
 | 
			
		||||
			Signal* todelete = queue;
 | 
			
		||||
			queue = queue->nextsignal;
 | 
			
		||||
			delete todelete;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Queues the signal and schedules it for processing.
 | 
			
		||||
	bool SignalQueue::Push(int signum)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(0 <= signum && signum < 128);
 | 
			
		||||
 | 
			
		||||
		if ( Unifiable(signum) )
 | 
			
		||||
		{
 | 
			
		||||
			for ( Signal* signal = queue; signal != NULL; signal = signal->nextsignal )
 | 
			
		||||
			{
 | 
			
		||||
				if ( signal->signum != signum ) { continue; }
 | 
			
		||||
 | 
			
		||||
				signal->numpending++;
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Signal* signal = new Signal;
 | 
			
		||||
		if ( !signal ) { return false; }
 | 
			
		||||
 | 
			
		||||
		signal->signum = signum;
 | 
			
		||||
		signal->numpending = 1;
 | 
			
		||||
		signal->nextsignal = NULL;
 | 
			
		||||
		signal->returncode = 128 + signum;
 | 
			
		||||
 | 
			
		||||
		Insert(signal);
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Insert the signal in O(N), which is pretty fast for small Ns.
 | 
			
		||||
	void SignalQueue::Insert(Signal* signal)
 | 
			
		||||
	{
 | 
			
		||||
		if ( !queue )
 | 
			
		||||
		{
 | 
			
		||||
			queue = signal;
 | 
			
		||||
			last = signal;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If the signal is to be inserted last, then just do it quickly.
 | 
			
		||||
		if ( last != NULL && 0 <= CompareSignalPriority(last->signum, signal->signum) )
 | 
			
		||||
		{
 | 
			
		||||
			last->nextsignal = signal;
 | 
			
		||||
			signal->nextsignal = NULL;
 | 
			
		||||
			last = signal;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Check if the signal should be inserted first.
 | 
			
		||||
		if ( queue != NULL && CompareSignalPriority(queue->signum, signal->signum) < 0 )
 | 
			
		||||
		{
 | 
			
		||||
			signal->nextsignal = queue;
 | 
			
		||||
			queue = signal;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Find where the signal should be inserted.
 | 
			
		||||
		for ( Signal* tmp = queue; tmp != NULL; tmp = tmp->nextsignal )
 | 
			
		||||
		{
 | 
			
		||||
			Signal* next = tmp->nextsignal;
 | 
			
		||||
 | 
			
		||||
			if ( next != NULL && CompareSignalPriority(next->signum, signal->signum) < 0 )
 | 
			
		||||
			{
 | 
			
		||||
				tmp->nextsignal = signal;
 | 
			
		||||
				signal->nextsignal = next;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if ( next == NULL )
 | 
			
		||||
			{
 | 
			
		||||
				tmp->nextsignal = signal;
 | 
			
		||||
				signal->nextsignal = NULL;
 | 
			
		||||
				last = signal;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Given the stack of currently processing signals, return a new signal if
 | 
			
		||||
	// it is more important to handle at this point.
 | 
			
		||||
	Signal* SignalQueue::Pop(Signal* current)
 | 
			
		||||
	{
 | 
			
		||||
		if ( queue == NULL ) { return NULL; }
 | 
			
		||||
 | 
			
		||||
		bool returnqueue = false;
 | 
			
		||||
 | 
			
		||||
		// If we are currently handling no signal, then just return the first.
 | 
			
		||||
		if ( current == NULL ) { returnqueue = true; }
 | 
			
		||||
 | 
			
		||||
		// If we are handling a signal, only override it with another if it is
 | 
			
		||||
		// more important.
 | 
			
		||||
		else if ( CompareSignalPriority(current->signum, queue->signum) < 0 )
 | 
			
		||||
		{
 | 
			
		||||
			returnqueue = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( returnqueue )
 | 
			
		||||
		{
 | 
			
		||||
			Signal* result = queue;
 | 
			
		||||
			queue = queue->nextsignal;
 | 
			
		||||
			result->nextsignal = NULL;
 | 
			
		||||
			return result;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Signal* Signal::Fork()
 | 
			
		||||
	{
 | 
			
		||||
		Signal* clone = new Signal();
 | 
			
		||||
		if ( !clone ) { return NULL; }
 | 
			
		||||
 | 
			
		||||
		Memory::Copy(clone, this, sizeof(Signal));
 | 
			
		||||
 | 
			
		||||
		Signal* nextsignalclone = NULL;
 | 
			
		||||
		if ( nextsignal )
 | 
			
		||||
		{
 | 
			
		||||
			nextsignalclone = nextsignal->Fork();
 | 
			
		||||
			if ( !nextsignalclone ) { delete clone; return NULL; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		clone->nextsignal = nextsignalclone;
 | 
			
		||||
 | 
			
		||||
		return clone;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										99
									
								
								sortix/signal.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								sortix/signal.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,99 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 | 
			
		||||
	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
 | 
			
		||||
 | 
			
		||||
	This file is part of Sortix.
 | 
			
		||||
 | 
			
		||||
	Sortix is free software: you can redistribute it and/or modify it under the
 | 
			
		||||
	terms of the GNU General Public License as published by the Free Software
 | 
			
		||||
	Foundation, either version 3 of the License, or (at your option) any later
 | 
			
		||||
	version.
 | 
			
		||||
 | 
			
		||||
	Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 | 
			
		||||
	details.
 | 
			
		||||
 | 
			
		||||
	You should have received a copy of the GNU General Public License along
 | 
			
		||||
	with Sortix. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
	signal.h
 | 
			
		||||
	Classes and functions making it easier to handle Unix signals.
 | 
			
		||||
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef SORTIX_SIGNAL_H
 | 
			
		||||
#define SORTIX_SIGNAL_H
 | 
			
		||||
 | 
			
		||||
#include <libmaxsi/signalnum.h>
 | 
			
		||||
 | 
			
		||||
namespace Sortix
 | 
			
		||||
{
 | 
			
		||||
	#define SIGHUP		1 /* Hangup */
 | 
			
		||||
	#define SIGINT		2 /* Interrupt */
 | 
			
		||||
	#define SIGQUIT		3 /* Quit */
 | 
			
		||||
	#define SIGILL		4 /* Illegal Instruction */
 | 
			
		||||
	#define SIGTRAP		5 /* Trace/Breakpoint Trap */
 | 
			
		||||
	#define SIGABRT		6 /* Abort */
 | 
			
		||||
	#define SIGEMT		7 /* Emulation Trap */
 | 
			
		||||
	#define SIGFPE		8 /* Arithmetic Exception */
 | 
			
		||||
	#define SIGKILL		9 /* Killed */
 | 
			
		||||
	#define SIGBUS		10 /* Bus Error */
 | 
			
		||||
	#define SIGSEGV		11 /* Segmentation Fault */
 | 
			
		||||
	#define SIGSYS		12 /* Bad System Call */
 | 
			
		||||
	#define SIGPIPE		13 /* Broken Pipe */
 | 
			
		||||
	#define SIGALRM		14 /* Alarm Clock */
 | 
			
		||||
	#define SIGTERM		15 /* Terminated */
 | 
			
		||||
	#define SIGUSR1		16 /* User Signal 1 */
 | 
			
		||||
	#define SIGUSR2		17 /* User Signal 2 */
 | 
			
		||||
	#define SIGCHLD		18 /* Child Status */
 | 
			
		||||
	#define SIGPWR		19 /* Power Fail/Restart */
 | 
			
		||||
	#define SIGWINCH	20 /* Window Size Change */
 | 
			
		||||
	#define SIGURG		21 /* Urgent Socket Condition */
 | 
			
		||||
	#define SIGSTOP		23 /* Stopped (signal) */
 | 
			
		||||
	#define SIGTSTP		24 /* Stopped (user) */
 | 
			
		||||
	#define SIGCONT		25 /* Continued */
 | 
			
		||||
	#define SIGTTIN		26 /* Stopped (tty input) */
 | 
			
		||||
	#define SIGTTOU		27 /* Stopped (tty output) */
 | 
			
		||||
	#define SIGVTALRM	28 /* Virtual Timer Expired */
 | 
			
		||||
	#define SIGXCPU		30 /* CPU time limit exceeded */
 | 
			
		||||
	#define SIGXFSZ		31 /* File size limit exceeded */
 | 
			
		||||
	#define SIGWAITING	32 /* All LWPs blocked */
 | 
			
		||||
	#define SIGLWP		33 /* Virtual Interprocessor Interrupt for Threads Library */
 | 
			
		||||
	#define SIGAIO		34 /* Asynchronous I/O */
 | 
			
		||||
 | 
			
		||||
	struct Signal
 | 
			
		||||
	{
 | 
			
		||||
		int signum;
 | 
			
		||||
		int returncode;
 | 
			
		||||
		unsigned numpending;
 | 
			
		||||
		CPU::InterruptRegisters regs;
 | 
			
		||||
		Signal* nextsignal;
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		Signal* Fork();
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	class SignalQueue
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		SignalQueue();
 | 
			
		||||
		~SignalQueue();
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Signal* queue;
 | 
			
		||||
		Signal* last;
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		bool Push(int signum);
 | 
			
		||||
		Signal* Pop(Signal* current);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		void Insert(Signal* signal);
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +54,10 @@
 | 
			
		|||
#define SYSCALL_GETCWD 26
 | 
			
		||||
#define SYSCALL_UNLINK 27
 | 
			
		||||
#define SYSCALL_REGISTER_ERRNO 28
 | 
			
		||||
#define SYSCALL_MAX_NUM 29 /* index of highest constant + 1 */
 | 
			
		||||
#define SYSCALL_REGISTER_SIGNAL_HANDLER 29
 | 
			
		||||
#define SYSCALL_SIGRETURN 30
 | 
			
		||||
#define SYSCALL_KILL 31
 | 
			
		||||
#define SYSCALL_MAX_NUM 32 /* index of highest constant + 1 */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,12 +23,16 @@
 | 
			
		|||
******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include <libmaxsi/error.h>
 | 
			
		||||
#include <libmaxsi/memory.h>
 | 
			
		||||
#include "process.h"
 | 
			
		||||
#include "thread.h"
 | 
			
		||||
#include "scheduler.h"
 | 
			
		||||
#include "memorymanagement.h"
 | 
			
		||||
#include "time.h"
 | 
			
		||||
#include "syscall.h"
 | 
			
		||||
 | 
			
		||||
using namespace Maxsi;
 | 
			
		||||
 | 
			
		||||
namespace Sortix
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +50,8 @@ namespace Sortix
 | 
			
		|||
		Maxsi::Memory::Set(®isters, 0, sizeof(registers));
 | 
			
		||||
		ready = false;
 | 
			
		||||
		scfunc = NULL;
 | 
			
		||||
		currentsignal = NULL;
 | 
			
		||||
		sighandler = NULL;
 | 
			
		||||
		ResetCallbacks();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +71,7 @@ namespace Sortix
 | 
			
		|||
		schedulerlistprev = NULL;
 | 
			
		||||
		schedulerlistnext = NULL;
 | 
			
		||||
		scfunc = NULL;
 | 
			
		||||
		sighandler = forkfrom->sighandler;
 | 
			
		||||
		ResetCallbacks();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -78,6 +85,14 @@ namespace Sortix
 | 
			
		|||
		ASSERT(CurrentProcess() == process);
 | 
			
		||||
		ASSERT(nextsleepingthread == NULL);
 | 
			
		||||
 | 
			
		||||
		// Delete information about signals being processed.
 | 
			
		||||
		while ( currentsignal )
 | 
			
		||||
		{
 | 
			
		||||
			Signal* todelete = currentsignal;
 | 
			
		||||
			currentsignal = currentsignal->nextsignal;
 | 
			
		||||
			delete todelete;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Memory::UnmapRangeUser(stackpos, stacksize);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -85,8 +100,26 @@ namespace Sortix
 | 
			
		|||
	{
 | 
			
		||||
		ASSERT(ready);
 | 
			
		||||
 | 
			
		||||
		Signal* clonesignal = NULL;
 | 
			
		||||
		if ( currentsignal )
 | 
			
		||||
		{
 | 
			
		||||
			clonesignal = currentsignal->Fork();
 | 
			
		||||
			if ( !clonesignal ) { return NULL; }
 | 
			
		||||
		} 
 | 
			
		||||
 | 
			
		||||
		Thread* clone = new Thread(this);
 | 
			
		||||
		if ( !clone ) { return NULL; }
 | 
			
		||||
		if ( !clone )
 | 
			
		||||
		{
 | 
			
		||||
			while ( clonesignal )
 | 
			
		||||
			{
 | 
			
		||||
				Signal* todelete = clonesignal;
 | 
			
		||||
				clonesignal = clonesignal->nextsignal;
 | 
			
		||||
				delete todelete;
 | 
			
		||||
			}
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		clone->currentsignal = clonesignal;
 | 
			
		||||
 | 
			
		||||
		return clone;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -154,4 +187,83 @@ namespace Sortix
 | 
			
		|||
			Scheduler::SetThreadState(this, State::RUNNABLE);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void Thread::HandleSignal(CPU::InterruptRegisters* regs)
 | 
			
		||||
	{
 | 
			
		||||
		Signal* override = signalqueue.Pop(currentsignal);
 | 
			
		||||
		if ( !override ) { return; }
 | 
			
		||||
		if ( !sighandler ) { delete override; return; }
 | 
			
		||||
 | 
			
		||||
		if ( override->signum == SIGKILL )
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		override->nextsignal = currentsignal;
 | 
			
		||||
		Maxsi::Memory::Copy(&override->regs, regs, sizeof(override->regs));
 | 
			
		||||
		currentsignal = override;
 | 
			
		||||
 | 
			
		||||
		HandleSignalCPU(regs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void SysSigReturn()
 | 
			
		||||
	{
 | 
			
		||||
		Thread* thread = CurrentThread();
 | 
			
		||||
		if ( !thread->currentsignal ) { return; }
 | 
			
		||||
 | 
			
		||||
		CPU::InterruptRegisters* dest = Syscall::InterruptRegs();
 | 
			
		||||
		CPU::InterruptRegisters* src = &thread->currentsignal->regs;
 | 
			
		||||
		
 | 
			
		||||
		Maxsi::Memory::Copy(dest, src, sizeof(CPU::InterruptRegisters));
 | 
			
		||||
		thread->currentsignal = thread->currentsignal->nextsignal;
 | 
			
		||||
		Syscall::AsIs();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void SysRegisterSignalHandler(sighandler_t sighandler)
 | 
			
		||||
	{
 | 
			
		||||
		CurrentThread()->sighandler = sighandler;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int SysKill(pid_t pid, int signum)
 | 
			
		||||
	{
 | 
			
		||||
		if ( signum < 0 || 128 <= signum ) { Error::Set(EINVAL); return -1; }
 | 
			
		||||
 | 
			
		||||
		// Protect the system idle process.
 | 
			
		||||
		if ( pid == 0 ) { Error::Set(EPERM); return -1; }
 | 
			
		||||
 | 
			
		||||
		Process* process = Process::Get(pid);
 | 
			
		||||
		if ( !process ) { Error::Set(ESRCH); return -1; }
 | 
			
		||||
 | 
			
		||||
		// TODO: Protect init?
 | 
			
		||||
		// TODO: Check for permission.
 | 
			
		||||
		// TODO: Check for zombies.
 | 
			
		||||
 | 
			
		||||
		Thread* currentthread = CurrentThread();
 | 
			
		||||
		Thread* thread = NULL;
 | 
			
		||||
		if ( currentthread->process->pid == pid ) { thread = currentthread; }
 | 
			
		||||
		if ( !thread ) { thread = process->firstthread; }
 | 
			
		||||
		if ( !thread ) { Error::Set(ESRCH); return -1; /* TODO: Zombie? */ }
 | 
			
		||||
 | 
			
		||||
		// TODO: If thread is not runnable, wake it and runs its handler?
 | 
			
		||||
		if ( !thread->signalqueue.Push(signum) )
 | 
			
		||||
		{
 | 
			
		||||
			// TODO: Possibly kill the process?
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( thread == currentthread )
 | 
			
		||||
		{
 | 
			
		||||
			Syscall::SyscallRegs()->result = 0;
 | 
			
		||||
			thread->HandleSignal(Syscall::InterruptRegs());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void Thread::Init()
 | 
			
		||||
	{
 | 
			
		||||
		Syscall::Register(SYSCALL_KILL, (void*) SysKill);
 | 
			
		||||
		Syscall::Register(SYSCALL_REGISTER_SIGNAL_HANDLER, (void*) SysRegisterSignalHandler);
 | 
			
		||||
		Syscall::Register(SYSCALL_SIGRETURN, (void*) SysSigReturn);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,8 @@
 | 
			
		|||
#ifndef SORTIX_THREAD_H
 | 
			
		||||
#define SORTIX_THREAD_H
 | 
			
		||||
 | 
			
		||||
#include "signal.h"
 | 
			
		||||
 | 
			
		||||
namespace Sortix
 | 
			
		||||
{
 | 
			
		||||
	class Process;
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +36,8 @@ namespace Sortix
 | 
			
		|||
	Thread* CreateThread(addr_t entry, size_t stacksize = 0);
 | 
			
		||||
	Thread* CurrentThread();
 | 
			
		||||
 | 
			
		||||
	typedef void (*sighandler_t)(int);
 | 
			
		||||
 | 
			
		||||
	class Thread
 | 
			
		||||
	{
 | 
			
		||||
	friend Thread* CreateThread(addr_t entry, size_t stacksize);
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +45,9 @@ namespace Sortix
 | 
			
		|||
	public:
 | 
			
		||||
		enum State { NONE, RUNNABLE, BLOCKING };
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		static void Init();
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Thread();
 | 
			
		||||
		Thread(const Thread* forkfrom);
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +74,9 @@ namespace Sortix
 | 
			
		|||
	public:
 | 
			
		||||
		addr_t stackpos;
 | 
			
		||||
		size_t stacksize;
 | 
			
		||||
		Signal* currentsignal;
 | 
			
		||||
		SignalQueue signalqueue;
 | 
			
		||||
		sighandler_t sighandler;
 | 
			
		||||
 | 
			
		||||
	// After being created/forked, a thread is not inserted into the scheduler.
 | 
			
		||||
	// Whenever the thread has been safely established within a process, then
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +94,10 @@ namespace Sortix
 | 
			
		|||
		Thread* Fork();
 | 
			
		||||
		void SaveRegisters(const CPU::InterruptRegisters* src);
 | 
			
		||||
		void LoadRegisters(CPU::InterruptRegisters* dest);
 | 
			
		||||
		void HandleSignal(CPU::InterruptRegisters* regs);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		void HandleSignalCPU(CPU::InterruptRegisters* regs);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		void* scfunc;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -106,4 +106,10 @@ namespace Sortix
 | 
			
		|||
 | 
			
		||||
		thread->SaveRegisters(®s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void Thread::HandleSignalCPU(CPU::InterruptRegisters* regs)
 | 
			
		||||
	{
 | 
			
		||||
		regs->edi = currentsignal->signum;
 | 
			
		||||
		regs->eip = (size_t) sighandler;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,7 @@ help \
 | 
			
		|||
uname \
 | 
			
		||||
idle \
 | 
			
		||||
editor \
 | 
			
		||||
kill \
 | 
			
		||||
 | 
			
		||||
BINARIES:=$(addprefix $(INITRDDIR)/,$(LOCALBINARIES))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										38
									
								
								utils/kill.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								utils/kill.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
int usage()
 | 
			
		||||
{
 | 
			
		||||
	printf("usage: kill [-n] pid ...\n");
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char* argv[])
 | 
			
		||||
{
 | 
			
		||||
	if ( argc < 2 ) { return usage(); }
 | 
			
		||||
 | 
			
		||||
	int first = 1;
 | 
			
		||||
	int signum = SIGTERM;
 | 
			
		||||
	if ( argv[1][0] == '-' )
 | 
			
		||||
	{
 | 
			
		||||
		signum = atoi(argv[first++]);
 | 
			
		||||
		if ( argc < 3 ) { return usage(); }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int result = 0;
 | 
			
		||||
 | 
			
		||||
	for ( int i = first; i < argc; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		pid_t pid = atoi(argv[i]);
 | 
			
		||||
		if ( kill(pid, signum) )
 | 
			
		||||
		{
 | 
			
		||||
			printf("kill: (%u): %s\n", pid, strerror(errno));
 | 
			
		||||
			result |= 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue