Sigrid Solveig Haflínudóttiradd path-make-dir to create directories98d914e2 months agoHistory
443 lines · 6.8 KB · C
RawDownload
#include "inc/priv.h"#include <tos.h>#include "inc/nan.h"#include "inc/process.h"#include "inc/time.h"#include "lsd.h" u64intsec_realtime(void){	return nsec();} void *sl_segalloc(usize sz){	return segattach(SG_CEXEC, "memory", nil, sz);} voidsl_segfree(void *s, usize sz){	USED(sz);	if(s != nil)		segdetach(s);} voidsl_segused(void *s, usize sz, usize used){	USED(s); USED(sz); USED(used);} /* * nsec() is wallclock and can be adjusted by timesync * so need to use cycles() instead, but fall back to * nsec() in case we can't */u64intnanosec_monotonic(void){	static u64int fasthz, xstart;	u64int x; 	if(fasthz == ~0ULL)		return nsec() - xstart; 	if(fasthz == 0){		if(_tos->cyclefreq){			fasthz = _tos->cyclefreq;			cycles(&xstart);		}else{			fasthz = ~0ULL;			xstart = nsec();		}		return 0;	}	cycles(&x);	x -= xstart; 	u64int q = x / fasthz;	u64int r = x % fasthz; 	return q*Nsec + r*Nsec/fasthz;} voidtimestr(u64int ns, char *buf, int sz){	Tm tm;	snprint(buf, sz, "%τ", tmfmt(tmtime(&tm, ns/Nsec, tzload("local")), nil));} u64intparsetime(const char *s){	Tm tm;	if(tmparse(&tm, "?WWW, ?MM ?DD hh:mm:ss ?Z YYYY", s, tzload("local"), nil) == nil)		return -1;	return tmnorm(&tm)*Nsec;} voidsleep_ms(int ms){	if(ms != 0)		sleep(ms);} intftruncate(int f, soffset sz){	Dir d; 	nulldir(&d);	d.length = sz;	return dirfwstat(f, &d) > 0 ? 0 : -1;} intunsetenv(const char *name){	char ename[100]; 	if(*name == 0 || strchr(name, '/') != nil ||	   strcmp(name, ".") == 0 || strcmp(name, "..") == 0 ||	   strlen(name) >= sizeof(ename)-5){		werrstr("bad env name: %s", name);		return -1;	}	snprint(ename, sizeof(ename), "/env/%s", name);	if(access(ename, AEXIST) == 0)		return remove(ename);	return 0;} voidsys_setcurrpc(int dummy){	USED(dummy);	sys_setcallpc(dummy);} voidsys_seed(void *p, int sz){	u8int *o = p;	int f; 	if((f = open("/dev/random", OREAD)) >= 0){		while(sz > 0){			int n = read(f, o, sz);			if(n < 0)				break;			o += n;			sz -= n;		}		close(f);	}	// otherwise TOO BAD} intsys_read(int fd, u8int *buf, usize n, usize *nread){	ssize r; 	while(1){		r = read(fd, buf, n);		if(r > -1){			*nread = (usize)r;			break;		}		return r;	}	return 0;} intsys_write(int fd, const void *buf, usize n, usize *nwritten){	ssize r = write(fd, buf, n);	if(r < 0)		return -1;	*nwritten = (usize)r;	return 0;} intsys_open(const char *fname, ios_flags flags, usize mode){	int of =		(flags & IOS_WRITE)		? ((flags & IOS_READ) ? ORDWR : OWRITE)		: OREAD;	if(flags & IOS_TRUNC)		of |= OTRUNC;	if(flags & IOS_EXCL)		of |= OEXCL;	of |= OCEXEC;	if(flags & IOS_APPEND)		mode |= DMAPPEND;	return		(flags & IOS_CREATE)		? create(fname, of, mode)		: open(fname, of);} intsys_rename(const char *old, const char *new){	Dir d; 	nulldir(&d);	d.name = (char*)new; 	return dirwstat(old, &d) > 0 ? 0 : -1;} soffsetsys_seek(int fd, soffset offset, int whence){	return seek(fd, offset, whence);} intsys_close(int fd){	return close(fd);} intsys_dup(int oldfd, int newfd){	return dup(oldfd, newfd);} voidsys_fd_setup(int fd){	USED(fd);} intsys_exec(const char *path, char *const argv[], char *env[]){	if(env != nil){		for(int i = 0; env[i] != nil; i++){			char *v = strchr(env[i], '=');			if(v == nil)				abort();			*v++ = 0;			if(putenv(env[i], v) != 0)				return -1;		}	}	return exec(path, argv);} intsys_fork(fork_flags flags){	int rf = RFFDG|RFREND|RFPROC;	if(flags & FORK_CLEAR_ENV)		rf |= RFCENVG;	return rfork(rf);} char *sys_getcwd(void){	char tmp[4096];	if(getwd(tmp, sizeof(tmp)) != nil)		return MEM_STRDUP(tmp);	return nil;} intsys_chdir(int fd, const char *dir){	USED(fd);	return chdir(dir);} intsys_pipe(int fd[2], bool rd, bool wr){	if(pipe(fd) != 0)		return -1;	if(!rd)		write(fd[1], "", 0);	if(!wr)		write(fd[0], "", 0);	return 0;} char *sys_find_program(const char *p){	if((p[0] == '/') ||	   (p[0] == '.' && p[1] == '/') ||	   (p[0] == '.' && p[1] == '.' && p[2] == '/'))		return MEM_STRDUP(p); 	char *path = getenv("path");	if(path == nil)		return nil; 	char *s;	for(s = path; s != nil;){		char *e = strchr(s, ' ');		if(e != nil)			*e = 0;		s = smprint("%s/%s", s, p);		if(s != nil){			int r = access(s, AEXEC);			if(r == 0)				break;			free(s);		}		s = e != nil ? e+1 : nil;	} 	free(path);	return s;} static intmkdir_(const char *path, usize mode){	Dir *d;	int r = -1;	if((d = dirstat(path)) != nil){		if((d->mode & DMDIR) != 0)			r = 0;		free(d);	}else{		int f = create(path, OREAD, DMDIR|mode);		if(f >= 0)			r = 0;		close(f);	}	return r;} intsys_mkdir(const char *path, usize mode){	if(mkdir_(path, mode) == 0)		return 0;	char *p = MEM_STRDUP(path);	if(p == nil)		return -1;	int r = -1;	for(char *s = p+1; (s = strchr(s, '/')) != nil;){		*s = 0;		if(mkdir_(p, mode) != 0)			goto done;		*s++ = '/';		while(*s == '/')			s++;	}	if(mkdir_(path, mode) == 0)		r = 0;done:	MEM_FREE(p);	return r;} intsys_postnote(int pid, const char *note, const char *sig){	USED(sig);	return postnote(PNPROC, pid, note);} BUILTIN("getpid", getpid){	USED(args);	noargs();	return fixnum(getpid());} static voidprocess_updates(int f){	char wait[128]; 	snprint(wait, sizeof(wait), "/proc/%lud/args", (ulong)getpid());	int nfd = open(wait, OWRITE|OCEXEC);	if(nfd >= 0){		fprint(nfd, "process_updates");		close(nfd);	} 	for(;;){		char *waitfld[5];		int n = read(f, wait, sizeof(wait)-1);		if(n <= 0)			break;		wait[n] = 0;		if(tokenize(wait, waitfld, nelem(waitfld)) != nelem(waitfld))			continue;		int pid = atoi(waitfld[0]);		char *m = waitfld[4]; 		// the only way the status isn't there is if the process has		// already left the building		char stat[128], *statfld[5];		process_state_t state = PSTATE_EXITED;		snprint(stat, sizeof(stat), "/proc/%s/status", waitfld[0]);		int s = open(stat, OREAD|OCEXEC);		if(s >= 0){			n = read(s, stat, sizeof(stat)-1);			close(s);			if(n > 0){				stat[n] = 0;				if(tokenize(stat, statfld, nelem(statfld)) >= nelem(statfld)){					if(strcmp(statfld[2], "Broken") == 0)						state = PSTATE_DUMPED;					else if(strcmp(statfld[2], "Stopped") == 0)						state = PSTATE_STOPPED;					else if(strcmp(statfld[2], "Moribund") == 0)						state = PSTATE_EXITED;					else						state = PSTATE_RUNNING;				}			}		} 		process_update(pid, state, *m == 0 ? 0 : 1, *m == 0 ? nil : m);	}	exits(nil);} voidsys_init(void){	lsd_init(); 	char t[64];	snprint(t, sizeof(t), "/proc/%d/wait", getpid());	int waitfd = open(t, OREAD|OCEXEC);	if(waitfd < 0)		abort();	int r = rfork(RFREND|RFPROC|RFMEM);	if(r < 0)		abort();	if(r == 0)		process_updates(waitfd);} extern uchar bootcode[];extern ulong bootlen; voidmain(int argc, char **argv){	argv0 = argv[0];	setfcr(FPPDBL|FPRNR|FPOVFL);	tmfmtinstall();	slmain(bootcode, bootlen, argc, argv);}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t