⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shell.c

📁 Linux下写一个命令解释程序,实现了基本的功能.
💻 C
字号:
#include "jobctrl.h"
#include "types.h"
#include "common.h"
#include <setjmp.h>

static jmp_buf jmpbuffer;
static void sig_int(int);
static void sig_tstp(int);

CHAIN job_list = { NULL, NULL };

int main(int argc, char *argv[])
{
  char command[MAX_COMMAND_LEN + 1];
  char *next_cmd = NULL;
  JOB new_job;
  FILE *input = stdin;
  int i;
  int status;
  int in_bg;

  if (argc > 2) {
    fprintf(stderr, "unexpected arguments; usage:%s <commands>\n", argv[0]);
    exit(1);
  }
  if (argc == 2) {
    input = fopen(argv[1], "r");
    if (!input) {
      perror("fopen");
      exit(1);
    }
  }

  signal(SIGTTOU, SIG_IGN);
  signal(SIGINT, sig_int);
  signal(SIGTSTP, sig_tstp);

  while (1) {
    if (!job_list.fg) {
      check_jobs(&job_list);

      if (!next_cmd) {
        setjmp(jmpbuffer);
        if (get_cmd(input, command))
          break;
        next_cmd = command;
      }

      if (!parse_cmd(&next_cmd, &new_job, &in_bg) && new_job.num_progs) {
        run_command(new_job, &job_list, in_bg);
      }
    }
    else {
      i = 0;
      while (!job_list.fg->progs[i].pid || job_list.fg->progs[i].is_stopped)
        i++;

      waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED);

      if (WIFEXITED(status) || WIFSIGNALED(status)) {
        job_list.fg->running_progs--;
        job_list.fg->progs[i].pid = 0;

        if (!job_list.fg->running_progs) {
          remove_job(&job_list, job_list.fg);
          job_list.fg = NULL;

          if (tcsetpgrp(STDIN_FILENO, getpid()))
            perror("tcsetpgrp");
        }
      }
      else {
        job_list.fg->stopped_progs++;
        job_list.fg->progs[i].is_stopped = 1;

        if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
          printf("\n" JOB_STATUS_FORMAT, job_list.fg->id,
                 "Stopped", job_list.fg->text);
          job_list.fg = NULL;
        }
      }

      if (!job_list.fg) {
        if (tcsetpgrp(STDIN_FILENO, getpid()))
          perror("tcsetpgrp");
      }
    }
  }
  return 0;
}

static void sig_int(int signo)
{
  if (job_list.fg) {
    kill(-job_list.fg->pgrp, SIGINT);
    return;
  }
  sigrelse(SIGINT); /* do not handle this signal */
  printf("\n");
  longjmp(jmpbuffer, 0);
}

static void sig_tstp(int signo)
{
  sigrelse(SIGTSTP);
  if (job_list.fg) {
    kill(-job_list.fg->pgrp, SIGTSTP);
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -