Почему индекс не меняется после возврата к родителю после выполнения дочернего процесса

#c #shell #operating-system #fork

Вопрос:

Я пытаюсь реализовать простую оболочку с историей, которая принимает пакетные файлы процесса в качестве входных данных и выполняет их.

Мой файл заголовка head.h выглядит так:

 #include lt;stdlib.hgt; #include lt;stdio.hgt; #include lt;time.hgt; #include lt;unistd.hgt; #include lt;string.hgt;  #include lt;sys/wait.hgt;  typedef struct Process{  int index;  char **args; } Proc_t;  typedef struct historyNode{  Proc_t Process;  struct historyNode *next;  struct historyNode * prev; } his_t;   //Function Prototypes his_t * createNode(his_t *head, Proc_t *Process); char** ParseString(char *buffer); void execProcess(his_t *head, Proc_t *Process); void HistoryBrief(his_t *head); void HistoryFull(his_t *head); void printProcess(Proc_t Process); void printProcessCmd(Proc_t Process); int isNumber(char *arg); Proc_t *get_Process(his_t *head, int index);  Proc_t *existsInHistory(his_t *head, char **args);  

Вот main.c :

 #include "head.h"  his_t * head = NULL;  int main(int argc, char ** argv) {  int index = 1;    for(int i = 1 ; ilt;argc;i  )  {  char buffer[1000]; // to store the command read from file  FILE *f = fopen(argv[i],"r");  while(fgets(buffer,sizeof(buffer), f) != NULL)  {  char** currProcessArgs = ParseString(buffer);  Proc_t *currProcess = (Proc_t *)malloc(sizeof(Proc_t));  currProcess-gt;index = index;  //printf("index of currProcess: %dn",currProcess-gt;index);   currProcess-gt;args = currProcessArgs;  //printProcess(*currProcess);    if(head == NULL)   {   head = createNode(head, currProcess);  //printf("Process name:%s, head address:%pn", head, head-gt;Process.args[0]);    }  else  {  createNode(head, currProcess);  //printf("Process name:%s, head address:%pn", head, head-gt;Process.args[0]);  }  printf("n%d index in loopn", index);  index  ;  execProcess(head,currProcess);  //index  ;  }    // HistoryBrief(head);  //HistoryFull(head);  fclose(f);  }  //Ignore the while part for now  while(1)  {  char inputBuffer[1000];  puts("Please enter a command!: ");  scanf("%[^n]%*c", inputBuffer);  //fflush(stdin);  printf("inputBuffer: %sn",inputBuffer);  char **userCmdArgs = ParseString(inputBuffer);  if(strcmp(userCmdArgs[0],"EXEC")==0)  {   if(isNumber(userCmdArgs[1])==0)  {   Proc_t *userCmd = (Proc_t *)malloc(sizeof(Proc_t));  userCmd-gt;index=index;  userCmd-gt;args = userCmdArgs 1;  userCmd = existsInHistory(head, userCmd-gt;args);  if(userCmd!=NULL)  {  puts("This Command Already exists in History!!");   // execProcess(userCmd);  }  else   {  puts("This Command doesn't exist in history. Adding it to the history");  createNode(head,userCmd);  //execProcess(userCmd);  }  }  else  {  Proc_t *userProcessWithIndex = get_Process(head, atoi(userCmdArgs[1]));  if(userProcessWithIndex==NULL)  {   puts("Command with the given index doesn't exist!!n");  }  else  execProcess(head, userProcessWithIndex);  }  }  else if(strcmp(userCmdArgs[0], "HISTORY")==0)  {   if(strcmp(userCmdArgs[1],"BRIEF")==0)  {   printProcess(head-gt;Process);   HistoryBrief(head);  }  else  {   HistoryFull(head);   }  }  else if(strcmp(userCmdArgs[0],"STOP")==0)  {  puts("Exiting Normally, Bye!!n");  break;  }  }  return 0;   }  

