diff options
| -rw-r--r-- | libc/unistd/execl.c | 51 | ||||
| -rw-r--r-- | libc/unistd/execlp.c | 51 | ||||
| -rw-r--r-- | libc/unistd/execv.c | 9 | ||||
| -rw-r--r-- | libc/unistd/execvep.c | 43 | ||||
| -rw-r--r-- | libc/unistd/execvp.c | 9 | ||||
| -rw-r--r-- | libc/unistd/getcwd.c | 120 | ||||
| -rw-r--r-- | libc/unistd/getopt.c | 111 | ||||
| -rw-r--r-- | libc/unistd/sleep.c | 24 | 
8 files changed, 418 insertions, 0 deletions
diff --git a/libc/unistd/execl.c b/libc/unistd/execl.c new file mode 100644 index 000000000..531c2ee60 --- /dev/null +++ b/libc/unistd/execl.c @@ -0,0 +1,51 @@ + +#include <stdlib.h> +#include <unistd.h> +#include <stdarg.h> + +extern char **environ; + +int execl(__const char *path, __const char *arg, ...) +{ +	const char *shortargv[16]; +	const char **argv; +	const char *c; +	int i; +	va_list args; + +	i = 1; + +	va_start(args, arg); + +	do { +		c = va_arg(args, const char *); + +		i++; +	} while (c); + +	va_end(args); + +	if (i <= 16) +		argv = shortargv; +	else { +		argv = (const char **) malloc(sizeof(char *) * i); +	} + +	argv[0] = arg; +	i = 1; + +	va_start(args, arg); + +	do { +		argv[i] = va_arg(args, const char *); +	} while (argv[i++]); + +	va_end(args); + +	i = execve(path, (char *const *) argv, environ); + +	if (argv != shortargv) +		free(argv); + +	return i; +} diff --git a/libc/unistd/execlp.c b/libc/unistd/execlp.c new file mode 100644 index 000000000..571ab71b0 --- /dev/null +++ b/libc/unistd/execlp.c @@ -0,0 +1,51 @@ + +#include <stdlib.h> +#include <unistd.h> +#include <stdarg.h> + +extern char **environ; + +int execlp(__const char *file, __const char *arg, ...) +{ +	const char *shortargv[16]; +	const char **argv; +	const char *c; +	int i; +	va_list args; + +	i = 1; + +	va_start(args, arg); + +	do { +		c = va_arg(args, const char *); + +		i++; +	} while (c); + +	va_end(args); + +	if (i <= 16) +		argv = shortargv; +	else { +		argv = (const char **) malloc(sizeof(char *) * i); +	} + +	argv[0] = arg; +	i = 1; + +	va_start(args, arg); + +	do { +		argv[i] = va_arg(args, const char *); +	} while (argv[i++]); + +	va_end(args); + +	i = execvep(file, (char *const *) argv, environ); + +	if (argv != shortargv) +		free(argv); + +	return i; +} diff --git a/libc/unistd/execv.c b/libc/unistd/execv.c new file mode 100644 index 000000000..6c8ba0d97 --- /dev/null +++ b/libc/unistd/execv.c @@ -0,0 +1,9 @@ + +#include <unistd.h> + +extern char **environ; + +int execv(__const char *path, char *__const argv[]) +{ +	return execve(path, argv, environ); +} diff --git a/libc/unistd/execvep.c b/libc/unistd/execvep.c new file mode 100644 index 000000000..4ac7692e9 --- /dev/null +++ b/libc/unistd/execvep.c @@ -0,0 +1,43 @@ + +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +int execvep(const char *path, char *__const argv[], char *__const envp[]) +{ +	if (!strchr(path, '/')) { +		char partial[128]; +		char *p = getenv("PATH"); +		char *p2; + +		if (!p) +			p = "/bin:/usr/bin"; + +		for (; p && *p;) { + +			strcpy(partial, p); + +			p2 = strchr(partial, ':'); +			if (p2) +				*p2 = '\0'; + +			if (strlen(partial)) +				strcat(partial, "/"); +			strcat(partial, path); + +			execve(partial, argv, envp); + +			if (errno != ENOENT) +				return -1; + +			p2 = strchr(p, ':'); +			if (p2) +				p = p2 + 1; +			else +				p = 0; +		} +		return -1; +	} else +		return execve(path, argv, envp); +} diff --git a/libc/unistd/execvp.c b/libc/unistd/execvp.c new file mode 100644 index 000000000..b2aeee917 --- /dev/null +++ b/libc/unistd/execvp.c @@ -0,0 +1,9 @@ + +#include <unistd.h> + +extern char **environ; + +int execvp(__const char *path, char *__const argv[]) +{ +	return execvep(path, argv, environ); +} diff --git a/libc/unistd/getcwd.c b/libc/unistd/getcwd.c new file mode 100644 index 000000000..12eda45ca --- /dev/null +++ b/libc/unistd/getcwd.c @@ -0,0 +1,120 @@ + +#include <errno.h> +#include <sys/stat.h> +#include <dirent.h> +#include <string.h> +/* + * These functions find the absolute path to the current working directory. + * + * They don't use malloc or large amounts of stack space. + */ + +static char *recurser();		/* Routine to go up tree */ +static char *search_dir();		/* Routine to find the step back down */ +static char *path_buf; +static int path_size; + +static dev_t root_dev; +static ino_t root_ino; + +static struct stat st; + +char *getcwd(buf, size) +char *buf; +int size; +{ +	path_buf = buf; +	path_size = size; + +	if (size < 3) { +		errno = ERANGE; +		return 0; +	} +	strcpy(path_buf, "."); + +	if (stat("/", &st) < 0) +		return 0; + +	root_dev = st.st_dev; +	root_ino = st.st_ino; + +	return recurser(); +} + +static char *recurser() +{ +	dev_t this_dev; +	ino_t this_ino; + +	if (stat(path_buf, &st) < 0) +		return 0; +	this_dev = st.st_dev; +	this_ino = st.st_ino; +	if (this_dev == root_dev && this_ino == root_ino) { +		strcpy(path_buf, "/"); +		return path_buf; +	} +	if (strlen(path_buf) + 4 > path_size) { +		errno = ERANGE; +		return 0; +	} +	strcat(path_buf, "/.."); +	if (recurser() == 0) +		return 0; + +	return search_dir(this_dev, this_ino); +} + +static char *search_dir(this_dev, this_ino) +dev_t this_dev; +ino_t this_ino; +{ +	DIR *dp; +	struct dirent *d; +	char *ptr; +	int slen; + +	/* The test is for ELKS lib 0.0.9, this should be fixed in the real kernel */ +	int slow_search = (sizeof(ino_t) != sizeof(d->d_ino)); + +	if (stat(path_buf, &st) < 0) +		return 0; +	if (this_dev != st.st_dev) +		slow_search = 1; + +	slen = strlen(path_buf); +	ptr = path_buf + slen - 1; +	if (*ptr != '/') { +		if (slen + 2 > path_size) { +			errno = ERANGE; +			return 0; +		} +		strcpy(++ptr, "/"); +		slen++; +	} +	slen++; + +	dp = opendir(path_buf); +	if (dp == 0) +		return 0; + +	while ((d = readdir(dp)) != 0) { +		if (slow_search || this_ino == d->d_ino) { +			if (slen + strlen(d->d_name) > path_size) { +				errno = ERANGE; +				return 0; +			} +			strcpy(ptr + 1, d->d_name); +			if (stat(path_buf, &st) < 0) +				continue; +			if (st.st_ino == this_ino && st.st_dev == this_dev) { +				closedir(dp); +				return path_buf; +			} +		} +	} + +	closedir(dp); +	errno = ENOENT; +	return 0; +} diff --git a/libc/unistd/getopt.c b/libc/unistd/getopt.c new file mode 100644 index 000000000..70d20b06b --- /dev/null +++ b/libc/unistd/getopt.c @@ -0,0 +1,111 @@ + +/* + * From: gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) Newsgroups: net.sources + * Subject: getopt library routine Date: 30 Mar 85 04:45:33 GMT + */ +/* + * getopt -- public domain version of standard System V routine + *  + * Strictly enforces the System V Command Syntax Standard; provided by D A + * Gwyn of BRL for generic ANSI C implementations + *  + * #define STRICT to prevent acceptance of clustered options with arguments + * and ommision of whitespace between option and arg. + */ + +#include <stdio.h> +#include <string.h> + +int opterr = 1;					/* error => print message */ +int optind = 1;					/* next argv[] index */ +int optopt = 1;					/* Set for unknown arguments */ +char *optarg = NULL;			/* option parameter if any */ + +static int Err(name, mess, c) /* returns '?' */ +char *name;						/* program name argv[0] */ +char *mess;						/* specific message */ +int c;							/* defective option letter */ +{ +	optopt = c; +	if (opterr) { +		(void) fprintf(stderr, "%s: %s -- %c\n", name, mess, c); +	} + +	return '?';					/* erroneous-option marker */ +} + +int getopt(argc, argv, optstring) /* returns letter, '?', EOF */ +int argc;						/* argument count from main */ +char *argv[];					/* argument vector from main */ +char *optstring;				/* allowed args, e.g. "ab:c" */ +{ +	static int sp = 1;			/* position within argument */ +	register int osp;			/* saved `sp' for param test */ + +#ifndef STRICT +	register int oind;			/* saved `optind' for param test */ +#endif +	register int c;				/* option letter */ +	register char *cp;			/* -> option in `optstring' */ + +	optarg = NULL; + +	if (sp == 1) {				/* fresh argument */ +		if (optind >= argc		/* no more arguments */ +			|| argv[optind][0] != '-'	/* no more options */ +			|| argv[optind][1] == '\0'	/* not option; stdin */ +			) +			return EOF; +		else if (strcmp(argv[optind], "--") == 0) { +			++optind;			/* skip over "--" */ +			return EOF;			/* "--" marks end of options */ +		} +	} + +	c = argv[optind][sp];		/* option letter */ +	osp = sp++;					/* get ready for next letter */ + +#ifndef STRICT +	oind = optind;				/* save optind for param test */ +#endif +	if (argv[optind][sp] == '\0') {	/* end of argument */ +		++optind;				/* get ready for next try */ +		sp = 1;					/* beginning of next argument */ +	} + +	if (c == ':' || c == '?'	/* optstring syntax conflict */ +		|| (cp = strchr(optstring, c)) == NULL /* not found */ ) { +		return Err(argv[0], "illegal option", c); +	} + +	if (cp[1] == ':') {			/* option takes parameter */ +#ifdef STRICT +		if (osp != 1) { +			return Err(argv[0], "option must not be clustered", c); +		} + +		/* reset by end of argument */ +		if (sp != 1) { +			return Err(argv[0], "option must be followed by white space", +					   c); +		} +#else +		if (oind == optind) {	/* argument w/o whitespace */ +			optarg = &argv[optind][sp]; +			sp = 1;				/* beginning of next argument */ +		} + +		else +#endif +		if (optind >= argc) { +			return Err(argv[0], "option requires an argument", c); +		} + +		else					/* argument w/ whitespace */ +			optarg = argv[optind]; + +		++optind;				/* skip over parameter */ +	} + +	return c; +} diff --git a/libc/unistd/sleep.c b/libc/unistd/sleep.c new file mode 100644 index 000000000..5b458e07a --- /dev/null +++ b/libc/unistd/sleep.c @@ -0,0 +1,24 @@ + + +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> + +void usleep(unsigned long usec) +{ +	struct timeval tv; + +	tv.tv_sec = usec / 1000000; +	tv.tv_usec = usec % 1000000; +	select(0, 0, 0, 0, &tv); +} + +unsigned int sleep(unsigned int sec) +{ +	struct timeval tv; + +	tv.tv_sec = sec; +	tv.tv_usec = 0; +	select(0, 0, 0, 0, &tv); +	return tv.tv_sec; +}  | 
