[英]The usage of execlp() in a c-program
我对c中的execlp()有疑问。
我有以下程序:
#include <stdio.h>
#include <unistd.h>
#include <sys/unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>
#include <limits.h>
#include <signal.h>
void INThandler(int);
int main(int argc, char* argv[]) {
struct passwd *pwd;
char *lgn;
char *cwd;
char buff[PATH_MAX + 1];
char s1[10], s2[10];
/*Um den Namen zu bekommen*/
lgn = getlogin();
pwd = getpwnam(lgn);
/*Um den Hostnamen zu bekommen*/
char hostname[128];
gethostname(hostname, sizeof hostname);
/*Um das Arbeitsverzeichnis zu bekommen*/
cwd = getcwd(buff, PATH_MAX + 1);
if((cwd!=NULL)&& hostname!=NULL && ((lgn=getlogin())!=NULL ||
(pwd!=NULL)))
{
signal(SIGINT, INThandler);
while(1)
{
printf("%s@%s %s$", pwd->pw_name, hostname, cwd);
if(scanf("%s %s",s1, s2)<1)
return 1;
printf("Befehl: %s\nArgument: %s\n",s1,s2);
execlp(s1, s1, NULL);
printf("Zhopa");
return 1;
}
}
return 0;
}
void INThandler(int sig) {
char c;
signal(sig, SIG_IGN);
printf("Wollen Sie Program Verlassen? [y/n]");
c = getchar();
if(c == 'y' || c=='Y')
exit(0);
else
signal(SIGINT, INThandler);
getchar();
}
它应该打印用户名@主机名文件夹$,并以linux命令作为参数“ ls -al”,之后应以execlp()启动它,但是它不起作用,我认为应该这样做。
我在这里阅读了有关此命令的所有文章,但我想,我仍然不明白如何使用它。
我会感谢某人的帮助。
您必须使用fork()
创建一个新进程,然后在新进程(子execlp
)中使用execlp
。 这是示例代码。 它不处理任何错误,它仅适用于带有1个参数的命令,因为这是我所了解的(例如ls -all
)
#include <stdio.h>
#include <unistd.h>
#include <sys/unistd.h>
#include <sys/wait.h> /*Lib for waitpid*/
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>
#include <limits.h>
#include <signal.h>
void INThandler(int);
int main(int argc, char* argv[]) {
int pid = 0; /*PROCESS ID*/
struct passwd *pwd;
char *lgn;
char *cwd;
char buff[PATH_MAX + 1];
char s1[10], s2[10];
/*Um den Namen zu bekommen*/
lgn = getlogin();
pwd = getpwnam(lgn);
/*Um den Hostnamen zu bekommen*/
char hostname[128];
gethostname(hostname, sizeof hostname);
/*Um das Arbeitsverzeichnis zu bekommen*/
cwd = getcwd(buff, PATH_MAX + 1);
if((cwd!=NULL)&& hostname!=NULL && ((lgn=getlogin())!=NULL ||
(pwd!=NULL)))
{
signal(SIGINT, INThandler);
while(1)
{
printf("%s@%s %s$", pwd->pw_name, hostname, cwd);
if(scanf("%s %s",s1, s2)<1)
return 1;
printf("Befehl: %s\nArgument: %s\n",s1,s2);
pid = fork();
if(pid == 0){ /*Child*/
execlp(s1, s1, s2,(char*) NULL);
}else if(pid > 0){ /*Father*/
/*father waiting for the child*/
waitpid(pid,NULL,0);
}
printf("Zhopa");
}
}
return 0;
}
void INThandler(int sig) {
char c;
signal(sig, SIG_IGN);
printf("Wollen Sie Program Verlassen? [y/n]");
c = getchar();
if(c == 'y' || c=='Y')
exit(0);
else
signal(SIGINT, INThandler);
getchar();
}
您的信号处理程序将调用未定义的行为。
您只能在信号处理程序中调用异步信号安全功能。 根据POSIX标准 :
... 行为未定义 ...如果信号处理程序调用此标准中定义的任何函数,但下表中列出的函数之一除外。
下表定义了一组应为异步信号安全的功能。 因此,应用程序可以不受限制地从信号捕获功能中调用它们。 ...
[异步信号安全功能表]
上表中未列出的任何功能可能对信号都不安全。 ...
这个信号处理器
void INThandler(int sig) {
char c;
signal(sig, SIG_IGN);
printf("Wollen Sie Program Verlassen? [y/n]");
c = getchar();
if(c == 'y' || c=='Y')
exit(0);
else
signal(SIGINT, INThandler);
getchar();
}
其中具有多个非异步信号安全功能:
printf()
getchar()
exit()
不能从信号处理程序中安全地调用这些函数。
给定您的代码,可能会在scanf()
阻止该进程时尝试调用此信号处理程序-尝试从stdin
读取。 这可能涉及某种锁或互斥锁。 但是您的信号处理程序会调用getchar()
,该方法也会尝试从stdin
读取数据,该stdin
可能已锁定或处于不确定状态。 如果主线程在scanf()
被阻塞,则信号处理程序中对getchar()
的异步调用可能会死锁或破坏用于stdin
的内部结构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.