summaryrefslogtreecommitdiff
path: root/libc/misc/wordexp/wordexp.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/misc/wordexp/wordexp.c')
-rw-r--r--libc/misc/wordexp/wordexp.c127
1 files changed, 53 insertions, 74 deletions
diff --git a/libc/misc/wordexp/wordexp.c b/libc/misc/wordexp/wordexp.c
index d8b2db16f..b1cc60942 100644
--- a/libc/misc/wordexp/wordexp.c
+++ b/libc/misc/wordexp/wordexp.c
@@ -16,10 +16,11 @@
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ see <http://www.gnu.org/licenses/>. */
#include <features.h>
+#include <bits/kernel-features.h>
+#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
@@ -35,55 +36,19 @@
#include <glob.h>
#include <wordexp.h>
-/* Experimentally off - libc_hidden_proto(mempcpy) */
-/* Experimentally off - libc_hidden_proto(stpcpy) */
-/* Experimentally off - libc_hidden_proto(strchr) */
-/* Experimentally off - libc_hidden_proto(strcpy) */
-/* Experimentally off - libc_hidden_proto(strdup) */
-/* Experimentally off - libc_hidden_proto(strlen) */
-/* Experimentally off - libc_hidden_proto(strndup) */
-/* Experimentally off - libc_hidden_proto(strspn) */
-/* Experimentally off - libc_hidden_proto(strcspn) */
-libc_hidden_proto(setenv)
-libc_hidden_proto(unsetenv)
-libc_hidden_proto(waitpid)
-libc_hidden_proto(kill)
-libc_hidden_proto(getuid)
-libc_hidden_proto(getpwnam_r)
-libc_hidden_proto(getpwuid_r)
-libc_hidden_proto(execve)
-libc_hidden_proto(dup2)
-libc_hidden_proto(atoi)
-libc_hidden_proto(fnmatch)
-libc_hidden_proto(pipe)
-libc_hidden_proto(fork)
-libc_hidden_proto(open)
-libc_hidden_proto(close)
-libc_hidden_proto(read)
-libc_hidden_proto(getenv)
-libc_hidden_proto(getpid)
-libc_hidden_proto(sprintf)
-libc_hidden_proto(fprintf)
-libc_hidden_proto(abort)
-libc_hidden_proto(glob)
-libc_hidden_proto(globfree)
-libc_hidden_proto(wordfree)
-#ifdef __UCLIBC_HAS_XLOCALE__
-libc_hidden_proto(__ctype_b_loc)
-#elif defined __UCLIBC_HAS_CTYPE_TABLES__
-libc_hidden_proto(__ctype_b)
+#ifndef __ARCH_USE_MMU__
+# define fork vfork
#endif
#define __WORDEXP_FULL
-//#undef __WORDEXP_FULL
/*
* This is a recursive-descent-style word expansion routine.
*/
/* These variables are defined and initialized in the startup code. */
-//extern int __libc_argc;
-//extern char **__libc_argv;
+/*extern int __libc_argc;*/
+/*extern char **__libc_argv;*/
/* FIXME!!!! */
int attribute_hidden __libc_argc;
@@ -138,8 +103,9 @@ static __inline__ char *w_addchar(char *buffer, size_t * actlen,
return buffer;
}
-
+#ifndef MAX
#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
+#endif
static char *w_addmem(char *buffer, size_t * actlen, size_t * maxlen,
const char *str, size_t len)
{
@@ -373,8 +339,8 @@ parse_tilde(char **word, size_t * word_length, size_t * max_length,
static int
do_parse_glob(const char *glob_word, char **word, size_t * word_length,
- size_t * max_length, wordexp_t * pwordexp, const char *ifs,
- const char *ifs_white)
+ size_t * max_length, wordexp_t * pwordexp, const char *ifs
+ /*, const char *ifs_white*/)
{
int error;
int match;
@@ -497,7 +463,7 @@ parse_glob(char **word, size_t * word_length, size_t * max_length,
*word = w_newword(word_length, max_length);
for (i = 0; error == 0 && i < glob_list.we_wordc; i++)
error = do_parse_glob(glob_list.we_wordv[i], word, word_length,
- max_length, pwordexp, ifs, ifs_white);
+ max_length, pwordexp, ifs /*, ifs_white*/);
/* Now tidy up */
tidy_up:
@@ -787,6 +753,7 @@ parse_arith(char **word, size_t * word_length, size_t * max_length,
static void attribute_noreturn
exec_comm_child(char *comm, int *fildes, int showerr, int noexec)
{
+ int fd;
const char *args[4] = { _PATH_BSHELL, "-c", comm, NULL };
/* Execute the command, or just check syntax? */
@@ -794,16 +761,22 @@ exec_comm_child(char *comm, int *fildes, int showerr, int noexec)
args[1] = "-nc";
/* Redirect output. */
- dup2(fildes[1], 1);
- close(fildes[1]);
-
+ fd = fildes[1];
+ if (likely(fd != STDOUT_FILENO)) {
+ dup2(fd, STDOUT_FILENO);
+ close(fd);
+ }
+#if defined O_CLOEXEC && defined __UCLIBC_LINUX_SPECIFIC__ && defined __ASSUME_PIPE2
+ else {
+ /* Reset the close-on-exec flag (if necessary). */
+ fcntl (fd, F_SETFD, 0);
+ }
+#endif
/* Redirect stderr to /dev/null if we have to. */
if (showerr == 0) {
- int fd;
-
- close(2);
+ close(STDERR_FILENO);
fd = open(_PATH_DEVNULL, O_WRONLY);
- if (fd >= 0 && fd != 2) {
+ if (fd >= 0 && fd != STDERR_FILENO) {
dup2(fd, 2);
close(fd);
}
@@ -812,7 +785,8 @@ exec_comm_child(char *comm, int *fildes, int showerr, int noexec)
/* Make sure the subshell doesn't field-split on our behalf. */
unsetenv("IFS");
- close(fildes[0]);
+ if (fildes[0] != 1)
+ close(fildes[0]);
execve(_PATH_BSHELL, (char *const *) args, __environ);
/* Bad. What now? */
@@ -838,10 +812,15 @@ exec_comm(char *comm, char **word, size_t * word_length,
/* Don't fork() unless necessary */
if (!comm || !*comm)
return 0;
-
- if (pipe(fildes))
+#if defined O_CLOEXEC && defined __UCLIBC_LINUX_SPECIFIC__ && defined __ASSUME_PIPE2
+ if (pipe2(fildes, O_CLOEXEC) < 0)
/* Bad */
return WRDE_NOSPACE;
+#else
+ if (pipe(fildes) < 0)
+ /* Bad */
+ return WRDE_NOSPACE;
+#endif
if ((pid = fork()) < 0) {
/* Bad */
@@ -1481,28 +1460,28 @@ parse_param(char **word, size_t * word_length, size_t * max_length,
size_t exp_len;
size_t exp_maxl;
char *p;
- int quoted = 0; /* 1: single quotes; 2: double */
+ int quotes = 0; /* 1: single quotes; 2: double */
expanded = w_newword(&exp_len, &exp_maxl);
for (p = pattern; p && *p; p++) {
- size_t offset;
+ size_t _offset;
switch (*p) {
case '"':
- if (quoted == 2)
- quoted = 0;
- else if (quoted == 0)
- quoted = 2;
+ if (quotes == 2)
+ quotes = 0;
+ else if (quotes == 0)
+ quotes = 2;
else
break;
continue;
case '\'':
- if (quoted == 1)
- quoted = 0;
- else if (quoted == 0)
- quoted = 1;
+ if (quotes == 1)
+ quotes = 0;
+ else if (quotes == 0)
+ quotes = 1;
else
break;
@@ -1510,7 +1489,7 @@ parse_param(char **word, size_t * word_length, size_t * max_length,
case '*':
case '?':
- if (quoted) {
+ if (quotes) {
/* Convert quoted wildchar to escaped wildchar. */
expanded = w_addchar(expanded, &exp_len,
&exp_maxl, '\\');
@@ -1521,9 +1500,9 @@ parse_param(char **word, size_t * word_length, size_t * max_length,
break;
case '$':
- offset = 0;
+ _offset = 0;
error = parse_dollars(&expanded, &exp_len, &exp_maxl, p,
- &offset, flags, NULL, NULL, NULL, 1);
+ &_offset, flags, NULL, NULL, NULL, 1);
if (error) {
if (free_value)
free(value);
@@ -1533,16 +1512,16 @@ parse_param(char **word, size_t * word_length, size_t * max_length,
goto do_error;
}
- p += offset;
+ p += _offset;
continue;
case '~':
- if (quoted || exp_len)
+ if (quotes || exp_len)
break;
- offset = 0;
+ _offset = 0;
error = parse_tilde(&expanded, &exp_len, &exp_maxl, p,
- &offset, 0);
+ &_offset, 0);
if (error) {
if (free_value)
free(value);
@@ -1552,7 +1531,7 @@ parse_param(char **word, size_t * word_length, size_t * max_length,
goto do_error;
}
- p += offset;
+ p += _offset;
continue;
case '\\':