Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
UNIX:在fork之后在父进程上调用exec_Unix_Exec_Fork - Fatal编程技术网

UNIX:在fork之后在父进程上调用exec

UNIX:在fork之后在父进程上调用exec,unix,exec,fork,Unix,Exec,Fork,我用我的语法,用LEX,写了一些代码来fork()我的进程并运行一个孩子。子级实际上从父级获取一些输入,然后返回一个结果 我需要在加载父对象的同一个二进制文件上调用exec,但我遇到了一个问题。我知道exec并不意味着完全意义上的,但我这样做是因为我在LEX中有一些以前的语法,我只是想去掉它们,所以重新加载过程更容易 在子对象中,fork()之后有以下代码: 这段代码的问题是,如果进程是从同一个目录启动的,那么它可以工作,但是如果我尝试从这个目录中的文件夹加载,比如说,../shell,那么路径

我用我的语法,用LEX,写了一些代码来fork()我的进程并运行一个孩子。子级实际上从父级获取一些输入,然后返回一个结果

我需要在加载父对象的同一个二进制文件上调用exec,但我遇到了一个问题。我知道exec并不意味着完全意义上的,但我这样做是因为我在LEX中有一些以前的语法,我只是想去掉它们,所以重新加载过程更容易

在子对象中,fork()之后有以下代码:

这段代码的问题是,如果进程是从同一个目录启动的,那么它可以工作,但是如果我尝试从这个目录中的文件夹加载,比如说,../shell,那么路径实际上是错误的,它将包括这个目录

我想知道我如何才能得到正确的进程路径,如果有办法也得到进程的实际名称,请?我查看了环境变量,但没有发现任何有用的内容

多谢各位


Jary

据我所知,目标是让子进程重新执行代表父进程的相同程序

由于没有使用
/proc
文件系统中的数据的技巧,我不相信有完全可靠的方法可以做到这一点

通常,您依赖于
argv[0]
的值足以查找程序,并使用
execvp()
通过
$PATH
查找程序

尝试2-可能不那么混乱 如果您不介意的话,我将重新表述[问题]:现在,
execl()
执行二进制文件,但前提是我直接从其文件夹加载父文件。如果我进入一个子文件夹,我们称之为fd,那么路径将是“correctPath/fd/shell”,而不是“correctPath/shell”。问题似乎是调用getenv(“PWD”)来查找路径并不总是正确的

因此,目标是加载相同的进程或二进制文件;让我们假设二进制文件名为“shell”。问题是找到路径。我展示的代码在shell从其自身所在的文件夹加载(父)的情况下工作,否则它将不工作。我怀疑调用getenv(“PWD”)是不对的,但我不确定还可以调用什么

使用
getenv(“PWD”)
getcwd()
通常是不正确的,这是正确的

char *arg0 = 0;

int main(int argc, char **argv)
{
    ...declarations...

    arg0 = argv[0];

    ...actions...
}
因此,主程序将其
argv[0]
的值存储在全局变量
arg0
中,以使其可用于进程的其他部分,特别是将要(重新)运行该命令的代码

如果使用“/shell”在可执行文件所在的同一目录中调用该程序,则
argv[0]
(因此
arg0
)将包含该路径名。如果使用依赖$PATH的“shell”来定位程序,则
argv[0]
将只包含“shell”或“shell”的绝对路径名(不太常见)

如果从
fd
子目录调用该程序,它可能会被调用为“./shell”,或者它可能会被调用为“/absolute/path/to/shell”,或者它可能会被调用为依赖$path来查找可执行文件的“shell”。同样,在上述任何情况下,
arg0
中的值都是最初调用程序的名称,或者与之等效

唯一失败的时候是有人故意混淆可执行文件,幸运的是,这种情况很少发生

因此,在子代码中,您可以使用:

char *args[] = { arg0, 0 };
execvp(arg0, args);
重新执行最初执行的命令(除了最初传递的任何辅助参数)

尝试1-有点混乱 假设
argv[0]
的值通过变量
char*arg0
可用,则所需的全部内容是:

char *args[] = { arg0, 0 };
execvp(arg0, args);
如果必须使用
execl()
,则需要:

execl(arg0, arg0, (char *)0);

演员阵容是必要的
execl()
是一个变量参数列表函数,如果您写入0,它将转换为
int
,这将在
int
为32位且指针为64位的64位系统上失败。但是,如果
arg0
不表示可执行文件的路径(相对或绝对),则该操作将失败。然后,您必须决定如果
execl()
返回该怎么办-您可以放弃或通过
$PATH
搜索程序,但在这种情况下,为什么不首先使用
execvp()
来避免痛苦。

对不起,我对您的答案感到困惑。如果您不介意的话,我将重新措辞:现在,execl确实执行二进制文件,但前提是我直接从其父文件夹加载它。如果我进入一个子文件夹,我们称之为fd,那么路径将是“correctPath/fd/shell”,而不是“correctPath/shell”。问题似乎是调用getenv(“PWD”)来找到路径并不总是正确的。不,那很好,我可以重新解释,直到你理解,我可以理解它是如何不清楚的。因此,我们的目标是加载相同的进程或二进制文件,假设二进制文件被称为“shell”。问题是找到路径。我展示的代码在shell从其自身所在的文件夹加载(父)的情况下工作,否则它将不工作。我怀疑打电话给getenv(“PWD”)是不对的,但我不知道还能打什么。啊,我想我现在明白你的意思了,谢谢!我会尝试一下,告诉你它是否有效。非常感谢!你解决了我的问题!我现在得到了你的解决方案,它比我拥有的要简单得多,而且一直都有效。完美的谢谢。感谢您抽出时间重新整理您的回复!请注意,您显示的对
execl()
的调用不会给被调用的程序一个
argv[0]
(或者,更准确地说,如果null被定义为
(void*)0
,则它会给被调用的程序一个零整数,在64位机器上可能不够大)。Y
execl(arg0, arg0, (char *)0);