为什么我的 execvp() 在以下代码中不起作用?
我正在尝试使用 execvp() 来执行子进程,但它给了我以下错误,并且我无法修复它,有人可以指出我做错了什么吗?
我的代码:
#include "apue.h"
#include <sys/wait.h>
static void sig_int(int); /* our signal-catching function */
int
main(void)
{
char buf[MAXLINE]; /* from apue.h */
pid_t pid;
int status;
if (signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal error");
printf("%% "); /* print prompt (printf requires %% to print %) */
while (fgets(buf, MAXLINE, stdin) != NULL) {
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0; /* replace newline with null */
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* child */
execlp(buf, buf); //this line is where I am not sure if I am wrong.
err_ret("couldn't execute: %s", buf);
exit(127);
}
/* parent */
if ((pid = waitpid(pid, &status, 0)) < 0)
err_sys("waitpid error");
printf("%% ");
}
exit(0);
}
void
sig_int(int signo)
{
printf("interrupt\n%% ");
}
我的预热/错误:
shell2.c: In function ‘main’:
shell2.c:24:16: warning: passing argument 2 of ‘execvp’ from incompatible pointer type [-Wincompatible-pointer-types]
execvp(buf, buf);
^~~
In file included from ../csci3800sp22/apue.3e/include/apue.h:26:0,
from shell2.c:1:
/usr/include/unistd.h:578:12: note: expected ‘char * const*’ but argument is of type ‘char *’
extern int execvp (const char *__file, char *const __argv[])
预期结果:当我运行其他命令(execlp)时,它给出以下结果:
[singhrav@csci-gnode-02 ~/lab1]$ ls
Makefile shell2 shell2.c
[singhrav@csci-gnode-02 ~/lab1]$ ./shell2
% ls
Makefile shell2 shell2.c
% ps
PID TTY TIME CMD
24839 pts/1 00:00:00 tcsh
25175 pts/1 00:00:00 shell2
25204 pts/1 00:00:00 ps
% ls -l
couldn't execute: ls -l: No such file or directory
execlp()
的问题是它不执行ls -l,我希望能够使用
ls
、ps
& ls -l
这就是为什么我决定使用 execvp()
但当我使用 execvp()
并运行我的 ./shell2
命令它给我以下错误:
[singhrav@csci-gnode-02 ~/lab1]$ ./shell2
% ls
couldn't execute: ls: Bad address
% ps
couldn't execute: ps: Bad address
% ls -l
I am trying to make use of execvp()
to execute child processes but it gives me following error and I am unable to fix it can someone point me in direction what I am doing wrong?
My code:
#include "apue.h"
#include <sys/wait.h>
static void sig_int(int); /* our signal-catching function */
int
main(void)
{
char buf[MAXLINE]; /* from apue.h */
pid_t pid;
int status;
if (signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal error");
printf("%% "); /* print prompt (printf requires %% to print %) */
while (fgets(buf, MAXLINE, stdin) != NULL) {
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0; /* replace newline with null */
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* child */
execlp(buf, buf); //this line is where I am not sure if I am wrong.
err_ret("couldn't execute: %s", buf);
exit(127);
}
/* parent */
if ((pid = waitpid(pid, &status, 0)) < 0)
err_sys("waitpid error");
printf("%% ");
}
exit(0);
}
void
sig_int(int signo)
{
printf("interrupt\n%% ");
}
My warming/error:
shell2.c: In function ‘main’:
shell2.c:24:16: warning: passing argument 2 of ‘execvp’ from incompatible pointer type [-Wincompatible-pointer-types]
execvp(buf, buf);
^~~
In file included from ../csci3800sp22/apue.3e/include/apue.h:26:0,
from shell2.c:1:
/usr/include/unistd.h:578:12: note: expected ‘char * const*’ but argument is of type ‘char *’
extern int execvp (const char *__file, char *const __argv[])
Expected result: When I run other command (execlp) it gives me following result :
[singhrav@csci-gnode-02 ~/lab1]$ ls
Makefile shell2 shell2.c
[singhrav@csci-gnode-02 ~/lab1]$ ./shell2
% ls
Makefile shell2 shell2.c
% ps
PID TTY TIME CMD
24839 pts/1 00:00:00 tcsh
25175 pts/1 00:00:00 shell2
25204 pts/1 00:00:00 ps
% ls -l
couldn't execute: ls -l: No such file or directory
Problem with execlp()
is it does not execute ls -l
, I wanted to be able to use ls
, ps
& ls -l
so that's why I decided to use execvp()
but when I use execvp()
and run my ./shell2
command it gives me following error:
[singhrav@csci-gnode-02 ~/lab1]$ ./shell2
% ls
couldn't execute: ls: Bad address
% ps
couldn't execute: ps: Bad address
% ls -l
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题有两个方面:
1.原始问题
原始
execlp()
调用不执行ls -l
的问题在于您对的调用>execlp
,您不将命令的路径与其参数分开。execlp()
的手册页指出:因此,在您的调用
execlp(buf, buf)
中,该函数将尝试查找具有literal名称
ls -l
的文件(包括空间!)并执行它。另请注意,参数列表必须以(char *) NULL
指针终止,因此您需要将空白处的buf
内容分隔为单独的标记,然后分别馈送到execlp()
,如2 所示。
execvp
的问题您没有明确显示它,但您似乎“盲目”切换了
execlp
与execvp
不对参数进行任何更改。但是,execvp()
函数需要一个以 null 结尾的字符串数组,它是一个char
数组的数组 em> 作为第二个参数。但是,您只需提供一个字符串,即一个简单的char
数组作为第二个参数。因此,第二个参数的内容(字符)将被错误解释为预期字符串的地址,并访问未为进程分配的内存区域,这会导致错误地址
(=EFAULT
)错误消息。TL;DR
您必须更正程序中
exec...
函数的使用。Your problem is two-fold:
1. The original problem
The problem why your original
execlp()
call doesn't executels -l
is that in your call toexeclp
, you don't separate the command's path from its arguments.The man page of
execlp()
states:So, in your call
execlp(buf, buf)
, the function would try to locate a file with literal namels -l
(including the space!) and execute it. Also, note that the argument list must be terminated with a(char *) NULL
pointer, so you would need to separate the content ofbuf
at the whitespace into individual tokens that are then fed individually toexeclp()
, as in2. The problem with
execvp
You don't explicitly show it, but you seem to have "blindly" switched
execlp
withexecvp
without any changes to the arguments. However, theexecvp()
function expects an array of null-terminated strings, which is an array of array ofchar
as second argument. However, you simply provide a string, i.e. a simple array ofchar
as second argument. Hence, the content of the second argument (which are characters) will be mis-interpreted as addresses to the expected strings, and access memory regions not allocated for the process, which leads to theBad address
(=EFAULT
) error message.TL;DR
You have to correct the use of the
exec...
functions in your program.