Я собирался написать оболочку на языке C. Вот исходный код ниже:
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <stdlib.h>
int
getcmd(char *buf, int nbuf)
{
memset(buf, 0, nbuf);
fgets(buf, nbuf, stdin);
printf("pid: %d, ppid: %d\n", getpid(), getppid());
printf("buf: %s", buf);
if(buf[0] == 0) {// EOF
printf("end of getcmd\n");
return -1;
}
return 0;
}
int
main(void)
{
static char buf[100];
int fd, r, ret;
// Read and run input commands.
while((ret = getcmd(buf, sizeof(buf))) >= 0){
if(fork() == 0)
exit(0);
wait(&r);
}
exit(0);
}
Когда я запускаю скомпилированный исполняемый файл с перенаправлением стандартного ввода в файл с именем t.sh, содержимое которого равно «1111\n2222\n», например ./myshell ‹ t.sh, вывод:
pid: 2952, ppid: 2374
buf: 1111
pid: 2952, ppid: 2374
buf: 2222
pid: 2952, ppid: 2374
buf: 2222
pid: 2952, ppid: 2374
buf: end of getcmd
Очевидно, функция getcmd() получает 3 строки(1111, 2222, 2222), тогда как в t.sh всего 2 строки. И эта ситуация становится еще хуже, когда в t.sh помещается больше строк.
И главный процесс — это единственный процесс, выполняющий getcmd, о чем мы можем судить по выводу pid.
Кстати, я обнаружил, что если удалить строку кода wait(&r), вывод может стать нормальным.
int fd
в коде:)
- person David C. Rankin   schedule 13.08.2017fgets()
в Linux; Я компилировал с помощью-Werror
, и мне сказалиignoring return value of ‘fgets’, declared with attribute warn_unused_result
. (Заголовки macOS не используют эту функцию.) Мне также приходилось иметь дело с различными другими предупреждениями (неиспользуемые переменные, переменные установлены, но не используются и т. д.). - person Jonathan Leffler   schedule 13.08.2017