diff options
author | cvs2svn <> | 2012-10-20 19:31:51 +0400 |
---|---|---|
committer | cvs2svn <> | 2012-10-20 19:31:51 +0400 |
commit | 899ce99cebcb67deca7f9b2a4f1e750a2263881e (patch) | |
tree | 49ee41a55b15ab82f82305e4849859c4a2d1cc54 /newlib/libc/posix/wordexp.c | |
parent | c0956742a74d194b9c18c7a91aa6d6010beb4cd3 (diff) |
This commit was manufactured by cvs2svn to create tag 'cygwin-cygwin-1_7_17-release
1_7_17-release'.
Sprout from cygwin-64bit-branch 2012-08-10 09:37:33 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin-64bit-'
Cherrypick from cygwin-64bit-branch 2012-10-09 12:05:52 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin-64bit-':
newlib/libc/posix/wordexp2.h
Cherrypick from master 2012-10-20 15:31:50 UTC Corinna Vinschen <corinna@vinschen.de> ' * new-features.sgml (ov-new1.7.17): Add section.':
ChangeLog
Makefile.def
Makefile.in
Makefile.tpl
compile
config.guess
config.sub
config/ChangeLog
config/cloog.m4
config/isl.m4
config/mt-sde
configure
include/ChangeLog
include/demangle.h
include/dis-asm.h
include/dwarf2.def
include/elf/ChangeLog
include/elf/aarch64.h
include/elf/arm.h
include/elf/common.h
include/elf/tilegx.h
include/mach-o/ChangeLog
include/mach-o/codesign.h
include/mach-o/external.h
include/mach-o/loader.h
include/mach-o/reloc.h
include/mach-o/x86-64.h
include/objalloc.h
include/opcode/ChangeLog
include/opcode/aarch64.h
include/opcode/arm.h
include/opcode/hppa.h
include/opcode/ia64.h
include/opcode/mips.h
include/opcode/moxie.h
include/opcode/s390.h
include/opcode/sparc.h
include/plugin-api.h
libtool.m4
ltoptions.m4
ltversion.m4
lt~obsolete.m4
newlib/ChangeLog
newlib/HOWTO
newlib/README
newlib/configure.host
newlib/doc/makedoc.c
newlib/libc/include/_ansi.h
newlib/libc/include/assert.h
newlib/libc/include/machine/_default_types.h
newlib/libc/include/machine/ieeefp.h
newlib/libc/include/machine/setjmp.h
newlib/libc/include/machine/time.h
newlib/libc/include/math.h
newlib/libc/include/stdint.h
newlib/libc/include/sys/config.h
newlib/libc/include/sys/features.h
newlib/libc/include/tgmath.h
newlib/libc/machine/configure
newlib/libc/machine/configure.in
newlib/libc/machine/rl78/Makefile.am
newlib/libc/machine/rl78/Makefile.in
newlib/libc/machine/rl78/aclocal.m4
newlib/libc/machine/rl78/configure
newlib/libc/machine/rl78/configure.in
newlib/libc/machine/rl78/setjmp.S
newlib/libc/posix/engine.c
newlib/libc/posix/wordexp.c
newlib/libc/posix/wordfree.c
newlib/libc/search/hash_buf.c
newlib/libc/stdio/fgets.c
newlib/libc/stdio/flags.c
newlib/libc/stdio/vfprintf.c
newlib/libc/stdlib/btowc.c
newlib/libc/stdlib/getopt.c
newlib/libc/string/strcasestr.c
newlib/libc/sys/sysnecv850/sbrk.c
newlib/libc/time/strftime.c
newlib/libm/machine/configure
newlib/libm/machine/configure.in
newlib/testsuite/newlib.stdio/stdio.exp
newlib/testsuite/newlib.stdio/swprintf.c
winsup/cygwin/ChangeLog
winsup/cygwin/DevNotes
winsup/cygwin/child_info.h
winsup/cygwin/cygheap.cc
winsup/cygwin/cygthread.cc
winsup/cygwin/cygtls.cc
winsup/cygwin/cygtls.h
winsup/cygwin/cygwait.cc
winsup/cygwin/cygwait.h
winsup/cygwin/dll_init.cc
winsup/cygwin/errno.cc
winsup/cygwin/exceptions.cc
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_clipboard.cc
winsup/cygwin/fhandler_console.cc
winsup/cygwin/fhandler_floppy.cc
winsup/cygwin/fhandler_process.cc
winsup/cygwin/fhandler_raw.cc
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/fhandler_tape.cc
winsup/cygwin/fhandler_termios.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/flock.cc
winsup/cygwin/gendef
winsup/cygwin/glob.cc
winsup/cygwin/globals.cc
winsup/cygwin/gmon.c
winsup/cygwin/hookapi.cc
winsup/cygwin/include/cygwin/fs.h
winsup/cygwin/include/cygwin/in.h
winsup/cygwin/include/limits.h
winsup/cygwin/miscfuncs.cc
winsup/cygwin/mount.cc
winsup/cygwin/mount.h
winsup/cygwin/net.cc
winsup/cygwin/path.cc
winsup/cygwin/pinfo.cc
winsup/cygwin/posix_ipc.cc
winsup/cygwin/pseudo-reloc.cc
winsup/cygwin/release/1.7.10
winsup/cygwin/release/1.7.11
winsup/cygwin/release/1.7.12
winsup/cygwin/release/1.7.13
winsup/cygwin/release/1.7.14
winsup/cygwin/release/1.7.15
winsup/cygwin/release/1.7.16
winsup/cygwin/release/1.7.17
winsup/cygwin/sec_helper.cc
winsup/cygwin/signal.cc
winsup/cygwin/sigproc.h
winsup/cygwin/smallprint.cc
winsup/cygwin/spawn.cc
winsup/cygwin/syscalls.cc
winsup/cygwin/thread.cc
winsup/cygwin/thread.h
winsup/cygwin/tty.h
winsup/cygwin/wait.cc
winsup/doc/ChangeLog
winsup/doc/faq-what.xml
winsup/doc/new-features.sgml
winsup/utils/ChangeLog
winsup/utils/Makefile.in
winsup/utils/cygcheck.cc
winsup/w32api/ChangeLog
winsup/w32api/include/winbase.h
winsup/w32api/lib/kernel32.def
Diffstat (limited to 'newlib/libc/posix/wordexp.c')
-rw-r--r-- | newlib/libc/posix/wordexp.c | 120 |
1 files changed, 89 insertions, 31 deletions
diff --git a/newlib/libc/posix/wordexp.c b/newlib/libc/posix/wordexp.c index bfdb63fd0..5c58e461a 100644 --- a/newlib/libc/posix/wordexp.c +++ b/newlib/libc/posix/wordexp.c @@ -18,8 +18,10 @@ #include <string.h> #include <unistd.h> #include <sys/wait.h> +#include <sys/queue.h> #include <wordexp.h> +#include "wordexp2.h" #define MAXLINELEN 500 @@ -29,17 +31,21 @@ int wordexp(const char *words, wordexp_t *pwordexp, int flags) { - FILE *f; - FILE *f_err; + FILE *f = NULL; + FILE *f_err = NULL; 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; + int err = WRDE_NOSPACE; + ext_wordv_t *wordv = NULL; + char *eword; + struct ewords_entry *entry; if (pwordexp == NULL) { @@ -59,18 +65,39 @@ wordexp(const char *words, wordexp_t *pwordexp, int flags) { offs = pwordexp->we_offs; - if(!(pwordexp->we_wordv = (char **)realloc(pwordexp->we_wordv, (pwordexp->we_wordc + offs + 1) * sizeof(char *)))) - return WRDE_NOSPACE; + if (pwordexp->we_wordv) + wordv = WE_WORDV_TO_EXT_WORDV(pwordexp->we_wordv); + wordv = (ext_wordv_t *)realloc(wordv, sizeof(ext_wordv_t) + (offs + pwordexp->we_wordc) * sizeof(char *)); + if (!wordv) + return err; + if (!pwordexp->we_wordv) + SLIST_INIT(&wordv->list); + pwordexp->we_wordv = wordv->we_wordv; for (i = 0; i < offs; i++) pwordexp->we_wordv[i] = NULL; } - pipe(fd); - pipe(fd_err); + if (pipe(fd)) + return err; + if (pipe(fd_err)) + { + close(fd[0]); + close(fd[1]); + return err; + } pid = fork(); - if (pid > 0) + if (pid == -1) + { + /* In "parent" process, but fork failed */ + close(fd_err[0]); + close(fd_err[1]); + close(fd[0]); + close(fd[1]); + return err; + } + else if (pid > 0) { /* In parent process. */ @@ -79,7 +106,8 @@ wordexp(const char *words, wordexp_t *pwordexp, int flags) close(fd_err[1]); /* f_err is the standard error from the shell command. */ - f_err = fdopen(fd_err[0], "r"); + if (!(f_err = fdopen(fd_err[0], "r"))) + goto cleanup; /* Check for errors. */ if (fgets(tmp, MAXLINELEN, f_err)) @@ -104,52 +132,79 @@ wordexp(const char *words, wordexp_t *pwordexp, int flags) fprintf(stderr, tmp); } - return err; + goto cleanup; } /* f is the standard output from the shell command. */ - f = fdopen(fd[0], "r"); + if (!(f = fdopen(fd[0], "r"))) + goto cleanup; /* Get number of words expanded by shell. */ - fgets(tmp, MAXLINELEN, f); + if (!fgets(tmp, MAXLINELEN, f)) + goto cleanup; 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; + if (pwordexp->we_wordv) + wordv = WE_WORDV_TO_EXT_WORDV(pwordexp->we_wordv); + wordv = (ext_wordv_t *)realloc(wordv, sizeof(ext_wordv_t) + (offs + pwordexp->we_wordc + num_words) * sizeof(char *)); + if (!wordv) + return err; + if (!pwordexp->we_wordv) + SLIST_INIT(&wordv->list); + pwordexp->we_wordv = wordv->we_wordv; - /* Get number of bytes required for storage of num_words words. */ - fgets(tmp, MAXLINELEN, f); + /* Get number of bytes required for storage of all num_words words. */ + if (!fgets(tmp, MAXLINELEN, f)) + goto cleanup; if((iter = strchr(tmp, '\n'))) *iter = '\0'; - /* 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); + num_bytes = atoi(tmp); - if((iter = strchr(tmp, '\n'))) - *iter = '\0'; + if (!(entry = (struct ewords_entry *)malloc(sizeof(struct ewords_entry) + num_bytes + num_words))) + goto cleanup; + SLIST_INSERT_HEAD(&wordv->list, entry, next); - pwordexp->we_wordv[pwordexp->we_wordc + offs + i] = strdup(tmp); + /* Get expansion from the shell output. */ + if (!fread(entry->ewords, 1, num_bytes + num_words, f)) + goto cleanup; + entry->ewords[num_bytes + num_words] = 0; + + /* Store each entry in pwordexp's we_wordv vector. */ + eword = entry->ewords; + for(i = 0; i < num_words; i++, eword = iter) + { + if (!eword) + break; + pwordexp->we_wordv[offs + pwordexp->we_wordc + i] = eword; + if ((iter = strchr(eword, '\n'))) + *iter++ = '\0'; } - pwordexp->we_wordv[pwordexp->we_wordc + offs + i] = NULL; + pwordexp->we_wordv[offs + pwordexp->we_wordc + i] = NULL; pwordexp->we_wordc += num_words; + if (i == num_words) + err = WRDE_SUCCESS; - close(fd[0]); - close(fd_err[0]); +cleanup: + if (f) + fclose(f); + else + close(fd[0]); + if (f_err) + fclose(f_err); + else + close(fd_err[0]); /* Wait for child to finish. */ waitpid (pid, NULL, 0); - return WRDE_SUCCESS; + return err; } else { @@ -162,7 +217,8 @@ wordexp(const char *words, wordexp_t *pwordexp, int flags) /* Pipe standard output to parent process via fd. */ if (fd[1] != STDOUT_FILENO) { - dup2(fd[1], STDOUT_FILENO); + if (dup2(fd[1], STDOUT_FILENO) == -1) + _exit(EXIT_FAILURE); /* fd[1] no longer required. */ close(fd[1]); } @@ -170,7 +226,8 @@ wordexp(const char *words, wordexp_t *pwordexp, int flags) /* Pipe standard error to parent process via fd_err. */ if (fd_err[1] != STDERR_FILENO) { - dup2(fd_err[1], STDERR_FILENO); + if (dup2(fd_err[1], STDERR_FILENO) == -1) + _exit(EXIT_FAILURE); /* fd_err[1] no longer required. */ close(fd_err[1]); } @@ -179,6 +236,7 @@ wordexp(const char *words, wordexp_t *pwordexp, int flags) execl("/bin/bash", "bash", "--protected", "--wordexp", words, (char *)0); else execl("/bin/bash", "bash", "--wordexp", words, (char *)0); + _exit(EXIT_FAILURE); } return WRDE_SUCCESS; } |