Beispiel #1
0
/**
 * Invoke the main function.
 */
int invoke_as_new_process(ProgramInvoker* invoker) {
char line[4096];
build_command_line(invoker,line);
int ret=system(line);

return ret;
}
static bool ffmpeg_mux_start(void *data)
{
	struct ffmpeg_muxer *stream = data;
	obs_data_t *settings;
	struct dstr cmd;
	const char *path;

	if (!obs_output_can_begin_data_capture(stream->output, 0))
		return false;
	if (!obs_output_initialize_encoders(stream->output, 0))
		return false;

	settings = obs_output_get_settings(stream->output);
	path = obs_data_get_string(settings, "path");
	dstr_copy(&stream->path, path);
	dstr_replace(&stream->path, "\"", "\"\"");
	obs_data_release(settings);

	build_command_line(stream, &cmd);
	stream->pipe = os_process_pipe_create(cmd.array, "w");
	dstr_free(&cmd);

	if (!stream->pipe) {
		warn("Failed to create process pipe");
		return false;
	}

	/* write headers and start capture */
	stream->active = true;
	stream->capturing = true;
	obs_output_begin_data_capture(stream->output, 0);

	info("Writing file '%s'...", stream->path.array);
	return true;
}
Beispiel #3
0
int main(int argc, char *argv[])
{
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	DWORD exitcode;
	int uses_redirection, in_quotes, i;
	static const char cmd_prefix[] = "cmd.exe /c ";

	// build the new command line
	build_command_line(argc, argv);

	// do we use redirection?  if so, use cmd.exe
	uses_redirection = FALSE;
	in_quotes = FALSE;
	for (i = 0; command_line[i]; i++)
	{
		if (command_line[i] == '\"')
			in_quotes = !in_quotes;
		if (!in_quotes && strchr("|<>", command_line[i]))
			uses_redirection = TRUE;
	}
	if (uses_redirection)
	{
		memmove(command_line + strlen(cmd_prefix), command_line, strlen(command_line) + 1);
		memcpy(command_line, cmd_prefix, strlen(cmd_prefix));
	}

	if (PRINT_COMMAND_LINE)
		printf("%s\n", command_line);

	// create the process information structures
	memset(&si, 0, sizeof(si));
	si.cb = sizeof(si);
	memset(&pi, 0, sizeof(pi));

	// create and execute the process
	if (!CreateProcess(NULL, command_line, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) ||
		pi.hProcess == INVALID_HANDLE_VALUE)
		return -101;

	// block until done and fetch the error code
	WaitForSingleObject(pi.hProcess, INFINITE);
	GetExitCodeProcess(pi.hProcess, &exitcode);

	// clean up the handles
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);

	// return the child's error code
	return exitcode;
}
Beispiel #4
0
/**
 * \brief Calls the tokenize program in Cassys
 *
 *	Tokenize is called with target text_name and options --word_by_word, --alphabet=alphabet_name, --token=token_txt_name if
 *	if token_txt_name is not NULL. For more information about tokenize, see the unitex manual.
 *
 * \param [in/out] text_name the name of the text
 * \param [in] alphabet the name of the alphabet
 * \param [in/out] token_txt_name the file containing all the of the text or
 *
 *
 *
 *
 */
