I have an assignment to write a program that can be used in the bash shell that mimics certain default Unix commands, and we are supposed to build them from scratch. One of these commands is the PS1 command, which is supposed to change the $ prompt to whatever argument the command is given. I have implemented this in the code below, and it works almost perfectly.
Prior to using the PS1 command, the prompt works correctly, it prints the $ and does not indent, rather it lets the user continue typing on the same line. However, after using the command, whenever a prompt is supposed to come up, the program will print the prompt, and then go to a new line. I need it to print the PS1 char* without going to a newline.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char *argv[]) {
int exit = 0;
char* PS1 = "$";
while(exit == 0){
char* token;
char* string;
char input[500];
printf("%s", PS1);
fgets (input, 500, stdin);
token = strtok(input, " ");
if(strncmp(token, "exit", 4) == 0){
exit = 1;
break;
}
else if(strncmp(token, "echo", 4) == 0){
token = strtok (NULL, " ");
while (token != NULL){
printf ("%s", token);
printf("%s", " ");
token = strtok (NULL, " ");
}
}
else if(strcmp(token, "PS1") == 0){
token = strtok (NULL, " ");
char temp[300];
strcpy(temp, &input[4]);
PS1 = temp; }
}
}
fgets
retains the newline character at the end, so that gets printed. You could get rid of that after reading the line:
fgets (input, sizeof(input), stdin);
strtok(input, "\n");
Your code has other issues:
... else if (strcmp(token, "PS1") == 0) {
token = strtok (NULL, " ");
char temp[300];
strcpy(temp, &input[4]);
PS1 = temp;
}
The character array temp
is local to the block in curly braces and will be invalid after the closing }
. That means that PS1
is a handle to invalid memory. That is undefined bevaiour. It may not be visible right now, but it will bite you later, when you add more commands.
It might be better to make PS1
an array if chars that is visible throughout main
and copy to that. (The array can be initialised to hold "$"
at the beginning.)
You should also avoid the explicit index at &input[4]
. Let the tokenisation with strtok
handle this. After all, there might be additional white space and " PS1 Command: "
is valid input.