Пример #1
0
static void run_test(/*@notnull@*/ test_runner * runner, /*@notnull@*/ unit_test * test)
/*@globals
	fileSystem,
	internalState
@*/
/*@modifies
	fileSystem,
	internalState,

	runner->buffer,
	test
@*/
{

	const char *	last_output;
	const char *	last_error;
	int				termination_status;

	make_command_line(runner);

	printf("	%s_%s: ", (test->is_requirement ? "requirement" : "unit_test"), test->code);

	termination_status			= system(runner->buffer);
	test->found_exit_code		= GET_EXIT_CODE(termination_status);

	last_output	= load_file( runner->out, test->found_output, sizeof(test->found_output) );
	last_error	= load_file( runner->err, test->found_error, sizeof(test->found_error) );

	test->unexpected_exit_code	= ( test->expected_exit_code	!= EXIT_WHATEVER	&& test->found_exit_code != test->expected_exit_code );
	test->unexpected_error		= ( test->expected_error		!= ERROR_WHATEVER	&& is_unexpected_token(test->expected_error, last_error) );
	test->unexpected_output		= ( test->expected_output		!= OUTPUT_WHATEVER	&& is_unexpected_token(test->expected_output, last_output) );

	if(!test->unexpected_exit_code && !test->unexpected_output && !test->unexpected_error){
		test->status = STATUS_PASSED;
	}else if(!test->is_critical){
		test->status = STATUS_WARNING;
	}else{
		test->status = STATUS_FAILED;
	}

	if(test->status == STATUS_PASSED){
		printf("%s\n",
			(test->is_requirement ? "fulfilled" : "passed")
		);
	}else{
		printf("%s [%c%c%c]\n",
			(test->is_requirement
				? (test->is_critical ? "NOT FULFILLED!"	: "not fulfilled")
				: (test->is_critical ? "FAILED!"		: "failed!")
			),
			(test->unexpected_exit_code	? 'X' : '1'),
			(test->unexpected_output	? 'O' : '2'),
			(test->unexpected_error		? 'E' : '3')
		);
	}
}
Пример #2
0
void pipeline(const char *const *argv, struct pipeline *pl)
{
  HANDLE in_read_handle, in_write_handle;
  SECURITY_ATTRIBUTES sec_attr;
  PROCESS_INFORMATION proc_info;
  STARTUPINFO start_info;
  char *cmdline = make_command_line(argv);

  sec_attr.nLength = sizeof sec_attr;
  sec_attr.bInheritHandle = TRUE;
  sec_attr.lpSecurityDescriptor = NULL;

  if (!CreatePipe(&in_read_handle, &in_write_handle, &sec_attr, 0)) {
    die_windows_error("CreatePipe");
  }

  if (!SetHandleInformation(in_write_handle, HANDLE_FLAG_INHERIT, 0)) {
    die_windows_error("SetHandleInformation");
  }

  /* when in Rome... */
  ZeroMemory(&proc_info, sizeof proc_info);
  ZeroMemory(&start_info, sizeof start_info);

  start_info.cb = sizeof start_info;
  start_info.dwFlags |= STARTF_USESTDHANDLES;

  if ((start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE))
      == INVALID_HANDLE_VALUE
      || (start_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE))
      == INVALID_HANDLE_VALUE) {
    die_windows_error("GetStdHandle");
  }

  start_info.hStdInput = in_read_handle;

  if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0,
                     NULL, NULL, &start_info, &proc_info)) {
    die_windows_error("CreateProcess");
  }

  free(cmdline);

  if (!CloseHandle(proc_info.hThread)) {
    die_windows_error("CloseHandle for thread");
  }
  if (!CloseHandle(in_read_handle)) {
    die_windows_error("CloseHandle");
  }

  pl->proc_handle = proc_info.hProcess;
  pl->infd = _open_osfhandle((intptr_t)in_write_handle, 0);
}
Пример #3
0
static int win_spawn(const char *cmd, const char **argv, const char **envp,
		     const char *cwd, HANDLE handles[3], int background,
		     int shell)
{
    char *args = make_command_line(shell, cmd, argv);
    char *env = make_environment(envp);
    char *program = shell ? NULL : find_program(cmd);
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    BOOL result;
    DWORD exitcode;
    int i;

    if (!shell) {
	G_debug(3, "win_spawn: program = %s", program);

	if (!program) {
	    G_free(args);
	    G_free(env);
	    return -1;
	}
    }

    G_debug(3, "win_spawn: args = %s", args);

    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);

    si.dwFlags |= STARTF_USESTDHANDLES;
    si.hStdInput  = handles[0];
    si.hStdOutput = handles[1];
    si.hStdError  = handles[2];

    result = CreateProcess(
	program,	/* lpApplicationName */
	args,		/* lpCommandLine */
	NULL,		/* lpProcessAttributes */
	NULL,		/* lpThreadAttributes */
	1,		/* bInheritHandles */
	0,		/* dwCreationFlags */
	env,		/* lpEnvironment */
	cwd,		/* lpCurrentDirectory */
	&si,		/* lpStartupInfo */
	&pi		/* lpProcessInformation */
	);

    G_free(args);
    G_free(env);
    G_free(program);

    if (!result) {
	G_warning(_("CreateProcess() failed: error = %d"), GetLastError());
	return -1;
    }

    CloseHandle(pi.hThread);

    for (i = 0; i < 3; i++)
	if (handles[i] != INVALID_HANDLE_VALUE)
	    CloseHandle(handles[i]);

    if (!background) {
	WaitForSingleObject(pi.hProcess, INFINITE);
	if (!GetExitCodeProcess(pi.hProcess, &exitcode))
	    return -1;
	CloseHandle(pi.hProcess);
	return (int) exitcode;
    }

    CloseHandle(pi.hProcess);

    return pi.dwProcessId;
}
Пример #4
0
/*
 * Description:   Create the child process to be helped
 *
 * Returns: success <=> 0
 *
 * Notes/Dependencies:
 */
