]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/groff/src/libs/libgroff/spawnvp.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / groff / src / libs / libgroff / spawnvp.c
1 /* Copyright (C) 2004
2    Free Software Foundation, Inc.
3      Written by: Keith Marshall (keith.d.marshall@ntlworld.com)
4
5 This file is part of groff.
6
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with groff; see the file COPYING.  If not, write to the Free Software
19 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include <stdio.h>
26 #include <stdlib.h>
27
28 #ifdef HAVE_PROCESS_H
29 # include <process.h>
30 #endif
31
32 #if defined(__MSDOS__) \
33     || (defined(_WIN32) && !defined(_UWIN) && !defined(__CYGWIN__)) \
34     || defined(__EMX__)
35
36 #define SPAWN_FUNCTION_WRAPPERS 1
37
38 /* Define the default mechanism, and messages, for error reporting
39  * (user may substitute a preferred alternative, by defining his own
40  *  implementation of the macros REPORT_ERROR and ARGV_MALLOC_ERROR,
41  *  in the header file `nonposix.h').
42  */
43
44 #include "nonposix.h"
45
46 #ifndef  REPORT_ERROR
47 # define REPORT_ERROR(WHY)  fprintf(stderr, "%s:%s\n", program_name, WHY)
48 #endif
49 #ifndef  ARGV_MALLOC_ERROR
50 # define ARGV_MALLOC_ERROR    "malloc: Allocation for 'argv' failed"
51 #endif
52
53 extern char *program_name;
54
55 extern char *quote_arg(char *string);
56 extern void purge_quoted_args(char **argv);
57
58 int
59 spawnvp_wrapper(int mode, char *path, char **argv)
60 {
61   /* Invoke the system `spawnvp' service
62    * enclosing the passed arguments in double quotes, as required,
63    * so that the (broken) default parsing in the MSVC runtime doesn't
64    * split them at whitespace. */
65
66   char **quoted_argv;   /* used to build a quoted local copy of `argv' */
67
68   int i;                /* used as an index into `argv' or `quoted_argv' */
69   int status = -1;      /* initialise return code, in case we fail */
70   int argc = 0;         /* initialise argument count; may be none  */
71
72   /* First count the number of arguments
73    * which are actually present in the passed `argv'. */
74
75   if (argv)
76     for (quoted_argv = argv; *quoted_argv; ++argc, ++quoted_argv)
77       ;
78
79   /* If we do not now have an argument count,
80    * then we must fall through and fail. */
81   
82   if (argc) {
83     /* We do have at least one argument:
84      * We will use a copy of the `argv', in which to do the quoting,
85      * so we must allocate space for it. */
86
87     if ((quoted_argv = (char **)malloc(++argc * sizeof(char **))) == NULL) {
88       /* If we didn't get enough space,
89        * then complain, and bail out gracefully. */
90
91       REPORT_ERROR(ARGV_MALLOC_ERROR);
92       exit(1);
93     }
94
95     /* Now copy the passed `argv' into our new vector,
96      * quoting its contents as required. */
97     
98     for (i = 0; i < argc; i++)
99       quoted_argv[i] = quote_arg(argv[i]);
100
101     /* Invoke the MSVC `spawnvp' service
102      * passing our now appropriately quoted copy of `argv'. */
103
104     status = spawnvp(mode, path, quoted_argv);
105
106     /* Clean up our memory allocations
107      * for the quoted copy of `argv', which is no longer required. */
108
109     purge_quoted_args(quoted_argv);
110     free(quoted_argv);
111   }
112
113   /* Finally,
114    * return the status code returned by `spawnvp',
115    * or a failure code if we fell through. */
116
117   return status;
118 }
119
120 #endif  /* __MSDOS__ || _WIN32 */
121
122 /* spawnvp.c: end of file */