int launch_tokenize_in_Cassys(const char *text_name, const char *alphabet_name, const char *token_txt_name,
    Encoding encoding_output,int bom_output,int mask_encoding_compatibility_input){

	fprintf(stdout,"Launch tokenize in Cassys\n");

	ProgramInvoker *invoker = new_ProgramInvoker(main_Tokenize,"main_Tokenize");

    char tmp[FILENAME_MAX];
    {
        tmp[0]=0;
        get_reading_encoding_text(tmp,sizeof(tmp)-1,mask_encoding_compatibility_input);
        if (tmp[0] != '\0') {
            add_argument(invoker,"-k");
            add_argument(invoker,tmp);
        }

        tmp[0]=0;
        get_writing_encoding_text(tmp,sizeof(tmp)-1,encoding_output,bom_output);
        if (tmp[0] != '\0') {
            add_argument(invoker,"-q");
            add_argument(invoker,tmp);
        }
    }

	// add the alphabet
	char alphabet_argument[FILENAME_MAX + 11];
	sprintf(alphabet_argument, "--alphabet=%s", alphabet_name);
	add_argument(invoker, alphabet_argument);

	// Tokenize word by word
	add_argument(invoker, "--word_by_word");

	// add the target text file
	add_argument(invoker,text_name);

	// if a token.txt file already exists, use it
	if(token_txt_name != NULL){
		char token_argument[FILENAME_MAX + 9];
		sprintf(token_argument,"--tokens=%s",token_txt_name);
		add_argument(invoker,token_argument);
	}

	char line_command[4096];
	build_command_line(invoker, line_command);
	fprintf(stdout, "%s\n", line_command);

	int result = invoke(invoker);
	free_ProgramInvoker(invoker);
	return result;
}
Beispiel #5
0
int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
		 unsigned long initrd_addr, unsigned long initrd_size)
{
	struct setup_header *hdr = &setup_base->hdr;
	int bootproto = get_boot_protocol(hdr);

	setup_base->e820_entries = install_e820_map(
		ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);

	if (bootproto == 0x0100) {
		setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
		setup_base->screen_info.cl_offset = COMMAND_LINE_OFFSET;
	}
	if (bootproto >= 0x0200) {
		hdr->type_of_loader = 8;

		if (initrd_addr) {
			printf("Initial RAM disk at linear address "
			       "0x%08lx, size %ld bytes\n",
			       initrd_addr, initrd_size);

			hdr->ramdisk_image = initrd_addr;
			hdr->ramdisk_size = initrd_size;
		}
	}

	if (bootproto >= 0x0201) {
		hdr->heap_end_ptr = HEAP_END_OFFSET;
		hdr->loadflags |= HEAP_FLAG;
	}

	if (cmd_line) {
		if (bootproto >= 0x0202) {
			hdr->cmd_line_ptr = (uintptr_t)cmd_line;
		} else if (bootproto >= 0x0200) {
			setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
			setup_base->screen_info.cl_offset =
				(uintptr_t)cmd_line - (uintptr_t)setup_base;

			hdr->setup_move_size = 0x9100;
		}

		/* build command line at COMMAND_LINE_OFFSET */
		build_command_line(cmd_line, auto_boot);
	}

	setup_video(&setup_base->screen_info);

	return 0;
}
Beispiel #6
0
OPENVPN_EXPORT openvpn_plugin_handle_t
openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[])
{
  struct down_root_context *context;

  /*
   * Allocate our context
   */
  context = (struct down_root_context *) calloc (1, sizeof (struct down_root_context));
  if (!context)
    goto error;
  context->foreground_fd = -1;

  /*
   * Intercept the --up and --down callbacks
   */
  *type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_DOWN);

  /*
   * Make sure we have two string arguments: the first is the .so name,
   * the second is the script command.
   */
  if (string_array_len (argv) < 2)
    {
      fprintf (stderr, "DOWN-ROOT: need down script command\n");
      goto error;
    }

  /*
   * Save our argument in context
   */
  context->command = build_command_line (&argv[1]);

  /*
   * Get verbosity level from environment
   */
  {
    const char *verb_string = get_env ("verb", envp);
    if (verb_string)
      context->verb = atoi (verb_string);
  }

  return (openvpn_plugin_handle_t) context;

 error:
  free_context (context);
  return NULL;
}
Beispiel #7
0
command_line_up
get_command_line (enum command_control_type type, const char *arg)
{
  /* Allocate and build a new command line structure.  */
  command_line_up cmd (build_command_line (type, arg));

  /* Read in the body of this command.  */
  if (recurse_read_control_structure (read_next_line, cmd.get (), 0, 0)
      == invalid_control)
    {
      warning (_("Error reading in canned sequence of commands."));
      return NULL;
    }

  return cmd;
}
Beispiel #8
0
/**
 * \brief Calls the Concord program in Cassys
 *
 *	Concord is called with target index_file and options
 *  --merge=text_name, --alphabet=alphabet_name.
 *
 *  For more information about Concord, see the unitex manual.
 *
 * \param [in/out] text_name the name of the text
 * \param [in] alphabet the name of the alphabet
 * \param [in] index_file file containing all the matches found by locate
 *
 */
