1 /* Copyright (C) 1992, 1997 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
19 #include <sys/types.h>
27 /* We do word expansion with a pipe to the shell.
28 The shell command `sh [-P] [-u] -w "words ..."' expands words.
29 If -P, command substitution is an error.
30 If -u, reference to an undefined variable is an error.
31 The shell writes on its stdout:
33 %u\0 Number of bytes in all words together (not counting \0s).
40 #define SHELL_PATH "/bin/sh"
41 #define SHELL_NAME "sh"
45 wordexp (string
, pwordexp
, flags
)
56 size_t wordc
, start
, buflen
;
59 /* Create the pipe through which we will communicate to the shell. */
69 /* Child. Run the shell. */
73 close (d
[STDIN_FILENO
]);
74 dup2 (d
[STDOUT_FILENO
], STDOUT_FILENO
);
75 if (!(flags
& WRDE_SHOWERR
))
76 close (STDERR_FILENO
);
79 argv
[i
++] = SHELL_NAME
;
80 if (flags
& WRDE_NOCMD
)
82 if (flags
& WRDE_UNDEF
)
88 execv (SHELL_PATH
, argv
);
97 close (d
[STDOUT_FILENO
]);
98 f
= fdopen (d
[STDIN_FILENO
]);
102 /* Read the number of words and number of bytes from the shell. */
103 if (fscanf (f
, "%u", &wordc
) != 1 || getc (f
) != '\0' ||
104 fscanf (f
, "%u", &buflen
) != 1 || getc (f
) != '\0')
107 /* Read the words from the shell, and wait for it to return. */
109 buf
= malloc (buflen
);
111 fread (buf
, buflen
, 1, f
) != 1 ||
112 waitpid (pid
, &status
, 0) != pid
)
115 if (WIFEXITED (status
))
117 if (WEXITSTATUS (status
) != 0)
119 error
= WEXITSTATUS (status
);
126 /* Pack the structure. */
129 if (flags
& WRDE_DOOFFS
)
130 start
+= pwordexp
->we_offs
;
131 if (flags
& WRDE_APPEND
)
132 start
+= pwordexp
->we_wordc
;
133 wordc
= start
+ wordc
+ 1;
135 if (flags
& WRDE_APPEND
)
136 wordv
= (char **) realloc ((void *) pwordexp
->we_wordv
,
137 wordc
* sizeof (char *));
139 wordv
= (char **) malloc (wordc
* sizeof (char *));
143 if (flags
& WRDE_DOOFFS
)
144 for (i
= 0; i
< pwordexp
->we_offs
; ++i
)
147 for (i
= start
; i
< wordc
; ++i
)
149 pwordexp
->we_wordv
[i
] = buf
;
150 buf
= strchr (buf
, '\0') + 1;
154 if (flags
& WRDE_REUSE
)
156 free (pwordexp
->we_wordv
[0]);
157 if (!(flags
& WRDE_APPEND
))
158 free (pwordexp
->we_wordv
);
161 pwordexp
->we_wordc
= wordc
;
162 pwordexp
->we_wordv
= wordv
;
170 (void) kill (pid
, SIGKILL
);
172 (void) waitpid (pid
, (int *) NULL
, 0);
180 DEFUN(wordexp
, (pwordexp
), wordexp_t
*pwordexp
)
182 /* All the other elts point into the first. */
183 free (pwordexp
->we_wordv
[0]);
184 free (pwordexp
->we_wordv
);