here is history.c

 #include "head.h"  his_t *createNode(his_t *head, Proc_t *Process) {  his_t * new_node = (his_t *) malloc(sizeof(his_t));   new_node-gt;Process = *Process;    new_node-gt;next = NULL;  new_node-gt;prev = NULL;  if(head == NULL)  {  head = new_node;  return head;  }   else   {  his_t * temp = head;  while(temp-gt;next != NULL)  {  temp=temp-gt;next;  }  temp-gt;next=new_node;  new_node-gt;prev=temp;  return new_node;  } } Proc_t *existsInHistory(his_t *head, char **args) {  his_t *temp = head;  int i = 0;  int exists = 1;  while(temp!=NULL)  {  while(args[i]!=NULL amp;amp; temp-gt;Process.args[i]!=NULL)  {  if(args[i]==temp-gt;Process.args[i])  exists=1;  else  {  exists = 0;  break;  }   }  if(exists)  {  Proc_t *tempProc = (Proc_t *)malloc(sizeof(Proc_t));  tempProc = amp;(temp-gt;Process);  return tempProc;  }  temp = temp-gt;next;  return NULL;  } } Proc_t *get_Process(his_t *head, int index) {  his_t * temp = head;  while(temp!=NULL)  {   if(temp-gt;Process.index == index)  break;  temp=temp-gt;next;  }  if(temp!=NULL)  {   Proc_t *procTemp = (Proc_t *)malloc(sizeof(Proc_t));  procTemp = amp;(temp-gt;Process);  return procTemp;  }  else  return NULL; } void HistoryBrief(his_t *head) {  his_t * temp = head;   while(temp-gt;next!=NULL)  {  printf("Address of head: %pn", temp);  if(temp-gt;prev!=NULL)   printProcessCmd(temp-gt;prev-gt;Process);  printProcessCmd(temp-gt;Process);  temp=temp-gt;next;  } }  void HistoryFull(his_t *head) {  his_t *temp = head;  while(temp-gt;next!=NULL)  {  printProcess(temp-gt;Process);  temp = temp -gt; next;  } }  }  

Here is process.c

 #include "head.h"  int isNumber(char *arg) {  int i = 0;  while(arg[i]!='')  {  if(isdigit(arg[i])==0)  return 0;  i  ;  }  return 1; } char** ParseString(char *buffer) {  int buff_size = strlen(buffer);  if(buffer[buff_size-1]=='n')  buffer[buff_size-1]='';   char **args =(char *)malloc(30*sizeof(char *));// array for storing arguments  int i = 0;  char *arg = strtok(buffer," ");  while(arg !='')  {  args[i] = arg;  arg = strtok(NULL," ");  i  ;  }  args[i] = '';  puts("n");  int k =0;  while(args[k]!=NULL)  {   printf("%s ",args[k]);  k  ;   }     return args;   } void printProcess(Proc_t Process) {  printf("%d.",Process.index);  puts("args: ");  int i = 0;  while(Process.args[i]!=NULL)  {  printf("%s ",Process.args[i]);  i  ;  }  puts("n"); }  void printProcessCmd(Proc_t Process) {  printf("%d.%sn",Process.index,Process.args[0]); }  void execProcess(his_t *head,Proc_t *Process) {  int pid = fork();  if(pid==0)  {   printf("Currently Executing: index:%d||command:%snn",Process-gt;index, Process-gt;args[0]);  execvp(Process-gt;args[0],Process-gt;args);   }  else if(pid)  {   wait(NULL);  (head-gt;Process.index)  ;  printf("index of head afgter returning to parent process: %dn",head-gt;Process.index);   printf("%s, cmd of head process after returning to parentn",head-gt;Process.args[0]);  }  else  return 0;  }  

Таким образом, в основном моя программа будет принимать входные данные в виде текстовых файлов, содержащих команды Linux. Каждая команда записывается в отдельной строке.

Пример файла —

 ls -al  echo Hello World touch newfile.c ps   

Я создал двусвязный список для хранения истории команд. Когда я вызываю HistoryBrief() его, он печатает 4 ps вместо печати каждой команды. Кроме того, после вызова fork индекс меняется внутри родительского, но не дочернего элемента. Это почему??

Комментарии:

1. Вы продолжаете повторно использовать один и тот же массив для значений, на которые указывают массивы аргументов, которые вы храните.

2. @Шон, не могли бы вы уточнить, я не мог понять.

3. ‘if(args[i]==temp-gt;Process.args[i])’ — сравнение указателей вместо строк (та же проблема, что и выше, на самом деле).

4. @MartinJames Спасибо, что указали на ошибку, я буду использовать strcmp() вместо==, но дело в том, что я все еще не могу понять, где я повторно использую массивы аргументов. Не могли бы вы, пожалуйста, помочь?

5. Относительно: Proc_t *procTemp = (Proc_t *)malloc(sizeof(Proc_t)); procTemp = amp;(temp-gt;Process); Это объявление указателя, установка этого указателя на некоторую выделенную память, а затем наложение этого указателя (приводит к утечке памяти).