예제 #1
0
파일: smallsh.c 프로젝트: cboseak/cs344
/*! Runloop, the central part of the shell. Read a line, parse it, execute it,
  repeat until EOF.
 */
void runloop() {
        char *line = NULL;
        size_t linecap = 0;
        ssize_t line_len;
        printf(":");
        while ((line_len = getline(&line, &linecap, stdin)) > 0) {
                parse_and_run(line, (unsigned int)line_len);
                printf(":");
                fflush(stdout);
        }
        destroy_child_list();
}
예제 #2
0
int main(int argc, char *argv[]) {
  (void)argc;(void)argv;
  /* See init_asm_interpreter in opcodes.c */
  init_asm_interpreter();
  /* In order:

     the following variables represent each section of inputted line passed to the interpreter

     (An example line)
     1000 0000 1111 1111
     maps each section (space separated blocks) to the following pattern
     func car  cadr caddr
     func represents the function to call
     car,cadr and caddr represent the arguments of that function, they are called such due to the naming scheme Common Lisp uses to denot the first, second, and third element of a list respectively. */
  char *func = NULL, *car = NULL, *cadr = NULL, *caddr = NULL;
#if __gnu_linux__
  /* This section of code (until the #elif ...) setups up the ^C handler on linux. */
  struct sigaction action;
  memset(&action, 0, sizeof(struct sigaction));
  action.sa_handler = term;
  sigaction(SIGINT, &action, NULL);
  while (!done) {
#elif __WIN32 || __WIN64
  /* This section of code sets up the ^C handler on Windows  */
  SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
  while (!done) {
#else
  while (1) {
#endif
    /* Allocate space for each of the variables.
       Calloc is used instead of malloc as calloc has the advantage of setting each portion of the allocated memory to 0, which is super important for strings who might have junk at the end if they aren't filled all the way.
     */
    func = calloc(4 + 1, sizeof(char));
    car = calloc(4 + 1, sizeof(char));
    cadr = calloc(4 + 1, sizeof(char));
    caddr = calloc(4 + 1, sizeof(char));
    /* Here is the actual prompt printed to the screen */
    printf("> ");
    /* each variable is parsed from scanf (see the scanf documentation for details on the formatting syntax) */
    int err = scanf("%5s %5s %5s %5s", func, car, cadr, caddr);
    /* if an error occurred while parsing OR the number of read sections was less than the required amount (4) */
    if (ferror(stdin) || err < 4) {
      fprintf(stderr, "\nASM: Error: Invalid input received\n");
    } else {
      /* see parse_and_run for more details */
      reg *res = parse_and_run(func, car, cadr, caddr);
#if __gnu_linux__ || __WIN32 || __WIN64
      /* For operating systems that support it, check user didn't press ^C and print the debug output (the feedback to the user) if they haven't */
      if (!done)
        puts(res->debug);
#else
      puts(res->debug);
#endif
      /* see maybe_print_error */
      maybe_print_error(res);
      res->err = 0; // reset the error code
      int c = 0;
      while ((c = fgetc(stdin)) != '\n' && c != EOF); /* Flush stdin */
    }
    /* Free all the various sections of the code (remembering we allocated at the start) */
    free(func); free(car); free(cadr); free(caddr);
    /* Set them to NULL so we can't accidentally attempt to free the same memory twice (this is called a double free error) */
    func = NULL; car = NULL; cadr = NULL; caddr = NULL;
  }
  /* Free each section */
  free(func); free(car); free(cadr); free(caddr);
  printf("\nExiting...\n");
  /* see free_asm_interpreter */
  free_asm_interpreter();
  return 0;
}