int launch_concord_in_Cassys(const char *text_name, const char *index_file, const char *alphabet_name,
    Encoding encoding_output,int bom_output,int mask_encoding_compatibility_input){
	ProgramInvoker *invoker = new_ProgramInvoker(main_Concord, "main_Concord");

	add_argument(invoker,index_file);

    char tmp[FILENAME_MAX];
    {
        tmp[0]=0;
        get_reading_encoding_text(tmp,sizeof(tmp)-1,mask_encoding_compatibility_input);
        if (tmp[0] != '\0') {
            add_argument(invoker,"-k");
            add_argument(invoker,tmp);
        }

        tmp[0]=0;
        get_writing_encoding_text(tmp,sizeof(tmp)-1,encoding_output,bom_output);
        if (tmp[0] != '\0') {
            add_argument(invoker,"-q");
            add_argument(invoker,tmp);
        }
    }

	char text_argument[FILENAME_MAX+7];
	sprintf(text_argument,"--merge=%s",text_name);
	add_argument(invoker,text_argument);

	char alphabet_argument[FILENAME_MAX+11];
	sprintf(alphabet_argument,"--alphabet=%s",alphabet_name);

	char line_command[4096];
	build_command_line(invoker, line_command);
	fprintf(stdout, "%s\n", line_command);

	int result = invoke(invoker);
	free_ProgramInvoker(invoker);
	return result;
}
Beispiel #9
0
struct command_line *
get_command_line (enum command_control_type type, char *arg)
{
  struct command_line *cmd;
  struct cleanup *old_chain = NULL;

  /* Allocate and build a new command line structure.  */
  cmd = build_command_line (type, arg);

  old_chain = make_cleanup_free_command_lines (&cmd);

  /* Read in the body of this command.  */
  if (recurse_read_control_structure (read_next_line, cmd, 0, 0)
      == invalid_control)
    {
      warning (_("Error reading in canned sequence of commands."));
      do_cleanups (old_chain);
      return NULL;
    }

  discard_cleanups (old_chain);
  return cmd;
}
Beispiel #10
0
/*
 * Background process -- runs with privilege.
 */
static void
down_root_server (const int fd, char *command, const char *argv[], const char *envp[], const int verb)
{
  const char *p[3];
  char *command_line = NULL;
  char *argv_cat = NULL;
  int i;

  /*
   * Do initialization
   */
  if (DEBUG (verb))
    fprintf (stderr, "DOWN-ROOT: BACKGROUND: INIT command='%s'\n", command);

  /*
   * Tell foreground that we initialized successfully
   */
  if (send_control (fd, RESPONSE_INIT_SUCCEEDED) == -1)
    {
      fprintf (stderr, "DOWN-ROOT: BACKGROUND: write error on response socket [1]\n");
      goto done;
    }

  /*
   * Build command line
   */
  if (string_array_len (argv) >= 2)
    argv_cat = build_command_line (&argv[1]);
  else
    argv_cat = build_command_line (NULL);
  p[0] = command;
  p[1] = argv_cat;
  p[2] = NULL;
  command_line = build_command_line (p);

  /*
   * Save envp in environment
   */
  for (i = 0; envp[i]; ++i)
    {
      putenv ((char *)envp[i]);
    }

  /*
   * Event loop
   */
  while (1)
    {
      int command_code;
      int status;

      /* get a command from foreground process */
      command_code = recv_control (fd);

      if (DEBUG (verb))
	fprintf (stderr, "DOWN-ROOT: BACKGROUND: received command code: %d\n", command_code);

      switch (command_code)
	{
	case COMMAND_RUN_SCRIPT:
	  status = system (command_line);
	  if (system_ok (status)) /* Succeeded */
	    {
	      if (send_control (fd, RESPONSE_SCRIPT_SUCCEEDED) == -1)
		{
		  fprintf (stderr, "DOWN-ROOT: BACKGROUND: write error on response socket [2]\n");
		  goto done;
		}
	    }
	  else /* Failed */
	    {
	      if (send_control (fd, RESPONSE_SCRIPT_FAILED) == -1)
		{
		  fprintf (stderr, "DOWN-ROOT: BACKGROUND: write error on response socket [3]\n");
		  goto done;
		}
	    }
	  break;

	case COMMAND_EXIT:
	  goto done;

	case -1:
	  fprintf (stderr, "DOWN-ROOT: BACKGROUND: read error on command channel\n");
	  goto done;

	default:
	  fprintf (stderr, "DOWN-ROOT: BACKGROUND: unknown command code: code=%d, exiting\n",
		   command_code);
	  goto done;
	}
    }

 done:
  if (argv_cat)
    free (argv_cat);
  if (command_line)
    free (command_line);
  if (DEBUG (verb))
    fprintf (stderr, "DOWN-ROOT: BACKGROUND: EXIT\n");

  return;
}
Beispiel #11
0
static enum misc_command_type
process_next_line (char *p, struct command_line **command, int parse_commands,
		   void (*validator)(char *, void *), void *closure)
{
  char *p_end;
  char *p_start;
  int not_handled = 0;

  /* Not sure what to do here.  */
  if (p == NULL)
    return end_command;

  /* Strip trailing whitespace.  */
  p_end = p + strlen (p);
  while (p_end > p && (p_end[-1] == ' ' || p_end[-1] == '\t'))
    p_end--;

  p_start = p;
  /* Strip leading whitespace.  */
  while (p_start < p_end && (*p_start == ' ' || *p_start == '\t'))
    p_start++;

  /* 'end' is always recognized, regardless of parse_commands value.
     We also permit whitespace before end and after.  */
  if (p_end - p_start == 3 && !strncmp (p_start, "end", 3))
    return end_command;
  
  if (parse_commands)
    {
      /* If commands are parsed, we skip initial spaces.  Otherwise,
	 which is the case for Python commands and documentation
	 (see the 'document' command), spaces are preserved.  */
      p = p_start;

      /* Blanks and comments don't really do anything, but we need to
	 distinguish them from else, end and other commands which can
	 be executed.  */
      if (p_end == p || p[0] == '#')
	return nop_command;

      /* Is the else clause of an if control structure?  */
      if (p_end - p == 4 && !strncmp (p, "else", 4))
	return else_command;

      /* Check for while, if, break, continue, etc and build a new
	 command line structure for them.  */
      if ((p_end - p >= 14 && !strncmp (p, "while-stepping", 14))
	  || (p_end - p >= 8 && !strncmp (p, "stepping", 8))
	  || (p_end - p >= 2 && !strncmp (p, "ws", 2)))
	{
	  /* Because validate_actionline and encode_action lookup
	     command's line as command, we need the line to
	     include 'while-stepping'.

	     For 'ws' alias, the command will have 'ws', not expanded
	     to 'while-stepping'.  This is intentional -- we don't
	     really want frontend to send a command list with 'ws',
	     and next break-info returning command line with
	     'while-stepping'.  This should work, but might cause the
	     breakpoint to be marked as changed while it's actually
	     not.  */
	  *command = build_command_line (while_stepping_control, p);
	}
      else if (p_end - p > 5 && !strncmp (p, "while", 5))
	{
	  char *first_arg;

	  first_arg = p + 5;
	  while (first_arg < p_end && isspace (*first_arg))
	    first_arg++;
	  *command = build_command_line (while_control, first_arg);
	}
      else if (p_end - p > 2 && !strncmp (p, "if", 2))
	{
	  char *first_arg;

	  first_arg = p + 2;
	  while (first_arg < p_end && isspace (*first_arg))
	    first_arg++;
	  *command = build_command_line (if_control, first_arg);
	}
      else if (p_end - p >= 8 && !strncmp (p, "commands", 8))
	{
	  char *first_arg;

	  first_arg = p + 8;
	  while (first_arg < p_end && isspace (*first_arg))
	    first_arg++;
	  *command = build_command_line (commands_control, first_arg);
	}
      else if (p_end - p == 6 && !strncmp (p, "python", 6))
	{
	  /* Note that we ignore the inline "python command" form
	     here.  */
	  *command = build_command_line (python_control, "");
	}
      else if (p_end - p == 10 && !strncmp (p, "loop_break", 10))
	{
	  *command = (struct command_line *)
	    xmalloc (sizeof (struct command_line));
	  (*command)->next = NULL;
	  (*command)->line = NULL;
	  (*command)->control_type = break_control;
	  (*command)->body_count = 0;
	  (*command)->body_list = NULL;
	}
      else if (p_end - p == 13 && !strncmp (p, "loop_continue", 13))
	{
	  *command = (struct command_line *)
	    xmalloc (sizeof (struct command_line));
	  (*command)->next = NULL;
	  (*command)->line = NULL;
	  (*command)->control_type = continue_control;
	  (*command)->body_count = 0;
	  (*command)->body_list = NULL;
	}
      else
	not_handled = 1;
    }

  if (!parse_commands || not_handled)
    {
      /* A normal command.  */
      *command = (struct command_line *)
	xmalloc (sizeof (struct command_line));
      (*command)->next = NULL;
      (*command)->line = savestring (p, p_end - p);
      (*command)->control_type = simple_control;
      (*command)->body_count = 0;
      (*command)->body_list = NULL;
    }

  if (validator)
    {
      volatile struct gdb_exception ex;

      TRY_CATCH (ex, RETURN_MASK_ALL)
	{
	  validator ((*command)->line, closure);
	}
      if (ex.reason < 0)
	{
	  xfree (*command);
	  throw_exception (ex);
	}
    }
Beispiel #12
0
/**
 * \brief Calls the Locate program in Cassys
 *
 *	Locate is called with target the transducer file name of transudcer and options
 *  --text=text_name, --alphabet=alphabet_name, --longest_matches, --all and --merge or --replace
 *  depending of the output policy of the transducer.
 *
 *  For more information about Locate, see the unitex manual.
 *
 * \param [in/out] text_name the name of the text
 * \param [in] alphabet the name of the alphabet
 * \param [in] transducer structure containing information about the transducer to be applied
 *
 */
int launch_locate_in_Cassys(const char *text_name, const transducer *transducer, const char* alphabet_name,
    const char*negation_operator,
    Encoding encoding_output,int bom_output,int mask_encoding_compatibility_input){

	ProgramInvoker *invoker = new_ProgramInvoker(main_Locate, "main_Locate");

    char tmp[FILENAME_MAX];
    {
        tmp[0]=0;
        get_reading_encoding_text(tmp,sizeof(tmp)-1,mask_encoding_compatibility_input);
        if (tmp[0] != '\0') {
            add_argument(invoker,"-k");
            add_argument(invoker,tmp);
        }

        tmp[0]=0;
        get_writing_encoding_text(tmp,sizeof(tmp)-1,encoding_output,bom_output);
        if (tmp[0] != '\0') {
            add_argument(invoker,"-q");
            add_argument(invoker,tmp);
        }
    }

	add_argument(invoker, transducer->transducer_file_name);

	// add the text
	char text_argument[FILENAME_MAX+7];
	sprintf(text_argument,"--text=%s",text_name);
	add_argument(invoker, text_argument);

	// add the merge or replace option
	switch (transducer ->output_policy) {
	   case MERGE_OUTPUTS: add_argument(invoker,"--merge"); break;
	   case REPLACE_OUTPUTS: add_argument(invoker,"--replace"); break;
	   default: add_argument(invoker,"--ignore"); break;
	}

	// add the alphabet
	char alphabet_argument[FILENAME_MAX+11];
	sprintf(alphabet_argument,"--alphabet=%s",alphabet_name);
	add_argument(invoker, alphabet_argument);

	// look for the longest match argument
	add_argument(invoker, "--longest_matches");

	// look for all the occurrences
	add_argument(invoker, "--all");

    if ((*negation_operator) != 0) {
        char negation_operator_argument[0x40];
        sprintf(negation_operator_argument,"--negation_operator=%s",negation_operator);
        add_argument(invoker,negation_operator_argument);
    }

	char line_command[4096];
	build_command_line(invoker,line_command);
	fprintf(stdout, "%s\n",line_command);

	int result = invoke(invoker);
	free_ProgramInvoker(invoker);
	return result;
}
Beispiel #13
0
/***********************************************************************
 *           main
 */
int main( int argc, char *argv[] )
{
    DWORD count;
    HINSTANCE16 instance;
    LOADPARAMS16 params;
    WORD showCmd[2];
    char buffer[MAX_PATH];
    STARTUPINFOA info;
    char *cmdline, *appname, **first_arg;
    char *p;

    if (!argv[1]) usage();

    if (!strcmp( argv[1], "--app-name" ))
    {
        if (!(appname = argv[2])) usage();
        first_arg = argv + 3;
    }
    else
    {
        if (!SearchPathA( NULL, argv[1], ".exe", sizeof(buffer), buffer, NULL ))
        {
            WINE_MESSAGE( "winevdm: unable to exec '%s': file not found\n", argv[1] );
            ExitProcess(1);
        }
        appname = buffer;
        first_arg = argv + 1;
    }

    if (*first_arg) first_arg++;  /* skip program name */
    cmdline = build_command_line( first_arg );

    if (WINE_TRACE_ON(winevdm))
    {
        int i;
        WINE_TRACE( "GetCommandLine = '%s'\n", GetCommandLineA() );
        WINE_TRACE( "appname = '%s'\n", appname );
        WINE_TRACE( "cmdline = '%.*s'\n", cmdline[0], cmdline+1 );
        for (i = 0; argv[i]; i++) WINE_TRACE( "argv[%d]: '%s'\n", i, argv[i] );
    }

    GetStartupInfoA( &info );
    showCmd[0] = 2;
    showCmd[1] = (info.dwFlags & STARTF_USESHOWWINDOW) ? info.wShowWindow : SW_SHOWNORMAL;

    params.hEnvironment = 0;
    params.cmdLine = MapLS( cmdline );
    params.showCmd = MapLS( showCmd );
    params.reserved = 0;

    RestoreThunkLock(1);  /* grab the Win16 lock */

    /* some programs assume mmsystem is always present */
    LoadLibrary16( "gdi.exe" );
    LoadLibrary16( "user.exe" );
    LoadLibrary16( "mmsystem.dll" );

    if ((instance = LoadModule16( appname, &params )) < 32)
    {
        if (instance == 11)
        {
            /* first see if it is a .pif file */
            if( ( p = strrchr( appname, '.' )) && !strcasecmp( p, ".pif"))
                pif_cmd( appname, cmdline + 1);
            else
            {
                /* try DOS format */
                /* loader expects arguments to be regular C strings */
                start_dos_exe( appname, cmdline + 1 );
            }
            /* if we get back here it failed */
            instance = GetLastError();
        }

        WINE_MESSAGE( "winevdm: can't exec '%s': ", appname );
        switch (instance)
        {
        case  2: WINE_MESSAGE("file not found\n" ); break;
        case 11: WINE_MESSAGE("invalid program file\n" ); break;
        default: WINE_MESSAGE("error=%d\n", instance ); break;
        }
        ExitProcess(instance);
    }

    /* wait forever; the process will be killed when the last task exits */
    ReleaseThunkLock( &count );
    Sleep( INFINITE );
    return 0;
}
Beispiel #14
0
static enum misc_command_type
process_next_line (char *p, struct command_line **command, int parse_commands,
		   void (*validator)(char *, void *), void *closure)
{
  char *p_end;
  char *p_start;
  int not_handled = 0;

  /* Not sure what to do here.  */
  if (p == NULL)
    return end_command;

  /* Strip trailing whitespace.  */
  p_end = p + strlen (p);
  while (p_end > p && (p_end[-1] == ' ' || p_end[-1] == '\t'))
    p_end--;

  p_start = p;
  /* Strip leading whitespace.  */
  while (p_start < p_end && (*p_start == ' ' || *p_start == '\t'))
    p_start++;

  /* 'end' is always recognized, regardless of parse_commands value.
     We also permit whitespace before end and after.  */
  if (p_end - p_start == 3 && startswith (p_start, "end"))
    return end_command;

  if (parse_commands)
    {
      /* Resolve command abbreviations (e.g. 'ws' for 'while-stepping').  */
      const char *cmd_name = p;
      struct cmd_list_element *cmd
	= lookup_cmd_1 (&cmd_name, cmdlist, NULL, 1);
      cmd_name = skip_spaces (cmd_name);
      bool inline_cmd = *cmd_name != '\0';

      /* If commands are parsed, we skip initial spaces.  Otherwise,
	 which is the case for Python commands and documentation
	 (see the 'document' command), spaces are preserved.  */
      p = p_start;

      /* Blanks and comments don't really do anything, but we need to
	 distinguish them from else, end and other commands which can
	 be executed.  */
      if (p_end == p || p[0] == '#')
	return nop_command;

      /* Is the else clause of an if control structure?  */
      if (p_end - p == 4 && startswith (p, "else"))
	return else_command;

      /* Check for while, if, break, continue, etc and build a new
	 command line structure for them.  */
      if (command_name_equals (cmd, "while-stepping"))
	{
	  /* Because validate_actionline and encode_action lookup
	     command's line as command, we need the line to
	     include 'while-stepping'.

	     For 'ws' alias, the command will have 'ws', not expanded
	     to 'while-stepping'.  This is intentional -- we don't
	     really want frontend to send a command list with 'ws',
	     and next break-info returning command line with
	     'while-stepping'.  This should work, but might cause the
	     breakpoint to be marked as changed while it's actually
	     not.  */
	  *command = build_command_line (while_stepping_control, p);
	}
      else if (command_name_equals (cmd, "while"))
	{
	  *command = build_command_line (while_control, line_first_arg (p));
	}
      else if (command_name_equals (cmd, "if"))
	{
	  *command = build_command_line (if_control, line_first_arg (p));
	}
      else if (command_name_equals (cmd, "commands"))
	{
	  *command = build_command_line (commands_control, line_first_arg (p));
	}
      else if (command_name_equals (cmd, "python") && !inline_cmd)
	{
	  /* Note that we ignore the inline "python command" form
	     here.  */
	  *command = build_command_line (python_control, "");
	}
      else if (command_name_equals (cmd, "compile") && !inline_cmd)
	{
	  /* Note that we ignore the inline "compile command" form
	     here.  */
	  *command = build_command_line (compile_control, "");
	  (*command)->control_u.compile.scope = COMPILE_I_INVALID_SCOPE;
	}
      else if (command_name_equals (cmd, "guile") && !inline_cmd)
	{
	  /* Note that we ignore the inline "guile command" form here.  */
	  *command = build_command_line (guile_control, "");
	}
      else if (p_end - p == 10 && startswith (p, "loop_break"))
	{
	  *command = XNEW (struct command_line);
	  (*command)->next = NULL;
	  (*command)->line = NULL;
	  (*command)->control_type = break_control;
	  (*command)->body_count = 0;
	  (*command)->body_list = NULL;
	}
      else if (p_end - p == 13 && startswith (p, "loop_continue"))
Beispiel #15
0
static int posix_spawn_common(
    bool search_path,
    pid_t *pid, const char *path,
    const posix_spawn_file_actions_t *file_actions,
    const posix_spawnattr_t *attrp,
    char *const argv[], char *const envp[]) {
  STARTUPINFO sinfo;
  SECURITY_ATTRIBUTES sec;
  PROCESS_INFORMATION pinfo;
  char *cmdbuf;
  char *env_block;
  DWORD create_flags = CREATE_NO_WINDOW;
  int ret;
  int i;
  unused_parameter(envp); // FIXME

  cmdbuf = build_command_line(argv);
  if (!cmdbuf) {
    return ENOMEM;
  }

  env_block = make_env_block(envp);
  if (!env_block) {
    free(cmdbuf);
    return ENOMEM;
  }

  memset(&sinfo, 0, sizeof(sinfo));
  sinfo.cb = sizeof(sinfo);
  sinfo.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
  sinfo.wShowWindow = SW_HIDE;

  memset(&sec, 0, sizeof(sec));
  sec.nLength = sizeof(sec);
  sec.bInheritHandle = TRUE;

  memset(&pinfo, 0, sizeof(pinfo));

  if (attrp->flags & POSIX_SPAWN_SETPGROUP) {
    create_flags |= CREATE_NEW_PROCESS_GROUP;
  }

  // Process any dup(2) actions
  for (i = 0; i < file_actions->ndups; i++) {
    struct _posix_spawn_file_dup *dup = &file_actions->dups[i];
    HANDLE *target = NULL;
    DWORD err;

    switch (dup->target_fd) {
      case 0:
        target = &sinfo.hStdInput;
        break;
      case 1:
        target = &sinfo.hStdOutput;
        break;
      case 2:
        target = &sinfo.hStdError;
        break;
    }

    if (!target) {
      w_log(W_LOG_ERR, "posix_spawn: can't target fd outside range [0-2]\n");
      ret = ENOSYS;
      goto done;
    }

    if (*target) {
      CloseHandle(*target);
      *target = INVALID_HANDLE_VALUE;
    }

    if (!DuplicateHandle(GetCurrentProcess(), dup->local_handle,
          GetCurrentProcess(), target, 0,
          TRUE, DUPLICATE_SAME_ACCESS)) {
      err = GetLastError();
      w_log(W_LOG_ERR, "posix_spawn: failed to duplicate handle: %s\n",
          win32_strerror(err));
      ret = map_win32_err(err);
      goto done;
    }
  }

  // Process any file opening actions
  for (i = 0; i < file_actions->nopens; i++) {
    struct _posix_spawn_file_open *op = &file_actions->opens[i];
    HANDLE h;
    HANDLE *target = NULL;

    switch (op->target_fd) {
      case 0:
        target = &sinfo.hStdInput;
        break;
      case 1:
        target = &sinfo.hStdOutput;
        break;
      case 2:
        target = &sinfo.hStdError;
        break;
    }

    if (!target) {
      w_log(W_LOG_ERR, "posix_spawn: can't target fd outside range [0-2]\n");
      ret = ENOSYS;
      goto done;
    }

    h = w_handle_open(op->name, op->flags & ~O_CLOEXEC);
    if (h == INVALID_HANDLE_VALUE) {
      ret = errno;
      w_log(W_LOG_ERR, "posix_spawn: failed to open %s:\n",
          op->name);
      goto done;
    }

    if (*target) {
      CloseHandle(*target);
    }
    *target = h;
  }

  if (!sinfo.hStdInput) {
    sinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
  }
  if (!sinfo.hStdOutput) {
    sinfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  }
  if (!sinfo.hStdError) {
    sinfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
  }

  if (!CreateProcess(search_path ? NULL : path,
        cmdbuf, &sec, &sec, TRUE, create_flags, env_block,
        attrp->working_dir, &sinfo, &pinfo)) {
    w_log(W_LOG_ERR, "CreateProcess: `%s`: (cwd=%s) %s\n", cmdbuf,
        attrp->working_dir ? attrp->working_dir : "<process cwd>",
        win32_strerror(GetLastError()));
    ret = EACCES;
  } else {
    *pid = (pid_t)pinfo.dwProcessId;

    // Record the pid -> handle mapping for later wait/reap
    pthread_mutex_lock(&child_proc_lock);
    if (!child_procs) {
      child_procs = w_ht_new(2, NULL);
    }
    w_ht_set(child_procs, pinfo.dwProcessId, w_ht_ptr_val(pinfo.hProcess));
    pthread_mutex_unlock(&child_proc_lock);

    CloseHandle(pinfo.hThread);
    ret = 0;
  }

done:
  free(cmdbuf);
  free(env_block);

  // If we manufactured any handles, close them out now
  if (sinfo.hStdInput != GetStdHandle(STD_INPUT_HANDLE)) {
    CloseHandle(sinfo.hStdInput);
  }
  if (sinfo.hStdOutput != GetStdHandle(STD_OUTPUT_HANDLE)) {
    CloseHandle(sinfo.hStdOutput);
  }
  if (sinfo.hStdError != GetStdHandle(STD_ERROR_HANDLE)) {
    CloseHandle(sinfo.hStdError);
  }

  return ret;
}