long
process_begin(
	HANDLE proc,
	char **argv,
	char **envp,
	char *exec_path,
	char *as_user)
{
	sub_process *pproc = (sub_process *)proc;
	char *shell_name = 0;
	int file_not_found=0;
	HANDLE exec_handle;
	char exec_fname[MAX_PATH];
	const char *path_var = NULL;
	char **ep;
	char buf[256];
	DWORD bytes_returned;
	DWORD flags;
	char *command_line;
	STARTUPINFO startInfo;
	PROCESS_INFORMATION procInfo;
	char *envblk=NULL;

	/*
	 *  Shell script detection...  if the exec_path starts with #! then
	 *  we want to exec shell-script-name exec-path, not just exec-path
	 *  NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl.  We do not
	 *  hard-code the path to the shell or perl or whatever:  Instead, we
	 *  assume it's in the path somewhere (generally, the NT tools
	 *  bin directory)
	 */

	/* Use the Makefile's value of PATH to look for the program to
	   execute, because it could be different from Make's PATH
	   (e.g., if the target sets its own value.  */
	if (envp)
		for (ep = envp; *ep; ep++) {
			if (strncmp (*ep, "PATH=", 5) == 0
			    || strncmp (*ep, "Path=", 5) == 0) {
				path_var = *ep + 5;
				break;
			}
		}
	exec_handle = find_file(exec_path, path_var,
				exec_fname, sizeof(exec_fname));

	/*
	 * If we couldn't open the file, just assume that Windows will be
	 * somehow able to find and execute it.
	 */
	if (exec_handle == INVALID_HANDLE_VALUE) {
		file_not_found++;
	}
	else {
		/* Attempt to read the first line of the file */
		if (ReadFile( exec_handle,
				buf, sizeof(buf) - 1, /* leave room for trailing NULL */
				&bytes_returned, 0) == FALSE || bytes_returned < 2) {

			pproc->last_err = GetLastError();
			pproc->lerrno = E_IO;
			CloseHandle(exec_handle);
			return(-1);
		}
		if (buf[0] == '#' && buf[1] == '!') {
			/*
			 *  This is a shell script...  Change the command line from
			 *	exec_path args to shell_name exec_path args
			 */
			char *p;

			/*  Make sure buf is NULL terminated */
			buf[bytes_returned] = 0;
			/*
			 * Depending on the file system type, etc. the first line
			 * of the shell script may end with newline or newline-carriage-return
			 * Whatever it ends with, cut it off.
			 */
			p= strchr(buf, '\n');
			if (p)
				*p = 0;
			p = strchr(buf, '\r');
			if (p)
				*p = 0;

			/*
			 *  Find base name of shell
			 */
			shell_name = strrchr( buf, '/');
			if (shell_name) {
				shell_name++;
			} else {
				shell_name = &buf[2];/* skipping "#!" */
			}

		}
		CloseHandle(exec_handle);
	}

	flags = 0;

	if (file_not_found)
		command_line = make_command_line( shell_name, exec_path, argv);
	else
		command_line = make_command_line( shell_name, exec_fname, argv);

	if ( command_line == NULL ) {
		pproc->last_err = 0;
		pproc->lerrno = E_NO_MEM;
		return(-1);
	}

	if (envp) {
		if (arr2envblk(envp, &envblk) ==FALSE) {
			pproc->last_err = 0;
			pproc->lerrno = E_NO_MEM;
			free( command_line );
			return(-1);
		}
	}

	if ((shell_name) || (file_not_found)) {
		exec_path = 0;	/* Search for the program in %Path% */
	} else {
		exec_path = exec_fname;
	}

	/*
	 *  Set up inherited stdin, stdout, stderr for child
	 */
	GetStartupInfo(&startInfo);
	startInfo.dwFlags = STARTF_USESTDHANDLES;
	startInfo.lpReserved = 0;
	startInfo.cbReserved2 = 0;
	startInfo.lpReserved2 = 0;
	startInfo.lpTitle = shell_name ? shell_name : exec_path;
	startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1];
	startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1];
	startInfo.hStdError = (HANDLE)pproc->sv_stderr[1];

	if (as_user) {
		if (envblk) free(envblk);
		return -1;
	} else {
		DB (DB_JOBS, ("CreateProcess(%s,%s,...)\n",
			exec_path ? exec_path : "NULL",
			command_line ? command_line : "NULL"));
		if (CreateProcess(
			exec_path,
			command_line,
			NULL,
			0, /* default security attributes for thread */
			TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */
			flags,
			envblk,
			0, /* default starting directory */
			&startInfo,
			&procInfo) == FALSE) {

			pproc->last_err = GetLastError();
			pproc->lerrno = E_FORK;
			fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n",
                                exec_path ? exec_path : "NULL", command_line);
			if (envblk) free(envblk);
			free( command_line );
			return(-1);
		}
	}

	pproc->pid = (pid_t)procInfo.hProcess;
	/* Close the thread handle -- we'll just watch the process */
	CloseHandle(procInfo.hThread);

	/* Close the halves of the pipes we don't need */
        CloseHandle((HANDLE)pproc->sv_stdin[1]);
        CloseHandle((HANDLE)pproc->sv_stdout[1]);
        CloseHandle((HANDLE)pproc->sv_stderr[1]);
        pproc->sv_stdin[1] = 0;
        pproc->sv_stdout[1] = 0;
        pproc->sv_stderr[1] = 0;

	free( command_line );
	if (envblk) free(envblk);
	pproc->lerrno=0;
	return 0;
}
Пример #5
0
/*
 * Description:   Create the child process to be helped
 *
 * Returns: 
 *
 * Notes/Dependencies:  
 */
