Я пытаюсь выполнить назначение, состоящее в том, чтобы эмулировать простую программу оболочки, которая получает только 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;
}
Заранее спасибо!