c - shell执行自定义函数不起作用

时间:2017-03-25 10:35:32

标签: c shell

我正在创建一个shell,它有一些用于执行自定义函数的bulit-in命令。但是,当我尝试两次调用相同的命令时会出现问题。

第一次执行没有问题,正确执行我的功能。但是,在第一次执行完成后,当我使用不同的选项集再次执行该命令时,除了runALS print语句之外,它不执行任何操作。发生了什么,如何解决?

如何执行:runALS -FCFSrunALS -SJF 自定义函数:fcfs()sjf()

输出:

     --WELCOME TO ALS-- 
Please enter:
> runALS -FCFS
runALS 
.... // normal output for fcfs()
Please enter:
> Please enter:
> runALS -SJF
runALS
// no output for sjf()

另一个执行:

     --WELCOME TO ALS-- 
Please enter:
> runALS -SJF
runALS 
.... // normal output for sjf()
Please enter:
> Please enter:
> runALS -FCFS
runALS
// no output for fcfs()

当前代码:

 #include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/*
  Function Declarations for builtin shell commands:
 */
int lsh_addOrder(char **args);
int lsh_runALS(char **args);
int lsh_printSchedule(char **args);
int lsh_printReport(char **args);
int lsh_endProgram(char **args); 



char *builtin_str[] = {
  "addOrder",
  "runALS",
  "printSchedule", 
  "printReport",
  "endProgram"
};

int (*builtin_func[]) (char **) = {
  &lsh_addOrder,
  &lsh_runALS,
  &lsh_printSchedule,
  &lsh_printReport,
  &lsh_endProgram
};

int lsh_num_builtins() {
  return sizeof(builtin_str) / sizeof(char *);
}
/*
  Builtin function implementations.
*/

/**
   @brief Bultin command: create order.
   @param args List of args.  args[0] is "addOrder".  args[1] is the "R0001". args[2] is start date "D001". args[3] is finish date. args[4] is product name. args[5] is number of product ordered
   @return Always returns 1, to continue executing.
 */
int lsh_addOrder(char **args)
{ 
    printf("addOrder\n"); 
    return 1;
}

int lsh_printSchedule(char **args)
{ 
    printf("printSchedule\n"); 
    return 1;
}
int lsh_printReport(char **args)
{ 
    printf("printReport\n"); 
    return 1;
}

/**
   @brief Builtin command: print help.
   @param args List of args.  Not examined.
   @return Always returns 1, to continue executing.
 */
int lsh_runALS(char **args)
{
  int i;
  printf("runALS\n");
  //printf("Type program names and arguments, and hit enter.\n");
  //printf("The following are built in:\n");

  //for (i = 0; i < lsh_num_builtins(); i++) {
    //printf("  %s\n", builtin_str[i]);
  //}
   int opt; 
   while ((opt = getopt(2, args, "F:S:")) != -1) {
        switch (opt) {
        case 'F':
            fcfs(); 
            break;
        case 'S':
            sjf(); 
            break;
        default: /* '?' */
            fprintf(stderr, "Unsupported option\n");
            exit(EXIT_FAILURE);
        }
    }
  return 1;
}

/**
   @brief Builtin command: exit.
   @param args List of args.  Not examined.
   @return Always returns 0, to terminate execution.
 */
int lsh_endProgram(char **args)
{
  printf("Bye-bye!");
  return 0;
}

/**
  @brief Launch a program and wait for it to terminate.
  @param args Null terminated list of arguments (including program).
  @return Always returns 1, to continue execution.
 */
int lsh_launch(char **args)
{
  pid_t pid;
  int status;

  pid = fork();
  if (pid == 0) {
    // Child process
    if (execvp(args[0], args) == -1) {
      perror("lsh");
    }
    exit(EXIT_FAILURE);
  } else if (pid < 0) {
    // Error forking
    perror("lsh");
  } else {
    // Parent process
    do {
      waitpid(pid, &status, WUNTRACED);
    } while (!WIFEXITED(status) && !WIFSIGNALED(status));
  }

  return 1;
}

