瀏覽代碼

Reorg unistd dir

Eric Andersen 23 年之前
父節點
當前提交
174dc1b8cd
共有 8 個文件被更改,包括 418 次插入0 次删除
  1. 51 0
      libc/unistd/execl.c
  2. 51 0
      libc/unistd/execlp.c
  3. 9 0
      libc/unistd/execv.c
  4. 43 0
      libc/unistd/execvep.c
  5. 9 0
      libc/unistd/execvp.c
  6. 120 0
      libc/unistd/getcwd.c
  7. 111 0
      libc/unistd/getopt.c
  8. 24 0
      libc/unistd/sleep.c

+ 51 - 0
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;
+}

+ 51 - 0
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;
+}

+ 9 - 0
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);
+}

+ 43 - 0
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);
+}

+ 9 - 0
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);
+}

+ 120 - 0
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;
+}

+ 111 - 0
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;
+}

+ 24 - 0
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;
+}