Charles.Forsyth20060303a828770d19 years agoHistory
146 lines · 2.8 KB · Brainfuck
RawDownload
implement Kill; include "sys.m";	sys: Sys;include "draw.m";include "arg.m"; Kill: module {	init: fn(nil: ref Draw->Context, args: list of string);}; stderr: ref Sys->FD; usage(){	sys->fprint(stderr, "usage: kill [-g] pid|module [...]\n");	raise "fail: usage";} init(nil: ref Draw->Context, args: list of string){	sys = load Sys Sys->PATH;	stderr = sys->fildes(2); 	arg := load Arg Arg->PATH;	if(arg == nil){		sys->fprint(stderr, "kill: cannot load %s: %r\n", Arg->PATH);		raise "fail:load";	} 	msg := array of byte "kill";	arg->init(args);	while((o := arg->opt()) != 0)		case o {		'g' =>			msg = array of byte "killgrp";		* =>			usage();		} 	argv := arg->argv();	arg = nil;	if(argv == nil)		usage();	n := 0;	for(v := argv; v != nil; v = tl v) {		s := hd v;		if (s == nil)			usage();		if(s[0] >= '0' && s[0] <= '9')			n += killpid(s, msg, 1);		else			n += killmod(s, msg);	}	if (n == 0 && argv != nil)		raise "fail:nothing killed";} killpid(pid: string, msg: array of byte, sbok: int): int{	fd := sys->open("/prog/"+pid+"/ctl", sys->OWRITE);	if(fd == nil) {		err := sys->sprint("%r");		elen := len err;		if(sbok || err != "thread exited" && elen >= 14 && err[elen-14:] != "does not exist")			sys->fprint(stderr, "kill: cannot open /prog/%s/ctl: %r\n", pid);		return 0;	} 	n := sys->write(fd, msg, len msg);	if(n < 0) {		err := sys->sprint("%r");		elen := len err;		if(sbok || err != "thread exited")			sys->fprint(stderr, "kill: cannot kill %s: %r\n", pid);		return 0;	}	return 1;} killmod(mod: string, msg: array of byte): int{	fd := sys->open("/prog", sys->OREAD);	if(fd == nil) {		sys->fprint(stderr, "kill: open /prog: %r\n");		return 0;	} 	pids: list of string;	for(;;) {		(n, d) := sys->dirread(fd);		if(n <= 0) {			if (n < 0)				sys->fprint(stderr, "kill: read /prog: %r\n");			break;		} 		for(i := 0; i < n; i++)			if (killmatch(d[i].name, mod))				pids = d[i].name :: pids;			}	if (pids == nil) {		sys->fprint(stderr, "kill: cannot find %s\n", mod);		return 0;	}	n := 0;	for (; pids != nil; pids = tl pids)		if (killpid(hd pids, msg, 0)) {			sys->print("%s ", hd pids);			n++;		}	if (n > 0)		sys->print("\n");	return n;} killmatch(dir, mod: string): int{	status := "/prog/"+dir+"/status";	fd := sys->open(status, sys->OREAD);	if(fd == nil)		return 0;	buf := array[512] of byte;	n := sys->read(fd, buf, len buf);	if(n < 0) {		err := sys->sprint("%r");		if(err != "thread exited")			sys->fprint(stderr, "kill: cannot read %s: %s\n", status, err);		return 0;	} 	# module name is last field	(nil, fields) := sys->tokenize(string buf[0:n], " ");	for(s := ""; fields != nil; fields = tl fields)		s = hd fields; 	# strip builtin module, e.g. Sh[$Sys]	for(i := 0; i < len s; i++) {		if(s[i] == '[') {			s = s[0:i];			break;		}	} 	return s == mod;}