mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 913953 - Part h: Remove unused WaitForExitCode and GetAppOutput functions; r=ehsan
This commit is contained in:
parent
d5fd6876ed
commit
b123565484
@ -190,21 +190,6 @@ void SetCurrentProcessPrivileges(ChildPrivileges privs);
|
||||
bool LaunchApp(const CommandLine& cl,
|
||||
bool wait, bool start_hidden, ProcessHandle* process_handle);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Executes the application specified by |cmd_line| and copies the contents
|
||||
// printed to the standard output to |output|, which should be non NULL.
|
||||
// Blocks until the started process terminates.
|
||||
// Returns true if the application was run successfully, false otherwise.
|
||||
bool GetAppOutput(const std::wstring& cmd_line, std::string* output);
|
||||
#elif defined(OS_POSIX)
|
||||
// Executes the application specified by |cl| and wait for it to exit. Stores
|
||||
// the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true
|
||||
// on success (application launched and exited cleanly, with exit code
|
||||
// indicating success). |output| is modified only when the function finished
|
||||
// successfully.
|
||||
bool GetAppOutput(const CommandLine& cl, std::string* output);
|
||||
#endif
|
||||
|
||||
// Used to filter processes by process ID.
|
||||
class ProcessFilter {
|
||||
public:
|
||||
@ -229,12 +214,6 @@ bool KillProcess(ProcessHandle process, int exit_code, bool wait);
|
||||
// a different manner on POSIX.
|
||||
bool DidProcessCrash(bool* child_exited, ProcessHandle handle);
|
||||
|
||||
// Waits for process to exit. In POSIX systems, if the process hasn't been
|
||||
// signaled then puts the exit code in |exit_code|; otherwise it's considered
|
||||
// a failure. On Windows |exit_code| is always filled. Returns true on success,
|
||||
// and closes |handle| in any case.
|
||||
bool WaitForExitCode(ProcessHandle handle, int* exit_code);
|
||||
|
||||
// This class provides a way to iterate through the list of processes
|
||||
// on the current machine that were started from the given executable
|
||||
// name. To use, create an instance and then call NextProcessEntry()
|
||||
|
@ -280,23 +280,6 @@ bool DidProcessCrash(bool* child_exited, ProcessHandle handle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
|
||||
int status;
|
||||
if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
*exit_code = WEXITSTATUS(status);
|
||||
return true;
|
||||
}
|
||||
|
||||
// If it didn't exit cleanly, it must have been signaled.
|
||||
DCHECK(WIFSIGNALED(status));
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
int64_t TimeValToMicroseconds(const struct timeval& tv) {
|
||||
@ -344,86 +327,4 @@ int ProcessMetrics::GetCPUUsage() {
|
||||
return cpu;
|
||||
}
|
||||
|
||||
bool GetAppOutput(const CommandLine& cl, std::string* output) {
|
||||
int pipe_fd[2];
|
||||
pid_t pid;
|
||||
|
||||
// Illegal to allocate memory after fork and before execvp
|
||||
InjectiveMultimap fd_shuffle1, fd_shuffle2;
|
||||
fd_shuffle1.reserve(3);
|
||||
fd_shuffle2.reserve(3);
|
||||
const std::vector<std::string>& argv = cl.argv();
|
||||
scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
|
||||
|
||||
if (pipe(pipe_fd) < 0)
|
||||
return false;
|
||||
|
||||
switch (pid = fork()) {
|
||||
case -1: // error
|
||||
close(pipe_fd[0]);
|
||||
close(pipe_fd[1]);
|
||||
return false;
|
||||
case 0: // child
|
||||
{
|
||||
// Obscure fork() rule: in the child, if you don't end up doing exec*(),
|
||||
// you call _exit() instead of exit(). This is because _exit() does not
|
||||
// call any previously-registered (in the parent) exit handlers, which
|
||||
// might do things like block waiting for threads that don't even exist
|
||||
// in the child.
|
||||
int dev_null = open("/dev/null", O_WRONLY);
|
||||
if (dev_null < 0)
|
||||
_exit(127);
|
||||
|
||||
fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
|
||||
fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
|
||||
fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
|
||||
// Adding another element here? Remeber to increase the argument to
|
||||
// reserve(), above.
|
||||
|
||||
std::copy(fd_shuffle1.begin(), fd_shuffle1.end(),
|
||||
std::back_inserter(fd_shuffle2));
|
||||
|
||||
// fd_shuffle1 is mutated by this call because it cannot malloc.
|
||||
if (!ShuffleFileDescriptors(&fd_shuffle1))
|
||||
_exit(127);
|
||||
|
||||
CloseSuperfluousFds(fd_shuffle2);
|
||||
|
||||
for (size_t i = 0; i < argv.size(); i++)
|
||||
argv_cstr[i] = const_cast<char*>(argv[i].c_str());
|
||||
argv_cstr[argv.size()] = NULL;
|
||||
execvp(argv_cstr[0], argv_cstr.get());
|
||||
_exit(127);
|
||||
}
|
||||
default: // parent
|
||||
{
|
||||
// Close our writing end of pipe now. Otherwise later read would not
|
||||
// be able to detect end of child's output (in theory we could still
|
||||
// write to the pipe).
|
||||
close(pipe_fd[1]);
|
||||
|
||||
int exit_code = EXIT_FAILURE;
|
||||
bool success = WaitForExitCode(pid, &exit_code);
|
||||
if (!success || exit_code != EXIT_SUCCESS) {
|
||||
close(pipe_fd[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[256];
|
||||
std::string buf_output;
|
||||
|
||||
while (true) {
|
||||
ssize_t bytes_read =
|
||||
HANDLE_EINTR(read(pipe_fd[0], buffer, sizeof(buffer)));
|
||||
if (bytes_read <= 0)
|
||||
break;
|
||||
buf_output.append(buffer, bytes_read);
|
||||
}
|
||||
output->swap(buf_output);
|
||||
close(pipe_fd[0]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
@ -355,82 +355,6 @@ bool LaunchApp(const CommandLine& cl,
|
||||
start_hidden, process_handle);
|
||||
}
|
||||
|
||||
bool GetAppOutput(const std::wstring& cmd_line, std::string* output) {
|
||||
if (!output) {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE out_read = NULL;
|
||||
HANDLE out_write = NULL;
|
||||
|
||||
SECURITY_ATTRIBUTES sa_attr;
|
||||
// Set the bInheritHandle flag so pipe handles are inherited.
|
||||
sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa_attr.bInheritHandle = TRUE;
|
||||
sa_attr.lpSecurityDescriptor = NULL;
|
||||
|
||||
// Create the pipe for the child process's STDOUT.
|
||||
if (!CreatePipe(&out_read, &out_write, &sa_attr, 0)) {
|
||||
NOTREACHED() << "Failed to create pipe";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure we don't leak the handles.
|
||||
ScopedHandle scoped_out_read(out_read);
|
||||
ScopedHandle scoped_out_write(out_write);
|
||||
|
||||
// Ensure the read handle to the pipe for STDOUT is not inherited.
|
||||
if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) {
|
||||
NOTREACHED() << "Failed to disabled pipe inheritance";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now create the child process
|
||||
PROCESS_INFORMATION proc_info = { 0 };
|
||||
STARTUPINFO start_info = { 0 };
|
||||
|
||||
start_info.cb = sizeof(STARTUPINFO);
|
||||
start_info.hStdOutput = out_write;
|
||||
// Keep the normal stdin and stderr.
|
||||
start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||||
start_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||
|
||||
// Create the child process.
|
||||
if (!CreateProcess(NULL, const_cast<wchar_t*>(cmd_line.c_str()), NULL, NULL,
|
||||
TRUE, // Handles are inherited.
|
||||
0, NULL, NULL, &start_info, &proc_info)) {
|
||||
NOTREACHED() << "Failed to start process";
|
||||
return false;
|
||||
}
|
||||
|
||||
// We don't need the thread handle, close it now.
|
||||
CloseHandle(proc_info.hThread);
|
||||
|
||||
// Close our writing end of pipe now. Otherwise later read would not be able
|
||||
// to detect end of child's output.
|
||||
scoped_out_write.Close();
|
||||
|
||||
// Read output from the child process's pipe for STDOUT
|
||||
const int kBufferSize = 1024;
|
||||
char buffer[kBufferSize];
|
||||
|
||||
for (;;) {
|
||||
DWORD bytes_read = 0;
|
||||
BOOL success = ReadFile(out_read, buffer, kBufferSize, &bytes_read, NULL);
|
||||
if (!success || bytes_read == 0)
|
||||
break;
|
||||
output->append(buffer, bytes_read);
|
||||
}
|
||||
|
||||
// Let's wait for the process to finish.
|
||||
WaitForSingleObject(proc_info.hProcess, INFINITE);
|
||||
CloseHandle(proc_info.hProcess);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KillProcess(ProcessHandle process, int exit_code, bool wait) {
|
||||
bool result = (TerminateProcess(process, exit_code) != FALSE);
|
||||
if (result && wait) {
|
||||
@ -474,19 +398,6 @@ bool DidProcessCrash(bool* child_exited, ProcessHandle handle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
|
||||
ScopedHandle closer(handle); // Ensure that we always close the handle.
|
||||
if (::WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0) {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
DWORD temp_code; // Don't clobber out-parameters in case of failure.
|
||||
if (!::GetExitCodeProcess(handle, &temp_code))
|
||||
return false;
|
||||
*exit_code = temp_code;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetCurrentProcessPrivileges(ChildPrivileges privs) {
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user