Простая оболочка с двумя параметрами (проблема параллелизма) - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь выполнить назначение, состоящее в том, чтобы эмулировать простую программу оболочки, которая получает только 2 параметра и выполняется последовательно или одновременно, в зависимости от ввода пользователя.

Хотя мне нелегко реализовать параллельную версию, потому что, когда я набираю ввод sleep 1 & (амперсан указывает параллелизм), родитель не ожидает ожидаемого потомка и продолжает итерацию,но когда он переходит ко второй итерации цикла while, функция readSplit вместо того, чтобы останавливать программу на ожидание пользовательского ввода, принимает пустой buff в качестве ввода.

Тем не менее, если я напишу sleep 1, ls или любую команду, которая требует только 2 параметра, она прекрасно работает.

Некоторые пояснения:

- readSplit простополучает ввод пользователя.Он работает как функция read (), но останавливает чтение, когда достигает символа разделения.(Я знаю, что есть лучшая функция, которая делает то же самое, но этот код был предоставлен курсом.)

int readSplit( int fin, char* buff, char* s, int maxlen ) {
   int i = 0;
   int oneread = 1;
   char c = *s+1;
   while(c != *s && c != '\n' && oneread == 1 && i < maxlen) {
       oneread = read( fin, &c, 1);
       if(c != *s && c != '\n' && oneread == 1) {
              buff[i] = c;
           i++;
       }
   }
   if(c=='\n') *s = c;
   if(i < maxlen) buff[i] = '\0';
   return i;
}

- startTimer и endTimer можно игнорировать, они просто измеряют выполнениевремя.

ГЛАВНЫЙ код:

#include <sys/types.h> /* pid_t */
#include <sys/wait.h>  /* waitpid */
#include <sys/types.h> /* pid_t */
#include <sys/wait.h>  /* waitpid */
#include <stdio.h>     /* printf, perror */
#include <stdlib.h>    /* exit */
#include <unistd.h>    /* _exit, fork */
#include <string.h>
#include "myutils.h"

int main(void) {
   int ret;
   int status;
   char buff[80];
   char buff_aux[80];
   char ampersan[1];
   long timer;
   int continueloop = 1;

while (continueloop == 1) {

    char s = ' '; //Separator
    /*Cleaning the information in each loop*/


    memset(buff, 0, sizeof (buff));
    memset(buff_aux, 0, sizeof (buff_aux));
    memset(ampersan, 0, sizeof (ampersan));
    write(1, ">", 1);
    /*Reading user input*/

        readSplit(0, buff, &s, 80);
        printf("%s its my buff string\n", buff);

    if (strcmp(buff, "exit") == 0)break; //If the user wants to exit


    /*If the user has one more parameter we read it and put it in the buff_aux*/
    if (s == ' ' ) {
        if (readSplit(0, buff_aux, &s, 80) == 0)
            exit(1);
    }
    printf("%s is my buff_aux string\n", buff_aux);

    if (s == ' ' ) {
        readSplit(0, ampersan, &s, 1);
        printf("%c is the letter read by ampersan\n", ampersan[0]);

    }
    startTimer();
    /*Creating child*/
    ret = fork();
    printf("ret %d\n", ret);
    printf("im checking if it is a child\n");
    if (ret == 0) {
        printf("im a child\n");
        if (buff[0] == 0) {
            printf("Son: shell program does not exist\n");
            exit(255);
        } else if (buff_aux[0] == 0 || buff_aux[0] == '&') {
            printf("Im about to execute 1\n");
            execlp(buff, buff, NULL);
            exit(2);
        } else {
            printf("Im about to execute 2\n");
            execlp(buff, buff, buff_aux, NULL);
            exit(2);

        }
    }
    if (ampersan[0] != '&') {
        wait(NULL);
        timer = endTimer();
        printf("The process finished and lasted ... %li miliseconds\n", timer);
    }


}
/*waiting to children to finish*/
while (wait(NULL) > 0);
timer=endTimer();

printf("Father waited for son\n");
if (WIFEXITED(status)) {
    status = WEXITSTATUS(status);
    if (status > 0) printf("Father: shell program does not exist\n");
}

return 0;
}

Заранее спасибо!

1 Ответ

0 голосов
/ 02 февраля 2019

если вы введете sleep 1 &, входной буфер будет sleep 1 &\n

первым, в то время как:

  1. вызов readSplit(0, buff, &s, 80);, buff равен sleep, входной буфер оставлен1 &\n
  2. вызов readSplit(0, buff_aux, &s, 80), buffer_aux равен 1, оставлен входной буфер &\n
  3. вызов readSplit(0, ampersan, &s, 1); ampersan равен &, оставлен входной буфер \n

следующее время:

оставлен входной буфер \n

  1. вызов readSplit(0, buff, &s, 80);, buff пуст, c равно \n, в дочернем процессе вызовет:
if (buff[0] == 0) {
   printf("Son: shell program does not exist\n");
   exit(255);
}

вы должны обрабатывать \n в каждом while

...