Постановка задачи
Составить программу, моделирующую работу Shell-интерпретатора при обработке следующей командной строки: «who | wc –l & ps | wc –l». При реализации программы путем выдачи сообщений информировать обо всех этапах ее работы (создан процесс, выполнение команды закончено и т.д.).
Алгоритм решения
Задача решается путем создания нескольких процессов, алгоритмы работы которых выглядят следующим образом:
Процесс-родитель:
1. Создать два процесса-потомка.
2. Дождаться их завершения.
Процесс-потомок № 1:
1. Создать программный канал.
2. Породить процесс-предок, выполнив из него команду «who», предварительно перенаправив ее вывод в программный канал.
3. Дождаться завершения работы процесса-потомка.
4. Выполнить команду «wc –l», предварительно перенаправив ее ввод на программный канал.
Процесс-потомок № 2:
1. Создать программный канал.
2. Породить процесс-предок, выполнив из него команду «ps», предварительно перенаправив ее вывод в программный канал.
3. Дождаться завершения работы процесса-потомка.
4. Выполнить команду «wc –l», предварительно перенаправив ее ввод на программный канал.
Описание программного средства
Программа написана на языке C. Для получения исполнимого файла исходный текст программы следует скомпилировать каким-либо компилятором языка C. Исполнимый файл может работать под любой UNIX-совместимой ОС, поддерживающей соответствующий формат исполнимого файла.
Запуск программы осуществляется командой laba6 без параметров. При передаче программе каких-либо параметров они будут проигнорированы. Во время своей работы программа выводит на экран сообщения, поясняющие этапы ее работы (процесс создан, процесс завершен, создан программный канал и т.д.).
Исходныйтекст
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
void error(char *msg)
{
printf("%s\n", msg);
exit(1);
}
int main()
{
int fd[2];
int file;
pid_t pid[2], ppid, childpid;
int status;
int i;
// creating 2 process from parent
ppid = getpid();
for(i = 0; i < 2; i++)
pid[i] = -1;
for(i = 0; i < 2; i++)
if(getpid() == ppid)
{
printf("Creating process %d\n", i+1);
if((pid[i] = fork()) == -1)
{
printf("Error creating process %d\n", i+1);
exit(1);
}
//printf("Process %d created\n", i+1);
}
if(pid[0] == 0)
{
// first process
printf("Creating a pipe from process 1\n");
if(pipe(fd) == -1)
{
printf("Error creating a pipe from process 1\n");
exit(1);
}
printf("Creating child process from process 1\n");
childpid = fork();
if(childpid == -1)
error("Error creating child from process 1\n");
if(childpid == 0)
{
printf("Executing \"who\" from child of process 1\n");
close(1);
fcntl(fd[1], F_DUPFD, 1);
if(execlp("who", "", 0) != 0)
{
printf("Error executing \"who\" from child of process 1\n");
exit(1);
}
}
else
{
wait(&status);
printf("Executing \"who\" from child of process 1 complete\n");
printf("Executing \"wc -l\" from from process 1\n");
close(fd[1]);
close(0);
fcntl(fd[0], F_DUPFD, 0);
if(execlp("wc", "wc", "-l", 0) != 0)
{
printf("Error starting \"wc -l\" from process 1\n");
exit(1);
}
}
}
if(pid[1] == 0)
{
// second process
printf("Creating a pipe from process 2\n");
if(pipe(fd) == -1)
{
printf("Error creating a pipe from process 2\n");
exit(1);
}
printf("Creating child process from process 2\n");
childpid = fork();
if(childpid == -1)
error("Error creating child from process 2\n");
if(childpid == 0)
{
printf("Executing \"ps\" from child of process 2\n");
close(1);
fcntl(fd[1], F_DUPFD, 1);
if(execlp("ps", "", 0) != 0)
{
printf("Error executing \"ps\" from child of process 2\n");
exit(1);
}
}
else
{
wait(&status);
printf("Executing \"ps\" from child of process 2 complete\n");
close(fd[1]);
close(0);
fcntl(fd[0], F_DUPFD, 0);
printf("Executing \"wc -l\" from from process 2\n");
if(execlp("wc", "wc", "-l", 0) != 0)
{
printf("Error starting \"wc -l\" from process 2\n");
exit(1);
}
}
}
if(getpid() == ppid)
{
// parent process
for(i = 0; i < 2; i++)
{
wait(&status);
printf("Executing \"wc -l\" from from process %d completed\n", i+1);
printf("Executing process %d completed\n", i+1);
}
}
return 0;
}
Creating process 1
Creating process 2
Creating a pipe from process 1
Creating chile process from process 1
Creating a pipe from process 2
Creating chile process from process 2
Executing "who" from child of process 1
Executing "who" from child of process 1 completed
Executing "wc -l" from process 1
5
Executing "wc -l" from process 1 completed
Executing process 1 completed
Executing "ps" from child of process 2
Executing "ps" from child of process 2 completed
Executing "wc -l" from process 2
Executing "wc -l" from process 2 completed
Executing process 2 completed
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.