gpt4 book ai didi

c++ - Win32 C API : Alternative to broken execl*() family of functions?

转载 作者:太空宇宙 更新时间:2023-11-04 06:56:14 24 4
gpt4 key购买 nike

因此,在 Windows 上,似乎 execl() 在不同版本的 Windows 中以不同的方式损坏。我花了很多时间缩小范围和调试,但它并没有真正意义,我只能认为微软的 execl() 实现(对我来说实际上是 execlp())有问题。

唯一的 Windows 版本 execlp() 似乎可以在 7 上正常工作。

在 Windows 10 上,它工作正常,直到我在 MinGW 中使用 -mwindows 进行编译。然后它只会让我的程序以零退出代码终止。

在 Windows XP 上,它将参数参数中的空格解释为单独的参数,尽管参数的实际数量已由函数原型(prototype)的性质明确指定...

所以,看起来我必须使用一些 Windows 原生函数并将其包装在“#ifdef WIN32”中。

我真正需要的是 execl()(execlp 不是必需的),就像 Windows 上的行为一样,因为它将当前进程镜像替换为新进程镜像,并像 execl() 那样保持网络描述符打开。

我真的不知道什么是好的选择,虽然 CreateProcess 似乎能做一些,但我找不到足够的信息来说明我正在尝试做什么。

感谢任何帮助。谢谢!

最佳答案

不幸的是,在 Windows 上您将需要一个完全不同的代码路径,因为在 win32 子系统中,创建一个进程与在一次调用中加载和运行新图像耦合在一起:CreateProcess() .

在典型的 posix 场景中,您将 fork() 您的新进程,设置诸如文件描述符,然后 exec*() 新的二进制文件。要在 Windows 中实现类似的功能,您必须依赖从 CreateProcess() 获得的可能性。对于打开的文件(或套接字),win32 使用“句柄”并且这些可以标记为可继承的,例如我对管道执行以下操作:

HANDLE pin, pout;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = 0;
sa.bInheritHandle = 1;

if (!CreatePipe(&pin, &pout, &sa, 0))
{
fprintf(stderr, "Error creating pipe: %lu\n", GetLastError());
return;
}

这样,管道的句柄是可继承的。然后,在调用 CreateProcess() 时,通过为 bInheritHandles 传递 1(或 TRUE),新进程继承所有 handle 都以这种方式标记。在此示例中,我执行以下操作:

STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.hStdInput = nul;
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
si.dwFlags |= STARTF_USESTDHANDLES;

// simple example, my production code looks different, e.g. quoting the command:
char cmdline[1024];
strcpy(cmdline, exename);
strcat(cmdline, " ");
snprintf(cmdline + strlen(cmdline), 1024 - strlen(cmdline), "%" PRIxPTR, (uintptr_t)pout);

// [...]

PROCESS_INFORMATION pi;
CreateProcess(0, cmdline, 0, 0, 1, 0, 0, 0, &si, &pi);

在 child 中,管道可以这样使用:

uintptr_t testPipeHandleValue;
if (sscanf(argv[1], "%" SCNxPTR, &testPipeHandleValue) != 1)
{
exit(EXIT_FAILURE);
}

int testPipeFd = _open_osfhandle(
(intptr_t)testPipeHandleValue, _O_APPEND | _O_WRONLY);
FILE *testPipe = _fdopen(testPipeFd, "a");
setvbuf(testPipe, 0, _IONBF, 0);

当然,对于网络套接字,这看起来会有所不同,但我希望总体思路有所帮助。

关于c++ - Win32 C API : Alternative to broken execl*() family of functions?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44105982/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com