Tag: exec

强制使用`exec`创建的程序执行无缓冲的I / O.

我正在尝试使用pipe , fork和exec与C中的外部程序进行交互。 我想强制外部程序执行无缓冲的I / O. 这是我的代码到目前为止的相关代码段: … pid = fork(); if (pid == (pid_t) 0) { /* child process */ /* make pipe connections to standard streams */ dup2(wpipe[0], STDIN_FILENO); dup2(rpipe[1], STDOUT_FILENO); /* close pipe endings */ close(wpipe[0]); close(rpipe[0]); close(wpipe[1]); close(rpipe[1]); /* unbuffered I/O */ setvbuf(stdin, NULL, _IONBF, BUFSIZ); setvbuf(stdout, NULL, _IONBF, BUFSIZ); if […]

阻止版本的execvp(windows)

这个问题与系统的非阻塞版本完全相反() 我想用另一个替换当前进程(不创建另一个进程)。 我想开始(例如) notepad ,但是以阻塞的方式(我不希望得到提示,直到notepad关闭。 在Windows shell中我只是这样做 cmd /c notepad (如果没有以cmd /c为前缀,则notepad自动从提示中分离) 在C中,使用system我就是这么做的 system(“notepad”); 但这是在幕后分手。 我想用notepad 替换当前进程,我希望它是阻塞的。 我试过了: #include #include int main(int argc,char **argv) { char * const args[] = {“cmd”,”/c”,”notepad”,NULL}; execvp(args[0],args); } notepad运行,但控制台立即返回提示。(非阻塞)。 我希望它阻止,我不想使用fork因为它会创建另一个进程:我想替换当前进程。 (我尝试过使用自定义阻塞可执行文件,它也不会阻塞。所以cmd /c notepad示例和其他任何一个一样好) 所以,如果我运行这个可执行文件,我只是从父进程构建: 在notepad进程退出之前,我不希望进程返回到父进程 我希望能够从命令中获得输出( notepad在这种情况下不是一个好例子) 我不想创建额外的进程(这是一个大型多处理应用程序的一部分,我们不能创建2个进程,我们需要为每次运行保留1个进程) 它甚至可能吗?

我可以将const char *数组传递给execv吗?

这是execv的原型: int execv(const char *path, char *const argv[]); 我可以传递一个const char指针数组作为第二个参数吗? 此示例程序在未设置USE_CAST时发出警告: #include int main(int argc, char *argv[]) { if (argc > 0) { const char *exe_name = “/bin/echo”, *message = “You ran”; const char *exe_args[] = { exe_name, message, argv[0], NULL }; #ifdef USE_CAST execv(“/bin/echo”, (char **) exe_args); #else execv(“/bin/echo”, exe_args); #endif } return 0; […]

在Linux 3.x上挂钩sys_execve()

我试图通过修改系统调用表来挂钩Linux 3.x内核上的sys_execve()函数。 问题是sys_execve()只应在执行失败时返回错误代码。 使用我正在使用的包装器函数(见下文),当在有效的可执行文件上调用sys_execve()时,它执行正常并且一切正常。 但是,当调用不存在的文件或导致错误情况的其他内容时,调用程序将崩溃: segfault at 3b ip 000000000000003b… 使用strace来检查钩子sys_execve()的返回值,显示-1或ENOSYS而不是正确的错误代码,这让我感到困惑,因为我检查了我的包装器函数的程序集以及sys_execve()的Linux源代码。 有关为什么我的包装器没有正确传递错误代码的任何建议? asmlinkage long new_execve(const char* name, const char const** argv, const char const** envp, struct pt_regs* regs) { return orig_func(name, argv, envp, regs); }

管道流和子进程

我需要编写我的管道流。 我的程序应该获取另一个程序的名称并调用它们,第一个程序应该从第一个输出的stdin读取第二个等等。 最后一个程序在stdout中打印结果。 问题是它不起作用。 当我把这个程序称为另外两个简单程序时(它们都是读取x并打印2 * x,而它可以读取),并给它一些数据,我想我应该立即得到结果,但我没有。 更重要的是,当我给它文件结束它没有反应。 不要注意safe_ *函数,它们与标准相同,但检查错误。 帮帮我,请=) #include #include #include #include #include #include #include #include “error.h” #include “safe_functions.h” void call(const char *filename, int in_descr, int out_descr, pid_t *sons, int n) { sons[n] = safe_fork(); if(sons[n] == 0) { safe_dup2(in_descr, STDIN_FILENO); safe_dup2(out_descr, STDOUT_FILENO); safe_execv(filename, (char **)NULL); } } int find_num(pid_t * sons, […]

重新启动Windows进程,保留进程ID和句柄

我创建了一个Windows可执行文件,作为某些嵌入式设备的模拟器(所有业务逻辑与原始设备完全相同,只有硬件相关的东西是存根的)。 此模拟需要不时重置,在“正常”用例中,它会执行以下操作: //some global environment … int main(int argc, char* argv[]) { __debugbreak(); //… do some stuff //if( restart needed ){ printf(“before _execv”); _execv(argv[0], argv); //”reset” simulated device //} //… do some other testing stuff return 0; } 注意:上面的代码仅用于说明主要思想,在实际应用中, execv调用实际上位于HW_Reset()存根中,即从原始代码中的多个位置调用。 问题是Windows上的_execv在Linux上的行为与execv完全不同:当我在Visual Studio中调试此应用程序时, _execv不会用“重新启动”的图像替换当前的过程映像。 相反,它只是创建一个带有新ID的新进程并终止当前进程,导致将其从Visual Studio中分离出来,因此,要保留我需要一次又一次地重新连接到该新进程的所有断点(在单个调试会话中有几十次重新启动) )。 目前我使用__debugbreak()作为解决方法。 其他选项是通过重新初始化全局环境并使用setjmp / longjmp的某种组合来重置模拟 – 但是全局环境和相应的初始化程序通过原始文件的thousends传播,并且大多数是静态的,因此无法手动处理此类重置(我也不允许编辑原始文件)。 所以问题是:是否有一些Windows API /通用解决方法通过重置所有全局(和静态)变量导致当前进程“就地”重新启动,例如,如果可以在同一地址内重新加载相同的进程映像空间,保留向外可观察的进程ID,进程句柄和与visual […]

C:execv之前的dup2()

对于家庭作业,我必须编写一个基本的shell,包括重定向。 该程序使用readline来提示输入,解析输入字符串,并将其分解为可执行文件名,参数和输入/输出文件(如果适用)。 在解析字符串之后,它将forx和子execv()传递给传入的可执行文件。我使用dup2()在fork之后和execv之前更改文件描述符,但是一旦遇到问题我就会遇到问题程序已执行新的可执行文件。 如果在我的shell中我运行ls > foo.out ,我得到: ls: cannot access H y A $ L H) I $ : No such file or directory 构建c-> argv: char *args[6]; int i; for(i=0;i<=4;i++){ char *_arg=strsep(&_str_cmd," "); printf("Found _arg: %s\n",_arg); // If there is an argument and it is not blank if(_arg && strcmp(_arg,"")!=0){ if(strcmp(_arg,"”)==0){ _cmd.outfile=strsep(&_str_cmd,” “); i–; […]

在fork和exec之后在父级和子级之间共享文件描述符

我在Linux,A和B上有两个进程。我想从进程A与进程B共享文件描述符,现在我只是将它序列化为char*并将其传递给execl参数,但这不起作用。 Ac看起来像这样: union descriptor{ char c[sizeof(int)]; int i; } fd; pid_t pid; fd.i = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Perform other socket functions pid = fork(); if(pid == 0){ // Read data from socket if(execl(“./B”, fd.c, NULL) < 0){ exit(EXIT_FAILURE); }else( exit(EXIT_SUCCESS); } }else if(pid < 0){ exit(EXIT_FAILURE); }else{ waitpid(pid, NULL, 0); } Bc看起来像这样: union descriptor{ […]

用路径搜索执行?

我想从我的代码中执行一个程序,并为它提供环境变量和参数。 AFAICT, execve是正确的选择。 但是, execve接收path参数,而不是filename ,这意味着它期望第一个参数是可执行文件的路径。 我知道我可以自己解析$PATH找到路径,但实际上,没有其他选择吗? 没有其他人在某处实现它供我使用吗?

为什么禁止在mac中使用fork而不使用exec?

我的问题很简单。 在Linux上,使用fork而不使用exec非常流行 但是,我发现在MacOS上这是不可能的(参见fork手册) https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/fork.2.html 您在子进程中可以做的事情是有限的。 为了完全安全,你应该自己限制自己只执行异步信号安全操作,直到调用其中一个exec函数为止。 除非明确记录为安全或异步信号安全,否则在fork()之后,应假定任何框架或库中的所有API(包括全局数据符号)都是不安全的。 如果您需要在子进程中使用这些框架,则必须执行。 在这种情况下,执行自己是合理的。 这对我来说很奇怪? 是什么原因? 有可能解决它吗?