diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2008-10-31 21:03:42 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2008-10-31 21:03:42 +0000 |
commit | d456d606e35a460db59c6609f8c994e658fe3d7c (patch) | |
tree | ad333ffd13bbc4aab45e4f7ff147836da64cf052 /newlib/libc/posix/wordexp.c | |
parent | 029d147e9488a30456226dd76be4ec25aff350d6 (diff) | |
download | newlib-d456d606e35a460db59c6609f8c994e658fe3d7c.zip newlib-d456d606e35a460db59c6609f8c994e658fe3d7c.tar.gz newlib-d456d606e35a460db59c6609f8c994e658fe3d7c.tar.bz2 |
2008-10-31 Jeff Johnston <jjohnstn@redhat.com>
* libc/include/limits.h: Add ARG_MAX, PATH_MAX, and _POSIX2_RE_DUP_MAX.
* libc/include/envlock.h: New file.
* libc/include/fnmatch.h: Ditto.
* libc/include/glob.h: Ditto.
* libc/include/regex.h: Ditto.
* libc/include/wordexp.h: Ditto.
* libc/posix/Makefile.am: Add new files moved from
libc/sys/linux/stdlib.
* libc/posix/Makefile.in: Regenerated.
* libc/posix/COPYRIGHT: New file moved from libc/sys/linux/stdlib.
* libc/posix/cclass.h: Ditto.
* libc/posix/cname.h: Ditto.
* libc/posix/collate.c: Ditto.
* libc/posix/collate.h: Ditto.
* libc/posix/collcmp.c: Ditto.
* libc/posix/engine.c: Ditto.
* libc/posix/fnmatch.3: Ditto.
* libc/posix/glob.3: Ditto.
* libc/posix/fnmatch.c: Ditto.
* libc/posix/glob.c: Ditto.
* libc/posix/namespace.h: Ditto.
* libc/posix/reallocf.c: Ditto.
* libc/posix/regcomp.c: Ditto.
* libc/posix/regerror.c: Ditto.
* libc/posix/regex.3: Ditto.
* libc/posix/regex2.h: Ditto.
* libc/posix/regexec.c: Ditto.
* libc/posix/regfree.c: Ditto.
* libc/posix/rune.h: Ditto.
* libc/posix/runetype.h: Ditto.
* libc/posix/scandir.c: Remove advertising clause which is not in
effect.
* libc/posix/sysexits.h: Ditto.
* libc/posix/un-namespace.h: Ditto.
* libc/posix/utils.h: Ditto.
* libc/posix/wordexp.c: Ditto.
* libc/posix/wordfree.c: Ditto.
* libc/posix/execl.c: Add !_NO_EXECVE flag check.
* libc/posix/execle.c: Ditto.
* libc/posix/execlp.c: Ditto.
* libc/posix/execv.c: Ditto.
* libc/posix/execve.c: Ditto.
* libc/posix/execvp.c: Ditto.
* libc/posix/popen.c: Add !_NO_POPEN flag check.
* libc/sys/linux/configure: Regenerated.
* libc/sys/linux/configure.in: Remove stdlib.
* libc/sys/linux/include/limits.h: Add include of linux/limits.h.
* libc/sys/linux/stdlib/Makefile.am: Removed.
* libc/sys/linux/stdlib/Makefile.in: Ditto.
* libc/sys/linux/stdlib/COPYRIGHT: Moved to libc/posix.
* libc/sys/linux/stdlib/cclass.h: Ditto.
* libc/sys/linux/stdlib/cname.h: Ditto.
* libc/sys/linux/stdlib/collate.c: Ditto.
* libc/sys/linux/stdlib/collate.h: Ditto.
* libc/sys/linux/stdlib/collcmp.c: Ditto.
* libc/sys/linux/stdlib/engine.c: Ditto.
* libc/sys/linux/stdlib/fnmatch.3: Ditto.
* libc/sys/linux/stdlib/fnmatch.c: Ditto.
* libc/sys/linux/stdlib/glob.3: Ditto.
* libc/sys/linux/stdlib/glob.c: Ditto.
* libc/sys/linux/stdlib/reallocf.c: Ditto.
* libc/sys/linux/stdlib/regcomp.c: Ditto.
* libc/sys/linux/stdlib/regerror.c: Ditto.
* libc/sys/linux/stdlib/regex.3: Ditto.
* libc/sys/linux/stdlib/regex2.h: Ditto.
* libc/sys/linux/stdlib/regexec.c: Ditto.
* libc/sys/linux/stdlib/regfree.c: Ditto.
* libc/sys/linux/stdlib/utils.h: Ditto.
* libc/sys/linux/stdlib/wordexp.c: Ditto.
* libc/sys/linux/stdlib/wordfree.c: Ditto.
Diffstat (limited to 'newlib/libc/posix/wordexp.c')
-rw-r--r-- | newlib/libc/posix/wordexp.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/newlib/libc/posix/wordexp.c b/newlib/libc/posix/wordexp.c new file mode 100644 index 0000000..b6c4a6d --- /dev/null +++ b/newlib/libc/posix/wordexp.c @@ -0,0 +1,188 @@ +/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software + * is freely granted, provided that this notice is preserved. + */ +#ifndef _NO_WORDEXP + +#include <sys/param.h> +#include <sys/stat.h> + +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <glob.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/wait.h> + +#include <wordexp.h> + +#define MAXLINELEN 500 + +/* Note: This implementation of wordexp requires a version of bash + that supports the --wordexp and --protected arguments to be present + on the system. It does not support the WRDE_UNDEF flag. */ +int +wordexp(const char *words, wordexp_t *pwordexp, int flags) +{ + FILE *f; + FILE *f_err; + char tmp[MAXLINELEN]; + int i = 0; + int offs = 0; + char *iter; + pid_t pid; + int num_words = 0; + int num_bytes = 0; + int fd[2]; + int fd_err[2]; + int err = 0; + + if (pwordexp == NULL) + { + return WRDE_NOSPACE; + } + + if (flags & WRDE_REUSE) + wordfree(pwordexp); + + if ((flags & WRDE_APPEND) == 0) + { + pwordexp->we_wordc = 0; + pwordexp->we_wordv = NULL; + } + + if (flags & WRDE_DOOFFS) + { + offs = pwordexp->we_offs; + + if(!(pwordexp->we_wordv = (char **)realloc(pwordexp->we_wordv, (pwordexp->we_wordc + offs + 1) * sizeof(char *)))) + return WRDE_NOSPACE; + + for (i = 0; i < offs; i++) + pwordexp->we_wordv[i] = NULL; + } + + pipe(fd); + pipe(fd_err); + pid = fork(); + + if (pid > 0) + { + /* In parent process. */ + + /* Close write end of parent's pipe. */ + close(fd[1]); + close(fd_err[1]); + + /* f_err is the standard error from the shell command. */ + f_err = fdopen(fd_err[0], "r"); + + /* Check for errors. */ + if (fgets(tmp, MAXLINELEN, f_err)) + { + if (strstr(tmp, "EOF")) + err = WRDE_SYNTAX; + else if (strstr(tmp, "`\n'") || strstr(tmp, "`|'") + || strstr(tmp, "`&'") || strstr(tmp, "`;'") + || strstr(tmp, "`<'") || strstr(tmp, "`>'") + || strstr(tmp, "`('") || strstr(tmp, "`)'") + || strstr(tmp, "`{'") || strstr(tmp, "`}'")) + err = WRDE_BADCHAR; + else if (strstr(tmp, "command substitution")) + err = WRDE_CMDSUB; + else + err = WRDE_SYNTAX; + + if (flags & WRDE_SHOWERR) + { + fprintf(stderr, tmp); + while(fgets(tmp, MAXLINELEN, f_err)) + fprintf(stderr, tmp); + } + + return err; + } + + /* f is the standard output from the shell command. */ + f = fdopen(fd[0], "r"); + + /* Get number of words expanded by shell. */ + fgets(tmp, MAXLINELEN, f); + + if((iter = strchr(tmp, '\n'))) + *iter = '\0'; + + num_words = atoi(tmp); + + if(!(pwordexp->we_wordv = (char **)realloc(pwordexp->we_wordv, + (pwordexp->we_wordc + num_words + offs + 1) * sizeof(char *)))) + return WRDE_NOSPACE; + + /* Get number of bytes required for storage of num_words words. */ + fgets(tmp, MAXLINELEN, f); + + if((iter = strchr(tmp, '\n'))) + *iter = '\0'; + + num_bytes = atoi(tmp) + pwordexp->we_wordc; + + /* Get each expansion from the shell output, and store each in + pwordexp's we_wordv vector. */ + for(i = 0; i < num_words; i++) + { + fgets(tmp, MAXLINELEN, f); + + if((iter = strchr(tmp, '\n'))) + *iter = '\0'; + + pwordexp->we_wordv[pwordexp->we_wordc + offs + i] = strdup(tmp); + } + + pwordexp->we_wordv[pwordexp->we_wordc + offs + i] = NULL; + pwordexp->we_wordc += num_words; + + close(fd[0]); + close(fd_err[0]); + + /* Wait for child to finish. */ + waitpid (pid, NULL, 0); + + return WRDE_SUCCESS; + } + else + { + /* In child process. */ + + /* Close read end of child's pipe. */ + close(fd[0]); + close(fd_err[0]); + + /* Pipe standard output to parent process via fd. */ + if (fd[1] != STDOUT_FILENO) + { + dup2(fd[1], STDOUT_FILENO); + /* fd[1] no longer required. */ + close(fd[1]); + } + + /* Pipe standard error to parent process via fd_err. */ + if (fd_err[1] != STDERR_FILENO) + { + dup2(fd_err[1], STDERR_FILENO); + /* fd_err[1] no longer required. */ + close(fd_err[1]); + } + + if (flags & WRDE_NOCMD) + execl("/bin/bash", "bash", "--protected", "--wordexp", words, (char *)0); + else + execl("/bin/bash", "bash", "--wordexp", words, (char *)0); + } + return WRDE_SUCCESS; +} +#endif /* !_NO_WORDEXP */ |