Skip to content

input/ipc-win: allow Windows handles for --input-ipc-client - #18250

Merged
kasper93 merged 1 commit into
mpv-player:masterfrom
diniamo:input-ipc-client-windows-handle
Jul 23, 2026
Merged

input/ipc-win: allow Windows handles for --input-ipc-client#18250
kasper93 merged 1 commit into
mpv-player:masterfrom
diniamo:input-ipc-client-windows-handle

Conversation

@diniamo

@diniamo diniamo commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Previously, you could only provide a CRT FD, which works great on Unix systems, but it makes life hard on Windows. As far as I can tell, there is no way to make CreateProcess inherit CRT FDs, which made using this option impossible in cases where you couldn't just switch to an API that allows for that. CreateProcess does allow inheriting Windows handles however, which the FD would have been converted to anyway.

@kasper93

kasper93 commented Jul 10, 2026

Copy link
Copy Markdown
Member

As far as I can tell, there is no way to make CreateProcess inherit CRT FDs

You can inherit FDs by passing them in lpReserved2 field of STARTUPINFO. See how we do it

// Copy the list of inherited CRT file descriptors to the new process
STARTUPINFOW our_si = {sizeof(our_si)};
GetStartupInfoW(&our_si);
// Don't redirect std streams if they are attached to a console. Let mpv
// attach to the console directly in this case. In theory, it should work
// out of the box because "console-like" handles should be managed by Windows
// internally, which works for INPUT and OUTPUT, but in certain cases,
// not for ERROR.
DWORD mode;
HANDLE hStdInput = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hStdError = GetStdHandle(STD_ERROR_HANDLE);
STARTUPINFOW si = {
.cb = sizeof(si),
.lpReserved2 = our_si.lpReserved2,
.cbReserved2 = our_si.cbReserved2,
.hStdInput = GetConsoleMode(hStdInput, &mode) ? NULL : hStdInput,
.hStdOutput = GetConsoleMode(hStdOutput, &mode) ? NULL : hStdOutput,
.hStdError = GetConsoleMode(hStdError, &mode) ? NULL : hStdError,
};
this is a wrapper, so it just pass-through the list, but you can put there what you need.

Comment thread input/ipc-win.c Outdated
Comment thread input/ipc-win.c
Comment thread input/ipc-win.c Outdated
fd = ll;
long long fd = bstrtoll(str, &str, 0);
if (!str.len && fd >= 0 && fd <= INT_MAX)
h = (HANDLE)_get_osfhandle((int)fd);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this useless cast. Why LLMs like this integer casts so much. You already check the range. And we don't have integer conversion warnings enabled, but even then it shouldn't trigger here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the code was written by me, and I usually like being explicit. I can remove it though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, sorry.

@diniamo

diniamo commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Right, I didn't find that honestly. Unfortunately I use Go's os/exec API, which doesn't expose any way to set the reserve fields, so I still think this PR would be helpful.

@kasper93

Copy link
Copy Markdown
Member

Right, I didn't find that honestly. Unfortunately I use Go's os/exec API, which doesn't expose any way to set the reserve fields, so I still think this PR would be helpful.

Sure, the change is ok. I'm just saying, it's possible to share FDs and is commonly used even if not documented, there was a need for such mechanism. In Go world indeed it's not nativelly supported golang/go#53686

Previously, you could only provide a CRT FD, which works great for the
most part, but when using CreateProcess on Windows, it requires the use
of the reserved fields of STARTUPINFO to inherit the FD to a child mpv
process. This becomes a problem for example if you use Go's os/exec API,
which does not expose a way to set those reserved fields. Exposing a way
to allow passing handles directly fixes the mentioned scenario, and
makes --input-ipc-client more flexible at no cost.
@diniamo
diniamo force-pushed the input-ipc-client-windows-handle branch from f03c306 to 970e5ba Compare July 10, 2026 18:49
@diniamo

diniamo commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Alright, pushed the changes. Hopefully this satisfies the failed workflow as well.

@diniamo

diniamo commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

@kasper93 is there anything else you want me to change?

@kasper93 kasper93 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@kasper93
kasper93 merged commit 0fb136f into mpv-player:master Jul 23, 2026
35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants