diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | a27d2baa0c1a2ec70f47ea9199b1dd6762c8a349 (patch) | |
tree | defd1cc07d16ad2f3b21154114e092d11c94c5bb /libc/unistd | |
download | bionic-a27d2baa0c1a2ec70f47ea9199b1dd6762c8a349.zip bionic-a27d2baa0c1a2ec70f47ea9199b1dd6762c8a349.tar.gz bionic-a27d2baa0c1a2ec70f47ea9199b1dd6762c8a349.tar.bz2 |
Initial Contributionandroid-1.0
Diffstat (limited to 'libc/unistd')
58 files changed, 4914 insertions, 0 deletions
diff --git a/libc/unistd/abort.c b/libc/unistd/abort.c new file mode 100644 index 0000000..3291287 --- /dev/null +++ b/libc/unistd/abort.c @@ -0,0 +1,84 @@ +/* $OpenBSD: abort.c,v 1.14 2005/08/08 08:05:36 espie Exp $ */ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <signal.h> +#include <stdlib.h> +#include <unistd.h> +#include "thread_private.h" +#include "atexit.h" + +void +abort(void) +{ + struct atexit *p = __atexit; + static int cleanup_called = 0; + sigset_t mask; + + + sigfillset(&mask); + /* + * don't block SIGABRT to give any handler a chance; we ignore + * any errors -- X311J doesn't allow abort to return anyway. + */ + sigdelset(&mask, SIGABRT); + (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); + + /* + * POSIX requires we flush stdio buffers on abort + */ + if (cleanup_called == 0) { + while (p != NULL && p->next != NULL) + p = p->next; + if (p != NULL && p->fns[0] != NULL) { + cleanup_called = 1; + (*p->fns[0])(); + } + } + + (void)kill(getpid(), SIGABRT); + + /* + * if SIGABRT ignored, or caught and the handler returns, do + * it again, only harder. + */ + { + struct sigaction sa; + + sa.sa_handler = SIG_DFL; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + + (void)sigaction( SIGABRT, &sa, &sa ); + } + + (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); + (void)kill(getpid(), SIGABRT); + _exit(1); +} diff --git a/libc/unistd/alarm.c b/libc/unistd/alarm.c new file mode 100644 index 0000000..01863a4 --- /dev/null +++ b/libc/unistd/alarm.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)alarm.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> +//__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/alarm.c,v 1.3 2007/01/09 00:27:53 imp Exp $"); + +/* + * Backwards compatible alarm. + */ +#include <sys/time.h> +#include <unistd.h> + +unsigned int +alarm(secs) + unsigned int secs; +{ + struct itimerval it, oitv; + struct itimerval *itp = ⁢ + + itp->it_interval.tv_usec = 0; + itp->it_interval.tv_sec = 0; + itp->it_value.tv_sec = secs; + itp->it_value.tv_usec = 0; + if (setitimer(ITIMER_REAL, itp, &oitv) < 0) + return (-1); + if (oitv.it_value.tv_usec) + oitv.it_value.tv_sec++; + return (oitv.it_value.tv_sec); +} diff --git a/libc/unistd/brk.c b/libc/unistd/brk.c new file mode 100644 index 0000000..bf2f108 --- /dev/null +++ b/libc/unistd/brk.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <stddef.h> +#include <unistd.h> +#include <sys/types.h> + +/* shared with sbrk.c */ +char *__bionic_brk; + +int brk(void* end_data) +{ + char* new_brk = __brk( end_data ); + + if (new_brk != end_data) + return -1; + + __bionic_brk = new_brk; + + return 0; +} diff --git a/libc/unistd/creat.c b/libc/unistd/creat.c new file mode 100644 index 0000000..1b14465 --- /dev/null +++ b/libc/unistd/creat.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <fcntl.h> + +int creat(const char* pathname, mode_t mode) +{ + return open(pathname, O_WRONLY|O_TRUNC|O_CREAT, mode); +} diff --git a/libc/unistd/daemon.c b/libc/unistd/daemon.c new file mode 100644 index 0000000..8181d16 --- /dev/null +++ b/libc/unistd/daemon.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> + +int daemon( int nochdir, int noclose ) +{ + pid_t pid; + + if ( !nochdir && chdir("/") != 0 ) + return -1; + + if ( !noclose ) + { + int fd = open("/dev/null", O_RDWR); + + if ( fd < 0 ) + return -1; + + if ( dup2( fd, 0 ) < 0 || + dup2( fd, 1 ) < 0 || + dup2( fd, 2 ) < 0 ) + { + close(fd); + return -1; + } + close(fd); + } + + pid = fork(); + if (pid < 0) + return -1; + + if (pid > 0) + _exit(0); + + if ( setsid() < 0 ) + return -1; + + return 0; +} + diff --git a/libc/unistd/exec.c b/libc/unistd/exec.c new file mode 100644 index 0000000..cbb98b3 --- /dev/null +++ b/libc/unistd/exec.c @@ -0,0 +1,244 @@ +/* $OpenBSD: exec.c,v 1.18 2005/08/08 08:05:34 espie Exp $ */ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <errno.h> +#include <unistd.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <paths.h> +#include <stdarg.h> +#include <alloca.h> + +extern char **environ; + +int +execl(const char *name, const char *arg, ...) +{ + va_list ap; + char **argv; + int n; + + va_start(ap, arg); + n = 1; + while (va_arg(ap, char *) != NULL) + n++; + va_end(ap); + argv = alloca((n + 1) * sizeof(*argv)); + if (argv == NULL) { + errno = ENOMEM; + return (-1); + } + va_start(ap, arg); + n = 1; + argv[0] = (char *)arg; + while ((argv[n] = va_arg(ap, char *)) != NULL) + n++; + va_end(ap); + return (execve(name, argv, environ)); +} + +int +execle(const char *name, const char *arg, ...) +{ + va_list ap; + char **argv, **envp; + int n; + + va_start(ap, arg); + n = 1; + while (va_arg(ap, char *) != NULL) + n++; + va_end(ap); + argv = alloca((n + 1) * sizeof(*argv)); + if (argv == NULL) { + errno = ENOMEM; + return (-1); + } + va_start(ap, arg); + n = 1; + argv[0] = (char *)arg; + while ((argv[n] = va_arg(ap, char *)) != NULL) + n++; + envp = va_arg(ap, char **); + va_end(ap); + return (execve(name, argv, envp)); +} + +int +execlp(const char *name, const char *arg, ...) +{ + va_list ap; + char **argv; + int n; + + va_start(ap, arg); + n = 1; + while (va_arg(ap, char *) != NULL) + n++; + va_end(ap); + argv = alloca((n + 1) * sizeof(*argv)); + if (argv == NULL) { + errno = ENOMEM; + return (-1); + } + va_start(ap, arg); + n = 1; + argv[0] = (char *)arg; + while ((argv[n] = va_arg(ap, char *)) != NULL) + n++; + va_end(ap); + return (execvp(name, argv)); +} + +int +execv(const char *name, char * const *argv) +{ + (void)execve(name, argv, environ); + return (-1); +} + +int +execvp(const char *name, char * const *argv) +{ + char **memp; + int cnt, lp, ln, len; + char *p; + int eacces = 0; + char *bp, *cur, *path, buf[MAXPATHLEN]; + + /* + * Do not allow null name + */ + if (name == NULL || *name == '\0') { + errno = ENOENT; + return (-1); + } + + /* If it's an absolute or relative path name, it's easy. */ + if (strchr(name, '/')) { + bp = (char *)name; + cur = path = NULL; + goto retry; + } + bp = buf; + + /* Get the path we're searching. */ + if (!(path = getenv("PATH"))) + path = _PATH_DEFPATH; + len = strlen(path) + 1; + cur = alloca(len); + if (cur == NULL) { + errno = ENOMEM; + return (-1); + } + strlcpy(cur, path, len); + path = cur; + while ((p = strsep(&cur, ":"))) { + /* + * It's a SHELL path -- double, leading and trailing colons + * mean the current directory. + */ + if (!*p) { + p = "."; + lp = 1; + } else + lp = strlen(p); + ln = strlen(name); + + /* + * If the path is too long complain. This is a possible + * security issue; given a way to make the path too long + * the user may execute the wrong program. + */ + if (lp + ln + 2 > (int)sizeof(buf)) { + struct iovec iov[3]; + + iov[0].iov_base = "execvp: "; + iov[0].iov_len = 8; + iov[1].iov_base = p; + iov[1].iov_len = lp; + iov[2].iov_base = ": path too long\n"; + iov[2].iov_len = 16; + (void)writev(STDERR_FILENO, iov, 3); + continue; + } + bcopy(p, buf, lp); + buf[lp] = '/'; + bcopy(name, buf + lp + 1, ln); + buf[lp + ln + 1] = '\0'; + +retry: (void)execve(bp, argv, environ); + switch(errno) { + case E2BIG: + goto done; + case EISDIR: + case ELOOP: + case ENAMETOOLONG: + case ENOENT: + break; + case ENOEXEC: + for (cnt = 0; argv[cnt]; ++cnt) + ; + memp = alloca((cnt + 2) * sizeof(char *)); + if (memp == NULL) + goto done; + memp[0] = "sh"; + memp[1] = bp; + bcopy(argv + 1, memp + 2, cnt * sizeof(char *)); + (void)execve(_PATH_BSHELL, memp, environ); + goto done; + case ENOMEM: + goto done; + case ENOTDIR: + break; + case ETXTBSY: + /* + * We used to retry here, but sh(1) doesn't. + */ + goto done; + case EACCES: + eacces = 1; + break; + default: + goto done; + } + } + if (eacces) + errno = EACCES; + else if (!errno) + errno = ENOENT; +done: + return (-1); +} diff --git a/libc/unistd/fcntl.c b/libc/unistd/fcntl.c new file mode 100644 index 0000000..b49db0a --- /dev/null +++ b/libc/unistd/fcntl.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <stdarg.h> +#include <errno.h> + +extern int __fcntl64(int, int, void *); + +int fcntl(int fd, int cmd, ...) +{ + va_list ap; + void * arg; + + va_start(ap, cmd); + arg = va_arg(ap, void *); + va_end(ap); + + return __fcntl64(fd, cmd, arg); +} diff --git a/libc/unistd/fnmatch.c b/libc/unistd/fnmatch.c new file mode 100644 index 0000000..ad31c9e --- /dev/null +++ b/libc/unistd/fnmatch.c @@ -0,0 +1,205 @@ +/* $OpenBSD: fnmatch.c,v 1.13 2006/03/31 05:34:14 deraadt Exp $ */ + +/* + * Copyright (c) 1989, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. + * Compares a filename or pathname to a pattern. + */ + +#include <ctype.h> +#include <stdio.h> +#include <string.h> +#include <fnmatch.h> + +#define EOS '\0' + +#define RANGE_MATCH 1 +#define RANGE_NOMATCH 0 +#define RANGE_ERROR (-1) + +static int rangematch(const char *, char, int, char **); + +int +fnmatch(const char *pattern, const char *string, int flags) +{ + const char *stringstart; + char *newp; + char c, test; + + for (stringstart = string;;) + switch (c = *pattern++) { + case EOS: + if ((flags & FNM_LEADING_DIR) && *string == '/') + return (0); + return (*string == EOS ? 0 : FNM_NOMATCH); + case '?': + if (*string == EOS) + return (FNM_NOMATCH); + if (*string == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + ++string; + break; + case '*': + c = *pattern; + /* Collapse multiple stars. */ + while (c == '*') + c = *++pattern; + + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + + /* Optimize for pattern with * at end or before /. */ + if (c == EOS) { + if (flags & FNM_PATHNAME) + return ((flags & FNM_LEADING_DIR) || + strchr(string, '/') == NULL ? + 0 : FNM_NOMATCH); + else + return (0); + } else if (c == '/' && (flags & FNM_PATHNAME)) { + if ((string = strchr(string, '/')) == NULL) + return (FNM_NOMATCH); + break; + } + + /* General case, use recursion. */ + while ((test = *string) != EOS) { + if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) + return (0); + if (test == '/' && (flags & FNM_PATHNAME)) + break; + ++string; + } + return (FNM_NOMATCH); + case '[': + if (*string == EOS) + return (FNM_NOMATCH); + if (*string == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + + switch (rangematch(pattern, *string, flags, &newp)) { + case RANGE_ERROR: + /* not a good range, treat as normal text */ + goto normal; + case RANGE_MATCH: + pattern = newp; + break; + case RANGE_NOMATCH: + return (FNM_NOMATCH); + } + ++string; + break; + case '\\': + if (!(flags & FNM_NOESCAPE)) { + if ((c = *pattern++) == EOS) { + c = '\\'; + --pattern; + } + } + /* FALLTHROUGH */ + default: + normal: + if (c != *string && !((flags & FNM_CASEFOLD) && + (tolower((unsigned char)c) == + tolower((unsigned char)*string)))) + return (FNM_NOMATCH); + ++string; + break; + } + /* NOTREACHED */ +} + +static int +rangematch(const char *pattern, char test, int flags, char **newp) +{ + int negate, ok; + char c, c2; + + /* + * A bracket expression starting with an unquoted circumflex + * character produces unspecified results (IEEE 1003.2-1992, + * 3.13.2). This implementation treats it like '!', for + * consistency with the regular expression syntax. + * J.T. Conklin (conklin@ngai.kaleida.com) + */ + if ((negate = (*pattern == '!' || *pattern == '^'))) + ++pattern; + + if (flags & FNM_CASEFOLD) + test = (char)tolower((unsigned char)test); + + /* + * A right bracket shall lose its special meaning and represent + * itself in a bracket expression if it occurs first in the list. + * -- POSIX.2 2.8.3.2 + */ + ok = 0; + c = *pattern++; + do { + if (c == '\\' && !(flags & FNM_NOESCAPE)) + c = *pattern++; + if (c == EOS) + return (RANGE_ERROR); + if (c == '/' && (flags & FNM_PATHNAME)) + return (RANGE_NOMATCH); + if ((flags & FNM_CASEFOLD)) + c = (char)tolower((unsigned char)c); + if (*pattern == '-' + && (c2 = *(pattern+1)) != EOS && c2 != ']') { + pattern += 2; + if (c2 == '\\' && !(flags & FNM_NOESCAPE)) + c2 = *pattern++; + if (c2 == EOS) + return (RANGE_ERROR); + if (flags & FNM_CASEFOLD) + c2 = (char)tolower((unsigned char)c2); + if (c <= test && test <= c2) + ok = 1; + } else if (c == test) + ok = 1; + } while ((c = *pattern++) != ']'); + + *newp = (char *)pattern; + return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); +} diff --git a/libc/unistd/ftok.c b/libc/unistd/ftok.c new file mode 100644 index 0000000..638bd0a --- /dev/null +++ b/libc/unistd/ftok.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <sys/ipc.h> +#include <sys/stat.h> + +key_t ftok(const char* path, int id) +{ + struct stat st; + + if ( lstat(path, &st) < 0 ) + return -1; + + return (key_t)( (st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ((id & 255) << 24) ); +} diff --git a/libc/unistd/getcwd.c b/libc/unistd/getcwd.c new file mode 100644 index 0000000..1cf80e9 --- /dev/null +++ b/libc/unistd/getcwd.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> + +extern int __getcwd(char * buf, size_t size); + +char *getcwd(char *buf, size_t size) +{ + return ( __getcwd(buf, size) < 0 ) ? NULL : buf; +} diff --git a/libc/unistd/getdtablesize.c b/libc/unistd/getdtablesize.c new file mode 100644 index 0000000..91315a5 --- /dev/null +++ b/libc/unistd/getdtablesize.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/resource.h> +#include <sys/sysconf.h> + +int getdtablesize() +{ + struct rlimit r; + + if (getrlimit(RLIMIT_NOFILE, &r) < 0) { + return sysconf(_SC_OPEN_MAX); + } + return r.rlim_cur; +} diff --git a/libc/unistd/gethostname.c b/libc/unistd/gethostname.c new file mode 100644 index 0000000..369d21e --- /dev/null +++ b/libc/unistd/gethostname.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <sys/utsname.h> + +int gethostname(char* buff, size_t buflen) +{ + struct utsname name; + int result = 0; + + result = uname(&name); + if (result != -1) + { + int namelen = strlen(name.nodename); + + if ((int)buflen < namelen+1) { + errno = EINVAL; + result = -1; + } else { + memcpy( buff, name.nodename, namelen+1 ); + } + } + return result; +} diff --git a/libc/unistd/getopt_long.c b/libc/unistd/getopt_long.c new file mode 100644 index 0000000..dbdf01a --- /dev/null +++ b/libc/unistd/getopt_long.c @@ -0,0 +1,537 @@ +/* $OpenBSD: getopt_long.c,v 1.20 2005/10/25 15:49:37 jmc Exp $ */ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/* + * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <err.h> +#include <errno.h> +#include <getopt.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ + +#ifdef REPLACE_GETOPT +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +char *optarg; /* argument associated with option */ +#endif +int optreset; /* reset getopt */ + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too) +{ + char *current_argv, *has_equal; + size_t current_argv_len; + int i, match; + + current_argv = place; + match = -1; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* partial match */ + match = i; + else { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + fprintf(stderr, + ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return (BADCH); + } + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + fprintf(stderr, + noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + fprintf(stderr, + recargstring, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + fprintf(stderr, illoptstring, current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + char *oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; + + if (options == NULL) + return (-1); + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + */ + if (posixly_correct == -1) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + else if (*options == '-') + flags |= FLAG_ALLARGS; + if (*options == '+' || *options == '-') + options++; + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if (((optchar = (int)*place++) == (int)':') || + (optchar == (int)'-' && *place != '\0') || + (oli = strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; + if (PRINT_ERROR) + fprintf(stderr, illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + fprintf(stderr, recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, + idx, 0); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + /* XXX: disable test for :: if PC? (GNU doesn't) */ + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + fprintf(stderr, recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; + } else if (!(flags & FLAG_PERMUTE)) { + /* + * If permutation is disabled, we can accept an + * optional arg separated by whitespace so long + * as it does not start with a dash (-). + */ + if (optind + 1 < nargc && *nargv[optind + 1] != '-') + optarg = nargv[++optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); +} + +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the BSD getopt] + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} +#endif /* REPLACE_GETOPT */ + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ +int +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} diff --git a/libc/unistd/getpgrp.c b/libc/unistd/getpgrp.c new file mode 100644 index 0000000..af7ced5 --- /dev/null +++ b/libc/unistd/getpgrp.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> + +pid_t getpgrp(void) +{ + return getpgid(0); +} diff --git a/libc/unistd/getpriority.c b/libc/unistd/getpriority.c new file mode 100644 index 0000000..efc9d4e --- /dev/null +++ b/libc/unistd/getpriority.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/resource.h> + +extern int __getpriority(int, int); + +int getpriority(int which, int who) +{ + int result = __getpriority(which, who); + + return ( result < 0 ) ? result : 20-result; +} diff --git a/libc/unistd/getpt.c b/libc/unistd/getpt.c new file mode 100644 index 0000000..8bb5c11 --- /dev/null +++ b/libc/unistd/getpt.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <fcntl.h> + +int getpt(void) +{ + return open("/dev/ptmx", O_RDWR|O_NOCTTY); +} diff --git a/libc/unistd/isatty.c b/libc/unistd/isatty.c new file mode 100644 index 0000000..93af6c5 --- /dev/null +++ b/libc/unistd/isatty.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <unistd.h> +#include <termios.h> +#include <errno.h> + +int +isatty (int fd) +{ + struct termios term; + + return tcgetattr (fd, &term) == 0; +} diff --git a/libc/unistd/issetugid.c b/libc/unistd/issetugid.c new file mode 100644 index 0000000..81f8e41 --- /dev/null +++ b/libc/unistd/issetugid.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> + +int issetugid(void) +{ + /* for Bionic, this is sufficient */ + return 0; +} + diff --git a/libc/unistd/lseek64.c b/libc/unistd/lseek64.c new file mode 100644 index 0000000..017b331 --- /dev/null +++ b/libc/unistd/lseek64.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> + +extern int __llseek(int fd, unsigned long offset_hi, unsigned long offset_lo, loff_t* result, int whence); + +loff_t lseek64(int fd, loff_t off, int whence) +{ + loff_t result; + + if ( __llseek(fd, (unsigned long)(off >> 32),(unsigned long)(off), &result, whence ) < 0 ) + return -1; + + return result; +} diff --git a/libc/unistd/mmap.c b/libc/unistd/mmap.c new file mode 100644 index 0000000..848abbb --- /dev/null +++ b/libc/unistd/mmap.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <errno.h> +#include <sys/mman.h> + +extern void* __mmap2(void*, size_t, int, int, int, size_t); + +#define MMAP2_SHIFT 12 +void* mmap( void* addr, size_t size, int prot, int flags, int fd, long offset ) +{ + if ( offset & ((1UL << MMAP2_SHIFT)-1) ) { + errno = EINVAL; + return MAP_FAILED; + } + + return __mmap2(addr, size, prot, flags, fd, (size_t)offset >> MMAP2_SHIFT); +} diff --git a/libc/unistd/nice.c b/libc/unistd/nice.c new file mode 100644 index 0000000..09b6469 --- /dev/null +++ b/libc/unistd/nice.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/resource.h> + +int nice(int increment) +{ + int priority = getpriority(PRIO_PROCESS, 0); + + return setpriority( PRIO_PROCESS, 0, priority+increment); +} diff --git a/libc/unistd/open.c b/libc/unistd/open.c new file mode 100644 index 0000000..e8b1c89 --- /dev/null +++ b/libc/unistd/open.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <fcntl.h> +#include <stdarg.h> + +extern int __open(const char*, int, int); + +int open(const char *pathname, int flags, ...) +{ + mode_t mode = 0; + +#if !defined(__i386__) + flags |= O_LARGEFILE; +#endif + + if (flags & O_CREAT) + { + va_list args; + + va_start(args, flags); + mode = (mode_t) va_arg(args, int); + va_end(args); + } + + return __open(pathname, flags, mode); +} + diff --git a/libc/unistd/openat.c b/libc/unistd/openat.c new file mode 100644 index 0000000..88b39a4 --- /dev/null +++ b/libc/unistd/openat.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <fcntl.h> +#include <stdarg.h> + +extern int __openat(int, const char*, int, int); + +int openat(int fd, const char *pathname, int flags, ...) +{ + mode_t mode = 0; + +#if !defined(__i386__) + flags |= O_LARGEFILE; +#endif + + if (flags & O_CREAT) + { + va_list args; + + va_start(args, flags); + mode = (mode_t) va_arg(args, int); + va_end(args); + } + + return __openat(fd, pathname, flags, mode); +} + diff --git a/libc/unistd/opendir.c b/libc/unistd/opendir.c new file mode 100644 index 0000000..1b06057 --- /dev/null +++ b/libc/unistd/opendir.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <dirent.h> +#include <memory.h> +#include <string.h> +#include <fcntl.h> +#include <stdlib.h> +#include <pthread.h> +#include <errno.h> + +struct DIR +{ + int _DIR_fd; + size_t _DIR_avail; + struct dirent* _DIR_next; + pthread_mutex_t _DIR_lock; + struct dirent _DIR_buff[15]; +}; + +int dirfd(DIR* dirp) +{ + return dirp->_DIR_fd; +} + +DIR* opendir( const char* dirpath ) +{ + DIR* dir = malloc(sizeof(DIR)); + + if (!dir) + goto Exit; + + dir->_DIR_fd = open(dirpath, O_RDONLY|O_DIRECTORY); + if (dir->_DIR_fd < 0) + { + free(dir); + dir = NULL; + } + else + { + dir->_DIR_avail = 0; + dir->_DIR_next = NULL; + pthread_mutex_init( &dir->_DIR_lock, NULL ); + } +Exit: + return dir; +} + + +DIR* fdopendir(int fd) +{ + DIR* dir = malloc(sizeof(DIR)); + + if (!dir) + return 0; + + dir->_DIR_fd = fd; + dir->_DIR_avail = 0; + dir->_DIR_next = NULL; + pthread_mutex_init( &dir->_DIR_lock, NULL ); + + return dir; +} + + +static struct dirent* +_readdir_unlocked(DIR* dir) +{ + struct dirent* entry; + + if ( !dir->_DIR_avail ) + { + int rc; + + for (;;) { + rc = getdents( dir->_DIR_fd, dir->_DIR_buff, sizeof(dir->_DIR_buff)); + if (rc >= 0 || errno != EINTR) + break; + } + if (rc <= 0) + return NULL; + + dir->_DIR_avail = rc; + dir->_DIR_next = dir->_DIR_buff; + } + + entry = dir->_DIR_next; + + /* perform some sanity checks here */ + if (((long)(void*)entry & 3) != 0) + return NULL; + + if ( (unsigned)entry->d_reclen > sizeof(*entry) || + entry->d_reclen <= offsetof(struct dirent, d_name) ) + goto Bad; + + if ( (char*)entry + entry->d_reclen > (char*)dir->_DIR_buff + sizeof(dir->_DIR_buff) ) + goto Bad; + + if ( !memchr( entry->d_name, 0, entry->d_reclen - offsetof(struct dirent, d_name)) ) + goto Bad; + + dir->_DIR_next = (struct dirent*)((char*)entry + entry->d_reclen); + dir->_DIR_avail -= entry->d_reclen; + + return entry; + + Bad: + errno = EINVAL; + return NULL; +} + + +struct dirent* +readdir(DIR * dir) +{ + struct dirent *entry = NULL; + + pthread_mutex_lock( &dir->_DIR_lock ); + entry = _readdir_unlocked(dir); + pthread_mutex_unlock( &dir->_DIR_lock ); + + return entry; +} + + +int readdir_r(DIR* dir, struct dirent *entry, struct dirent **result) +{ + struct dirent* ent; + int save_errno = errno; + int retval; + + *result = NULL; + errno = 0; + + pthread_mutex_lock( &dir->_DIR_lock ); + + ent = _readdir_unlocked(dir); + retval = errno; + if (ent == NULL) { + if (!retval) { + errno = save_errno; + } + } else { + if (!retval) { + errno = save_errno; + *result = entry; + memcpy( entry, ent, ent->d_reclen ); + } + } + + pthread_mutex_unlock( &dir->_DIR_lock ); + + return retval; +} + + + +int closedir(DIR *dir) +{ + int rc; + + rc = close(dir->_DIR_fd); + dir->_DIR_fd = -1; + + pthread_mutex_destroy( &dir->_DIR_lock ); + + free(dir); + return rc; +} + + +void rewinddir(DIR *dir) +{ + pthread_mutex_lock( &dir->_DIR_lock ); + lseek( dir->_DIR_fd, 0, SEEK_SET ); + dir->_DIR_avail = 0; + pthread_mutex_unlock( &dir->_DIR_lock ); +} + diff --git a/libc/unistd/pathconf.c b/libc/unistd/pathconf.c new file mode 100644 index 0000000..032f918 --- /dev/null +++ b/libc/unistd/pathconf.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <pathconf.h> +#include <sys/vfs.h> +#include <sys/limits.h> +#include <linux/ext2_fs.h> +#include <linux/ext3_fs.h> +#include <errno.h> + +/* these may not be defined yet by our headers */ +#ifndef _POSIX_VDISABLE +#define _POSIX_VDISABLE -1 +#endif + +#ifndef _POSIX_SYNC_IO +#define _POSIX_SYNC_IO -1 +#endif + +#ifndef _POSIX_PRIO_IO +#define _POSIX_PRIO_IO -1 +#endif + +#ifndef _POSIX_ASYNC_IO +#define _POSIX_ASYNC_IO -1 +#endif + + +static long +__filesizebits( struct statfs* s ) +{ +#define EOL_MAGIC 0x0000U + + /* list of known 64-bit aware filesystems */ + static const uint32_t known64[] = { + EXT2_SUPER_MAGIC, + UFS_MAGIC, + REISERFS_SUPER_MAGIC, + XFS_SUPER_MAGIC, + SMB_SUPER_MAGIC, + UDF_SUPER_MAGIC, + JFS_SUPER_MAGIC, + NTFS_SB_MAGIC, + VXFS_SUPER_MAGIC, + EOL_MAGIC + }; + int nn = 0; + + for (;;) { + if ( known64[nn] == EOL_MAGIC ) + return 32; + + if ( known64[nn] == s->f_type ) + return 64; + } +} + + +static long +__link_max( struct statfs* s ) +{ + /* constant values were taken from official kernel headers. + * I don't think this justified bringing in <linux/minix_fs.h> et al + * into our cleaned-up kernel three + */ + static const struct { uint32_t type; int max; } knownMax[] = + { + { EXT2_SUPER_MAGIC, EXT2_LINK_MAX }, + { EXT3_SUPER_MAGIC, EXT3_LINK_MAX }, + { MINIX_SUPER_MAGIC, 250 }, + { MINIX2_SUPER_MAGIC, 65530 }, + { REISERFS_SUPER_MAGIC, 0xffff - 1000 }, + { UFS_MAGIC, 32000 }, + { EOL_MAGIC, 0 } + }; + int nn = 0; + + for (;;) { + if ( knownMax[nn].type == EOL_MAGIC ) + return LINK_MAX; + + if ( knownMax[nn].type == s->f_type ) + return knownMax[nn].max; + } + return LINK_MAX; +} + +static long +__2_symlinks( struct statfs* s ) +{ + /* list of know filesystems that don't support symlinks */ + static const uint32_t knownNoSymlinks[] = { + ADFS_SUPER_MAGIC, BFS_MAGIC, CRAMFS_MAGIC, + EFS_SUPER_MAGIC, MSDOS_SUPER_MAGIC, NTFS_SB_MAGIC, + QNX4_SUPER_MAGIC, + EOL_MAGIC + }; + int nn = 0; + + for (;;) { + if (knownNoSymlinks[nn] == 0) + return 1; + if (knownNoSymlinks[nn] == s->f_type) + return 0; + } +} + +static long +__name_max( struct statfs* s ) +{ + return s->f_namelen; +} + +long +pathconf(const char *path, int name) +{ + struct statfs buf; + int ret = statfs( path, &buf ); + + if (ret < 0) + return -1; + + switch (name) { + case _PC_FILESIZEBITS: + return __filesizebits(&buf); + + case _PC_LINK_MAX: + return __link_max(&buf); + + case _PC_MAX_CANON: + return MAX_CANON; + + case _PC_MAX_INPUT: + return MAX_INPUT; + + case _PC_NAME_MAX: + return __name_max(&buf); + + case _PC_PATH_MAX: + return PATH_MAX; + + case _PC_PIPE_BUF: + return PIPE_BUF; + + case _PC_2_SYMLINKS: + return __2_symlinks(&buf); + +#if 0 /* don't know what to do there, the specs are really weird */ + case _PC_ALLOC_SIZE_MIN: + case _PC_REC_INCR_XFER_SIZE: + case _PC_REC_MAX_XFER_SIZE: + case _PC_REC_MIN_XFER_SIZE: + case _PC_REC_XFER_ALIGN: +#endif + + case _PC_SYMLINK_MAX: + return -1; /* no limit */ + + case _PC_CHOWN_RESTRICTED: + return _POSIX_CHOWN_RESTRICTED; + + case _PC_NO_TRUNC: + return _POSIX_NO_TRUNC; + + case _PC_VDISABLE: + return _POSIX_VDISABLE; + + case _PC_ASYNC_IO: + return _POSIX_ASYNC_IO; + + case _PC_PRIO_IO: + return _POSIX_PRIO_IO; + + case _PC_SYNC_IO: + return _POSIX_SYNC_IO; + + default: + errno = EINVAL; + return -1; + } +} + +long fpathconf(int fildes, int name) +{ + struct statfs buf; + int ret = fstatfs(fildes, &buf); + + if (ret < 0) + return -1; + + switch (name) { + case _PC_FILESIZEBITS: + return __filesizebits(&buf); + + case _PC_LINK_MAX: + return __link_max(&buf); + + case _PC_MAX_CANON: + return MAX_CANON; + + case _PC_MAX_INPUT: + return MAX_INPUT; + + case _PC_NAME_MAX: + return __name_max(&buf); + + case _PC_PATH_MAX: + return PATH_MAX; + + case _PC_PIPE_BUF: + return PIPE_BUF; + + case _PC_2_SYMLINKS: + return __2_symlinks(&buf); + +#if 0 /* don't know what to do there, the specs are really weird */ + case _PC_ALLOC_SIZE_MIN: + case _PC_REC_INCR_XFER_SIZE: + case _PC_REC_MAX_XFER_SIZE: + case _PC_REC_MIN_XFER_SIZE: + case _PC_REC_XFER_ALIGN: +#endif + + case _PC_SYMLINK_MAX: + return -1; /* no limit */ + + case _PC_CHOWN_RESTRICTED: + return _POSIX_CHOWN_RESTRICTED; + + case _PC_NO_TRUNC: + return _POSIX_NO_TRUNC; + + case _PC_VDISABLE: + return _POSIX_VDISABLE; + + case _PC_ASYNC_IO: + return _POSIX_ASYNC_IO; + + case _PC_PRIO_IO: + return _POSIX_PRIO_IO; + + case _PC_SYNC_IO: + return _POSIX_SYNC_IO; + + default: + errno = EINVAL; + return -1; + } +} diff --git a/libc/unistd/perror.c b/libc/unistd/perror.c new file mode 100644 index 0000000..de55f72 --- /dev/null +++ b/libc/unistd/perror.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <errno.h> +#include <unistd.h> +#include <string.h> + +void perror(const char *prefix) +{ + char buff[256]; + + strerror_r( errno, buff, sizeof(buff) ); + + if (prefix) { + write( 2, prefix, strlen(prefix) ); + write( 2, ": ", 2 ); + } + write( 2, buff, strlen(buff) ); + write( 2, "\n", 1 ); +} diff --git a/libc/unistd/popen.c b/libc/unistd/popen.c new file mode 100644 index 0000000..15f8325 --- /dev/null +++ b/libc/unistd/popen.c @@ -0,0 +1,167 @@ +/* $OpenBSD: popen.c,v 1.17 2005/08/08 08:05:34 espie Exp $ */ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software written by Ken Arnold and + * published in UNIX Review, Vol. 6, No. 8. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/wait.h> + +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <paths.h> + +static struct pid { + struct pid *next; + FILE *fp; + pid_t pid; +} *pidlist; + +FILE * +popen(const char *program, const char *type) +{ + struct pid * volatile cur; + FILE *iop; + int pdes[2]; + pid_t pid; + + if ((*type != 'r' && *type != 'w') || type[1] != '\0') { + errno = EINVAL; + return (NULL); + } + + if ((cur = malloc(sizeof(struct pid))) == NULL) + return (NULL); + + if (pipe(pdes) < 0) { + free(cur); + return (NULL); + } + + switch (pid = vfork()) { + case -1: /* Error. */ + (void)close(pdes[0]); + (void)close(pdes[1]); + free(cur); + return (NULL); + /* NOTREACHED */ + case 0: /* Child. */ + { + struct pid *pcur; + /* + * because vfork() instead of fork(), must leak FILE *, + * but luckily we are terminally headed for an execl() + */ + for (pcur = pidlist; pcur; pcur = pcur->next) + close(fileno(pcur->fp)); + + if (*type == 'r') { + int tpdes1 = pdes[1]; + + (void) close(pdes[0]); + /* + * We must NOT modify pdes, due to the + * semantics of vfork. + */ + if (tpdes1 != STDOUT_FILENO) { + (void)dup2(tpdes1, STDOUT_FILENO); + (void)close(tpdes1); + tpdes1 = STDOUT_FILENO; + } + } else { + (void)close(pdes[1]); + if (pdes[0] != STDIN_FILENO) { + (void)dup2(pdes[0], STDIN_FILENO); + (void)close(pdes[0]); + } + } + execl(_PATH_BSHELL, "sh", "-c", program, (char *)NULL); + _exit(127); + /* NOTREACHED */ + } + } + + /* Parent; assume fdopen can't fail. */ + if (*type == 'r') { + iop = fdopen(pdes[0], type); + (void)close(pdes[1]); + } else { + iop = fdopen(pdes[1], type); + (void)close(pdes[0]); + } + + /* Link into list of file descriptors. */ + cur->fp = iop; + cur->pid = pid; + cur->next = pidlist; + pidlist = cur; + + return (iop); +} + +/* + * pclose -- + * Pclose returns -1 if stream is not associated with a `popened' command, + * if already `pclosed', or waitpid returns an error. + */ +int +pclose(FILE *iop) +{ + struct pid *cur, *last; + int pstat; + pid_t pid; + + /* Find the appropriate file pointer. */ + for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next) + if (cur->fp == iop) + break; + + if (cur == NULL) + return (-1); + + (void)fclose(iop); + + do { + pid = waitpid(cur->pid, &pstat, 0); + } while (pid == -1 && errno == EINTR); + + /* Remove the entry from the linked list. */ + if (last == NULL) + pidlist = cur->next; + else + last->next = cur->next; + free(cur); + + return (pid == -1 ? -1 : pstat); +} diff --git a/libc/unistd/pread.c b/libc/unistd/pread.c new file mode 100644 index 0000000..7bfaeaa --- /dev/null +++ b/libc/unistd/pread.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> + +/* + * Non-atomic emulation of the pread system call. + */ +ssize_t pread(int fd, void *buf, size_t count, off_t offset) +{ + int save_errno; + ssize_t nread; + off_t save_offset = lseek(fd, offset, SEEK_SET); + if (save_offset < 0) { + return -1; + } + nread = read(fd, buf, count); + save_errno = errno; + /* Even if the read failed, try to restore the seek pointer */ + lseek(fd, save_offset, SEEK_SET); + errno = save_errno; + return nread; +} diff --git a/libc/unistd/pselect.c b/libc/unistd/pselect.c new file mode 100644 index 0000000..76ce2c0 --- /dev/null +++ b/libc/unistd/pselect.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/select.h> +#include <signal.h> +#include <pthread.h> + +int +pselect(int n, fd_set* readfds, fd_set* writefds, fd_set* errfds, + const struct timespec* timeout, const sigset_t* sigmask) +{ + sigset_t oldmask; + int result; + struct timeval tv, *tv_timeout = NULL; + + if (sigmask != NULL) + pthread_sigmask( SIG_SETMASK, sigmask, &oldmask ); + + if (timeout != NULL) { + tv_timeout = &tv; + tv.tv_sec = timeout->tv_sec; + tv.tv_usec = (timeout->tv_nsec + 999)/1000; // round up + if (tv.tv_usec >= 1000000) { + tv.tv_sec += 1; + tv.tv_usec -= 1000000; + } + } + + result = select( n, readfds, writefds, errfds, tv_timeout ); + + if (sigmask != NULL) + pthread_sigmask( SIG_SETMASK, &oldmask, NULL ); + + return result; +} diff --git a/libc/unistd/ptsname.c b/libc/unistd/ptsname.c new file mode 100644 index 0000000..24d5d30 --- /dev/null +++ b/libc/unistd/ptsname.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <stdio.h> +#include <unistd.h> +#include <termios.h> +#include <sys/ioctl.h> + +/* not thread-safe */ +char* ptsname( int fd ) +{ + unsigned int pty_num; + static char buff[64]; + + if ( ioctl( fd, TIOCGPTN, &pty_num ) != 0 ) + return NULL; + + snprintf( buff, sizeof(buff), "/dev/pts/%u", pty_num ); + return buff; +} diff --git a/libc/unistd/ptsname_r.c b/libc/unistd/ptsname_r.c new file mode 100644 index 0000000..1ed067b --- /dev/null +++ b/libc/unistd/ptsname_r.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <stdio.h> +#include <unistd.h> +#include <termios.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <string.h> + +char* ptsname_r( int fd, char* buf, size_t buflen) +{ + unsigned int pty_num; + char buff[64]; + int len; + + if (buf == NULL) { + errno = EINVAL; + return NULL; + } + + if ( ioctl( fd, TIOCGPTN, &pty_num ) != 0 ) + return NULL; + + len = snprintf( buff, sizeof(buff), "/dev/pts/%u", pty_num ); + if (len+1 > (int)buflen) { + errno = ERANGE; + return NULL; + } + memcpy( buf, buff, len+1 ); + return buf; +} diff --git a/libc/unistd/pwrite.c b/libc/unistd/pwrite.c new file mode 100644 index 0000000..7f5e071 --- /dev/null +++ b/libc/unistd/pwrite.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> + +/* + * Non-atomic emulation of the pwrite system call. + */ +ssize_t pwrite(int fd, void *buf, size_t count, off_t offset) +{ + int save_errno; + ssize_t nwrite; + off_t save_offset = lseek(fd, offset, SEEK_SET); + if (save_offset < 0) { + return -1; + } + nwrite = write(fd, buf, count); + save_errno = errno; + /* Even if the write failed, try to restore the seek pointer */ + lseek(fd, save_offset, SEEK_SET); + errno = save_errno; + return nwrite; +} diff --git a/libc/unistd/raise.c b/libc/unistd/raise.c new file mode 100644 index 0000000..de099da --- /dev/null +++ b/libc/unistd/raise.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <signal.h> + +int raise(int signum) +{ + return kill(getpid(), signum); +} diff --git a/libc/unistd/reboot.c b/libc/unistd/reboot.c new file mode 100644 index 0000000..0fe8cdc --- /dev/null +++ b/libc/unistd/reboot.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <sys/reboot.h> + +int reboot (int mode) +{ + return __reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, mode, NULL ); +} diff --git a/libc/unistd/recv.c b/libc/unistd/recv.c new file mode 100644 index 0000000..779d7fa --- /dev/null +++ b/libc/unistd/recv.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <stddef.h> +#include <sys/socket.h> + +ssize_t recv(int socket, void *buf, size_t buflen, unsigned int flags) +{ + return recvfrom(socket, buf, buflen, flags, NULL, 0); +} diff --git a/libc/unistd/sbrk.c b/libc/unistd/sbrk.c new file mode 100644 index 0000000..a112b6c --- /dev/null +++ b/libc/unistd/sbrk.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <errno.h> + + +#define SBRK_ALIGN 32 + +/* shared with brk() implementation */ +char* __bionic_brk; + +void *sbrk(ptrdiff_t increment) +{ + char* start; + char* end; + char* new_brk; + + if ( !__bionic_brk) + __bionic_brk = __brk((void*)0); + + start = (char*)(((long)__bionic_brk + SBRK_ALIGN-1) & ~(SBRK_ALIGN-1)); + end = start + increment; + + new_brk = __brk(end); + if (new_brk == (void*)-1) + return new_brk; + else if (new_brk < end) + { + errno = ENOMEM; + return (void*)-1; + } + + __bionic_brk = new_brk; + return start; +} diff --git a/libc/unistd/send.c b/libc/unistd/send.c new file mode 100644 index 0000000..9978f98 --- /dev/null +++ b/libc/unistd/send.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <stddef.h> +#include <sys/socket.h> + +ssize_t send(int socket, const void *buf, size_t buflen, unsigned int flags) +{ + return (ssize_t) sendto(socket, buf, buflen, flags, NULL, 0); +} diff --git a/libc/unistd/setegid.c b/libc/unistd/setegid.c new file mode 100644 index 0000000..9bd697b --- /dev/null +++ b/libc/unistd/setegid.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> + +int setegid(gid_t egid) +{ + return setresgid(-1, egid, -1); +} diff --git a/libc/unistd/seteuid.c b/libc/unistd/seteuid.c new file mode 100644 index 0000000..42ee780 --- /dev/null +++ b/libc/unistd/seteuid.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> + +int seteuid(uid_t euid) +{ + return setresuid(-1, euid,-1); +} diff --git a/libc/unistd/setpgrp.c b/libc/unistd/setpgrp.c new file mode 100644 index 0000000..6dff822 --- /dev/null +++ b/libc/unistd/setpgrp.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> + +int setpgrp(void) +{ + return setpgid(0,0); +} diff --git a/libc/unistd/sigblock.c b/libc/unistd/sigblock.c new file mode 100644 index 0000000..863d7da --- /dev/null +++ b/libc/unistd/sigblock.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <signal.h> + +/* this function is called from the ARM assembly setjmp fragments */ +int +sigblock(int mask) +{ + int n; + union { + int the_mask; + sigset_t the_sigset; + } in, out; + + in.the_mask = mask; + + n = sigprocmask(SIG_BLOCK, &in.the_sigset, &out.the_sigset); + if (n) + return n; + + return out.the_mask; +} + + diff --git a/libc/unistd/siglist.c b/libc/unistd/siglist.c new file mode 100644 index 0000000..a2ac9fe --- /dev/null +++ b/libc/unistd/siglist.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <signal.h> + +const char * const sys_siglist[NSIG] = { +#define __BIONIC_SIGDEF(x,y,z) [ x ] = z, +#include <sys/_sigdefs.h> +}; diff --git a/libc/unistd/signal.c b/libc/unistd/signal.c new file mode 100644 index 0000000..949db13 --- /dev/null +++ b/libc/unistd/signal.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <signal.h> + + +static __sighandler_t +_signal(int signum, __sighandler_t handler, int flags) +{ + struct sigaction sa; + __sighandler_t result = SIG_ERR; + + sigemptyset( &sa.sa_mask ); + + sa.sa_handler = handler; + sa.sa_flags = flags; + + if ( !sigaction( signum, &sa, &sa ) ) + result = (__sighandler_t) sa.sa_handler; + + return result; +} + + +__sighandler_t bsd_signal(int signum, __sighandler_t handler) +{ + return _signal(signum, handler, SA_RESTART); +} + +__sighandler_t sysv_signal(int signum, __sighandler_t handler) +{ + return _signal(signum, handler, SA_RESETHAND); +} diff --git a/libc/unistd/sigsetmask.c b/libc/unistd/sigsetmask.c new file mode 100644 index 0000000..b987595 --- /dev/null +++ b/libc/unistd/sigsetmask.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <signal.h> + +/* called from setjmp assembly fragment */ +int +sigsetmask(int mask) +{ + int n; + + union { + int the_mask; + sigset_t the_sigset; + } in, out; + + n = sigprocmask(SIG_SETMASK, &in.the_sigset, &out.the_sigset); + if (n) + return n; + + return out.the_mask; +} + diff --git a/libc/unistd/sigsuspend.c b/libc/unistd/sigsuspend.c new file mode 100644 index 0000000..0db05ed --- /dev/null +++ b/libc/unistd/sigsuspend.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <signal.h> + +extern int __sigsuspend(int, int, unsigned int); + +int sigsuspend(const sigset_t *_mask) +{ + unsigned int mask = (unsigned int)*_mask; + + return __sigsuspend(0, 0, mask); +} diff --git a/libc/unistd/sigwait.c b/libc/unistd/sigwait.c new file mode 100644 index 0000000..c9c2a54 --- /dev/null +++ b/libc/unistd/sigwait.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <errno.h> +#include <signal.h> +#include <string.h> +#include <time.h> + +int __rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo, const struct timespec *uts, size_t sigsetsize); + +/* ok, this is really subtle: <asm/signal.h> defines sigset_t differently + * when you're in the kernel or in the C library. + * + * in the kernel, this is an array of 2 32-bit unsigned longs + * in the C library, this is a single 32-bit unsigned long + * + * moreover, the kernel implementation of rt_sigtimedwait doesn't + * accept anything except kernel-sized signal sets (probably a bug !) + * + * we thus need to create a fake kernel sigset !! + */ + +int sigwait(const sigset_t *set, int *sig) +{ + int ret; + /* use a union to get rid of aliasing warnings */ + union { + unsigned long kernel_sigset[2]; + sigset_t dummy_sigset; + } u; + + u.kernel_sigset[0] = *set; + u.kernel_sigset[1] = 0; /* no real-time signals supported ? */ + for (;;) + { + /* __rt_sigtimedwait can return EAGAIN or EINTR, we need to loop + * around them since sigwait is only allowed to return EINVAL + */ + ret = __rt_sigtimedwait ( &u.dummy_sigset, NULL, NULL, sizeof(u.kernel_sigset)); + if (ret >= 0) + break; + + if (errno != EAGAIN && errno != EINTR) + return errno; + } + + *sig = ret; + return 0; +} + diff --git a/libc/unistd/sleep.c b/libc/unistd/sleep.c new file mode 100644 index 0000000..aafbd60 --- /dev/null +++ b/libc/unistd/sleep.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <time.h> +#include <errno.h> + +unsigned int sleep(unsigned int seconds) +{ + struct timespec t; + + /* seconds is unsigned, while t.tv_sec is signed + * some people want to do sleep(UINT_MAX), so fake + * support for it by only sleeping 2 billion seconds + */ + if ((int)seconds < 0) + seconds = 0x7fffffff; + + t.tv_sec = seconds; + t.tv_nsec = 0; + + if ( !nanosleep( &t, &t ) ) + return 0; + + if ( errno == EINTR ) + return t.tv_sec; + + return -1; +} diff --git a/libc/unistd/socketcalls.c b/libc/unistd/socketcalls.c new file mode 100644 index 0000000..d97abc2 --- /dev/null +++ b/libc/unistd/socketcalls.c @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <sys/socket.h> +#include <sys/linux-syscalls.h> + +enum +{ + SYS_SOCKET = 1, + SYS_BIND, + SYS_CONNECT, + SYS_LISTEN, + SYS_ACCEPT, + SYS_GETSOCKNAME, + SYS_GETPEERNAME, + SYS_SOCKETPAIR, + SYS_SEND, + SYS_RECV, + SYS_SENDTO, + SYS_RECVFROM, + SYS_SHUTDOWN, + SYS_SETSOCKOPT, + SYS_GETSOCKOPT, + SYS_SENDMSG, + SYS_RECVMSG +}; + +#ifndef __NR_socket +int socket(int domain, int type, int protocol) +{ + unsigned long t[3]; + + t[0] = (unsigned long) domain; + t[1] = (unsigned long) type; + t[2] = (unsigned long) protocol; + + return (int) __socketcall( SYS_SOCKET, t ); +} +#endif /* !__NR_socket */ + + +#ifndef __NR_bind +int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen) +{ + unsigned long t[3]; + + t[0] = (unsigned long) sockfd; + t[1] = (unsigned long) my_addr; + t[2] = (unsigned long) addrlen; + + return (int) __socketcall( SYS_BIND, t ); +} +#endif /* !__NR_bind */ + +#ifndef __NR_connect +int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen ) +{ + unsigned long t[3]; + + t[0] = (unsigned long) sockfd; + t[1] = (unsigned long) serv_addr; + t[2] = (unsigned long) addrlen; + + return (int) __socketcall( SYS_CONNECT, t ); +} +#endif /* !__NR_connect */ + +#ifndef __NR_listen +int listen(int s, int backlog) +{ + unsigned long t[2]; + + t[0] = (unsigned long) s; + t[1] = (unsigned long) backlog; + + return (int) __socketcall( SYS_LISTEN, t ); +} +#endif /* __NR_listen */ + +#ifndef __NR_accept +int accept(int sock, struct sockaddr *adresse, socklen_t *longueur) +{ + unsigned long t[3]; + + t[0] = (unsigned long) sock; + t[1] = (unsigned long) adresse; + t[2] = (unsigned long) longueur; + + return (int) __socketcall( SYS_ACCEPT, t ); +} +#endif /* __NR_accept */ + +#ifndef __NR_getsockname +int getsockname(int s, struct sockaddr * name, socklen_t * namelen ) +{ + unsigned long t[3]; + + t[0] = (unsigned long) s; + t[1] = (unsigned long) name; + t[2] = (unsigned long) namelen; + + return (int) __socketcall( SYS_GETSOCKNAME, t ); +} +#endif /* __NR_getsockname */ + +#ifndef __NR_getpeername +int getpeername(int s, struct sockaddr *name, socklen_t *namelen) +{ + unsigned long t[3]; + + t[0] = (unsigned long) s; + t[1] = (unsigned long) name; + t[2] = (unsigned long) namelen; + + return (int) __socketcall( SYS_GETPEERNAME, t ); +} +#endif /* !__NR_getpeername */ + +#ifndef __NR_socketpair +int socketpair(int d, int type, int protocol, int sv[2]) +{ + unsigned long t[4]; + + t[0] = (unsigned long) d; + t[1] = (unsigned long) type; + t[2] = (unsigned long) protocol; + t[3] = (unsigned long) sv; + + return (int) __socketcall( SYS_SOCKETPAIR, t ); +} +#endif /* __NR_socketpair */ + +#ifndef __NR_sendto +ssize_t sendto(int socket, const void *message, size_t length, int flags, + const struct sockaddr *dest_addr, socklen_t dest_len) +{ + unsigned long t[6]; + + t[0] = (unsigned long) socket; + t[1] = (unsigned long) message; + t[2] = (unsigned long) length; + t[3] = (unsigned long) flags; + t[4] = (unsigned long) dest_addr; + t[5] = (unsigned long) dest_len; + + return __socketcall( SYS_SENDTO, t ); +} +#endif /* !__NR_sendto */ + +#ifndef __NR_recvfrom +ssize_t recvfrom(int socket, void *buffer, size_t length, unsigned int flags, + const struct sockaddr *address, socklen_t *address_len) +{ + unsigned long t[6]; + + t[0] = (unsigned long) socket; + t[1] = (unsigned long) buffer; + t[2] = (unsigned long) length; + t[3] = (unsigned long) flags; + t[4] = (unsigned long) address; + t[5] = (unsigned long) address_len; + + return __socketcall( SYS_RECVFROM, t ); +} +#endif /* !__NR_recvfrom */ + +#ifndef __NR_shutdown +int shutdown(int socket, int how) +{ + unsigned long t[2]; + + t[0] = (unsigned long) socket; + t[1] = (unsigned long) how; + + return (int) __socketcall( SYS_SHUTDOWN, t ); +} +#endif /* !__NR_shutdown */ + +#ifndef __NR_setsockopt +int setsockopt( int s, int level, int optname, const void* optval, socklen_t optlen ) +{ + unsigned long t[5]; + + t[0] = (unsigned long) s; + t[1] = (unsigned long) level; + t[2] = (unsigned long) optname; + t[3] = (unsigned long) optval; + t[4] = (unsigned long) optlen; + + return (int) __socketcall( SYS_SETSOCKOPT, t ); +} +#endif /* !__NR_setsockopt */ + +#ifndef __NR_getsockopt +int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + unsigned long t[5]; + + t[0] = (unsigned long) s; + t[1] = (unsigned long) level; + t[2] = (unsigned long) optname; + t[3] = (unsigned long) optval; + t[4] = (unsigned long) optlen; + + return (int) __socketcall( SYS_GETSOCKOPT, t ); +} +#endif /* !__NR_getsockopt */ + +#ifndef __NR_sendmsg +ssize_t sendmsg (int socket, const struct msghdr *message, unsigned int flags) +{ + unsigned long t[3]; + + t[0] = (unsigned long) socket; + t[1] = (unsigned long) message; + t[2] = (unsigned long) flags; + + return __socketcall( SYS_SENDMSG, t ); +} +#endif /* __NR_sendmsg */ + +#ifndef __NR_recvmsg +ssize_t recvmsg(int socket, struct msghdr *message, unsigned int flags) +{ + unsigned long t[3]; + + t[0] = (unsigned long) socket; + t[1] = (unsigned long) message; + t[2] = (unsigned long) flags; + + return __socketcall( SYS_RECVMSG, t ); +} +#endif /* __NR_recvmsg */ + diff --git a/libc/unistd/statfs.c b/libc/unistd/statfs.c new file mode 100644 index 0000000..491ef7a --- /dev/null +++ b/libc/unistd/statfs.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/vfs.h> + +extern int __statfs64(const char *, size_t, struct statfs *); + +int statfs(const char* path, struct statfs* stat) +{ + return __statfs64(path, sizeof(struct statfs), stat); +} diff --git a/libc/unistd/strsignal.c b/libc/unistd/strsignal.c new file mode 100644 index 0000000..171de3d --- /dev/null +++ b/libc/unistd/strsignal.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <signal.h> +#include <string.h> + +char* +strsignal(int sig) +{ + if ((unsigned)sig < NSIG) + return (char*) sys_siglist[sig]; + else + return "Invalid signal number"; +} diff --git a/libc/unistd/sysconf.c b/libc/unistd/sysconf.c new file mode 100644 index 0000000..a19edbb --- /dev/null +++ b/libc/unistd/sysconf.c @@ -0,0 +1,434 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <sys/sysconf.h> +#include <limits.h> +#include <sys/tls.h> +#include <asm/page.h> +#include <stdio.h> /* for FOPEN_MAX */ +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <ctype.h> + +/* seems to be the default on Linux, per the GLibc sources and my own digging */ + +#define SYSTEM_CLK_TCK 100 +#define SYSTEM_IOV_MAX 1024 +#define SYSTEM_DELAYTIMER_MAX 2147483647 +#define SYSTEM_MQ_OPEN_MAX 8 +#define SYSTEM_MQ_PRIO_MAX 32768 +#define SYSTEM_SEM_NSEMS_MAX 256 +#define SYSTEM_SEM_VALUE_MAX (2147483647) +#define SYSTEM_SIGQUEUE_MAX 32 +#define SYSTEM_TIMER_MAX 32 +#define SYSTEM_LOGIN_NAME_MAX 256 +#define SYSTEM_TTY_NAME_MAX 32 + +/* the following depends on our implementation */ +#define SYSTEM_ATEXIT_MAX 65536 /* our implementation is unlimited */ +#define SYSTEM_THREAD_KEYS_MAX BIONIC_TLS_SLOTS +#define SYSTEM_THREAD_STACK_MIN 32768 /* lower values may be possible, but be conservative */ +#define SYSTEM_THREAD_THREADS_MAX 2048 /* really unlimited */ + +#define SYSTEM_2_C_BIND _POSIX_VERSION /* Posix C binding version */ +#define SYSTEM_2_C_VER _POSIX2_C_VERSION +#define SYSTEM_2_C_DEV -1 /* Posix C development tools unsupported on the device */ +#define SYSTEM_2_FORT_DEV -1 /* Fortran development unsupported */ +#define SYSTEM_2_FORT_RUN -1 /* Fortran runtime unsupported */ +#define SYSTEM_2_SW_DEV -1 /* posix software dev utilities unsupported */ +#define SYSTEM_2_LOCALEDEF -1 /* localdef() unimplemented */ +#define SYSTEM_2_UPE -1 /* No UPE for you ! (User Portability Utilities) */ +#define SYSTEM_2_VERSION -1 /* No posix command-line tools */ + +static int __get_nproc_conf(void); +static int __get_nproc_onln(void); +static int __get_phys_pages(void); +static int __get_avphys_pages(void); + +int +sysconf( int name ) +{ + switch (name) { +#ifdef _POSIX_ARG_MAX + case _SC_ARG_MAX: return _POSIX_ARG_MAX; +#endif +#ifdef _POSIX2_BC_BASE_MAX + case _SC_BC_BASE_MAX: return _POSIX2_BC_BASE_MAX; +#endif +#ifdef _POSIX2_BC_DIM_MAX + case _SC_BC_DIM_MAX: return _POSIX2_BC_DIM_MAX; +#endif +#ifdef _POSIX2_BC_SCALE_MAX + case _SC_BC_SCALE_MAX: return _POSIX2_BC_SCALE_MAX; +#endif +#ifdef _POSIX2_BC_STRING_MAX + case _SC_BC_STRING_MAX: return _POSIX2_BC_STRING_MAX; +#endif + case _SC_CHILD_MAX: return CHILD_MAX; + case _SC_CLK_TCK: return SYSTEM_CLK_TCK; +#ifdef _POSIX2_COLL_WEIGHTS_MASK + case _SC_COLL_WEIGHTS_MAX: return _POSIX2_COLL_WEIGHTS_MASK; +#endif +#ifdef _POSIX2_EXPR_NEST_MAX + case _SC_EXPR_NEXT_MASK: return _POSIX2_EXPR_NEST_MAX; +#endif +#ifdef _POSIX2_LINE_MAX + case _SC_LINE_MAX: return _POSIX2_LINE_MAX; +#endif + case _SC_NGROUPS_MAX: return NGROUPS_MAX; + case _SC_OPEN_MAX: return OPEN_MAX; + //case _SC_PASS_MAX: return PASS_MAX; + case _SC_2_C_BIND: return SYSTEM_2_C_BIND; + case _SC_2_C_DEV: return SYSTEM_2_C_DEV; + case _SC_2_C_VERSION: return SYSTEM_2_C_VER; + //case _SC_2_CHAR_TERM: return ; + case _SC_2_FORT_DEV: return SYSTEM_2_FORT_DEV; + case _SC_2_FORT_RUN: return SYSTEM_2_FORT_RUN; + case _SC_2_LOCALEDEF: return SYSTEM_2_LOCALEDEF; + case _SC_2_SW_DEV: return SYSTEM_2_SW_DEV; + case _SC_2_UPE: return SYSTEM_2_UPE; + case _SC_2_VERSION: return SYSTEM_2_VERSION; +#ifdef _POSIX_JOB_CONTROL + case _SC_JOB_CONTROL: return _POSIX_JOB_CONTROL; +#endif +#ifdef _POSIX_SAVED_IDS + case _SC_SAVED_IDS: return _POSIX_SAVED_IDS; +#endif +#ifdef _POSIX_VERSION + case _SC_VERSION: return _POSIX_VERSION; +#endif + //case _SC_RE_DUP_<AX: return ; + case _SC_STREAM_MAX: return FOPEN_MAX; + //case _SC_TZNAME_MAX: return ; +#if _XOPEN_CRYPT + case _SC_XOPEN_CRYPT: return _XOPEN_CRYPT; +#endif +#ifdef _XOPEN_ENH_I18N + case _SC_XOPEN_ENH_I18N: return _XOPEN_ENH_I18N; +#endif +#ifdef _XOPEN_SHM + case _SC_XOPEN_SHM: return _XOPEN_SHM; +#endif +#ifdef _XOPEN_VERSION + case _SC_XOPEN_VERSION: return _XOPEN_VERSION; +#endif +#ifdef _XOPEN_XCU_VERSION + case _SC_XOPEN_XCU_VERSION: return _XOPEN_XCU_VERSION; +#endif +#ifdef _XOPEN_REALTIME + case _SC_XOPEN_REALTIME: return _XOPEN_REALTIME; +#endif +#ifdef _XOPEN_REALTIME_THREADS + case _SC_XOPEN_REALTIME_THREADS: return _XOPEN_REALTIME_THREADS; +#endif +#ifdef _XOPEN_LEGACY + case _SC_XOPEN_LEGACY: return _XOPEN_LEGACY; +#endif + case _SC_ATEXIT_MAX: return SYSTEM_ATEXIT_MAX; + case _SC_IOV_MAX: return SYSTEM_IOV_MAX; + case _SC_PAGESIZE: return PAGE_SIZE; + case _SC_PAGE_SIZE: return PAGE_SIZE; +#ifdef _XOPEN_UNIX + case _SC_XOPEN_UNIX: return _XOPEN_UNIX; +#endif + + // XXX: TODO: XBS5 nonsense + +#ifdef AIO_LISTIO_MAX + case _SC_AIO_LISTIO_MAX: return AIO_LISTIO_MAX; +#endif +#ifdef AIO_MAX + case _SC_AIO_MAX: return AIO_MAX; +#endif +#ifdef AIO_PRIO_DELTA_MAX + case _SC_AIO_PRIO_DELTA_MAX: return AIO_PRIO_DELTA_MAX; +#endif + case _SC_DELAYTIMER_MAX: return SYSTEM_DELAYTIMER_MAX; + case _SC_MQ_OPEN_MAX: return SYSTEM_MQ_OPEN_MAX; + case _SC_MQ_PRIO_MAX: return SYSTEM_MQ_PRIO_MAX; + case _SC_RTSIG_MAX: return RTSIG_MAX; + case _SC_SEM_NSEMS_MAX: return SYSTEM_SEM_NSEMS_MAX; + case _SC_SEM_VALUE_MAX: return SYSTEM_SEM_VALUE_MAX; + case _SC_SIGQUEUE_MAX: return SYSTEM_SIGQUEUE_MAX; + case _SC_TIMER_MAX: return SYSTEM_TIMER_MAX; +#ifdef _POSIX_ASYNCHRONOUS_IO + case _SC_ASYNCHRONOUS_IO: return _POSIX_ASYNCHRONOUS_IO; +#endif +#ifdef _POSIX_FSYNC + case _SC_FSYNC: return _POSIX_FSYNC; +#endif +#ifdef _POSIX_MAPPED_FILES + case _SC_MAPPED_FILES: return _POSIX_MAPPED_FILES; +#endif +#ifdef _POSIX_MEMLOCK + case _SC_MEMLOCK: return _POSIX_MEMLOCK; +#endif +#ifdef _POSIX_MEMLOCK_RANGE + case _SC_MEMLOCK_RANGE: return _POSIX_MEMLOCK_RANGE +#endif +#ifdef _POSIX_MEMORY_PROTECTION + case _SC_MEMORY_PROTECTION: return _POSIX_MEMORY_PROTECTION; +#endif +#ifdef _POSIX_MESSAGE_PASSING + case _SC_MESSAGE_PASSING: return _POSIX_MESSAGE_PASSING; +#endif +#ifdef _POSIX_PRIORITIZED_IO + case _SC_PRIORITIZED_IO: return _POSIX_PRIORITIZED_IO; +#endif +#ifdef _POSIX_PRIORITY_SCHEDULING + case _SC_PRIORITY_SCHEDULING: return _POSIX_PRIORITY_SCHEDULING; +#endif +#ifdef _POSIX_REALTIME_SIGNALS + case _SC_REALTIME_SIGNALS: return _POSIX_REALTIME_SIGNALS; +#endif +#ifdef _POSIX_SEMAPHORES + case _SC_SEMAPHORES: return _POSIX_SEMAPHORES; +#endif +#ifdef _POSIX_SHARED_MEMORY_OBJECTS + case _SC_SHARED_MEMORY_OBJECTS: return _POSIX_SHARED_MEMORY_OBJECTS; +#endif +#ifdef _POSIX_SYNCHRONIZED_IO + case _SC_SYNCHRONIZED_IO: return _POSIX_SYNCHRONIZED_IO; +#endif +#ifdef _POSIX_TIMERS + case _SC_TIMERS: return _POSIX_TIMERS; +#endif + + // GETGR_R_SIZE_MAX ? + // GETPW_R_SIZE_MAX ? + + case _SC_LOGIN_NAME_MAX: return SYSTEM_LOGIN_NAME_MAX; +#ifdef _POSIX_THREAD_DESTRUCTOR_ITERATIONS + case _SC_THREAD_DESTRUCTOR_ITERATIONS: return _POSIX_THREAD_DESTRUCTOR_ITERATIONS; +#endif + case _SC_THREAD_KEYS_MAX: return SYSTEM_THREAD_KEYS_MAX; + case _SC_THREAD_STACK_MIN: return SYSTEM_THREAD_STACK_MIN; + case _SC_THREAD_THREADS_MAX: return SYSTEM_THREAD_THREADS_MAX; + case _SC_TTY_NAME_MAX: return SYSTEM_TTY_NAME_MAX; +#ifdef _POSIX_THREADS + case _SC_THREADS: return _POSIX_THREADS; +#endif +#ifdef _POSIX_THREAD_ATTR_STACKADDR + case _SC_THREAD_ATTR_STACKADDR: return _POSIX_THREAD_ATTR_STACKADDR; +#endif +#ifdef _POSIX_THREAD_ATTR_STACKSIZE + case _SC_THREAD_ATTR_STACKSIZE: return _POSIX_THREAD_ATTR_STACKSIZE; +#endif +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING + case _SC_THREAD_PRIORITY_SCHEDULING: return _POSIX_THREAD_PRIORITY_SCHEDULING; +#endif +#ifdef _POSIX_THREAD_PRIO_INHERIT + case _SC_THREAD_PRIO_INHERIT: return _POSIX_THREAD_PRIO_INHERIT; +#endif +#ifdef _POSIX_THREAD_PRIO_PROTECT + case _SC_THREAD_PRIO_PROTECT: return _POSIX_THREAD_PRIO_PROTECT; +#endif +#ifdef _POSIX_THREAD_SAFE_FUNCTIONS + case _SC_THREAD_SAFE_FUNCTIONS: return _POSIX_THREAD_SAFE_FUNCTIONS +#endif + + + case _SC_NPROCESSORS_CONF: return __get_nproc_conf(); + case _SC_NPROCESSORS_ONLN: return __get_nproc_onln(); + case _SC_PHYS_PAGES: return __get_phys_pages(); + case _SC_AVPHYS_PAGES: return __get_avphys_pages(); + + default: + /* Posix says EINVAL is the only error that shall be returned, + * but GLibc uses ENOSYS */ + errno = ENOSYS; + return -1; + } +} + + +typedef struct { + int rpos; + int len; + int overflow; + int fd; + int in_len; + int in_pos; + char buff[128]; + char input[128]; +} LineParser; + +static int +line_parser_init( LineParser* p, const char* path ) +{ + p->rpos = 0; + p->len = (int)sizeof(p->buff); + p->overflow = 0; + + p->in_len = 0; + p->in_pos = 0; + p->fd = open( path, O_RDONLY ); + + return p->fd; +} + + +static int +line_parser_addc( LineParser* p, int c ) +{ + if (p->overflow) { + p->overflow = (c == '\n'); + return 0; + } + if (p->rpos >= p->len) { + p->overflow = 1; + return 0; + } + if (c == '\n') { + p->buff[p->rpos] = 0; + p->rpos = 0; + return 1; + } + p->buff[p->rpos++] = (char) c; + return 0; +} + +static int +line_parser_getc( LineParser* p ) +{ + if (p->in_len >= p->in_pos) { + int ret; + + p->in_len = p->in_pos = 0; + do { + ret = read(p->fd, p->input, sizeof(p->input)); + } while (ret < 0 && errno == EINTR); + + if (ret <= 0) + return -1; + + p->in_len = ret; + } + return p->input[ p->in_pos++ ]; +} + +static const char* +line_parser_gets( LineParser* p ) +{ + for (;;) { + for (;;) { + int c = line_parser_getc(p); + + if (c < 0) { + close(p->fd); + p->fd = -1; + return NULL; + } + if (line_parser_addc(p, c)) + return p->buff; + } + } +} + +static void +line_parser_done( LineParser* p ) +{ + if (p->fd >= 0) { + close(p->fd); + p->fd = -1; + } +} + +static int +__get_nproc_conf(void) +{ + LineParser parser[1]; + const char* p; + int count = 0; + + if (line_parser_init(parser, "/proc/cpuinfo") < 0) + return 1; + + while ((p = line_parser_gets(parser))) { + if ( !memcmp(p, "processor", 9) ) + count += 1; + } + return (count < 1) ? 1 : count; +} + + +static int +__get_nproc_onln(void) +{ + LineParser parser[1]; + const char* p; + int count = 0; + + if (line_parser_init(parser, "/proc/stat") < 0) + return 1; + + while ((p = line_parser_gets(parser))) { + if ( !memcmp(p, "cpu", 3) && isdigit(p[3]) ) + count += 1; + } + return (count < 1) ? 1 : count; +} + +static int +__get_phys_pages(void) +{ + LineParser parser[1]; + const char* p; + + if (line_parser_init(parser, "/proc/meminfo") < 0) + return -2; /* what ? */ + + while ((p = line_parser_gets(parser))) { + long total; + if ( sscanf(p, "MemTotal: %ld kB", &total) == 1 ) { + line_parser_done(parser); + return (int) (total / (PAGE_SIZE/1024)); + } + } + return -3; +} + +static int +__get_avphys_pages(void) +{ + LineParser parser[1]; + const char* p; + + if (line_parser_init(parser, "/proc/meminfo") < 0) + return -1; /* what ? */ + + while ((p = line_parser_gets(parser))) { + long total; + if ( sscanf(p, "MemFree: %ld kB", &total) == 1 ) { + line_parser_done(parser); + return (int) (total / (PAGE_SIZE/1024)); + } + } + return -1; +} diff --git a/libc/unistd/syslog.c b/libc/unistd/syslog.c new file mode 100644 index 0000000..3571d59 --- /dev/null +++ b/libc/unistd/syslog.c @@ -0,0 +1,368 @@ +/* $OpenBSD: syslog.c,v 1.28 2005/08/08 08:05:34 espie Exp $ */ +/* + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include <syslog.h> +#include <sys/un.h> +#include <netdb.h> + +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <stdarg.h> + +static struct syslog_data sdata = SYSLOG_DATA_INIT; + +extern char *__progname; /* Program name, from crt0. */ + +static void disconnectlog_r(struct syslog_data *); /* disconnect from syslogd */ +static void connectlog_r(struct syslog_data *); /* (re)connect to syslogd */ + +/* + * syslog, vsyslog -- + * print message on log file; output is intended for syslogd(8). + */ +void +syslog(int pri, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsyslog(pri, fmt, ap); + va_end(ap); +} + +void +vsyslog(int pri, const char *fmt, va_list ap) +{ + vsyslog_r(pri, &sdata, fmt, ap); +} + +void +openlog(const char *ident, int logstat, int logfac) +{ + openlog_r(ident, logstat, logfac, &sdata); +} + +void +closelog(void) +{ + closelog_r(&sdata); +} + +/* setlogmask -- set the log mask level */ +int +setlogmask(int pmask) +{ + return setlogmask_r(pmask, &sdata); +} + +/* Reentrant version of syslog, i.e. syslog_r() */ + +void +syslog_r(int pri, struct syslog_data *data, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsyslog_r(pri, data, fmt, ap); + va_end(ap); +} + +void +vsyslog_r(int pri, struct syslog_data *data, const char *fmt, va_list ap) +{ + int cnt; + char ch, *p, *t; + time_t now; + int fd, saved_errno, error; +#define TBUF_LEN 2048 +#define FMT_LEN 1024 + char *stdp = NULL, tbuf[TBUF_LEN], fmt_cpy[FMT_LEN]; + int tbuf_left, fmt_left, prlen; + +#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID + /* Check for invalid bits. */ + if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { + if (data == &sdata) { + syslog(INTERNALLOG, + "syslog: unknown facility/priority: %x", pri); + } else { + syslog_r(INTERNALLOG, data, + "syslog_r: unknown facility/priority: %x", pri); + } + pri &= LOG_PRIMASK|LOG_FACMASK; + } + + /* Check priority against setlogmask values. */ + if (!(LOG_MASK(LOG_PRI(pri)) & data->log_mask)) + return; + + saved_errno = errno; + + /* Set default facility if none specified. */ + if ((pri & LOG_FACMASK) == 0) + pri |= data->log_fac; + + /* If we have been called through syslog(), no need for reentrancy. */ + if (data == &sdata) + (void)time(&now); + + p = tbuf; + tbuf_left = TBUF_LEN; + +#define DEC() \ + do { \ + if (prlen < 0) \ + prlen = 0; \ + if (prlen >= tbuf_left) \ + prlen = tbuf_left - 1; \ + p += prlen; \ + tbuf_left -= prlen; \ + } while (0) + + prlen = snprintf(p, tbuf_left, "<%d>", pri); + DEC(); + + /* + * syslogd will expand time automagically for reentrant case, and + * for normal case, just do like before + */ + if (data == &sdata) { + prlen = strftime(p, tbuf_left, "%h %e %T ", localtime(&now)); + DEC(); + } + + if (data->log_stat & LOG_PERROR) + stdp = p; + if (data->log_tag == NULL) + data->log_tag = __progname; + if (data->log_tag != NULL) { + prlen = snprintf(p, tbuf_left, "%s", data->log_tag); + DEC(); + } + if (data->log_stat & LOG_PID) { + prlen = snprintf(p, tbuf_left, "[%ld]", (long)getpid()); + DEC(); + } + if (data->log_tag != NULL) { + if (tbuf_left > 1) { + *p++ = ':'; + tbuf_left--; + } + if (tbuf_left > 1) { + *p++ = ' '; + tbuf_left--; + } + } + + /* strerror() is not reentrant */ + + for (t = fmt_cpy, fmt_left = FMT_LEN; (ch = *fmt); ++fmt) { + if (ch == '%' && fmt[1] == 'm') { + ++fmt; + if (data == &sdata) { + prlen = snprintf(t, fmt_left, "%s", + strerror(saved_errno)); + } else { + prlen = snprintf(t, fmt_left, "Error %d", + saved_errno); + } + if (prlen < 0) + prlen = 0; + if (prlen >= fmt_left) + prlen = fmt_left - 1; + t += prlen; + fmt_left -= prlen; + } else if (ch == '%' && fmt[1] == '%' && fmt_left > 2) { + *t++ = '%'; + *t++ = '%'; + fmt++; + fmt_left -= 2; + } else { + if (fmt_left > 1) { + *t++ = ch; + fmt_left--; + } + } + } + *t = '\0'; + + prlen = vsnprintf(p, tbuf_left, fmt_cpy, ap); + DEC(); + cnt = p - tbuf; + + /* Output to stderr if requested. */ + if (data->log_stat & LOG_PERROR) { + struct iovec iov[2]; + + iov[0].iov_base = stdp; + iov[0].iov_len = cnt - (stdp - tbuf); + iov[1].iov_base = "\n"; + iov[1].iov_len = 1; + (void)writev(STDERR_FILENO, iov, 2); + } + + /* Get connected, output the message to the local logger. */ + if (!data->opened) + openlog_r(data->log_tag, data->log_stat, 0, data); + connectlog_r(data); + + /* + * If the send() failed, there are two likely scenarios: + * 1) syslogd was restarted + * 2) /dev/log is out of socket buffer space + * We attempt to reconnect to /dev/log to take care of + * case #1 and keep send()ing data to cover case #2 + * to give syslogd a chance to empty its socket buffer. + */ + if ((error = send(data->log_file, tbuf, cnt, 0)) < 0) { + if (errno != ENOBUFS) { + disconnectlog_r(data); + connectlog_r(data); + } + do { + usleep(1); + if ((error = send(data->log_file, tbuf, cnt, 0)) >= 0) + break; + } while (errno == ENOBUFS); + } + + /* + * Output the message to the console; try not to block + * as a blocking console should not stop other processes. + * Make sure the error reported is the one from the syslogd failure. + */ + if (error == -1 && (data->log_stat & LOG_CONS) && + (fd = open(_PATH_CONSOLE, O_WRONLY|O_NONBLOCK, 0)) >= 0) { + struct iovec iov[2]; + + p = strchr(tbuf, '>') + 1; + iov[0].iov_base = p; + iov[0].iov_len = cnt - (p - tbuf); + iov[1].iov_base = "\r\n"; + iov[1].iov_len = 2; + (void)writev(fd, iov, 2); + (void)close(fd); + } + + if (data != &sdata) + closelog_r(data); +} + +static void +disconnectlog_r(struct syslog_data *data) +{ + /* + * If the user closed the FD and opened another in the same slot, + * that's their problem. They should close it before calling on + * system services. + */ + if (data->log_file != -1) { + close(data->log_file); + data->log_file = -1; + } + data->connected = 0; /* retry connect */ +} + +static void +connectlog_r(struct syslog_data *data) +{ + union { + struct sockaddr syslogAddr; + struct sockaddr_un syslogAddrUn; + } u; + +#define SyslogAddr u.syslogAddrUn + + if (data->log_file == -1) { + if ((data->log_file = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) + return; + (void)fcntl(data->log_file, F_SETFD, 1); + } + if (data->log_file != -1 && !data->connected) { + memset(&SyslogAddr, '\0', sizeof(SyslogAddr)); +#if 0 + /* BIONIC: no sun_len field to fill on Linux */ + SyslogAddr.sun_len = sizeof(SyslogAddr); +#endif + SyslogAddr.sun_family = AF_UNIX; + strlcpy(SyslogAddr.sun_path, _PATH_LOG, + sizeof(SyslogAddr.sun_path)); + if (connect(data->log_file, &u.syslogAddr, + sizeof(SyslogAddr)) == -1) { + (void)close(data->log_file); + data->log_file = -1; + } else + data->connected = 1; + } +} + +void +openlog_r(const char *ident, int logstat, int logfac, struct syslog_data *data) +{ + if (ident != NULL) + data->log_tag = ident; + data->log_stat = logstat; + if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) + data->log_fac = logfac; + + if (data->log_stat & LOG_NDELAY) /* open immediately */ + connectlog_r(data); + + data->opened = 1; /* ident and facility has been set */ +} + +void +closelog_r(struct syslog_data *data) +{ + (void)close(data->log_file); + data->log_file = -1; + data->connected = 0; + data->log_tag = NULL; +} + +/* setlogmask -- set the log mask level */ +int +setlogmask_r(int pmask, struct syslog_data *data) +{ + int omask; + + omask = data->log_mask; + if (pmask != 0) + data->log_mask = pmask; + return (omask); +} diff --git a/libc/unistd/system.c b/libc/unistd/system.c new file mode 100644 index 0000000..72cc37e --- /dev/null +++ b/libc/unistd/system.c @@ -0,0 +1,74 @@ +/* $OpenBSD: system.c,v 1.8 2005/08/08 08:05:37 espie Exp $ */ +/* + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <signal.h> +#include <stdlib.h> +#include <unistd.h> +#include <paths.h> +#include <sys/wait.h> + +extern char **environ; + +int +system(const char *command) +{ + pid_t pid; + sig_t intsave, quitsave; + sigset_t mask, omask; + int pstat; + char *argp[] = {"sh", "-c", NULL, NULL}; + + if (!command) /* just checking... */ + return(1); + + argp[2] = (char *)command; + + sigemptyset(&mask); + sigaddset(&mask, SIGCHLD); + sigprocmask(SIG_BLOCK, &mask, &omask); + switch (pid = vfork()) { + case -1: /* error */ + sigprocmask(SIG_SETMASK, &omask, NULL); + return(-1); + case 0: /* child */ + sigprocmask(SIG_SETMASK, &omask, NULL); + execve(_PATH_BSHELL, argp, environ); + _exit(127); + } + + intsave = (sig_t) bsd_signal(SIGINT, SIG_IGN); + quitsave = (sig_t) bsd_signal(SIGQUIT, SIG_IGN); + pid = waitpid(pid, (int *)&pstat, 0); + sigprocmask(SIG_SETMASK, &omask, NULL); + (void)bsd_signal(SIGINT, intsave); + (void)bsd_signal(SIGQUIT, quitsave); + return (pid == -1 ? -1 : pstat); +} diff --git a/libc/unistd/time.c b/libc/unistd/time.c new file mode 100644 index 0000000..13d7366 --- /dev/null +++ b/libc/unistd/time.c @@ -0,0 +1,62 @@ +/* $OpenBSD: time.c,v 1.5 2005/08/08 08:05:34 espie Exp $ */ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <time.h> + +time_t +time(time_t *t) +{ + struct timeval tt; + + if (gettimeofday(&tt, (struct timezone *)0) < 0) + return (-1); + if (t) + *t = (time_t)tt.tv_sec; + return (tt.tv_sec); +} + + +clock_t +clock(void) +{ + struct timespec tm; + static int clock_inited; + static clock_t clock_start; + clock_t now; + + clock_gettime( CLOCK_MONOTONIC, &tm); + now = tm.tv_sec * CLOCKS_PER_SEC + (tm.tv_nsec * (CLOCKS_PER_SEC/1e9)); + + if (!clock_inited) { + clock_start = now; + clock_inited = 1; + } + return now - clock_start; +} diff --git a/libc/unistd/umount.c b/libc/unistd/umount.c new file mode 100644 index 0000000..642e42c --- /dev/null +++ b/libc/unistd/umount.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> + +extern int umount2(const char*, int); + +int umount(const char* dir) +{ + return umount2(dir, 0); +} diff --git a/libc/unistd/unlockpt.c b/libc/unistd/unlockpt.c new file mode 100644 index 0000000..998b7a3 --- /dev/null +++ b/libc/unistd/unlockpt.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <unistd.h> +#include <sys/ioctl.h> + +int unlockpt( int fd ) +{ + int unlock = 0; + + return ioctl( fd, TIOCSPTLCK, &unlock ); +} diff --git a/libc/unistd/usleep.c b/libc/unistd/usleep.c new file mode 100644 index 0000000..75458b1 --- /dev/null +++ b/libc/unistd/usleep.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <time.h> +#include <errno.h> + +void usleep(unsigned long usec) +{ + struct timespec ts; + + ts.tv_sec = usec/1000000UL; + +#ifdef __arm__ + /* avoid divisions and modulos on the ARM */ + ts.tv_nsec = (usec - ts.tv_sec*1000000UL)*1000; +#else + ts.tv_nsec = (usec % 1000000UL) * 1000UL; +#endif + + for (;;) + { + if ( nanosleep( &ts, &ts ) >= 0 ) + break; + + if ( errno != EINTR ) + break; + } +} diff --git a/libc/unistd/wait.c b/libc/unistd/wait.c new file mode 100644 index 0000000..d172419 --- /dev/null +++ b/libc/unistd/wait.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/wait.h> +#include <stddef.h> + +extern pid_t __wait4 (pid_t pid, int *status, int options, struct rusage *rusage); + +pid_t wait( int* status ) +{ + return __wait4( (pid_t)-1, status, 0, NULL ); +} + +pid_t wait3(int* status, int options, struct rusage* rusage) +{ + return __wait4( (pid_t)-1, status, options, rusage ); +} + +pid_t waitpid(pid_t pid, int* status, int options) +{ + return __wait4( pid, status, options, NULL ); +} |