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