Fix access after end of search string in regex matcher
[platform/upstream/glibc.git] / posix / wordexp.c
1 /* POSIX.2 wordexp implementation.
2    Copyright (C) 1997-2003,2005,2006,2008,2011 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Tim Waugh <tim@cyberelk.demon.co.uk>.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #include <alloca.h>
22 #include <ctype.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <fnmatch.h>
26 #include <glob.h>
27 #include <libintl.h>
28 #include <paths.h>
29 #include <pwd.h>
30 #include <signal.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/param.h>
35 #include <sys/stat.h>
36 #include <sys/time.h>
37 #include <sys/types.h>
38 #include <sys/types.h>
39 #include <sys/wait.h>
40 #include <unistd.h>
41 #include <wchar.h>
42 #include <wordexp.h>
43 #include <kernel-features.h>
44
45 #include <bits/libc-lock.h>
46 #include <stdio-common/_itoa.h>
47
48 /* Undefine the following line for the production version.  */
49 /* #define NDEBUG 1 */
50 #include <assert.h>
51
52 /* Get some device information.  */
53 #include <device-nrs.h>
54
55 /*
56  * This is a recursive-descent-style word expansion routine.
57  */
58
59 /* These variables are defined and initialized in the startup code.  */
60 extern int __libc_argc attribute_hidden;
61 extern char **__libc_argv attribute_hidden;
62
63 /* Some forward declarations */
64 static int parse_dollars (char **word, size_t *word_length, size_t *max_length,
65                           const char *words, size_t *offset, int flags,
66                           wordexp_t *pwordexp, const char *ifs,
67                           const char *ifs_white, int quoted)
68      internal_function;
69 static int parse_backtick (char **word, size_t *word_length,
70                            size_t *max_length, const char *words,
71                            size_t *offset, int flags, wordexp_t *pwordexp,
72                            const char *ifs, const char *ifs_white)
73      internal_function;
74 static int parse_dquote (char **word, size_t *word_length, size_t *max_length,
75                          const char *words, size_t *offset, int flags,
76                          wordexp_t *pwordexp, const char *ifs,
77                          const char *ifs_white)
78      internal_function;
79 static int eval_expr (char *expr, long int *result) internal_function;
80
81 /* The w_*() functions manipulate word lists. */
82
83 #define W_CHUNK (100)
84
85 /* Result of w_newword will be ignored if it's the last word. */
86 static inline char *
87 w_newword (size_t *actlen, size_t *maxlen)
88 {
89   *actlen = *maxlen = 0;
90   return NULL;
91 }
92
93 static char *
94 w_addchar (char *buffer, size_t *actlen, size_t *maxlen, char ch)
95      /* (lengths exclude trailing zero) */
96 {
97   /* Add a character to the buffer, allocating room for it if needed.  */
98
99   if (*actlen == *maxlen)
100     {
101       char *old_buffer = buffer;
102       assert (buffer == NULL || *maxlen != 0);
103       *maxlen += W_CHUNK;
104       buffer = (char *) realloc (buffer, 1 + *maxlen);
105
106       if (buffer == NULL)
107         free (old_buffer);
108     }
109
110   if (buffer != NULL)
111     {
112       buffer[*actlen] = ch;
113       buffer[++(*actlen)] = '\0';
114     }
115
116   return buffer;
117 }
118
119 static char *
120 internal_function
121 w_addmem (char *buffer, size_t *actlen, size_t *maxlen, const char *str,
122           size_t len)
123 {
124   /* Add a string to the buffer, allocating room for it if needed.
125    */
126   if (*actlen + len > *maxlen)
127     {
128       char *old_buffer = buffer;
129       assert (buffer == NULL || *maxlen != 0);
130       *maxlen += MAX (2 * len, W_CHUNK);
131       buffer = realloc (old_buffer, 1 + *maxlen);
132
133       if (buffer == NULL)
134         free (old_buffer);
135     }
136
137   if (buffer != NULL)
138     {
139       *((char *) __mempcpy (&buffer[*actlen], str, len)) = '\0';
140       *actlen += len;
141     }
142
143   return buffer;
144 }
145
146 static char *
147 internal_function
148 w_addstr (char *buffer, size_t *actlen, size_t *maxlen, const char *str)
149      /* (lengths exclude trailing zero) */
150 {
151   /* Add a string to the buffer, allocating room for it if needed.
152    */
153   size_t len;
154
155   assert (str != NULL); /* w_addstr only called from this file */
156   len = strlen (str);
157
158   return w_addmem (buffer, actlen, maxlen, str, len);
159 }
160
161 static int
162 internal_function
163 w_addword (wordexp_t *pwordexp, char *word)
164 {
165   /* Add a word to the wordlist */
166   size_t num_p;
167   char **new_wordv;
168   bool allocated = false;
169
170   /* Internally, NULL acts like "".  Convert NULLs to "" before
171    * the caller sees them.
172    */
173   if (word == NULL)
174     {
175       word = __strdup ("");
176       if (word == NULL)
177         goto no_space;
178       allocated = true;
179     }
180
181   num_p = 2 + pwordexp->we_wordc + pwordexp->we_offs;
182   new_wordv = realloc (pwordexp->we_wordv, sizeof (char *) * num_p);
183   if (new_wordv != NULL)
184     {
185       pwordexp->we_wordv = new_wordv;
186       pwordexp->we_wordv[pwordexp->we_offs + pwordexp->we_wordc++] = word;
187       pwordexp->we_wordv[pwordexp->we_offs + pwordexp->we_wordc] = NULL;
188       return 0;
189     }
190
191   if (allocated)
192     free (word);
193
194 no_space:
195   return WRDE_NOSPACE;
196 }
197
198 /* The parse_*() functions should leave *offset being the offset in 'words'
199  * to the last character processed.
200  */
201
202 static int
203 internal_function
204 parse_backslash (char **word, size_t *word_length, size_t *max_length,
205                  const char *words, size_t *offset)
206 {
207   /* We are poised _at_ a backslash, not in quotes */
208
209   switch (words[1 + *offset])
210     {
211     case 0:
212       /* Backslash is last character of input words */
213       return WRDE_SYNTAX;
214
215     case '\n':
216       ++(*offset);
217       break;
218
219     default:
220       *word = w_addchar (*word, word_length, max_length, words[1 + *offset]);
221       if (*word == NULL)
222         return WRDE_NOSPACE;
223
224       ++(*offset);
225       break;
226     }
227
228   return 0;
229 }
230
231 static int
232 internal_function
233 parse_qtd_backslash (char **word, size_t *word_length, size_t *max_length,
234                      const char *words, size_t *offset)
235 {
236   /* We are poised _at_ a backslash, inside quotes */
237
238   switch (words[1 + *offset])
239     {
240     case 0:
241       /* Backslash is last character of input words */
242       return WRDE_SYNTAX;
243
244     case '\n':
245       ++(*offset);
246       break;
247
248     case '$':
249     case '`':
250     case '"':
251     case '\\':
252       *word = w_addchar (*word, word_length, max_length, words[1 + *offset]);
253       if (*word == NULL)
254         return WRDE_NOSPACE;
255
256       ++(*offset);
257       break;
258
259     default:
260       *word = w_addchar (*word, word_length, max_length, words[*offset]);
261       if (*word != NULL)
262         *word = w_addchar (*word, word_length, max_length, words[1 + *offset]);
263
264       if (*word == NULL)
265         return WRDE_NOSPACE;
266
267       ++(*offset);
268       break;
269     }
270
271   return 0;
272 }
273
274 static int
275 internal_function
276 parse_tilde (char **word, size_t *word_length, size_t *max_length,
277              const char *words, size_t *offset, size_t wordc)
278 {
279   /* We are poised _at_ a tilde */
280   size_t i;
281
282   if (*word_length != 0)
283     {
284       if (!((*word)[*word_length - 1] == '=' && wordc == 0))
285         {
286           if (!((*word)[*word_length - 1] == ':'
287                 && strchr (*word, '=') && wordc == 0))
288             {
289               *word = w_addchar (*word, word_length, max_length, '~');
290               return *word ? 0 : WRDE_NOSPACE;
291             }
292         }
293     }
294
295   for (i = 1 + *offset; words[i]; i++)
296     {
297       if (words[i] == ':' || words[i] == '/' || words[i] == ' ' ||
298           words[i] == '\t' || words[i] == 0 )
299         break;
300
301       if (words[i] == '\\')
302         {
303           *word = w_addchar (*word, word_length, max_length, '~');
304           return *word ? 0 : WRDE_NOSPACE;
305         }
306     }
307
308   if (i == 1 + *offset)
309     {
310       /* Tilde appears on its own */
311       uid_t uid;
312       struct passwd pwd, *tpwd;
313       int buflen = 1000;
314       char* home;
315       char* buffer;
316       int result;
317
318       /* POSIX.2 says ~ expands to $HOME and if HOME is unset the
319          results are unspecified.  We do a lookup on the uid if
320          HOME is unset. */
321
322       home = getenv ("HOME");
323       if (home != NULL)
324         {
325           *word = w_addstr (*word, word_length, max_length, home);
326           if (*word == NULL)
327             return WRDE_NOSPACE;
328         }
329       else
330         {
331           uid = __getuid ();
332           buffer = __alloca (buflen);
333
334           while ((result = __getpwuid_r (uid, &pwd, buffer, buflen, &tpwd)) != 0
335                  && errno == ERANGE)
336             buffer = extend_alloca (buffer, buflen, buflen + 1000);
337
338           if (result == 0 && tpwd != NULL && pwd.pw_dir != NULL)
339             {
340               *word = w_addstr (*word, word_length, max_length, pwd.pw_dir);
341               if (*word == NULL)
342                 return WRDE_NOSPACE;
343             }
344           else
345             {
346               *word = w_addchar (*word, word_length, max_length, '~');
347               if (*word == NULL)
348                 return WRDE_NOSPACE;
349             }
350         }
351     }
352   else
353     {
354       /* Look up user name in database to get home directory */
355       char *user = strndupa (&words[1 + *offset], i - (1 + *offset));
356       struct passwd pwd, *tpwd;
357       int buflen = 1000;
358       char* buffer = __alloca (buflen);
359       int result;
360
361       while ((result = __getpwnam_r (user, &pwd, buffer, buflen, &tpwd)) != 0
362              && errno == ERANGE)
363         buffer = extend_alloca (buffer, buflen, buflen + 1000);
364
365       if (result == 0 && tpwd != NULL && pwd.pw_dir)
366         *word = w_addstr (*word, word_length, max_length, pwd.pw_dir);
367       else
368         {
369           /* (invalid login name) */
370           *word = w_addchar (*word, word_length, max_length, '~');
371           if (*word != NULL)
372             *word = w_addstr (*word, word_length, max_length, user);
373         }
374
375       *offset = i - 1;
376     }
377   return *word ? 0 : WRDE_NOSPACE;
378 }
379
380
381 static int
382 internal_function
383 do_parse_glob (const char *glob_word, char **word, size_t *word_length,
384                size_t *max_length, wordexp_t *pwordexp, const char *ifs,
385                const char *ifs_white)
386 {
387   int error;
388   unsigned int match;
389   glob_t globbuf;
390
391   error = glob (glob_word, GLOB_NOCHECK, NULL, &globbuf);
392
393   if (error != 0)
394     {
395       /* We can only run into memory problems.  */
396       assert (error == GLOB_NOSPACE);
397       return WRDE_NOSPACE;
398     }
399
400   if (ifs && !*ifs)
401     {
402       /* No field splitting allowed. */
403       assert (globbuf.gl_pathv[0] != NULL);
404       *word = w_addstr (*word, word_length, max_length, globbuf.gl_pathv[0]);
405       for (match = 1; match < globbuf.gl_pathc && *word != NULL; ++match)
406         {
407           *word = w_addchar (*word, word_length, max_length, ' ');
408           if (*word != NULL)
409             *word = w_addstr (*word, word_length, max_length,
410                               globbuf.gl_pathv[match]);
411         }
412
413       globfree (&globbuf);
414       return *word ? 0 : WRDE_NOSPACE;
415     }
416
417   assert (ifs == NULL || *ifs != '\0');
418   if (*word != NULL)
419     {
420       free (*word);
421       *word = w_newword (word_length, max_length);
422     }
423
424   for (match = 0; match < globbuf.gl_pathc; ++match)
425     {
426       char *matching_word = __strdup (globbuf.gl_pathv[match]);
427       if (matching_word == NULL || w_addword (pwordexp, matching_word))
428         {
429           globfree (&globbuf);
430           return WRDE_NOSPACE;
431         }
432     }
433
434   globfree (&globbuf);
435   return 0;
436 }
437
438 static int
439 internal_function
440 parse_glob (char **word, size_t *word_length, size_t *max_length,
441             const char *words, size_t *offset, int flags,
442             wordexp_t *pwordexp, const char *ifs, const char *ifs_white)
443 {
444   /* We are poised just after a '*', a '[' or a '?'. */
445   int error = WRDE_NOSPACE;
446   int quoted = 0; /* 1 if singly-quoted, 2 if doubly */
447   size_t i;
448   wordexp_t glob_list; /* List of words to glob */
449
450   glob_list.we_wordc = 0;
451   glob_list.we_wordv = NULL;
452   glob_list.we_offs = 0;
453   for (; words[*offset] != '\0'; ++*offset)
454     {
455       if (strchr (ifs, words[*offset]) != NULL)
456         /* Reached IFS */
457         break;
458
459       /* Sort out quoting */
460       if (words[*offset] == '\'')
461         {
462           if (quoted == 0)
463             {
464               quoted = 1;
465               continue;
466             }
467           else if (quoted == 1)
468             {
469               quoted = 0;
470               continue;
471             }
472         }
473       else if (words[*offset] == '"')
474         {
475           if (quoted == 0)
476             {
477               quoted = 2;
478               continue;
479             }
480           else if (quoted == 2)
481             {
482               quoted = 0;
483               continue;
484             }
485         }
486
487       /* Sort out other special characters */
488       if (quoted != 1 && words[*offset] == '$')
489         {
490           error = parse_dollars (word, word_length, max_length, words,
491                                  offset, flags, &glob_list, ifs, ifs_white,
492                                  quoted == 2);
493           if (error)
494             goto tidy_up;
495
496           continue;
497         }
498       else if (words[*offset] == '\\')
499         {
500           if (quoted)
501             error = parse_qtd_backslash (word, word_length, max_length,
502                                          words, offset);
503           else
504             error = parse_backslash (word, word_length, max_length,
505                                      words, offset);
506
507           if (error)
508             goto tidy_up;
509
510           continue;
511         }
512
513       *word = w_addchar (*word, word_length, max_length, words[*offset]);
514       if (*word == NULL)
515         goto tidy_up;
516     }
517
518   /* Don't forget to re-parse the character we stopped at. */
519   --*offset;
520
521   /* Glob the words */
522   error = w_addword (&glob_list, *word);
523   *word = w_newword (word_length, max_length);
524   for (i = 0; error == 0 && i < glob_list.we_wordc; i++)
525     error = do_parse_glob (glob_list.we_wordv[i], word, word_length,
526                            max_length, pwordexp, ifs, ifs_white);
527
528   /* Now tidy up */
529 tidy_up:
530   wordfree (&glob_list);
531   return error;
532 }
533
534 static int
535 internal_function
536 parse_squote (char **word, size_t *word_length, size_t *max_length,
537               const char *words, size_t *offset)
538 {
539   /* We are poised just after a single quote */
540   for (; words[*offset]; ++(*offset))
541     {
542       if (words[*offset] != '\'')
543         {
544           *word = w_addchar (*word, word_length, max_length, words[*offset]);
545           if (*word == NULL)
546             return WRDE_NOSPACE;
547         }
548       else return 0;
549     }
550
551   /* Unterminated string */
552   return WRDE_SYNTAX;
553 }
554
555 /* Functions to evaluate an arithmetic expression */
556 static int
557 internal_function
558 eval_expr_val (char **expr, long int *result)
559 {
560   char *digit;
561
562   /* Skip white space */
563   for (digit = *expr; digit && *digit && isspace (*digit); ++digit);
564
565   if (*digit == '(')
566     {
567       /* Scan for closing paren */
568       for (++digit; **expr && **expr != ')'; ++(*expr));
569
570       /* Is there one? */
571       if (!**expr)
572         return WRDE_SYNTAX;
573
574       *(*expr)++ = 0;
575
576       if (eval_expr (digit, result))
577         return WRDE_SYNTAX;
578
579       return 0;
580     }
581
582   /* POSIX requires that decimal, octal, and hexadecimal constants are
583      recognized.  Therefore we pass 0 as the third parameter to strtol.  */
584   *result = strtol (digit, expr, 0);
585   if (digit == *expr)
586     return WRDE_SYNTAX;
587
588   return 0;
589 }
590
591 static int
592 internal_function
593 eval_expr_multdiv (char **expr, long int *result)
594 {
595   long int arg;
596
597   /* Read a Value */
598   if (eval_expr_val (expr, result) != 0)
599     return WRDE_SYNTAX;
600
601   while (**expr)
602     {
603       /* Skip white space */
604       for (; *expr && **expr && isspace (**expr); ++(*expr));
605
606       if (**expr == '*')
607         {
608           ++(*expr);
609           if (eval_expr_val (expr, &arg) != 0)
610             return WRDE_SYNTAX;
611
612           *result *= arg;
613         }
614       else if (**expr == '/')
615         {
616           ++(*expr);
617           if (eval_expr_val (expr, &arg) != 0)
618             return WRDE_SYNTAX;
619
620           *result /= arg;
621         }
622       else break;
623     }
624
625   return 0;
626 }
627
628 static int
629 internal_function
630 eval_expr (char *expr, long int *result)
631 {
632   long int arg;
633
634   /* Read a Multdiv */
635   if (eval_expr_multdiv (&expr, result) != 0)
636     return WRDE_SYNTAX;
637
638   while (*expr)
639     {
640       /* Skip white space */
641       for (; expr && *expr && isspace (*expr); ++expr);
642
643       if (*expr == '+')
644         {
645           ++expr;
646           if (eval_expr_multdiv (&expr, &arg) != 0)
647             return WRDE_SYNTAX;
648
649           *result += arg;
650         }
651       else if (*expr == '-')
652         {
653           ++expr;
654           if (eval_expr_multdiv (&expr, &arg) != 0)
655             return WRDE_SYNTAX;
656
657           *result -= arg;
658         }
659       else break;
660     }
661
662   return 0;
663 }
664
665 static int
666 internal_function
667 parse_arith (char **word, size_t *word_length, size_t *max_length,
668              const char *words, size_t *offset, int flags, int bracket)
669 {
670   /* We are poised just after "$((" or "$[" */
671   int error;
672   int paren_depth = 1;
673   size_t expr_length;
674   size_t expr_maxlen;
675   char *expr;
676
677   expr = w_newword (&expr_length, &expr_maxlen);
678   for (; words[*offset]; ++(*offset))
679     {
680       switch (words[*offset])
681         {
682         case '$':
683           error = parse_dollars (&expr, &expr_length, &expr_maxlen,
684                                  words, offset, flags, NULL, NULL, NULL, 1);
685           /* The ``1'' here is to tell parse_dollars not to
686            * split the fields.
687            */
688           if (error)
689             {
690               free (expr);
691               return error;
692             }
693           break;
694
695         case '`':
696           (*offset)++;
697           error = parse_backtick (&expr, &expr_length, &expr_maxlen,
698                                   words, offset, flags, NULL, NULL, NULL);
699           /* The first NULL here is to tell parse_backtick not to
700            * split the fields.
701            */
702           if (error)
703             {
704               free (expr);
705               return error;
706             }
707           break;
708
709         case '\\':
710           error = parse_qtd_backslash (&expr, &expr_length, &expr_maxlen,
711                                        words, offset);
712           if (error)
713             {
714               free (expr);
715               return error;
716             }
717           /* I think that a backslash within an
718            * arithmetic expansion is bound to
719            * cause an error sooner or later anyway though.
720            */
721           break;
722
723         case ')':
724           if (--paren_depth == 0)
725             {
726               char result[21];  /* 21 = ceil(log10(2^64)) + 1 */
727               long int numresult = 0;
728               long long int convertme;
729
730               if (bracket || words[1 + *offset] != ')')
731                 {
732                   free (expr);
733                   return WRDE_SYNTAX;
734                 }
735
736               ++(*offset);
737
738               /* Go - evaluate. */
739               if (*expr && eval_expr (expr, &numresult) != 0)
740                 {
741                   free (expr);
742                   return WRDE_SYNTAX;
743                 }
744
745               if (numresult < 0)
746                 {
747                   convertme = -numresult;
748                   *word = w_addchar (*word, word_length, max_length, '-');
749                   if (!*word)
750                     {
751                       free (expr);
752                       return WRDE_NOSPACE;
753                     }
754                 }
755               else
756                 convertme = numresult;
757
758               result[20] = '\0';
759               *word = w_addstr (*word, word_length, max_length,
760                                 _itoa (convertme, &result[20], 10, 0));
761               free (expr);
762               return *word ? 0 : WRDE_NOSPACE;
763             }
764           expr = w_addchar (expr, &expr_length, &expr_maxlen, words[*offset]);
765           if (expr == NULL)
766             return WRDE_NOSPACE;
767
768           break;
769
770         case ']':
771           if (bracket && paren_depth == 1)
772             {
773               char result[21];  /* 21 = ceil(log10(2^64)) + 1 */
774               long int numresult = 0;
775
776               /* Go - evaluate. */
777               if (*expr && eval_expr (expr, &numresult) != 0)
778                 {
779                   free (expr);
780                   return WRDE_SYNTAX;
781                 }
782
783               result[20] = '\0';
784               *word = w_addstr (*word, word_length, max_length,
785                                 _itoa_word (numresult, &result[20], 10, 0));
786               free (expr);
787               return *word ? 0 : WRDE_NOSPACE;
788             }
789
790           free (expr);
791           return WRDE_SYNTAX;
792
793         case '\n':
794         case ';':
795         case '{':
796         case '}':
797           free (expr);
798           return WRDE_BADCHAR;
799
800         case '(':
801           ++paren_depth;
802         default:
803           expr = w_addchar (expr, &expr_length, &expr_maxlen, words[*offset]);
804           if (expr == NULL)
805             return WRDE_NOSPACE;
806         }
807     }
808
809   /* Premature end */
810   free (expr);
811   return WRDE_SYNTAX;
812 }
813
814 /* Function called by child process in exec_comm() */
815 static inline void
816 internal_function __attribute__ ((always_inline))
817 exec_comm_child (char *comm, int *fildes, int showerr, int noexec)
818 {
819   const char *args[4] = { _PATH_BSHELL, "-c", comm, NULL };
820
821   /* Execute the command, or just check syntax? */
822   if (noexec)
823     args[1] = "-nc";
824
825   /* Redirect output.  */
826   if (__builtin_expect (fildes[1] != STDOUT_FILENO, 1))
827     {
828       __dup2 (fildes[1], STDOUT_FILENO);
829       __close (fildes[1]);
830     }
831   else
832     {
833 #ifdef O_CLOEXEC
834       /* Reset the close-on-exec flag (if necessary).  */
835 # ifndef __ASSUME_PIPE2
836       if (__have_pipe2 > 0)
837 # endif
838         __fcntl (fildes[1], F_SETFD, 0);
839 #endif
840     }
841
842   /* Redirect stderr to /dev/null if we have to.  */
843   if (showerr == 0)
844     {
845       struct stat64 st;
846       int fd;
847       __close (STDERR_FILENO);
848       fd = __open (_PATH_DEVNULL, O_WRONLY);
849       if (fd >= 0 && fd != STDERR_FILENO)
850         {
851           __dup2 (fd, STDERR_FILENO);
852           __close (fd);
853         }
854       /* Be paranoid.  Check that we actually opened the /dev/null
855          device.  */
856       if (__builtin_expect (__fxstat64 (_STAT_VER, STDERR_FILENO, &st), 0) != 0
857           || __builtin_expect (S_ISCHR (st.st_mode), 1) == 0
858 #if defined DEV_NULL_MAJOR && defined DEV_NULL_MINOR
859           || st.st_rdev != makedev (DEV_NULL_MAJOR, DEV_NULL_MINOR)
860 #endif
861           )
862         /* It's not the /dev/null device.  Stop right here.  The
863            problem is: how do we stop?  We use _exit() with an
864            hopefully unusual exit code.  */
865         _exit (90);
866     }
867
868   /* Make sure the subshell doesn't field-split on our behalf. */
869   __unsetenv ("IFS");
870
871   __close (fildes[0]);
872   __execve (_PATH_BSHELL, (char *const *) args, __environ);
873
874   /* Bad.  What now?  */
875   abort ();
876 }
877
878 /* Function to execute a command and retrieve the results */
879 /* pwordexp contains NULL if field-splitting is forbidden */
880 static int
881 internal_function
882 exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
883            int flags, wordexp_t *pwordexp, const char *ifs,
884            const char *ifs_white)
885 {
886   int fildes[2];
887 #define bufsize 128
888   int buflen;
889   int i;
890   int status = 0;
891   size_t maxnewlines = 0;
892   char buffer[bufsize];
893   pid_t pid;
894   int noexec = 0;
895
896   /* Don't fork() unless necessary */
897   if (!comm || !*comm)
898     return 0;
899
900 #ifdef O_CLOEXEC
901 # ifndef __ASSUME_PIPE2
902   if (__have_pipe2 >= 0)
903 # endif
904     {
905       int r = __pipe2 (fildes, O_CLOEXEC);
906 # ifndef __ASSUME_PIPE2
907       if (__have_pipe2 == 0)
908         __have_pipe2 = r != -1 || errno != ENOSYS ? 1 : -1;
909
910       if (__have_pipe2 > 0)
911 # endif
912         if (r < 0)
913           /* Bad */
914           return WRDE_NOSPACE;
915     }
916 #endif
917 #ifndef __ASSUME_PIPE2
918 # ifdef O_CLOEXEC
919   if (__have_pipe2 < 0)
920 # endif
921     if (__pipe (fildes) < 0)
922       /* Bad */
923       return WRDE_NOSPACE;
924 #endif
925
926  again:
927   if ((pid = __fork ()) < 0)
928     {
929       /* Bad */
930       __close (fildes[0]);
931       __close (fildes[1]);
932       return WRDE_NOSPACE;
933     }
934
935   if (pid == 0)
936     exec_comm_child (comm, fildes, noexec ? 0 : flags & WRDE_SHOWERR, noexec);
937
938   /* Parent */
939
940   /* If we are just testing the syntax, only wait.  */
941   if (noexec)
942     return (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) == pid
943             && status != 0) ? WRDE_SYNTAX : 0;
944
945   __close (fildes[1]);
946   fildes[1] = -1;
947
948   if (!pwordexp)
949     /* Quoted - no field splitting */
950     {
951       while (1)
952         {
953           if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer,
954                                                     bufsize))) < 1)
955             {
956               if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, WNOHANG)) == 0)
957                 continue;
958               if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer,
959                                                         bufsize))) < 1)
960                 break;
961             }
962
963           maxnewlines += buflen;
964
965           *word = w_addmem (*word, word_length, max_length, buffer, buflen);
966           if (*word == NULL)
967             goto no_space;
968         }
969     }
970   else
971     /* Not quoted - split fields */
972     {
973       int copying = 0;
974       /* 'copying' is:
975        *  0 when searching for first character in a field not IFS white space
976        *  1 when copying the text of a field
977        *  2 when searching for possible non-whitespace IFS
978        *  3 when searching for non-newline after copying field
979        */
980
981       while (1)
982         {
983           if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer,
984                                                     bufsize))) < 1)
985             {
986               if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, WNOHANG)) == 0)
987                 continue;
988               if ((buflen = TEMP_FAILURE_RETRY (__read (fildes[0], buffer,
989                                                         bufsize))) < 1)
990                 break;
991             }
992
993           for (i = 0; i < buflen; ++i)
994             {
995               if (strchr (ifs, buffer[i]) != NULL)
996                 {
997                   /* Current character is IFS */
998                   if (strchr (ifs_white, buffer[i]) == NULL)
999                     {
1000                       /* Current character is IFS but not whitespace */
1001                       if (copying == 2)
1002                         {
1003                           /*            current character
1004                            *                   |
1005                            *                   V
1006                            * eg: text<space><comma><space>moretext
1007                            *
1008                            * So, strip whitespace IFS (like at the start)
1009                            */
1010                           copying = 0;
1011                           continue;
1012                         }
1013
1014                       copying = 0;
1015                       /* fall through and delimit field.. */
1016                     }
1017                   else
1018                     {
1019                       if (buffer[i] == '\n')
1020                         {
1021                           /* Current character is (IFS) newline */
1022
1023                           /* If copying a field, this is the end of it,
1024                              but maybe all that's left is trailing newlines.
1025                              So start searching for a non-newline. */
1026                           if (copying == 1)
1027                             copying = 3;
1028
1029                           continue;
1030                         }
1031                       else
1032                         {
1033                           /* Current character is IFS white space, but
1034                              not a newline */
1035
1036                           /* If not either copying a field or searching
1037                              for non-newline after a field, ignore it */
1038                           if (copying != 1 && copying != 3)
1039                             continue;
1040
1041                           /* End of field (search for non-ws IFS afterwards) */
1042                           copying = 2;
1043                         }
1044                     }
1045
1046                   /* First IFS white space (non-newline), or IFS non-whitespace.
1047                    * Delimit the field.  Nulls are converted by w_addword. */
1048                   if (w_addword (pwordexp, *word) == WRDE_NOSPACE)
1049                     goto no_space;
1050
1051                   *word = w_newword (word_length, max_length);
1052
1053                   maxnewlines = 0;
1054                   /* fall back round the loop.. */
1055                 }
1056               else
1057                 {
1058                   /* Not IFS character */
1059
1060                   if (copying == 3)
1061                     {
1062                       /* Nothing but (IFS) newlines since the last field,
1063                          so delimit it here before starting new word */
1064                       if (w_addword (pwordexp, *word) == WRDE_NOSPACE)
1065                         goto no_space;
1066
1067                       *word = w_newword (word_length, max_length);
1068                     }
1069
1070                   copying = 1;
1071
1072                   if (buffer[i] == '\n') /* happens if newline not in IFS */
1073                     maxnewlines++;
1074                   else
1075                     maxnewlines = 0;
1076
1077                   *word = w_addchar (*word, word_length, max_length,
1078                                      buffer[i]);
1079                   if (*word == NULL)
1080                     goto no_space;
1081                 }
1082             }
1083         }
1084     }
1085
1086   /* Chop off trailing newlines (required by POSIX.2)  */
1087   /* Ensure we don't go back further than the beginning of the
1088      substitution (i.e. remove maxnewlines bytes at most) */
1089   while (maxnewlines-- != 0 &&
1090          *word_length > 0 && (*word)[*word_length - 1] == '\n')
1091     {
1092       (*word)[--*word_length] = '\0';
1093
1094       /* If the last word was entirely newlines, turn it into a new word
1095        * which can be ignored if there's nothing following it. */
1096       if (*word_length == 0)
1097         {
1098           free (*word);
1099           *word = w_newword (word_length, max_length);
1100           break;
1101         }
1102     }
1103
1104   __close (fildes[0]);
1105   fildes[0] = -1;
1106
1107   /* Check for syntax error (re-execute but with "-n" flag) */
1108   if (buflen < 1 && status != 0)
1109     {
1110       noexec = 1;
1111       goto again;
1112     }
1113
1114   return 0;
1115
1116 no_space:
1117   __kill (pid, SIGKILL);
1118   TEMP_FAILURE_RETRY (__waitpid (pid, NULL, 0));
1119   __close (fildes[0]);
1120   return WRDE_NOSPACE;
1121 }
1122
1123 static int
1124 internal_function
1125 parse_comm (char **word, size_t *word_length, size_t *max_length,
1126             const char *words, size_t *offset, int flags, wordexp_t *pwordexp,
1127             const char *ifs, const char *ifs_white)
1128 {
1129   /* We are poised just after "$(" */
1130   int paren_depth = 1;
1131   int error = 0;
1132   int quoted = 0; /* 1 for singly-quoted, 2 for doubly-quoted */
1133   size_t comm_length;
1134   size_t comm_maxlen;
1135   char *comm = w_newword (&comm_length, &comm_maxlen);
1136
1137   for (; words[*offset]; ++(*offset))
1138     {
1139       switch (words[*offset])
1140         {
1141         case '\'':
1142           if (quoted == 0)
1143             quoted = 1;
1144           else if (quoted == 1)
1145             quoted = 0;
1146
1147           break;
1148
1149         case '"':
1150           if (quoted == 0)
1151             quoted = 2;
1152           else if (quoted == 2)
1153             quoted = 0;
1154
1155           break;
1156
1157         case ')':
1158           if (!quoted && --paren_depth == 0)
1159             {
1160               /* Go -- give script to the shell */
1161               if (comm)
1162                 {
1163 #ifdef __libc_ptf_call
1164                   /* We do not want the exec_comm call to be cut short
1165                      by a thread cancellation since cleanup is very
1166                      ugly.  Therefore disable cancellation for
1167                      now.  */
1168                   // XXX Ideally we do want the thread being cancelable.
1169                   // XXX If demand is there we'll change it.
1170                   int state = PTHREAD_CANCEL_ENABLE;
1171                   __libc_ptf_call (pthread_setcancelstate,
1172                                    (PTHREAD_CANCEL_DISABLE, &state), 0);
1173 #endif
1174
1175                   error = exec_comm (comm, word, word_length, max_length,
1176                                      flags, pwordexp, ifs, ifs_white);
1177
1178 #ifdef __libc_ptf_call
1179                   __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
1180 #endif
1181
1182                   free (comm);
1183                 }
1184
1185               return error;
1186             }
1187
1188           /* This is just part of the script */
1189           break;
1190
1191         case '(':
1192           if (!quoted)
1193             ++paren_depth;
1194         }
1195
1196       comm = w_addchar (comm, &comm_length, &comm_maxlen, words[*offset]);
1197       if (comm == NULL)
1198         return WRDE_NOSPACE;
1199     }
1200
1201   /* Premature end.  */
1202   free (comm);
1203
1204   return WRDE_SYNTAX;
1205 }
1206
1207 static int
1208 internal_function
1209 parse_param (char **word, size_t *word_length, size_t *max_length,
1210              const char *words, size_t *offset, int flags, wordexp_t *pwordexp,
1211              const char *ifs, const char *ifs_white, int quoted)
1212 {
1213   /* We are poised just after "$" */
1214   enum action
1215   {
1216     ACT_NONE,
1217     ACT_RP_SHORT_LEFT = '#',
1218     ACT_RP_LONG_LEFT = 'L',
1219     ACT_RP_SHORT_RIGHT = '%',
1220     ACT_RP_LONG_RIGHT = 'R',
1221     ACT_NULL_ERROR = '?',
1222     ACT_NULL_SUBST = '-',
1223     ACT_NONNULL_SUBST = '+',
1224     ACT_NULL_ASSIGN = '='
1225   };
1226   size_t env_length;
1227   size_t env_maxlen;
1228   size_t pat_length;
1229   size_t pat_maxlen;
1230   size_t start = *offset;
1231   char *env;
1232   char *pattern;
1233   char *value = NULL;
1234   enum action action = ACT_NONE;
1235   int depth = 0;
1236   int colon_seen = 0;
1237   int seen_hash = 0;
1238   int free_value = 0;
1239   int pattern_is_quoted = 0; /* 1 for singly-quoted, 2 for doubly-quoted */
1240   int error;
1241   int special = 0;
1242   char buffer[21];
1243   int brace = words[*offset] == '{';
1244
1245   env = w_newword (&env_length, &env_maxlen);
1246   pattern = w_newword (&pat_length, &pat_maxlen);
1247
1248   if (brace)
1249     ++*offset;
1250
1251   /* First collect the parameter name. */
1252
1253   if (words[*offset] == '#')
1254     {
1255       seen_hash = 1;
1256       if (!brace)
1257         goto envsubst;
1258       ++*offset;
1259     }
1260
1261   if (isalpha (words[*offset]) || words[*offset] == '_')
1262     {
1263       /* Normal parameter name. */
1264       do
1265         {
1266           env = w_addchar (env, &env_length, &env_maxlen,
1267                            words[*offset]);
1268           if (env == NULL)
1269             goto no_space;
1270         }
1271       while (isalnum (words[++*offset]) || words[*offset] == '_');
1272     }
1273   else if (isdigit (words[*offset]))
1274     {
1275       /* Numeric parameter name. */
1276       special = 1;
1277       do
1278         {
1279           env = w_addchar (env, &env_length, &env_maxlen,
1280                            words[*offset]);
1281           if (env == NULL)
1282             goto no_space;
1283           if (!brace)
1284             goto envsubst;
1285         }
1286       while (isdigit(words[++*offset]));
1287     }
1288   else if (strchr ("*@$", words[*offset]) != NULL)
1289     {
1290       /* Special parameter. */
1291       special = 1;
1292       env = w_addchar (env, &env_length, &env_maxlen,
1293                        words[*offset]);
1294       if (env == NULL)
1295         goto no_space;
1296       ++*offset;
1297     }
1298   else
1299     {
1300       if (brace)
1301         goto syntax;
1302     }
1303
1304   if (brace)
1305     {
1306       /* Check for special action to be applied to the value. */
1307       switch (words[*offset])
1308         {
1309         case '}':
1310           /* Evaluate. */
1311           goto envsubst;
1312
1313         case '#':
1314           action = ACT_RP_SHORT_LEFT;
1315           if (words[1 + *offset] == '#')
1316             {
1317               ++*offset;
1318               action = ACT_RP_LONG_LEFT;
1319             }
1320           break;
1321
1322         case '%':
1323           action = ACT_RP_SHORT_RIGHT;
1324           if (words[1 + *offset] == '%')
1325             {
1326               ++*offset;
1327               action = ACT_RP_LONG_RIGHT;
1328             }
1329           break;
1330
1331         case ':':
1332           if (strchr ("-=?+", words[1 + *offset]) == NULL)
1333             goto syntax;
1334
1335           colon_seen = 1;
1336           action = words[++*offset];
1337           break;
1338
1339         case '-':
1340         case '=':
1341         case '?':
1342         case '+':
1343           action = words[*offset];
1344           break;
1345
1346         default:
1347           goto syntax;
1348         }
1349
1350       /* Now collect the pattern, but don't expand it yet. */
1351       ++*offset;
1352       for (; words[*offset]; ++(*offset))
1353         {
1354           switch (words[*offset])
1355             {
1356             case '{':
1357               if (!pattern_is_quoted)
1358                 ++depth;
1359               break;
1360
1361             case '}':
1362               if (!pattern_is_quoted)
1363                 {
1364                   if (depth == 0)
1365                     goto envsubst;
1366                   --depth;
1367                 }
1368               break;
1369
1370             case '\\':
1371               if (pattern_is_quoted)
1372                 /* Quoted; treat as normal character. */
1373                 break;
1374
1375               /* Otherwise, it's an escape: next character is literal. */
1376               if (words[++*offset] == '\0')
1377                 goto syntax;
1378
1379               pattern = w_addchar (pattern, &pat_length, &pat_maxlen, '\\');
1380               if (pattern == NULL)
1381                 goto no_space;
1382
1383               break;
1384
1385             case '\'':
1386               if (pattern_is_quoted == 0)
1387                 pattern_is_quoted = 1;
1388               else if (pattern_is_quoted == 1)
1389                 pattern_is_quoted = 0;
1390
1391               break;
1392
1393             case '"':
1394               if (pattern_is_quoted == 0)
1395                 pattern_is_quoted = 2;
1396               else if (pattern_is_quoted == 2)
1397                 pattern_is_quoted = 0;
1398
1399               break;
1400             }
1401
1402           pattern = w_addchar (pattern, &pat_length, &pat_maxlen,
1403                                words[*offset]);
1404           if (pattern == NULL)
1405             goto no_space;
1406         }
1407     }
1408
1409   /* End of input string -- remember to reparse the character that we
1410    * stopped at.  */
1411   --(*offset);
1412
1413 envsubst:
1414   if (words[start] == '{' && words[*offset] != '}')
1415     goto syntax;
1416
1417   if (env == NULL)
1418     {
1419       if (seen_hash)
1420         {
1421           /* $# expands to the number of positional parameters */
1422           buffer[20] = '\0';
1423           value = _itoa_word (__libc_argc - 1, &buffer[20], 10, 0);
1424           seen_hash = 0;
1425         }
1426       else
1427         {
1428           /* Just $ on its own */
1429           *offset = start - 1;
1430           *word = w_addchar (*word, word_length, max_length, '$');
1431           return *word ? 0 : WRDE_NOSPACE;
1432         }
1433     }
1434   /* Is it a numeric parameter? */
1435   else if (isdigit (env[0]))
1436     {
1437       int n = atoi (env);
1438
1439       if (n >= __libc_argc)
1440         /* Substitute NULL. */
1441         value = NULL;
1442       else
1443         /* Replace with appropriate positional parameter. */
1444         value = __libc_argv[n];
1445     }
1446   /* Is it a special parameter? */
1447   else if (special)
1448     {
1449       /* Is it `$$'? */
1450       if (*env == '$')
1451         {
1452           buffer[20] = '\0';
1453           value = _itoa_word (__getpid (), &buffer[20], 10, 0);
1454         }
1455       /* Is it `${#*}' or `${#@}'? */
1456       else if ((*env == '*' || *env == '@') && seen_hash)
1457         {
1458           buffer[20] = '\0';
1459           value = _itoa_word (__libc_argc > 0 ? __libc_argc - 1 : 0,
1460                               &buffer[20], 10, 0);
1461           *word = w_addstr (*word, word_length, max_length, value);
1462           free (env);
1463           free (pattern);
1464           return *word ? 0 : WRDE_NOSPACE;
1465         }
1466       /* Is it `$*' or `$@' (unquoted) ? */
1467       else if (*env == '*' || (*env == '@' && !quoted))
1468         {
1469           size_t plist_len = 0;
1470           int p;
1471           char *end;
1472
1473           /* Build up value parameter by parameter (copy them) */
1474           for (p = 1; __libc_argv[p]; ++p)
1475             plist_len += strlen (__libc_argv[p]) + 1; /* for space */
1476           value = malloc (plist_len);
1477           if (value == NULL)
1478             goto no_space;
1479           end = value;
1480           *end = 0;
1481           for (p = 1; __libc_argv[p]; ++p)
1482             {
1483               if (p > 1)
1484                 *end++ = ' ';
1485               end = __stpcpy (end, __libc_argv[p]);
1486             }
1487
1488           free_value = 1;
1489         }
1490       else
1491         {
1492           /* Must be a quoted `$@' */
1493           assert (*env == '@' && quoted);
1494
1495           /* Each parameter is a separate word ("$@") */
1496           if (__libc_argc == 2)
1497             value = __libc_argv[1];
1498           else if (__libc_argc > 2)
1499             {
1500               int p;
1501
1502               /* Append first parameter to current word. */
1503               value = w_addstr (*word, word_length, max_length,
1504                                 __libc_argv[1]);
1505               if (value == NULL || w_addword (pwordexp, value))
1506                 goto no_space;
1507
1508               for (p = 2; __libc_argv[p + 1]; p++)
1509                 {
1510                   char *newword = __strdup (__libc_argv[p]);
1511                   if (newword == NULL || w_addword (pwordexp, newword))
1512                     goto no_space;
1513                 }
1514
1515               /* Start a new word with the last parameter. */
1516               *word = w_newword (word_length, max_length);
1517               value = __libc_argv[p];
1518             }
1519           else
1520             {
1521               free (env);
1522               free (pattern);
1523               return 0;
1524             }
1525         }
1526     }
1527   else
1528     value = getenv (env);
1529
1530   if (value == NULL && (flags & WRDE_UNDEF))
1531     {
1532       /* Variable not defined. */
1533       error = WRDE_BADVAL;
1534       goto do_error;
1535     }
1536
1537   if (action != ACT_NONE)
1538     {
1539       int expand_pattern = 0;
1540
1541       /* First, find out if we need to expand pattern (i.e. if we will
1542        * use it). */
1543       switch (action)
1544         {
1545         case ACT_RP_SHORT_LEFT:
1546         case ACT_RP_LONG_LEFT:
1547         case ACT_RP_SHORT_RIGHT:
1548         case ACT_RP_LONG_RIGHT:
1549           /* Always expand for these. */
1550           expand_pattern = 1;
1551           break;
1552
1553         case ACT_NULL_ERROR:
1554         case ACT_NULL_SUBST:
1555         case ACT_NULL_ASSIGN:
1556           if (!value || (!*value && colon_seen))
1557             /* If param is unset, or set but null and a colon has been seen,
1558                the expansion of the pattern will be needed. */
1559             expand_pattern = 1;
1560
1561           break;
1562
1563         case ACT_NONNULL_SUBST:
1564           /* Expansion of word will be needed if parameter is set and not null,
1565              or set null but no colon has been seen. */
1566           if (value && (*value || !colon_seen))
1567             expand_pattern = 1;
1568
1569           break;
1570
1571         default:
1572           assert (! "Unrecognised action!");
1573         }
1574
1575       if (expand_pattern)
1576         {
1577           /* We need to perform tilde expansion, parameter expansion,
1578              command substitution, and arithmetic expansion.  We also
1579              have to be a bit careful with wildcard characters, as
1580              pattern might be given to fnmatch soon.  To do this, we
1581              convert quotes to escapes. */
1582
1583           char *expanded;
1584           size_t exp_len;
1585           size_t exp_maxl;
1586           char *p;
1587           int quoted = 0; /* 1: single quotes; 2: double */
1588
1589           expanded = w_newword (&exp_len, &exp_maxl);
1590           for (p = pattern; p && *p; p++)
1591             {
1592               size_t offset;
1593
1594               switch (*p)
1595                 {
1596                 case '"':
1597                   if (quoted == 2)
1598                     quoted = 0;
1599                   else if (quoted == 0)
1600                     quoted = 2;
1601                   else break;
1602
1603                   continue;
1604
1605                 case '\'':
1606                   if (quoted == 1)
1607                     quoted = 0;
1608                   else if (quoted == 0)
1609                     quoted = 1;
1610                   else break;
1611
1612                   continue;
1613
1614                 case '*':
1615                 case '?':
1616                   if (quoted)
1617                     {
1618                       /* Convert quoted wildchar to escaped wildchar. */
1619                       expanded = w_addchar (expanded, &exp_len,
1620                                             &exp_maxl, '\\');
1621
1622                       if (expanded == NULL)
1623                         goto no_space;
1624                     }
1625                   break;
1626
1627                 case '$':
1628                   offset = 0;
1629                   error = parse_dollars (&expanded, &exp_len, &exp_maxl, p,
1630                                          &offset, flags, NULL, NULL, NULL, 1);
1631                   if (error)
1632                     {
1633                       if (free_value)
1634                         free (value);
1635
1636                       free (expanded);
1637
1638                       goto do_error;
1639                     }
1640
1641                   p += offset;
1642                   continue;
1643
1644                 case '~':
1645                   if (quoted || exp_len)
1646                     break;
1647
1648                   offset = 0;
1649                   error = parse_tilde (&expanded, &exp_len, &exp_maxl, p,
1650                                        &offset, 0);
1651                   if (error)
1652                     {
1653                       if (free_value)
1654                         free (value);
1655
1656                       free (expanded);
1657
1658                       goto do_error;
1659                     }
1660
1661                   p += offset;
1662                   continue;
1663
1664                 case '\\':
1665                   expanded = w_addchar (expanded, &exp_len, &exp_maxl, '\\');
1666                   ++p;
1667                   assert (*p); /* checked when extracted initially */
1668                   if (expanded == NULL)
1669                     goto no_space;
1670                 }
1671
1672               expanded = w_addchar (expanded, &exp_len, &exp_maxl, *p);
1673
1674               if (expanded == NULL)
1675                 goto no_space;
1676             }
1677
1678           free (pattern);
1679
1680           pattern = expanded;
1681         }
1682
1683       switch (action)
1684         {
1685         case ACT_RP_SHORT_LEFT:
1686         case ACT_RP_LONG_LEFT:
1687         case ACT_RP_SHORT_RIGHT:
1688         case ACT_RP_LONG_RIGHT:
1689           {
1690             char *p;
1691             char c;
1692             char *end;
1693
1694             if (value == NULL || pattern == NULL || *pattern == '\0')
1695               break;
1696
1697             end = value + strlen (value);
1698
1699             switch (action)
1700               {
1701               case ACT_RP_SHORT_LEFT:
1702                 for (p = value; p <= end; ++p)
1703                   {
1704                     c = *p;
1705                     *p = '\0';
1706                     if (fnmatch (pattern, value, 0) != FNM_NOMATCH)
1707                       {
1708                         *p = c;
1709                         if (free_value)
1710                           {
1711                             char *newval = __strdup (p);
1712                             if (newval == NULL)
1713                               {
1714                                 free (value);
1715                                 goto no_space;
1716                               }
1717                             free (value);
1718                             value = newval;
1719                           }
1720                         else
1721                           value = p;
1722                         break;
1723                       }
1724                     *p = c;
1725                   }
1726
1727                 break;
1728
1729               case ACT_RP_LONG_LEFT:
1730                 for (p = end; p >= value; --p)
1731                   {
1732                     c = *p;
1733                     *p = '\0';
1734                     if (fnmatch (pattern, value, 0) != FNM_NOMATCH)
1735                       {
1736                         *p = c;
1737                         if (free_value)
1738                           {
1739                             char *newval = __strdup (p);
1740                             if (newval == NULL)
1741                               {
1742                                 free (value);
1743                                 goto no_space;
1744                               }
1745                             free (value);
1746                             value = newval;
1747                           }
1748                         else
1749                           value = p;
1750                         break;
1751                       }
1752                     *p = c;
1753                   }
1754
1755                 break;
1756
1757               case ACT_RP_SHORT_RIGHT:
1758                 for (p = end; p >= value; --p)
1759                   {
1760                     if (fnmatch (pattern, p, 0) != FNM_NOMATCH)
1761                       {
1762                         char *newval;
1763                         newval = malloc (p - value + 1);
1764
1765                         if (newval == NULL)
1766                           {
1767                             if (free_value)
1768                               free (value);
1769                             goto no_space;
1770                           }
1771
1772                         *(char *) __mempcpy (newval, value, p - value) = '\0';
1773                         if (free_value)
1774                           free (value);
1775                         value = newval;
1776                         free_value = 1;
1777                         break;
1778                       }
1779                   }
1780
1781                 break;
1782
1783               case ACT_RP_LONG_RIGHT:
1784                 for (p = value; p <= end; ++p)
1785                   {
1786                     if (fnmatch (pattern, p, 0) != FNM_NOMATCH)
1787                       {
1788                         char *newval;
1789                         newval = malloc (p - value + 1);
1790
1791                         if (newval == NULL)
1792                           {
1793                             if (free_value)
1794                               free (value);
1795                             goto no_space;
1796                           }
1797
1798                         *(char *) __mempcpy (newval, value, p - value) = '\0';
1799                         if (free_value)
1800                           free (value);
1801                         value = newval;
1802                         free_value = 1;
1803                         break;
1804                       }
1805                   }
1806
1807                 break;
1808
1809               default:
1810                 break;
1811               }
1812
1813             break;
1814           }
1815
1816         case ACT_NULL_ERROR:
1817           if (value && *value)
1818             /* Substitute parameter */
1819             break;
1820
1821           error = 0;
1822           if (!colon_seen && value)
1823             /* Substitute NULL */
1824             ;
1825           else
1826             {
1827               const char *str = pattern;
1828
1829               if (str[0] == '\0')
1830                 str = _("parameter null or not set");
1831
1832               __fxprintf (NULL, "%s: %s\n", env, str);
1833             }
1834
1835           if (free_value)
1836             free (value);
1837           goto do_error;
1838
1839         case ACT_NULL_SUBST:
1840           if (value && *value)
1841             /* Substitute parameter */
1842             break;
1843
1844           if (free_value)
1845             free (value);
1846
1847           if (!colon_seen && value)
1848             /* Substitute NULL */
1849             goto success;
1850
1851           value = pattern ? __strdup (pattern) : pattern;
1852           free_value = 1;
1853
1854           if (pattern && !value)
1855             goto no_space;
1856
1857           break;
1858
1859         case ACT_NONNULL_SUBST:
1860           if (value && (*value || !colon_seen))
1861             {
1862               if (free_value)
1863                 free (value);
1864
1865               value = pattern ? __strdup (pattern) : pattern;
1866               free_value = 1;
1867
1868               if (pattern && !value)
1869                 goto no_space;
1870
1871               break;
1872             }
1873
1874           /* Substitute NULL */
1875           if (free_value)
1876             free (value);
1877           goto success;
1878
1879         case ACT_NULL_ASSIGN:
1880           if (value && *value)
1881             /* Substitute parameter */
1882             break;
1883
1884           if (!colon_seen && value)
1885             {
1886               /* Substitute NULL */
1887               if (free_value)
1888                 free (value);
1889               goto success;
1890             }
1891
1892           if (free_value)
1893             free (value);
1894
1895           value = pattern ? __strdup (pattern) : pattern;
1896           free_value = 1;
1897
1898           if (pattern && !value)
1899             goto no_space;
1900
1901           __setenv (env, value, 1);
1902           break;
1903
1904         default:
1905           assert (! "Unrecognised action!");
1906         }
1907     }
1908
1909   free (env);
1910   env = NULL;
1911   free (pattern);
1912   pattern = NULL;
1913
1914   if (seen_hash)
1915     {
1916       char param_length[21];
1917       param_length[20] = '\0';
1918       *word = w_addstr (*word, word_length, max_length,
1919                         _itoa_word (value ? strlen (value) : 0,
1920                                     &param_length[20], 10, 0));
1921       if (free_value)
1922         {
1923           assert (value != NULL);
1924           free (value);
1925         }
1926
1927       return *word ? 0 : WRDE_NOSPACE;
1928     }
1929
1930   if (value == NULL)
1931     return 0;
1932
1933   if (quoted || !pwordexp)
1934     {
1935       /* Quoted - no field split */
1936       *word = w_addstr (*word, word_length, max_length, value);
1937       if (free_value)
1938         free (value);
1939
1940       return *word ? 0 : WRDE_NOSPACE;
1941     }
1942   else
1943     {
1944       /* Need to field-split */
1945       char *value_copy = __strdup (value); /* Don't modify value */
1946       char *field_begin = value_copy;
1947       int seen_nonws_ifs = 0;
1948
1949       if (free_value)
1950         free (value);
1951
1952       if (value_copy == NULL)
1953         goto no_space;
1954
1955       do
1956         {
1957           char *field_end = field_begin;
1958           char *next_field;
1959
1960           /* If this isn't the first field, start a new word */
1961           if (field_begin != value_copy)
1962             {
1963               if (w_addword (pwordexp, *word) == WRDE_NOSPACE)
1964                 {
1965                   free (value_copy);
1966                   goto no_space;
1967                 }
1968
1969               *word = w_newword (word_length, max_length);
1970             }
1971
1972           /* Skip IFS whitespace before the field */
1973           field_begin += strspn (field_begin, ifs_white);
1974
1975           if (!seen_nonws_ifs && *field_begin == 0)
1976             /* Nothing but whitespace */
1977             break;
1978
1979           /* Search for the end of the field */
1980           field_end = field_begin + strcspn (field_begin, ifs);
1981
1982           /* Set up pointer to the character after end of field and
1983              skip whitespace IFS after it. */
1984           next_field = field_end + strspn (field_end, ifs_white);
1985
1986           /* Skip at most one non-whitespace IFS character after the field */
1987           seen_nonws_ifs = 0;
1988           if (*next_field && strchr (ifs, *next_field))
1989             {
1990               seen_nonws_ifs = 1;
1991               next_field++;
1992             }
1993
1994           /* Null-terminate it */
1995           *field_end = 0;
1996
1997           /* Tag a copy onto the current word */
1998           *word = w_addstr (*word, word_length, max_length, field_begin);
1999
2000           if (*word == NULL && *field_begin != '\0')
2001             {
2002               free (value_copy);
2003               goto no_space;
2004             }
2005
2006           field_begin = next_field;
2007         }
2008       while (seen_nonws_ifs || *field_begin);
2009
2010       free (value_copy);
2011     }
2012
2013   return 0;
2014
2015 success:
2016   error = 0;
2017   goto do_error;
2018
2019 no_space:
2020   error = WRDE_NOSPACE;
2021   goto do_error;
2022
2023 syntax:
2024   error = WRDE_SYNTAX;
2025
2026 do_error:
2027   free (env);
2028
2029   free (pattern);
2030
2031   return error;
2032 }
2033
2034 static int
2035 internal_function
2036 parse_dollars (char **word, size_t *word_length, size_t *max_length,
2037                const char *words, size_t *offset, int flags,
2038                wordexp_t *pwordexp, const char *ifs, const char *ifs_white,
2039                int quoted)
2040 {
2041   /* We are poised _at_ "$" */
2042   switch (words[1 + *offset])
2043     {
2044     case '"':
2045     case '\'':
2046     case 0:
2047       *word = w_addchar (*word, word_length, max_length, '$');
2048       return *word ? 0 : WRDE_NOSPACE;
2049
2050     case '(':
2051       if (words[2 + *offset] == '(')
2052         {
2053           /* Differentiate between $((1+3)) and $((echo);(ls)) */
2054           int i = 3 + *offset;
2055           int depth = 0;
2056           while (words[i] && !(depth == 0 && words[i] == ')'))
2057             {
2058               if (words[i] == '(')
2059                 ++depth;
2060               else if (words[i] == ')')
2061                 --depth;
2062
2063               ++i;
2064             }
2065
2066           if (words[i] == ')' && words[i + 1] == ')')
2067             {
2068               (*offset) += 3;
2069               /* Call parse_arith -- 0 is for "no brackets" */
2070               return parse_arith (word, word_length, max_length, words, offset,
2071                                   flags, 0);
2072             }
2073         }
2074
2075       if (flags & WRDE_NOCMD)
2076         return WRDE_CMDSUB;
2077
2078       (*offset) += 2;
2079       return parse_comm (word, word_length, max_length, words, offset, flags,
2080                          quoted? NULL : pwordexp, ifs, ifs_white);
2081
2082     case '[':
2083       (*offset) += 2;
2084       /* Call parse_arith -- 1 is for "brackets" */
2085       return parse_arith (word, word_length, max_length, words, offset, flags,
2086                           1);
2087
2088     case '{':
2089     default:
2090       ++(*offset);      /* parse_param needs to know if "{" is there */
2091       return parse_param (word, word_length, max_length, words, offset, flags,
2092                            pwordexp, ifs, ifs_white, quoted);
2093     }
2094 }
2095
2096 static int
2097 internal_function
2098 parse_backtick (char **word, size_t *word_length, size_t *max_length,
2099                 const char *words, size_t *offset, int flags,
2100                 wordexp_t *pwordexp, const char *ifs, const char *ifs_white)
2101 {
2102   /* We are poised just after "`" */
2103   int error;
2104   int squoting = 0;
2105   size_t comm_length;
2106   size_t comm_maxlen;
2107   char *comm = w_newword (&comm_length, &comm_maxlen);
2108
2109   for (; words[*offset]; ++(*offset))
2110     {
2111       switch (words[*offset])
2112         {
2113         case '`':
2114           /* Go -- give the script to the shell */
2115           error = exec_comm (comm, word, word_length, max_length, flags,
2116                              pwordexp, ifs, ifs_white);
2117           free (comm);
2118           return error;
2119
2120         case '\\':
2121           if (squoting)
2122             {
2123               error = parse_qtd_backslash (&comm, &comm_length, &comm_maxlen,
2124                                            words, offset);
2125
2126               if (error)
2127                 {
2128                   free (comm);
2129                   return error;
2130                 }
2131
2132               break;
2133             }
2134
2135           ++(*offset);
2136           error = parse_backslash (&comm, &comm_length, &comm_maxlen, words,
2137                                    offset);
2138
2139           if (error)
2140             {
2141               free (comm);
2142               return error;
2143             }
2144
2145           break;
2146
2147         case '\'':
2148           squoting = 1 - squoting;
2149         default:
2150           comm = w_addchar (comm, &comm_length, &comm_maxlen, words[*offset]);
2151           if (comm == NULL)
2152             return WRDE_NOSPACE;
2153         }
2154     }
2155
2156   /* Premature end */
2157   free (comm);
2158   return WRDE_SYNTAX;
2159 }
2160
2161 static int
2162 internal_function
2163 parse_dquote (char **word, size_t *word_length, size_t *max_length,
2164               const char *words, size_t *offset, int flags,
2165               wordexp_t *pwordexp, const char * ifs, const char * ifs_white)
2166 {
2167   /* We are poised just after a double-quote */
2168   int error;
2169
2170   for (; words[*offset]; ++(*offset))
2171     {
2172       switch (words[*offset])
2173         {
2174         case '"':
2175           return 0;
2176
2177         case '$':
2178           error = parse_dollars (word, word_length, max_length, words, offset,
2179                                  flags, pwordexp, ifs, ifs_white, 1);
2180           /* The ``1'' here is to tell parse_dollars not to
2181            * split the fields.  It may need to, however ("$@").
2182            */
2183           if (error)
2184             return error;
2185
2186           break;
2187
2188         case '`':
2189           if (flags & WRDE_NOCMD)
2190             return WRDE_CMDSUB;
2191
2192           ++(*offset);
2193           error = parse_backtick (word, word_length, max_length, words,
2194                                   offset, flags, NULL, NULL, NULL);
2195           /* The first NULL here is to tell parse_backtick not to
2196            * split the fields.
2197            */
2198           if (error)
2199             return error;
2200
2201           break;
2202
2203         case '\\':
2204           error = parse_qtd_backslash (word, word_length, max_length, words,
2205                                        offset);
2206
2207           if (error)
2208             return error;
2209
2210           break;
2211
2212         default:
2213           *word = w_addchar (*word, word_length, max_length, words[*offset]);
2214           if (*word == NULL)
2215             return WRDE_NOSPACE;
2216         }
2217     }
2218
2219   /* Unterminated string */
2220   return WRDE_SYNTAX;
2221 }
2222
2223 /*
2224  * wordfree() is to be called after pwordexp is finished with.
2225  */
2226
2227 void
2228 wordfree (wordexp_t *pwordexp)
2229 {
2230
2231   /* wordexp can set pwordexp to NULL */
2232   if (pwordexp && pwordexp->we_wordv)
2233     {
2234       char **wordv = pwordexp->we_wordv;
2235
2236       for (wordv += pwordexp->we_offs; *wordv; ++wordv)
2237         free (*wordv);
2238
2239       free (pwordexp->we_wordv);
2240       pwordexp->we_wordv = NULL;
2241     }
2242 }
2243 libc_hidden_def (wordfree)
2244
2245 /*
2246  * wordexp()
2247  */
2248
2249 int
2250 wordexp (const char *words, wordexp_t *pwordexp, int flags)
2251 {
2252   size_t words_offset;
2253   size_t word_length;
2254   size_t max_length;
2255   char *word = w_newword (&word_length, &max_length);
2256   int error;
2257   char *ifs;
2258   char ifs_white[4];
2259   wordexp_t old_word = *pwordexp;
2260
2261   if (flags & WRDE_REUSE)
2262     {
2263       /* Minimal implementation of WRDE_REUSE for now */
2264       wordfree (pwordexp);
2265       old_word.we_wordv = NULL;
2266     }
2267
2268   if ((flags & WRDE_APPEND) == 0)
2269     {
2270       pwordexp->we_wordc = 0;
2271
2272       if (flags & WRDE_DOOFFS)
2273         {
2274           pwordexp->we_wordv = calloc (1 + pwordexp->we_offs, sizeof (char *));
2275           if (pwordexp->we_wordv == NULL)
2276             {
2277               error = WRDE_NOSPACE;
2278               goto do_error;
2279             }
2280         }
2281       else
2282         {
2283           pwordexp->we_wordv = calloc (1, sizeof (char *));
2284           if (pwordexp->we_wordv == NULL)
2285             {
2286               error = WRDE_NOSPACE;
2287               goto do_error;
2288             }
2289
2290           pwordexp->we_offs = 0;
2291         }
2292     }
2293
2294   /* Find out what the field separators are.
2295    * There are two types: whitespace and non-whitespace.
2296    */
2297   ifs = getenv ("IFS");
2298
2299   if (ifs == NULL)
2300     /* IFS unset - use <space><tab><newline>. */
2301     ifs = strcpy (ifs_white, " \t\n");
2302   else
2303     {
2304       char *ifsch = ifs;
2305       char *whch = ifs_white;
2306
2307       while (*ifsch != '\0')
2308         {
2309           if (*ifsch == ' ' || *ifsch == '\t' || *ifsch == '\n')
2310             {
2311               /* Whitespace IFS.  See first whether it is already in our
2312                  collection.  */
2313               char *runp = ifs_white;
2314
2315               while (runp < whch && *runp != *ifsch)
2316                 ++runp;
2317
2318               if (runp == whch)
2319                 *whch++ = *ifsch;
2320             }
2321
2322           ++ifsch;
2323         }
2324       *whch = '\0';
2325     }
2326
2327   for (words_offset = 0 ; words[words_offset] ; ++words_offset)
2328     switch (words[words_offset])
2329       {
2330       case '\\':
2331         error = parse_backslash (&word, &word_length, &max_length, words,
2332                                  &words_offset);
2333
2334         if (error)
2335           goto do_error;
2336
2337         break;
2338
2339       case '$':
2340         error = parse_dollars (&word, &word_length, &max_length, words,
2341                                &words_offset, flags, pwordexp, ifs, ifs_white,
2342                                0);
2343
2344         if (error)
2345           goto do_error;
2346
2347         break;
2348
2349       case '`':
2350         if (flags & WRDE_NOCMD)
2351           {
2352             error = WRDE_CMDSUB;
2353             goto do_error;
2354           }
2355
2356         ++words_offset;
2357         error = parse_backtick (&word, &word_length, &max_length, words,
2358                                 &words_offset, flags, pwordexp, ifs,
2359                                 ifs_white);
2360
2361         if (error)
2362           goto do_error;
2363
2364         break;
2365
2366       case '"':
2367         ++words_offset;
2368         error = parse_dquote (&word, &word_length, &max_length, words,
2369                               &words_offset, flags, pwordexp, ifs, ifs_white);
2370
2371         if (error)
2372           goto do_error;
2373
2374         if (!word_length)
2375           {
2376             error = w_addword (pwordexp, NULL);
2377
2378             if (error)
2379               return error;
2380           }
2381
2382         break;
2383
2384       case '\'':
2385         ++words_offset;
2386         error = parse_squote (&word, &word_length, &max_length, words,
2387                               &words_offset);
2388
2389         if (error)
2390           goto do_error;
2391
2392         if (!word_length)
2393           {
2394             error = w_addword (pwordexp, NULL);
2395
2396             if (error)
2397               return error;
2398           }
2399
2400         break;
2401
2402       case '~':
2403         error = parse_tilde (&word, &word_length, &max_length, words,
2404                              &words_offset, pwordexp->we_wordc);
2405
2406         if (error)
2407           goto do_error;
2408
2409         break;
2410
2411       case '*':
2412       case '[':
2413       case '?':
2414         error = parse_glob (&word, &word_length, &max_length, words,
2415                             &words_offset, flags, pwordexp, ifs, ifs_white);
2416
2417         if (error)
2418           goto do_error;
2419
2420         break;
2421
2422       default:
2423         /* Is it a word separator? */
2424         if (strchr (" \t", words[words_offset]) == NULL)
2425           {
2426             char ch = words[words_offset];
2427
2428             /* Not a word separator -- but is it a valid word char? */
2429             if (strchr ("\n|&;<>(){}", ch))
2430               {
2431                 /* Fail */
2432                 error = WRDE_BADCHAR;
2433                 goto do_error;
2434               }
2435
2436             /* "Ordinary" character -- add it to word */
2437             word = w_addchar (word, &word_length, &max_length,
2438                               ch);
2439             if (word == NULL)
2440               {
2441                 error = WRDE_NOSPACE;
2442                 goto do_error;
2443               }
2444
2445             break;
2446           }
2447
2448         /* If a word has been delimited, add it to the list. */
2449         if (word != NULL)
2450           {
2451             error = w_addword (pwordexp, word);
2452             if (error)
2453               goto do_error;
2454           }
2455
2456         word = w_newword (&word_length, &max_length);
2457       }
2458
2459   /* End of string */
2460
2461   /* There was a word separator at the end */
2462   if (word == NULL) /* i.e. w_newword */
2463     return 0;
2464
2465   /* There was no field separator at the end */
2466   return w_addword (pwordexp, word);
2467
2468 do_error:
2469   /* Error:
2470    *    free memory used (unless error is WRDE_NOSPACE), and
2471    *    set pwordexp members back to what they were.
2472    */
2473
2474   free (word);
2475
2476   if (error == WRDE_NOSPACE)
2477     return WRDE_NOSPACE;
2478
2479   if ((flags & WRDE_APPEND) == 0)
2480     wordfree (pwordexp);
2481
2482   *pwordexp = old_word;
2483   return error;
2484 }