1151497Sru/* Copyright (C) 2004 2151497Sru Free Software Foundation, Inc. 3151497Sru Written by: Keith Marshall (keith.d.marshall@ntlworld.com) 4151497Sru 5151497SruThis file is part of groff. 6151497Sru 7151497Srugroff is free software; you can redistribute it and/or modify it under 8151497Sruthe terms of the GNU General Public License as published by the Free 9151497SruSoftware Foundation; either version 2, or (at your option) any later 10151497Sruversion. 11151497Sru 12151497Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY 13151497SruWARRANTY; without even the implied warranty of MERCHANTABILITY or 14151497SruFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15151497Srufor more details. 16151497Sru 17151497SruYou should have received a copy of the GNU General Public License along 18151497Sruwith groff; see the file COPYING. If not, write to the Free Software 19151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ 20151497Sru 21151497Sru#ifdef HAVE_CONFIG_H 22151497Sru# include "config.h" 23151497Sru#endif 24151497Sru 25151497Sru#include <stdio.h> 26151497Sru#include <stdlib.h> 27151497Sru 28151497Sru#ifdef HAVE_PROCESS_H 29151497Sru# include <process.h> 30151497Sru#endif 31151497Sru 32151497Sru#if defined(__MSDOS__) \ 33151497Sru || (defined(_WIN32) && !defined(_UWIN) && !defined(__CYGWIN__)) \ 34151497Sru || defined(__EMX__) 35151497Sru 36151497Sru#define SPAWN_FUNCTION_WRAPPERS 1 37151497Sru 38151497Sru/* Define the default mechanism, and messages, for error reporting 39151497Sru * (user may substitute a preferred alternative, by defining his own 40151497Sru * implementation of the macros REPORT_ERROR and ARGV_MALLOC_ERROR, 41151497Sru * in the header file `nonposix.h'). 42151497Sru */ 43151497Sru 44151497Sru#include "nonposix.h" 45151497Sru 46151497Sru#ifndef REPORT_ERROR 47151497Sru# define REPORT_ERROR(WHY) fprintf(stderr, "%s:%s\n", program_name, WHY) 48151497Sru#endif 49151497Sru#ifndef ARGV_MALLOC_ERROR 50151497Sru# define ARGV_MALLOC_ERROR "malloc: Allocation for 'argv' failed" 51151497Sru#endif 52151497Sru 53151497Sruextern char *program_name; 54151497Sru 55151497Sruextern char *quote_arg(char *string); 56151497Sruextern void purge_quoted_args(char **argv); 57151497Sru 58151497Sruint 59151497Sruspawnvp_wrapper(int mode, char *path, char **argv) 60151497Sru{ 61151497Sru /* Invoke the system `spawnvp' service 62151497Sru * enclosing the passed arguments in double quotes, as required, 63151497Sru * so that the (broken) default parsing in the MSVC runtime doesn't 64151497Sru * split them at whitespace. */ 65151497Sru 66151497Sru char **quoted_argv; /* used to build a quoted local copy of `argv' */ 67151497Sru 68151497Sru int i; /* used as an index into `argv' or `quoted_argv' */ 69151497Sru int status = -1; /* initialise return code, in case we fail */ 70151497Sru int argc = 0; /* initialise argument count; may be none */ 71151497Sru 72151497Sru /* First count the number of arguments 73151497Sru * which are actually present in the passed `argv'. */ 74151497Sru 75151497Sru if (argv) 76151497Sru for (quoted_argv = argv; *quoted_argv; ++argc, ++quoted_argv) 77151497Sru ; 78151497Sru 79151497Sru /* If we do not now have an argument count, 80151497Sru * then we must fall through and fail. */ 81151497Sru 82151497Sru if (argc) { 83151497Sru /* We do have at least one argument: 84151497Sru * We will use a copy of the `argv', in which to do the quoting, 85151497Sru * so we must allocate space for it. */ 86151497Sru 87151497Sru if ((quoted_argv = (char **)malloc(++argc * sizeof(char **))) == NULL) { 88151497Sru /* If we didn't get enough space, 89151497Sru * then complain, and bail out gracefully. */ 90151497Sru 91151497Sru REPORT_ERROR(ARGV_MALLOC_ERROR); 92151497Sru exit(1); 93151497Sru } 94151497Sru 95151497Sru /* Now copy the passed `argv' into our new vector, 96151497Sru * quoting its contents as required. */ 97151497Sru 98151497Sru for (i = 0; i < argc; i++) 99151497Sru quoted_argv[i] = quote_arg(argv[i]); 100151497Sru 101151497Sru /* Invoke the MSVC `spawnvp' service 102151497Sru * passing our now appropriately quoted copy of `argv'. */ 103151497Sru 104151497Sru status = spawnvp(mode, path, quoted_argv); 105151497Sru 106151497Sru /* Clean up our memory allocations 107151497Sru * for the quoted copy of `argv', which is no longer required. */ 108151497Sru 109151497Sru purge_quoted_args(quoted_argv); 110151497Sru free(quoted_argv); 111151497Sru } 112151497Sru 113151497Sru /* Finally, 114151497Sru * return the status code returned by `spawnvp', 115151497Sru * or a failure code if we fell through. */ 116151497Sru 117151497Sru return status; 118151497Sru} 119151497Sru 120151497Sru#endif /* __MSDOS__ || _WIN32 */ 121151497Sru 122151497Sru/* spawnvp.c: end of file */ 123