Skip to content

Commit

Permalink
fix: fix process implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ncvicchi committed Nov 26, 2024
1 parent 025bf47 commit 23397ea
Showing 1 changed file with 77 additions and 34 deletions.
111 changes: 77 additions & 34 deletions src/common/pal/src/windows/pal_process.c
Original file line number Diff line number Diff line change
@@ -1,51 +1,94 @@
#include <windows.h>
#include <memory>
#include <string>
#include <vector>
#include <cstdio>

FILE* popen(const char* command, const char* mode) {
HANDLE hReadPipe, hWritePipe;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <io.h>

typedef struct {
HANDLE hProcess;
FILE* pipeStream;
} PopenHandle;

PopenHandle* popen(const char* command, const char* mode) {
HANDLE hReadPipe = NULL, hWritePipe = NULL;
SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};

// Create a pipe
if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
return nullptr;
return NULL;
}

STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdOutput = (strcmp(mode, "r") == 0) ? hWritePipe : GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = si.hStdOutput;
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};

ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;

// Crear el proceso
if (!CreateProcess(NULL, const_cast<LPSTR>(command), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
if (strcmp(mode, "r") == 0) {
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
} else if (strcmp(mode, "w") == 0) {
si.hStdInput = hReadPipe;
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
} else {
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
return NULL;
}

// Create the process
if (!CreateProcess(NULL, (LPSTR)command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
CloseHandle(hReadPipe);
return nullptr;
CloseHandle(hWritePipe);
return NULL;
}

// Cerramos el lado de escritura del pipe
CloseHandle(hWritePipe);
// Close the unused end of the pipe
if (strcmp(mode, "r") == 0) {
CloseHandle(hWritePipe);
} else {
CloseHandle(hReadPipe);
}

// Devolver el handle del pipe de lectura como FILE*
return _fdopen(_open_osfhandle((intptr_t)hReadPipe, _O_RDONLY), "r");
// Convert the HANDLE to a FILE*
FILE* pipeStream = _fdopen(_open_osfhandle((intptr_t)(strcmp(mode, "r") == 0 ? hReadPipe : hWritePipe), _O_BINARY), mode);
if (!pipeStream) {
CloseHandle(pi.hProcess);
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
return NULL;
}

// Store the process handle and stream in a custom struct
PopenHandle* popenHandle = (PopenHandle*)malloc(sizeof(PopenHandle));
popenHandle->hProcess = pi.hProcess;
popenHandle->pipeStream = pipeStream;

return popenHandle;
}

int pclose(FILE* stream) {
if (stream == nullptr) return -1;
int pclose(PopenHandle* handle) {
if (!handle || !handle->pipeStream) {
return -1;
}

// Close the FILE* stream
fclose(handle->pipeStream);

// Wait for the process to exit
WaitForSingleObject(handle->hProcess, INFINITE);

// Get the exit code
DWORD exitCode = 0;
if (!GetExitCodeProcess(handle->hProcess, &exitCode)) {
exitCode = -1; // Error occurred
}

HANDLE hReadPipe = (HANDLE)_get_osfhandle(_fileno(stream));
CloseHandle(hReadPipe);
fclose(stream);
// Close the process handle
CloseHandle(handle->hProcess);
free(handle);

// Aquí puedes agregar lógica para esperar el proceso y obtener su código de salida si es necesario
return 0; // Deberías devolver el código de salida real del proceso
return (int)exitCode;
}

0 comments on commit 23397ea

Please sign in to comment.