long
process_begin(
	HANDLE proc,
	char **argv,
	char **envp,
	char *exec_path,
	char *as_user)
{
	sub_process *pproc = (sub_process *)proc;
	char *shell_name = 0;
	int file_not_found=0;
	HANDLE exec_handle;
	char buf[256];
	DWORD bytes_returned;
	DWORD flags;
	char *command_line;
	STARTUPINFO startInfo;
	PROCESS_INFORMATION procInfo;
	char *envblk=NULL;
	OFSTRUCT file_info;


	/*
	 *  Shell script detection...  if the exec_path starts with #! then
	 *  we want to exec shell-script-name exec-path, not just exec-path
	 *  NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl.  We do not
	 *  hard-code the path to the shell or perl or whatever:  Instead, we
	 *  assume it's in the path somewhere (generally, the NT tools
	 *  bin directory)
	 *  We use OpenFile here because it is capable of searching the Path.
	 */

	exec_handle = find_file(exec_path, &file_info);

	/*
	 * If we couldn't open the file, just assume that Win32 will be able
	 * to find and execute it.
	 */
	if (exec_handle == (HANDLE)HFILE_ERROR) {
		file_not_found++;
	}
	else {
		/* Attempt to read the first line of the file */
		if (ReadFile( exec_handle, 
				buf, sizeof(buf) - 1, /* leave room for trailing NULL */
				&bytes_returned, 0) == FALSE || bytes_returned < 2) {
	
			pproc->last_err = GetLastError();
			pproc->lerrno = E_IO;
			CloseHandle(exec_handle);
			return(-1);
		}
		if (buf[0] == '#' && buf[1] == '!') {
			/*
			 *  This is a shell script...  Change the command line from
			 *	exec_path args to shell_name exec_path args
			 */
			char *p;
	
			/*  Make sure buf is NULL terminated */
			buf[bytes_returned] = 0;
			/*
			 * Depending on the file system type, etc. the first line
			 * of the shell script may end with newline or newline-carriage-return
			 * Whatever it ends with, cut it off.
			 */
			p= strchr(buf, '\n');
			if (p)
				*p = 0;
			p = strchr(buf, '\r');
			if (p)
				*p = 0;
		
			/*
			 *  Find base name of shell
			 */
			shell_name = strrchr( buf, '/');
			if (shell_name) {
				shell_name++;
			} else {
				shell_name = &buf[2];/* skipping "#!" */
			}

		} 
		CloseHandle(exec_handle);
	}

	flags = 0;

	if (file_not_found)
		command_line = make_command_line( shell_name, exec_path, argv);
	else
		command_line = make_command_line( shell_name, file_info.szPathName,
				 argv);

	if ( command_line == NULL ) {
		pproc->last_err = 0;
		pproc->lerrno = E_NO_MEM;
		return(-1);
	}

	if (envp) {
		if (arr2envblk(envp, &envblk) ==FALSE) {
			pproc->last_err = 0;
			pproc->lerrno = E_NO_MEM;
			free( command_line );
			return(-1);
		}
	}

	if ((shell_name) || (file_not_found)) {
		exec_path = 0;	/* Search for the program in %Path% */
	} else {
		exec_path = file_info.szPathName;
	}

	/*
	 *  Set up inherited stdin, stdout, stderr for child
	 */
	GetStartupInfo(&startInfo);
	startInfo.dwFlags = STARTF_USESTDHANDLES;
	startInfo.lpReserved = 0;
	startInfo.cbReserved2 = 0;
	startInfo.lpReserved2 = 0;
	startInfo.lpTitle = shell_name ? shell_name : exec_path;
	startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1];
	startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1];
	startInfo.hStdError = (HANDLE)pproc->sv_stderr[1];

	/*
	 * See if we need to setuid to a different user.
	 */
	if (as_user) {
		return -1;
	}

	if (as_user) {
		return -1;
	} else {
		if (CreateProcess(
			exec_path,
			command_line,
			NULL,
			0, /* default security attributes for thread */
			TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */
			flags, 
			envblk,
			0, /* default starting directory */
			&startInfo,
			&procInfo) == FALSE) {
		
			pproc->last_err = GetLastError();
			pproc->lerrno = E_FORK;
			fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n", exec_path, command_line);
			free( command_line );
			return(-1);
		}
	}
	
	pproc->pid = (int)procInfo.hProcess;
	/* Close the thread handle -- we'll just watch the process */
	CloseHandle(procInfo.hThread);
	
	/* Close the halves of the pipes we don't need */
	if (pproc->sv_stdin) {
		CloseHandle((HANDLE)pproc->sv_stdin[1]);
		(HANDLE)pproc->sv_stdin[1] = 0;
	}
	if (pproc->sv_stdout) {
		CloseHandle((HANDLE)pproc->sv_stdout[1]);
		(HANDLE)pproc->sv_stdout[1] = 0;
	}
	if (pproc->sv_stderr) {
		CloseHandle((HANDLE)pproc->sv_stderr[1]);
		(HANDLE)pproc->sv_stderr[1] = 0;
	}

	free( command_line );
	pproc->lerrno=0;
	return 0;
}
Пример #6
0
string exec_command( const string& str )
{
  // Construct this before any resources are claimed
  string result; 

  const char *argv[4]; // No ownership of memory

  // Respect the SHELL environment variable,
  // and drop back to using CMD.EXE
  argv[0] = getenv("SHELL");
  if ( !argv[0] || !*argv[0] ) {
    // TODO: On Windows NT 4, 2K and XP this is correct;
    // on Windows 95, 98 and ME, this should be COMMAND.COM,
    // though that'll probably be unusably slow.
    argv[0] = "CMD.EXE";
    argv[1] = "/C";
  } else {
    //
    argv[1] = "-c";
  }
  argv[2] = str.c_str();
  argv[3] = NULL;

  // -------
  // From now on we have to be careful about exceptions
  // as we have pipes and child processes hanging around
  //
  HANDLE hErr;
  if (DuplicateHandle(GetCurrentProcess(),
                      GetStdHandle(STD_ERROR_HANDLE),
                      GetCurrentProcess(),
                      &hErr,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE)
    THROW_SYSTEM_ERROR( "DuplicateHandle" );
  

  // Two ends of the pipe:
  HANDLE hChildOutRd, hChildOutWr;
  {
    SECURITY_ATTRIBUTES saAttr;
    saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0)) {
      CloseHandle(hErr);
      THROW_SYSTEM_ERROR( "CreatePipe" );
    }
  }

  PROCESS_INFORMATION procInfo;

  {
    string command_line( make_command_line( argv[0], argv ) );

    STARTUPINFO startInfo;
    GetStartupInfo(&startInfo);
    startInfo.dwFlags = STARTF_USESTDHANDLES;
    startInfo.lpReserved = 0;
    startInfo.cbReserved2 = 0;
    startInfo.lpReserved2 = 0;
    startInfo.lpTitle = 0;
    startInfo.hStdInput = NULL;
    startInfo.hStdOutput = hChildOutWr;
    startInfo.hStdError = hErr;

    if (CreateProcess(0,
                      // Const correctness -- we've heard of it
                      const_cast< char* >( command_line.c_str() ),
                      NULL,
                      0, // default security attributes for thread
                      TRUE, // inherit handles (e.g. helper pipes)
                      0,
                      NULL,
                      0, // default starting directory
                      &startInfo,
                      &procInfo) == FALSE) {
      CloseHandle(hErr);
      CloseHandle(hChildOutRd);
      CloseHandle(hChildOutWr);
      THROW_SYSTEM_ERROR( "CreateProcess" );
    }

    // Close the thread handle -- we'll just watch the process
    CloseHandle(procInfo.hThread);
  }

  CloseHandle( hErr );
  CloseHandle( hChildOutWr );

  try {
    while (true) {
      const size_t buflen(4096);
      char buffer[buflen];

      // TODO:  Unicode conversions???

      DWORD i;
      ReadFile( hChildOutRd, buffer, buflen, &i, NULL);
      if (i <= 0) break; // TODO: Do something more sensible
      result.append( buffer, i ); // Might throw
    }
  } 
  catch( ... ) {
    CloseHandle( hChildOutRd );

    DWORD rv = WaitForMultipleObjects( 1, &procInfo.hProcess, 
				       FALSE, INFINITE );
    if ( rv == WAIT_FAILED ) abort();

    throw;
  }

  CloseHandle( hChildOutRd );

  DWORD rv = WaitForMultipleObjects( 1, &procInfo.hProcess, FALSE, INFINITE );
  if ( rv == WAIT_FAILED )
    THROW_SYSTEM_ERROR( "WaitForMultipleObjects" );  
  return result;
}