execlp() 在 fork() 之后无法正常工作
execlp() is not properly working after fork()
我正在编写函数,该函数接收链表中的值,然后分叉进程并使用传递到命令行的参数执行新进程。这是我 prog2b.cc 的代码:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cplist.h"
#include <sys/time.h>
#include <iostream>
#include <sys/wait.h>
#include <errno.h>
struct timeval start, end;
char *key;
int launch_children(cplist *head){
pid_t cpid;
double execution_times = 0;
if(cpid = fork() < 0 ){ // Important to trap errors
std::cerr << "ARGH I'm likely in trouble, get me out of here!" << std::endl;
exit(1); // Important to exit on errors
}else if (cpid == 0 ){
std::cout << "Child process "<< getpid() << ". Running grep on " << key << head->path << std::endl;
execlp("prog2b", "prog2b", "grep", "-R", key, head->path, NULL);
std::cerr << "Exec failed.. Why?" << std::endl;
exit(1); // VERY IMPORTANT - DON'T LET CHILD KEEP RUNNING
} else { // parent
head->cpid = cpid;
wait(NULL);
std::cout << "Child "<< cpid << "has terminated in " << execution_times;
}
}
int main(int argc, char *argv[]){
int i;
int j = 0;
cplist *head = (cplist*) malloc(sizeof(cplist));
head->path = NULL;
head->next = NULL;
if(strcmp(argv[1], "-v") == 0){
key = argv[2];
for(i = 3; i < argc; i++){
cpl_add(head, argv[i]);
j++;
}
} else {
key = argv[1];
for(i = 2; i < argc; i++){
cpl_add(head, argv[i]);
j++;
}
}
printf("key: %sn", key);
launch_children(head);
return(0);
}
我的程序应该从命令行接收键和路径值,然后子进程应该使用"grep"'-r'和传入的值执行。我正在努力让高管正常工作。我花了很多时间在 vice 页上供高管们更好地理解它们并测试其他高管,但我陷入了困境。执行进程不会运行。下面是一个示例来展示它现在是如何工作的:
当我从命令行运行:./prog2b 5678 /hw1/02/
时,我的输出是:
key: 5678
Child process 70788. Running grep on 5678 /hw1/02
Exec failed.. Why?
key: 5678
Child process 70789. Running grep on 5678 /hw1/02
Exec failed.. Why?
正确的输出应该是:
key: 5678
Child process nnnnn. Running grep -R 5678 hw1/02
../../hw1/02/nYyLimCI:5678
../../hw1/02/ANFGmj97:5678
../../hw1/02/oFrtX8Sy:5678
../../hw1/02/UrYt9aBz:5678
../../hw1/02/wE1AMVeh:5678
../../hw1/02/F6TGJEiJ:5678
../../hw1/02/v1HG6zmh:5678
../../hw1/02/YyOSKcJG:5678
Child process nnnnn has terminated in a.bbbbbb seconds
我知道可执行文件失败了,我尝试使用 errno 并输出"没有这样的文件或目录"。我已经发现它指的是第一个 prog2b,但当更改为 ./prog2b 时,我相信它会导致叉子炸弹。我也没有完全掌握如何在执行中 grep,我觉得这可能是问题所在。希望这将有助于解决我在 fork 和 exec 方面的麻烦。我有一个头文件和链表函数类要_add和_dump但我不相信这些是导致错误的原因
errno
设置为ENOENT
(没有这样的文件或目录(这一事实告诉您execlp()
无法找到可执行文件。
从手册页:
如果指定的文件名不包含斜杠(
/
(字符,则execlp()
、execvp()
和execvpe()
函数会复制shell在搜索可执行文件时的操作。 该文件在PATH
环境变量中指定的以冒号分隔的目录路径名列表中查找。 如果未定义此变量,则路径列表默认为当前目录,后跟confstr(_CS_PATH)
返回的目录列表。(此confstr(3)
调用通常返回值"/bin:/usr/bin"
。
您当前的工作目录很可能不在您的PATH
中,因此找不到可执行文件。一个简单的解决方案是在其名称前面加上一个./
:
execlp("./prog2b", "prog2b", "grep", "-R", "key","head->path", NULL);
// here ^^
未来的提示:您可以使用strace
准确看到exec*()
尝试查看的位置:
$ strace -f -e execve ./prog2b 5678 /hw1/02/
execve("./prog2b ", ["./prog2b", "5678", "/hw1/02/"], [/* 40 vars */]) = 0
key: 5678
Child process 70788. Running grep on 5678 /hw1/02
execve("/usr/local/bin/prog2b", ["prog2b", "grep", "-R", "key","head->path"], [/* 40 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/bin/prog2b", ["prog2b", "grep", "-R", "key","head->path"], [/* 40 vars */]) = -1 ENOENT (No such file or directory)
execve("/bin/prog2b", ["prog2b", "grep", "-R", "key","head->path"], [/* 40 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/local/games/prog2b", ["prog2b", "grep", "-R", "key","head->path"], [/* 40 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/games/prog2b", ["prog2b", "grep", "-R", "key","head->path"], [/* 40 vars */]) = -1 ENOENT (No such file or directory)
Exec failed.. Why?
+++ exited with 1 +++
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 为什么STD ::计数将常数传递给Lambda,而不是在弦上工作时而不是字符
- C++程序已停止工作-求解常微分方程