in native/cyglaunch/main.c [144:225]
int main(int argc, char* argv[], char* envp[]) {
int arg = 1;
char *logFileName = argv[arg++];
if (strcmp(logFileName, "null") != 0) {
logFile = fopen(convert_path(logFileName), "w+");
}
bool consoleMode = (bool)atoi(argv[arg++]);
struct pty_t pty;
struct pty_t err_pty;
flog("opening pty");
if (create_pty(&pty) < 0) return -1;
flog("opening err_pty");
if (create_pty(&err_pty) < 0) return -1;
struct thread_data_t thread_data_in = {pty.fdm, CreateFile(argv[arg++], GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL), NULL, NULL, NULL};
if (thread_data_in.pipe == INVALID_HANDLE_VALUE) flog("Opening in-pipe failed with %d", GetLastError());
struct thread_data_t thread_data_out = {pty.fdm, CreateFile(argv[arg++], GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL), NULL, &out_cond, &out_mutex};
if (thread_data_out.pipe == INVALID_HANDLE_VALUE) flog("Opening out-pipe failed with %d", GetLastError());
char *errPipeName = argv[arg++];
struct thread_data_t thread_data_err;
if (consoleMode) {
thread_data_err = (struct thread_data_t) {err_pty.fdm, CreateFile(errPipeName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL), NULL, &err_cond, &err_mutex};
if (thread_data_err.pipe == INVALID_HANDLE_VALUE) flog("Opening err-pipe failed with %d", GetLastError());
}
char *command = argv[arg++];
flog("converting path: %s", command);
char *path = convert_path(command);
flog("converted: %s", path);
char * cargv[argc - arg + 2];
memcpy(cargv + 1, argv + arg, sizeof(char*) * (argc - arg));
cargv[0] = path;
cargv[argc - arg + 1] = NULL;
pid_t child_pid = exec_pty(path, cargv, envp, ".", pty.slave_name, pty.fdm, err_pty.slave_name, err_pty.fdm, consoleMode);
free(path);
flog("launched pid: %d", child_pid);
pthread_create(&thread_data_in.tid, NULL, &readPipe, &thread_data_in);
pthread_create(&thread_data_out.tid, NULL, &writePipe, &thread_data_out);
if (consoleMode) {
pthread_create(&thread_data_err.tid, NULL, &writePipe, &thread_data_err);
}
int status;
bool waitpid_ok = true;
if (waitpid(child_pid, &status, 0) < 0) {
flog("wait for child process failed, error: %d", errno);
waitpid_ok = false;
} else {
flog("child process terminated with status %d", status);
}
shutting_down = true;
// Not shutting down the stdin thread because there is no way to abort synchronous ReadFile.
// Since the process is already dead, it doesn't matter anyway.
readOutputAndClose(thread_data_out);
if (consoleMode) readOutputAndClose(thread_data_err);
if (logFile != NULL) fclose(logFile);
if (!waitpid_ok) {
return 1;
}
if (WIFEXITED(status)) {
return WEXITSTATUS(status);
}
if (WIFSIGNALED(status)) {
return 128 + WTERMSIG(status);
}
return status;
}