#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<stdlib.h>
#include<string.h>
#define MAX_LINE 80 /* Maximum length of command*/
struct List
{
char *commandName;
struct List *next;
struct List *prev;
};
struct List *head=NULL;
struct List *curr=NULL;
void accessList(int);
void addToList(char *);
struct List *createNode(char *);
I want to add history feature to my shell. For that I am creating a linked list using structs. The command which is entered on my shell gets divided into tokens and the first token should get stored in linked list (doubly).Below is the main() function.
int main(int argc, char *argv[])
{
char *args[MAX_LINE/2+1]; /* Command Line Argument*/
int should_run=1, status, i, num;
pid_t pid;
char str[41], teststr[41];
const char delimiter[2]=" ";
char *token;
while(should_run)
{
i=0;
printf("osh>");
fflush(stdout);
fgets(str, sizeof str, stdin); //reads user input
str[strlen(str)-1]='\0';
token=strtok(str, " "); //breaks them into tokens using the following while loop
while(token)
{
args[i]=strdup(token);
printf("args[%d]=%s\n", i, args[i]);
i++;
token=strtok(NULL, " ");
}
if(pid<0) // error in creating child process
{
printf("\tError in creating child process\n");
}
else if(pid==0) //child process will execute this block
{
printf("\tChild running it's block\n");
addToList(args[0]); //store args[0] in Linked List
execvp(args[0], args); //args[0] contains name of command
exit(1);
}
else //parent process will execute this block
{
pid=wait(&status);
printf("\tNow Parent resumes\n");
if(!strcmp(args[0], "exit"))
{
should_run=0;
}
}
}
printf("\tNo. of latest commands you want to view from history=\n");
scanf("%d", &num);
accessList(num); //function to traverse list
return 0;
}
void accessList(int number)
{
int i;
struct List *temp=(struct List*)malloc(sizeof(struct List));
temp=NULL;
temp=curr;
for(i=number;i>0;i--)
{
printf("%d %s", &i, temp->commandName);
temp=temp->prev;
}
}
void addToList(char *cmd)
{
struct List *ptrNode=(struct List*)malloc(sizeof(struct List));
ptrNode=NULL;
ptrNode=createNode(cmd);
if(head->next==NULL)
{
head->next=ptrNode;
ptrNode->prev=head;
curr=ptrNode;
}
else
{
curr->next=ptrNode;
ptrNode->prev=curr;
curr=curr->next;
}
}
struct List *createNode(char *cmd)
{
struct List *node=(struct List*)malloc(sizeof(struct List));
node->commandName=cmd;
node->next=NULL;
node->prev=NULL;
return node;
}
When I run this program, my shell works fine but when ask user to input number of latest commands they want to view from history, it gives me segmentation fault.