标题:关于MINI SHELL ~ 先谢过
只看楼主
chenjk
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2010-2-7
结帖率:0
已结贴  问题点数:20 回复次数:4 
关于MINI SHELL ~ 先谢过
学校要我们做一个MINI SHELL的程序~  我对C 一窍不通~  所以在网上找了个程序` 不知道对不对~

我们老师是法国人, 所以下面会有 法语的解释,大侠们可以略过。 能帮我解释下MINI SHELL 的用处和检查下这个程序吗?

感激不敬 我的 QQ 号 51622131 或跟帖 谢谢 了 ~


由于是新号 可能不能给太多分~ 但我一定记住的账号  日后再报  

MINI SHELL

*/

/* en-tetes standard */
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include <sys/stat.h>
#include <sys/wait.h>  /* pour avoir wait & co. */
#include <ctype.h>      /* pour avoir isspace & co. */
#include <string.h>
#include <errno.h>      /* pour avoir errno */
#include <signal.h>
#include <fcntl.h>

char  ligne[4096];    /* contient la ligne d'entree */

/* pointeurs sur les mots de ligne (voir decoupe) */
#define MAXELEMS 32
char* elems[MAXELEMS];


void affiche_invite()
{
  printf("> ");
  fflush(stdout);
}

void lit_ligne()
{
  /* fgets peut etre interrompu par le signal SIGCHLD => on boucle */
  while (1) {
    if (fgets(ligne,sizeof(ligne)-1,stdin)) break; /* lecture OK */
    if (feof(stdin)) {
      /* vrai fin */
      printf("\n");
      exit(0);
    }
  }
}

/* decoupe ligne en mots
  fait pointer chaque elems[i] sur un mot different
  elems se termine par NULL
*/
void decoupe()
{
  char* debut = ligne;
  int i;
  for (i=0; i <MAXELEMS-1; i++) {

    /* saute les espaces */
    while (*debut && isspace(*debut)) debut++;

    /* fin de ligne ? */
    if (!*debut) break;

    /* on se souvient du debut de ce mot */
    elems[i] = debut;

    /* cherche la fin du mot */
    while (*debut && !isspace(*debut)) debut++; /* saute le mot */

    /* termine le mot par un \0 et passe au suivant */
    if (*debut) { *debut = 0; debut++; }
  }

  elems[i] = NULL;
}


/* XXX
  front_pid = pid du processus au premier plan

  permet a sigchld de notifier a execute que la commande au premier
  plan vient de se terminer

  la variable etant partagee entre le programme principal (lance_commande) et
  un handler de signal asynchrone (sigchld), elle dont etre marquee volatile
*/
volatile int front_pid = -1;

void sigchld(int signal)
{
  /* un signal peut correspondre a plusieurs fils finis, donc on boucle */
  while (1) {
    int status;
    pid_t pid = waitpid(-1,&status,WNOHANG);
    if (pid <0) {
      if (errno==EINTR) continue; /* interrompu => on recommence */
      if (errno==ECHILD) break;  /* plus de fils termine=> on quitte */
      printf("erreur de wait (%s)\n",strerror(errno));
      break;
    }

    if (pid==0) break; /* plus de fils termine=> on quitte */

    /* XXX signale a execute que front_pid s'est termine*/
    if (pid==front_pid) front_pid = -1;

    if (WIFEXITED(status))
      printf("terminaison normale, pid=%i, status %i\n",pid,WEXITSTATUS(status));
    if (WIFSIGNALED(status))
      printf("terminaison par signal %i, pid=%i\n",WTERMSIG(status),pid);
  }
}

void execute()
{
  sigset_t sigset;
  pid_t pid;
  int en_fond;
  char* buffer = (char*)calloc(1024, sizeof(char));
  /* XXX detection du & */
  if (strchr(ligne,'&')) {
    *strchr(ligne,'&') = 0;
    en_fond = 1;
  }
  else {
    /* bloque SIGCHLD jusqu'à ce que le pare ait place le pid du
      fils dans front_pid
      sinon on risque de manquer la notification de fin du fils
      (race condition)
    */
    sigemptyset(&sigset);
    sigaddset(&sigset,SIGCHLD);
    sigprocmask(SIG_BLOCK,&sigset,NULL);
    en_fond = 0;
  }

  decoupe();
  if (!elems[0]) return; /* ligne vide */

  pid = fork();
  if (pid < 0) {
    printf("fork a achoue(%s)\n",strerror(errno));
    return;
  }

  if (pid==0) {
    /* fils */

    if (en_fond) {
      /* XXX redirection de l'entree standard sur /dev/null */
      int devnull = open("/dev/null",O_RDONLY);
      if (devnull != -1) {
close(0);
dup2(devnull,0);
      }
    }
    else {
      /* XXX reactivation de SIGINT & debloque SIGCLHD */
      struct sigaction sig;
      sig.sa_flags = 0;
      sig.sa_handler = SIG_DFL;
      sigemptyset(&sig.sa_mask);
      sigaction(SIGINT,&sig,NULL);
      sigprocmask(SIG_UNBLOCK,&sigset,NULL);
    }
if (strcmp(elems[0],"cd") == 0) {
          // change directory
int count_arg=0;
while(elems[count_arg]!=NULL){count_arg++;}
printf("nb : %d\n",count_arg);

          if ((count_arg) == 2) {
            if (chdir(strcat ( strcat (getcwd(buffer, 1024),"/"), strcat (elems[1],"/") )) != 0) {
              printf("Error: Invalid directory. %s\n",getcwd(buffer, 1024));
            }
          } else {
            printf("Error: Invalid use of cd command.\n");
          }
}
else{
    execvp(elems[0], /* programme a executer */
  elems    /* argv du programme a executer */
  );
    printf("impossible d'executer \"%s\" (%s)\n",elems[0],strerror(errno));
    exit(1);
}
  }

  else {

    if (!en_fond) {

      /* XXX attent la fin du processus au premier plan */
      printf("pid %i\n",pid);
      front_pid = pid;
      sigprocmask(SIG_UNBLOCK,&sigset,NULL);

      /* attente bloquante jusqu'à ce que sigchld signale que front_pid
        s'est termine*/
      while (front_pid!=-1) pause();
    }

  }
}

int main()
{
  struct sigaction sig;
  sig.sa_flags = 0;
  sig.sa_handler = sigchld;
  sigemptyset(&sig.sa_mask);
  sigaction(SIGCHLD,&sig,NULL);

  sig.sa_handler = SIG_IGN;
  sigaction(SIGINT, &sig, NULL);

  while (1) {
    affiche_invite();
    lit_ligne();
    execute();
  }
  return 0;
}
搜索更多相关主题的帖子: SHELL MINI 
2010-02-07 20:50
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
得分:20 
还法语的……
这么长的东西。可能不会有人给你解释哟~

你自己去找老师问呗,老师会喜欢这种学生的~~
2010-02-07 22:49
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
得分:0 
哦,如果你不知道 shell 是什么东西的话,可以上网查一查。
连这种代码都找的着,不是挺会找东西的嘛~~
2010-02-07 22:53
chenjk
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2010-2-7
得分:0 
先谢谢 上面2 位的关注~  

上面的 程序 是我 同学给我的~   可是他们又不能教我  因为后天就要交了

而且这是 很重要的考试~

所以我才会这么急

不过算了  我就 改改 交了吧~   

P.S 我在巴黎上学 所以程序要用法语
2010-02-08 04:52
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
得分:0 
在巴黎上学呀,真不错。
另外所谓 “楼上那两位”其实都是我,呵呵~~
2010-02-08 22:21



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




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

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