os: add support for signal handling on JS backend (#12818)
							parent
							
								
									d5c0bdf954
								
							
						
					
					
						commit
						cb4c67588c
					
				|  | @ -136,3 +136,7 @@ pub fn getuid() int { | ||||||
| pub fn execvp(cmd string, args []string) ? { | pub fn execvp(cmd string, args []string) ? { | ||||||
| 	panic('os.execvp() is not available on JS backend') | 	panic('os.execvp() is not available on JS backend') | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | pub fn stdin_resume() { | ||||||
|  | 	#$process.stdin.resume(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -94,6 +94,10 @@ pub fn (mut p Process) stdin_write(s string) { | ||||||
| 	#p.val.pid.stdin.write(s) | 	#p.val.pid.stdin.write(s) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pub fn (mut p Process) stdin_resume() { | ||||||
|  | 	#p.val.pid.stdin.resume() | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // todo(playX): probably does not work
 | // todo(playX): probably does not work
 | ||||||
| 
 | 
 | ||||||
| // will read from stdout pipe, will only return when EOF (end of file) or data
 | // will read from stdout pipe, will only return when EOF (end of file) or data
 | ||||||
|  |  | ||||||
|  | @ -2,48 +2,6 @@ module os | ||||||
| 
 | 
 | ||||||
| #include <signal.h> | #include <signal.h> | ||||||
| 
 | 
 | ||||||
| // os.Signal - enumerate possible POSIX signals and
 |  | ||||||
| // their integer codes.
 |  | ||||||
| // NB: the integer codes are given here explicitly,
 |  | ||||||
| // to make it easier to lookup, without needing to
 |  | ||||||
| // consult man pages / signal.h .
 |  | ||||||
| 
 |  | ||||||
| pub enum Signal { |  | ||||||
| 	hup = 1 |  | ||||||
| 	int = 2 |  | ||||||
| 	quit = 3 |  | ||||||
| 	ill = 4 |  | ||||||
| 	trap = 5 |  | ||||||
| 	abrt = 6 |  | ||||||
| 	bus = 7 |  | ||||||
| 	fpe = 8 |  | ||||||
| 	kill = 9 |  | ||||||
| 	usr1 = 10 |  | ||||||
| 	segv = 11 |  | ||||||
| 	usr2 = 12 |  | ||||||
| 	pipe = 13 |  | ||||||
| 	alrm = 14 |  | ||||||
| 	term = 15 |  | ||||||
| 	stkflt = 16 |  | ||||||
| 	chld = 17 |  | ||||||
| 	cont = 18 |  | ||||||
| 	stop = 19 |  | ||||||
| 	tstp = 20 |  | ||||||
| 	ttin = 21 |  | ||||||
| 	ttou = 22 |  | ||||||
| 	urg = 23 |  | ||||||
| 	xcpu = 24 |  | ||||||
| 	xfsz = 25 |  | ||||||
| 	vtalrm = 26 |  | ||||||
| 	prof = 27 |  | ||||||
| 	winch = 28 |  | ||||||
| 	poll = 29 |  | ||||||
| 	pwr = 30 |  | ||||||
| 	sys = 31 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type SignalHandler = fn (Signal) |  | ||||||
| 
 |  | ||||||
| fn C.signal(signal int, handlercb SignalHandler) voidptr | fn C.signal(signal int, handlercb SignalHandler) voidptr | ||||||
| 
 | 
 | ||||||
| // signal will assign `handler` callback to be called when `signum` signal is received.
 | // signal will assign `handler` callback to be called when `signum` signal is received.
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,133 @@ | ||||||
|  | module os | ||||||
|  | 
 | ||||||
|  | fn signal_str(signal Signal) string { | ||||||
|  | 	mut result := signal.str().to_upper() | ||||||
|  | 	result = 'SIG$result' | ||||||
|  | 	return result | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn signal_from_str(str JS.String) Signal { | ||||||
|  | 	s := string(str) | ||||||
|  | 	return match s { | ||||||
|  | 		'SIGHUP' { | ||||||
|  | 			Signal.hup | ||||||
|  | 		} | ||||||
|  | 		'SIGINT' { | ||||||
|  | 			Signal.int | ||||||
|  | 		} | ||||||
|  | 		'SIGQUIT' { | ||||||
|  | 			Signal.quit | ||||||
|  | 		} | ||||||
|  | 		'SIGILL' { | ||||||
|  | 			Signal.ill | ||||||
|  | 		} | ||||||
|  | 		'SIGTRAP' { | ||||||
|  | 			Signal.trap | ||||||
|  | 		} | ||||||
|  | 		'SIGABRT' { | ||||||
|  | 			Signal.abrt | ||||||
|  | 		} | ||||||
|  | 		'SIGBUS' { | ||||||
|  | 			Signal.bus | ||||||
|  | 		} | ||||||
|  | 		'SIGFPE' { | ||||||
|  | 			Signal.fpe | ||||||
|  | 		} | ||||||
|  | 		'SIGKILL' { | ||||||
|  | 			Signal.kill | ||||||
|  | 		} | ||||||
|  | 		'SIGUSR1' { | ||||||
|  | 			Signal.usr1 | ||||||
|  | 		} | ||||||
|  | 		'SIGSEGV' { | ||||||
|  | 			Signal.segv | ||||||
|  | 		} | ||||||
|  | 		'SIGUSR2' { | ||||||
|  | 			Signal.usr2 | ||||||
|  | 		} | ||||||
|  | 		'SIGPIPE' { | ||||||
|  | 			Signal.pipe | ||||||
|  | 		} | ||||||
|  | 		'SIGALRM' { | ||||||
|  | 			Signal.alrm | ||||||
|  | 		} | ||||||
|  | 		'SIGTERM' { | ||||||
|  | 			Signal.term | ||||||
|  | 		} | ||||||
|  | 		'SIGSTKFLT' { | ||||||
|  | 			Signal.stkflt | ||||||
|  | 		} | ||||||
|  | 		'SIGCHLD' { | ||||||
|  | 			Signal.chld | ||||||
|  | 		} | ||||||
|  | 		'SIGCONT' { | ||||||
|  | 			Signal.cont | ||||||
|  | 		} | ||||||
|  | 		'SIGSTOP' { | ||||||
|  | 			Signal.stop | ||||||
|  | 		} | ||||||
|  | 		'SIGTSTP' { | ||||||
|  | 			Signal.tstp | ||||||
|  | 		} | ||||||
|  | 		'SIGTTIN' { | ||||||
|  | 			Signal.ttin | ||||||
|  | 		} | ||||||
|  | 		'SIGTTOU' { | ||||||
|  | 			Signal.ttou | ||||||
|  | 		} | ||||||
|  | 		'SIGURG' { | ||||||
|  | 			Signal.urg | ||||||
|  | 		} | ||||||
|  | 		'SIGXCPU' { | ||||||
|  | 			Signal.xcpu | ||||||
|  | 		} | ||||||
|  | 		'SIGXFSZ' { | ||||||
|  | 			Signal.xfsz | ||||||
|  | 		} | ||||||
|  | 		'SIGVTALRM' { | ||||||
|  | 			Signal.vtalrm | ||||||
|  | 		} | ||||||
|  | 		'SIGPROF' { | ||||||
|  | 			Signal.prof | ||||||
|  | 		} | ||||||
|  | 		'SIGWINCH' { | ||||||
|  | 			Signal.winch | ||||||
|  | 		} | ||||||
|  | 		'SIGPOLL' { | ||||||
|  | 			Signal.poll | ||||||
|  | 		} | ||||||
|  | 		'SIGPWR' { | ||||||
|  | 			Signal.pwr | ||||||
|  | 		} | ||||||
|  | 		'SIGSYS' { | ||||||
|  | 			Signal.sys | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			panic('unknown signal: $s') | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // signal will assign `handler` callback to be called when `signum` signal is received.
 | ||||||
|  | //
 | ||||||
|  | // # Behaviour on different backends:
 | ||||||
|  | // - NodeJS: Will use `process.on` and add `handler` to the listeners list for `signum` to happen
 | ||||||
|  | // - Browser: Will use `window.addEventListener` for handling signal
 | ||||||
|  | //
 | ||||||
|  | // TODO: Add signal events implementation for browser backend
 | ||||||
|  | pub fn signal_opt(signum Signal, handler SignalHandler) ?SignalHandler { | ||||||
|  | 	signame := signal_str(signum) | ||||||
|  | 	_ := signame | ||||||
|  | 	$if js_node { | ||||||
|  | 		#$process.on(signame.str,function (sig) { handler(os__signal_from_str(sig));}); | ||||||
|  | 
 | ||||||
|  | 		return handler | ||||||
|  | 	} $else $if js_browser { | ||||||
|  | 		#let event = new CustomEvent(signame.str, {detail: signum}); | ||||||
|  | 		#window.addEventListener(signame.str, function (e) { handler(e.detail); }); | ||||||
|  | 
 | ||||||
|  | 		return handler | ||||||
|  | 	} $else { | ||||||
|  | 		return error('signal handlers are not supported on bare JS') | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,43 @@ | ||||||
|  | module os | ||||||
|  | 
 | ||||||
|  | // os.Signal - enumerate possible POSIX signals and
 | ||||||
|  | // their integer codes.
 | ||||||
|  | // NB: the integer codes are given here explicitly,
 | ||||||
|  | // to make it easier to lookup, without needing to
 | ||||||
|  | // consult man pages / signal.h .
 | ||||||
|  | 
 | ||||||
|  | pub enum Signal { | ||||||
|  | 	hup = 1 | ||||||
|  | 	int = 2 | ||||||
|  | 	quit = 3 | ||||||
|  | 	ill = 4 | ||||||
|  | 	trap = 5 | ||||||
|  | 	abrt = 6 | ||||||
|  | 	bus = 7 | ||||||
|  | 	fpe = 8 | ||||||
|  | 	kill = 9 | ||||||
|  | 	usr1 = 10 | ||||||
|  | 	segv = 11 | ||||||
|  | 	usr2 = 12 | ||||||
|  | 	pipe = 13 | ||||||
|  | 	alrm = 14 | ||||||
|  | 	term = 15 | ||||||
|  | 	stkflt = 16 | ||||||
|  | 	chld = 17 | ||||||
|  | 	cont = 18 | ||||||
|  | 	stop = 19 | ||||||
|  | 	tstp = 20 | ||||||
|  | 	ttin = 21 | ||||||
|  | 	ttou = 22 | ||||||
|  | 	urg = 23 | ||||||
|  | 	xcpu = 24 | ||||||
|  | 	xfsz = 25 | ||||||
|  | 	vtalrm = 26 | ||||||
|  | 	prof = 27 | ||||||
|  | 	winch = 28 | ||||||
|  | 	poll = 29 | ||||||
|  | 	pwr = 30 | ||||||
|  | 	sys = 31 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type SignalHandler = fn (Signal) | ||||||
		Loading…
	
		Reference in New Issue