Home > Net >  Making a terminal in c
Making a terminal in c

Time:11-04

When I run this c snippet, it outputs something really random every time, and then segfaults... Code:

#include <stdio.h>
#include <stdlib.h>

int parse(void) {
  int i = 0;
  int system(const char *command);
  char line[1024];
  scanf("%[^\n]", line);
  system(line);
  do {
    line[i] = "\0";
    i  ;
  } while (i != 1024);
  parse();
}

int main(void) {
  parse();
  return 0;
}

What I expected was a prompt, and when any shell command is entered (I used pwd for my testing), the output of the command prints and the prompt returns. And this is what actually happened:

Output:

> pwd
/home/runner/c-test
sh: 1: �: not found
sh: 1: : not found
sh: 1: ׀: not found
signal: segmentation fault (core dumped)

CodePudding user response:

  1. Print prompt
  2. Do not use scanf
  3. Use static storage duration buffer
#include <stdio.h>
#include <stdlib.h>


int parse(void) 
{
  static char line[1024];
  while(1)
  {
      printf(">>>");
      if(!fgets(line, 1024, stdin)) return 1;
      system(line);
  }
}

int main(void) {
  parse();
}

enter image description here

CodePudding user response:

The reason for your crash is most likely explained by the following:

scanf("%[^\n]", line);

means keep reading until there is a newline in the input stream. So once it completes the next character in the input stream is a newline.

The next time you do

scanf("%[^\n]", line);

that newline is still the first character, so the scanf will return without waiting for the user to type any input.

Since you are doing recursion this will happen again and again and again.... Then most likely the system crashes due to stack overflow after a while.

Solution: Read that newline from the input stream before calling scanf again.

Besides that you should:

  • Remove int system(const char *command);

  • Put a maximum field width on scanf

  • Check the return value of scanf

  • Change "\0" to '\0' (or delete the whole do-while loop as you don't need it)

  • Use a while(1) { ... } loop instead of recursive calls

  • Related