/**
   @brief Execute shell built-in or launch program.
   @param args Null terminated list of arguments.
   @return 1 if the shell should continue running, 0 if it should terminate
 */
int lsh_execute(char **args)
{
  int i;

  if (args[0] == NULL) {
    // An empty command was entered.
    return 1;
  }

  for (i = 0; i < lsh_num_builtins(); i++) {
    if (strcmp(args[0], builtin_str[i]) == 0) {
      return (*builtin_func[i])(args);
    }
  }

  return lsh_launch(args);
}

#define LSH_RL_BUFSIZE 1024
/**
   @brief Read a line of input from stdin.
   @return The line from stdin.
 */
char *lsh_read_line(void)
{
  int bufsize = LSH_RL_BUFSIZE;
  int position = 0;
  char *buffer = malloc(sizeof(char) * bufsize);
  int c;

  if (!buffer) {
    fprintf(stderr, "lsh: allocation error\n");
    exit(EXIT_FAILURE);
  }

  while (1) {
    // Read a character
    c = getchar();

    // If we hit EOF, replace it with a null character and return.
    if (c == EOF || c == '\n') {
      buffer[position] = '\0';
      return buffer;
    } else {
      buffer[position] = c;
    }
    position++;

    // If we have exceeded the buffer, reallocate.
    if (position >= bufsize) {
      bufsize += LSH_RL_BUFSIZE;
      buffer = realloc(buffer, bufsize);
      if (!buffer) {
        fprintf(stderr, "lsh: allocation error\n");
        exit(EXIT_FAILURE);
      }
    }
  }
}

#define LSH_TOK_BUFSIZE 64
#define LSH_TOK_DELIM " \t\r\n\a"
/**
   @brief Split a line into tokens (very naively).
   @param line The line.
   @return Null-terminated array of tokens.
 */
char **lsh_split_line(char *line)
{
  int bufsize = LSH_TOK_BUFSIZE, position = 0;
  char **tokens = malloc(bufsize * sizeof(char*));
  char *token, **tokens_backup;

  if (!tokens) {
    fprintf(stderr, "lsh: allocation error\n");
    exit(EXIT_FAILURE);
  }

      token = strtok(line, LSH_TOK_DELIM);
      while (token != NULL) {
      tokens[position] = token;
      position++;

    if (position >= bufsize) {
      bufsize += LSH_TOK_BUFSIZE;
      tokens_backup = tokens;
      tokens = realloc(tokens, bufsize * sizeof(char*));
      if (!tokens) {
        free(tokens_backup);
        fprintf(stderr, "lsh: allocation error\n");
        exit(EXIT_FAILURE);
      }
    }

       token = strtok(NULL, LSH_TOK_DELIM);
      }
         tokens[position] = NULL;
         return tokens;
       }

/**
   @brief Loop getting input and executing it.
 */
void lsh_loop(void)
{
  char *line;
  char **args;
  int status;

  do {
    printf("Please enter:\n> ");
    line = lsh_read_line();
    args = lsh_split_line(line);
    status = lsh_execute(args);

    free(line);
    free(args);
  } while (status);
}
int fcfs(){ 
...
return 0;
}

int sjf(){ 
...
return 0;
}
/**
   @brief Main entry point.
   @param argc Argument count.
   @param argv Argument vector.
   @return status code
 */
int main(int argc, char **argv)
{
     // Load config files, if any.
     printf(" --WELCOME TO ALS-- \n");
     // Run command loop.
     lsh_loop();

      // Perform any shutdown/cleanup.

      return EXIT_SUCCESS;
    }

1 个答案:

答案 0 :(得分:1)

|__ (user_id)使用一些需要重置的静态变量才能再次解析相同的字符串。

  

[static]变量getopt()是要处理的下一个元素的索引          在argv。系统将此值初始化为1.调用者可以          将其重置为1以重新开始扫描相同的argv或扫描时          一个新的参数向量。

所以:

optind

另请参阅:http://man7.org/linux/man-pages/man3/getopt.3.html