PageRenderTime 8ms CodeModel.GetById 1ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/groff/src/libs/libgroff/spawnvp.c

https://bitbucket.org/freebsd/freebsd-head/
C | 122 lines | 46 code | 29 blank | 47 comment | 10 complexity | 8e16a132635e5255d522edd7c41984d0 MD5 | raw file
  1/* Copyright (C) 2004
  2   Free Software Foundation, Inc.
  3     Written by: Keith Marshall (keith.d.marshall@ntlworld.com)
  4
  5This file is part of groff.
  6
  7groff is free software; you can redistribute it and/or modify it under
  8the terms of the GNU General Public License as published by the Free
  9Software Foundation; either version 2, or (at your option) any later
 10version.
 11
 12groff is distributed in the hope that it will be useful, but WITHOUT ANY
 13WARRANTY; without even the implied warranty of MERCHANTABILITY or
 14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 15for more details.
 16
 17You should have received a copy of the GNU General Public License along
 18with groff; see the file COPYING.  If not, write to the Free Software
 19Foundation, 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
 53extern char *program_name;
 54
 55extern char *quote_arg(char *string);
 56extern void purge_quoted_args(char **argv);
 57
 58int
 59spawnvp_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 */