码迷,mamicode.com
首页 > 其他好文 > 详细

利用fork()和execve()运行程序

时间:2015-05-23 00:08:11      阅读:711      评论:0      收藏:0      [点我收藏+]

标签:

#include "csapp.h"

#define MAXARGS 128

/*本案例学习fork()函数建立进程,以及execve()函数加载并运行程序*/

//eval函数用于解析命令行并执行相关命令
void eval(char *cmdline)
{
  char *argv[MAXARGS];
  char buf[MAXLINE];
  int bg;
  pid_t pid;

  strcpy(buf,cmdline); //复制字符串
  bg=parseline(buf,argv);//bg为1或0
  if(argv[0]==NULL) //参数为空,返回主函数
    return;
  if(!builtin_command(argv)) { //返回0的情况
    if((pid=fork())==0) { //新建子进程
      if(execve(argv[0],argv,environ)<0) { //运行带有参数的可执行程序,若出现错误,则execve函数会返回负数,执行错误提示,并且退出该子进程
    printf("%s:Command not found.\n",argv[0]);
    exit(0);
      }
    }
    if(!bg) { //当bg为0时,即输入命令不是空且结尾字符串不是&的情况
      int status;
      if(waitpid(pid,&status,0)<0) //若等待子进程终止或退出时发生了错误,则返回-1,并且执行以下错误提示
    printf("waitfg:waitpid error\n");
    }
    else //当bg为1时,输出进程ID及命令行参数
      printf("%d,%s",pid,cmdline);
  }
  return;
}

//builtin_command函数用于判断命令是否合法
//例如若命令行第一个字符串为quit,则表示正常退出父进程(主程序)
//若第一个字符串为&,则返回1,否则返回0
//可以认为&开头表示该行命令为注释行,不用执行
int builtin_command(char **argv)
{
  if(!strcmp(argv[0],"quit")) //quit键表示退出整个程序
    exit(0);
  if(!strcmp(argv[0],"&")) //&开头则返回1
    return 1;
  return 0; //一般情况下返回0
}


//parseline函数用于读取命令行参数,并将参数返回至argv中
int parseline(char *buf,char **argv)
{
  char *delim;
  int argc;
  int bg;

  buf[strlen(buf)-1]=‘ ‘; //将最后一位‘\0‘置为空格
  while(*buf&&(*buf==‘ ‘)) //跳过开头部分的所有空格
    buf++;

  argc=0; //用于计数(参数个数)
  while((delim=strchr(buf,‘ ‘))) { //strchr函数用于寻找字符在字符串中首次出现的位置,返回该位置指针
    argv[argc++]=buf;//将单个参数存入argv指针当中
    *delim=‘\0‘;
    buf=delim+1;//更新buf所指向的地址
    while(*buf&&(*buf==‘ ‘)) //跳过空格
      buf++;
  }

  argv[argc]=NULL;
  if(argc==0) //若参数个数为0,则返回1
    return 1;

  if((bg=(*argv[argc-1]==‘&‘))!=0) //若参数命令行最后一个字符为&,将&置为NULL,并且返回1;否则返回0
    argv[--argc]=NULL;
  return bg;

}

/*主函数入口*/
int main()
{
  char cmdline[MAXLINE];
  while(1) {
    printf("> ");
    fgets(cmdline,MAXLINE,stdin); //从终端读取输入
    if(feof(stdin))
      exit(0);
    eval(cmdline); //执行子程序
  }
}

运行示例

> ./main1.o
acbc> quit


利用fork()和execve()运行程序

标签:

原文地址:http://my.oschina.net/zzw922cn/blog/418800

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!