mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-16 14:56:00 +00:00
Use non-blocking pipes for process I/O on Windows
Fixes https://github.com/libsdl-org/SDL/issues/10846
This commit is contained in:
@@ -202,8 +202,17 @@ static size_t SDLCALL windows_file_read(void *userdata, void *ptr, size_t size,
|
|||||||
|
|
||||||
if (total_need < READAHEAD_BUFFER_SIZE) {
|
if (total_need < READAHEAD_BUFFER_SIZE) {
|
||||||
if (!ReadFile(iodata->h, iodata->data, READAHEAD_BUFFER_SIZE, &bytes, NULL)) {
|
if (!ReadFile(iodata->h, iodata->data, READAHEAD_BUFFER_SIZE, &bytes, NULL)) {
|
||||||
if (GetLastError() != ERROR_HANDLE_EOF && GetLastError() != ERROR_BROKEN_PIPE) {
|
DWORD error = GetLastError();
|
||||||
|
switch (error) {
|
||||||
|
case ERROR_BROKEN_PIPE:
|
||||||
|
case ERROR_HANDLE_EOF:
|
||||||
|
break;
|
||||||
|
case ERROR_NO_DATA:
|
||||||
|
*status = SDL_IO_STATUS_NOT_READY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
WIN_SetError("Error reading from datastream");
|
WIN_SetError("Error reading from datastream");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -214,8 +223,17 @@ static size_t SDLCALL windows_file_read(void *userdata, void *ptr, size_t size,
|
|||||||
total_read += read_ahead;
|
total_read += read_ahead;
|
||||||
} else {
|
} else {
|
||||||
if (!ReadFile(iodata->h, ptr, (DWORD)total_need, &bytes, NULL)) {
|
if (!ReadFile(iodata->h, ptr, (DWORD)total_need, &bytes, NULL)) {
|
||||||
if (GetLastError() != ERROR_HANDLE_EOF && GetLastError() != ERROR_BROKEN_PIPE) {
|
DWORD error = GetLastError();
|
||||||
|
switch (error) {
|
||||||
|
case ERROR_BROKEN_PIPE:
|
||||||
|
case ERROR_HANDLE_EOF:
|
||||||
|
break;
|
||||||
|
case ERROR_NO_DATA:
|
||||||
|
*status = SDL_IO_STATUS_NOT_READY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
WIN_SetError("Error reading from datastream");
|
WIN_SetError("Error reading from datastream");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -227,7 +245,6 @@ static size_t SDLCALL windows_file_read(void *userdata, void *ptr, size_t size,
|
|||||||
static size_t SDLCALL windows_file_write(void *userdata, const void *ptr, size_t size, SDL_IOStatus *status)
|
static size_t SDLCALL windows_file_write(void *userdata, const void *ptr, size_t size, SDL_IOStatus *status)
|
||||||
{
|
{
|
||||||
IOStreamWindowsData *iodata = (IOStreamWindowsData *) userdata;
|
IOStreamWindowsData *iodata = (IOStreamWindowsData *) userdata;
|
||||||
const size_t total_bytes = size;
|
|
||||||
DWORD bytes;
|
DWORD bytes;
|
||||||
|
|
||||||
if (iodata->left) {
|
if (iodata->left) {
|
||||||
@@ -248,11 +265,13 @@ static size_t SDLCALL windows_file_write(void *userdata, const void *ptr, size_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WriteFile(iodata->h, ptr, (DWORD)total_bytes, &bytes, NULL)) {
|
if (!WriteFile(iodata->h, ptr, (DWORD)size, &bytes, NULL)) {
|
||||||
WIN_SetError("Error writing to datastream");
|
WIN_SetError("Error writing to datastream");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (bytes == 0 && size > 0) {
|
||||||
|
*status = SDL_IO_STATUS_NOT_READY;
|
||||||
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -200,6 +200,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
|||||||
HANDLE stdin_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
|
HANDLE stdin_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
|
||||||
HANDLE stdout_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
|
HANDLE stdout_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
|
||||||
HANDLE stderr_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
|
HANDLE stderr_pipe[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
|
||||||
|
DWORD pipe_mode = PIPE_NOWAIT;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
// Keep the malloc() before exec() so that an OOM won't run a process at all
|
// Keep the malloc() before exec() so that an OOM won't run a process at all
|
||||||
@@ -263,6 +264,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
|||||||
stdin_pipe[WRITE_END] = INVALID_HANDLE_VALUE;
|
stdin_pipe[WRITE_END] = INVALID_HANDLE_VALUE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (!SetNamedPipeHandleState(stdin_pipe[WRITE_END], &pipe_mode, NULL, NULL)) {
|
||||||
|
WIN_SetError("SetNamedPipeHandleState()");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (!SetHandleInformation(stdin_pipe[WRITE_END], HANDLE_FLAG_INHERIT, 0) ) {
|
if (!SetHandleInformation(stdin_pipe[WRITE_END], HANDLE_FLAG_INHERIT, 0) ) {
|
||||||
WIN_SetError("SetHandleInformation()");
|
WIN_SetError("SetHandleInformation()");
|
||||||
goto done;
|
goto done;
|
||||||
@@ -296,6 +301,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
|||||||
stdout_pipe[WRITE_END] = INVALID_HANDLE_VALUE;
|
stdout_pipe[WRITE_END] = INVALID_HANDLE_VALUE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (!SetNamedPipeHandleState(stdout_pipe[READ_END], &pipe_mode, NULL, NULL)) {
|
||||||
|
WIN_SetError("SetNamedPipeHandleState()");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (!SetHandleInformation(stdout_pipe[READ_END], HANDLE_FLAG_INHERIT, 0) ) {
|
if (!SetHandleInformation(stdout_pipe[READ_END], HANDLE_FLAG_INHERIT, 0) ) {
|
||||||
WIN_SetError("SetHandleInformation()");
|
WIN_SetError("SetHandleInformation()");
|
||||||
goto done;
|
goto done;
|
||||||
@@ -338,6 +347,10 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
|||||||
stderr_pipe[WRITE_END] = INVALID_HANDLE_VALUE;
|
stderr_pipe[WRITE_END] = INVALID_HANDLE_VALUE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (!SetNamedPipeHandleState(stderr_pipe[READ_END], &pipe_mode, NULL, NULL)) {
|
||||||
|
WIN_SetError("SetNamedPipeHandleState()");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (!SetHandleInformation(stderr_pipe[READ_END], HANDLE_FLAG_INHERIT, 0) ) {
|
if (!SetHandleInformation(stderr_pipe[READ_END], HANDLE_FLAG_INHERIT, 0) ) {
|
||||||
WIN_SetError("SetHandleInformation()");
|
WIN_SetError("SetHandleInformation()");
|
||||||
goto done;
|
goto done;
|
||||||
|
Reference in New Issue
Block a user