向程序添加函数,并从函数中的命令行调用该函数

时间:2010-05-08 17:24:51

标签: c shell unix

我必须添加一个自定义函数,该函数显示此shell启动的当前正在运行的前台和后台进程。如何从shell的命令行定义和调用该函数?

#include "smallsh.h" /*include file for example*/

/*program buffers and work pointers*/
static char inpbuf[MAXBUF], tokbuf[2*MAXBUF],
*ptr = inpbuf, *tok = tokbuf;

userin(p) /*print prompt and read a line*/
char *p;
{

  int c, count;

  /*initialization for later routines*/
  ptr = inpbuf;
  tok = tokbuf;

  /*display prompt*/
  printf("%s ",p);

  for(count = 0;;)
  {
    if((c = getchar()) == EOF)
      return(EOF);

    if(count<MAXBUF)
      inpbuf[count++] = c;

    if(c == '\n' && count <MAXBUF)
    {
      inpbuf[count] = '\0';
      return(count);
    }

    /*if line too long restart*/
    if(c == '\n')
    {
      printf("smallsh:input line too long\n");
      count = 0;
      printf("%s",p);
    }
  }
}

gettok(outptr) /*get token and place into tokbuf*/
char **outptr;
{
  int type;

*outptr = tok;

/*strip white space*/
for(;*ptr == ' ' || *ptr == '\t'; ptr++)
  ;

*tok++ = *ptr;

  switch(*ptr++)
  {
    case '\n':
      type = EOL; break;
    case '&':
      type = AMPERSAND; break;
    case ';':
      type = SEMICOLON; break;
    case '#':
      type = POUND; break;
    default:
      type = ARG;
      while(inarg(*ptr))
        *tok++ = *ptr++;
  }

*tok++ = '\0';
return(type);
}

static char special[]=
{' ', '\t', '&', ':', '\n', '\0'};

inarg(c) /*are we in an ordinary argument*/
char c;
{
  char *wrk;

  for(wrk = special;*wrk != '\0';wrk++)
    if(c == *wrk)
      return(0);

    return(1);
}

#include "smallsh.h"

procline() /*process input line*/
{
  char *arg[MAXARG+1]; /*pointer array for runcommand*/
  int toktype; /*type of token in command*/
  int narg; /*number of arguments so far*/
  int type; /*FOREGROUND or BACKGROUND*/

  for(narg = 0;;)
  {
    /*loop FOREVER*/

    /*take action according to token type*/

    switch(toktype = gettok(&arg[narg]))
    {
      case ARG:

      if(narg<MAXARG)
        narg++;
      break;

      case EOL:
      case SEMICOLON:
      case AMPERSAND:
      case POUND:

        type = (toktype == AMPERSAND) ?
        BACKGROUND : FOREGROUND;

        if(narg!=0)
        {
          arg[narg] = NULL;
          runcommand(arg, type);
        }

        if((toktype == EOL)||(toktype=POUND))
          return;

        narg = 0;
        break;
    }
  }
}


#include "smallsh.h"

/*execute a command with optional wait*/
runcommand(cline,where)
char **cline;
int where;
{
  int pid, exitstat, ret;

  if((pid = fork()) <0)
  {
    perror("smallsh");
    return(-1);
  }

  if(pid == 0)
  {
    /*child*/
    execvp(*cline, cline);
    perror(*cline);
    exit(127);
  }

  /*code for parent*/
  /*if background process print pid and exit*/

  if(where == BACKGROUND)
  {
    printf("[Process id %d]\n", pid);
    return(0);
  }

  /*wait until process pid exists*/

  while( (ret=wait(&exitstat)) != pid && ret != -1)
    ;

  return(ret == -1 ? -1 : exitstat);
}

#include "smallsh.h"

char *prompt = "Command>"; /*prompt*/

main()
{
  while(userin(prompt) != EOF)
    procline();
}

为了尝试在子进程的代码之前调用一个函数,在runco​​mmand的内部,我尝试添加另一个if语句if(cline == "dowork"){dowork();},并尝试在其他地方添加类似的行,但没有这样的工作。

2 个答案:

答案 0 :(得分:1)

由于这是C,cline == "dowork"将无法执行您想要的操作。您需要将其更改为:

if (strcmp(cline, "dowork") == 0)
{
    ...
}

如果您希望shell也处理“DOWORK”,“DoWork”等,您可以将strcmp替换为strcasecmp

更新:由于您有char **cline,因此您需要将其更改为:

if (strcmp(*cline, "dowork") == 0)

此外,您应该编译警告 - 如果您这样做,编译将告诉您这里有类型不匹配。

答案 1 :(得分:0)

您可以维护一个内部命令列表,如:

cd”“ls”并根据此列表检查用户输入,如果内部命令被重新命名,则只需调用实现内部命令的函数。

编辑:我假设你正在实现一个类似应用程序的小shell。