标题:C用execlp实现的linux命令解释器问题
只看楼主
evilloop
Rank: 2
等 级:论坛游民
帖 子:36
专家分:22
注 册:2011-8-27
结帖率:71.43%
已结贴  问题点数:30 回复次数:5 
C用execlp实现的linux命令解释器问题
程序代码:
下边是一个unix高级环境编程中的一个实例,可以用来模拟shell,可是自己编译执行起来发现有两个问题:
1.示例中命令提示符是%,本意是执行完一条命令再出来一个提示符,一直循环,直到手动输入终止程序,但每次都是执行完一条就退出了。
2.命令执行完出来两遍结果,情形如下:
    [root@localhost c]# ./a.out
    % ls
    a.out  data  ls_c.c  myexec.c  no_cache_io.c  no_cache_io_v2.c
    a.out  data  ls_c.c  myexec.c  no_cache_io.c  no_cache_io_v2.c
    [root@localhost c]# pwd

附示例中的ourhdr.h头文件:[local]2[/local],求解惑。
/**********************************************/
#include <sys/types.h>
#include <sys/wait.h>
#include "ourhdr.h"

int
main(void)
{
    char    buf[MAXLINE];
    pid_t    pid;
    int        status;

    printf("%% ");
    while (fgets(buf, MAXLINE, stdin) != NULL)
    {
        buf[strlen(buf)-1] = 0;        /*替换换行符为null*/
        if (pid = fork() < 0)        /*fork一个进程*/
        {
            err_sys("fork error");
        }
        else if (pid == 0)
        {
            execlp(buf, buf, (char *) 0);
            err_ret("couldn't execute: %s", buf);
            exit(127);
        }

        if ((pid = waitpid(pid, &status, 0)) < 0)
        {
            err_sys("waitpid error");
        }
        printf("%% ");
    }
    exit(0);
}




ourhdr.zip (2.41 KB)
搜索更多相关主题的帖子: 解释器 
2012-11-23 14:14
jk_love
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:196
专家分:965
注 册:2012-10-22
得分:30 
问题在于 fork成功执行会返回两次,逻辑要处理一下,稍微修改如下:
int main(void)
{
    char    buf[MAXLINE];
    pid_t    pid;
    int        status;
   
   printf("%% ");
    while (fgets(buf, MAXLINE, stdin) != NULL)
    {
        pid = fork();
        buf[strlen(buf)-1] = 0;  /*替换换行符为null*/
        if (pid < 0)        /*fork一个进程*/
        {
            continue;
        }
        else if (pid == 0)
        {
            execlp(buf,buf,(char *)0);
            err_ret("couldn't execute: %s", buf);
            exit(127);
        }

        if ((pid = waitpid(pid, &status, 0)) < 0)
        {
            err_sys("waitpid error");
        }
        printf("%% ");
    }
    exit(0);
}
2012-11-23 15:05
evilloop
Rank: 2
等 级:论坛游民
帖 子:36
专家分:22
注 册:2011-8-27
得分:0 
回复 2楼 jk_love
非常感谢。我只是把你给的第一个逻辑,就是pid=fork()从while中抽出来,pid<0后边没加continue,也正常了,很奇怪,执行两次的问题明白了,但为什么之前执行后会退出呢,即使执行两次
2012-11-23 15:11
jk_love
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:196
专家分:965
注 册:2012-10-22
得分:0 
你拿出来了 就只执行一次,放while里面每次都执行,当然需要continue,合理的做法是拿出来,以为不是每执行一个命令就去fork一个子进程的。
退出是因为有pid<0的情况的时候,你调用这个函数的时候 已经exit了
void err_sys(const char *fmt,...)
{
   va_list ap;
   va_start(ap, fmt);
   err_doit(1, fmt, ap);
   va_end(ap);
   exit(1);
}
2012-11-23 15:17
lwb603569640
Rank: 6Rank: 6
等 级:侠之大者
威 望:2
帖 子:283
专家分:436
注 册:2012-11-9
得分:0 


[ 本帖最后由 lwb603569640 于 2012-11-23 16:31 编辑 ]

自由、民主、宪政!
2012-11-23 15:44
sohow
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2014-12-9
得分:0 
回复 5楼 lwb603569640
你抄书上的代码抄错了,这一句:
    if ((pid = fork()) < 0)    //注意括弧
剩下的就不用解释了。我刚开始看Unix环境高级编程,百度execlp,看到了这个帖子正是我在书上正在看的就点进来了。
楼主可能早已明白,只是希望后来者注意,明白错误的根本原因。
2014-12-09 11:59



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-388096-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.180138 second(s), 11 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved