Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.12.2018, 21:11   #1
lovgager
Новичок
Джуниор
 
Регистрация: 12.12.2018
Сообщений: 1
По умолчанию Реализовать shell-конвейер

Программе в аргументах командной строки передается произвольное (возможно пустое) количество команд для выполнения. Программа должна запустить на выполнение процессы, чтобы они выполнялись в конфигурации, соответствующей команде shell:

cmd1 | cmd2 | ... | cmdN

Родительский процесс должен дождаться завершения всех созданных им процессов и сам завершить выполнение. Если все системные вызовы, исполнявшиеся родителем (например, создание процесса), завершились успешно, родитель завершается с кодом 0. В случае ошибки выполнения системного вызова (например, невозможности создания очередного процесса), родитель уничтожает уже созданные к этому моменту процессы с помощью сигнала SIGKILL и сам завершается с кодом 1 после завершения сыновей.

Команды cmd1, cmd2, ... запускайте на выполнение с помощью execlp.

В родителе одновременно может быть открыто не более 6 файловых дескрипторов.

Создаваемые процессы должны оставаться в группе процессов родителя.

Программа не должна ничего выводить на стандартный поток ошибок.

Например, если скомпилированная программа называется solution, то ее запуск с аргументами

./solution ls cat wc

должен дать такой же результат на стандартном потоке вывода, как выполнение команды shell

ls | cat | wc

Код:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

int fd[2][2];

void
term(pid_t *pids, int n)
{
    close(fd[0][0]);
    close(fd[0][1]);
    close(fd[1][0]);
    close(fd[1][1]);
    for (int i = 1; i <= n; i++) {
        kill(pids[i], SIGKILL);
    }
    exit(1);
}

int
main(int argc, char **argv)
{
    if (argc == 1) {
        return 0;
    }
    if (pipe(fd[0]) == -1) {
        exit(1);
    }
    if (pipe(fd[1]) == -1) {
        exit(1);
    }

    for (int i = 1; i < argc; i++) {
        pids[i] = fork();
        if (pids[i] == -1) {
            term(pids, i - 1);
        }
        if (!pids[i]) {
            close(fd[i & 1][1]);
            close(fd[1 - (i & 1)][0]);
            if (i > 1 && dup2(fd[i & 1][0], 0) == -1) {
                exit(1);
            }
            close(fd[i & 1][0]);
            if (i != argc - 1) {
                if (dup2(fd[1 - (i & 1)][1], 1) == -1) {
                    exit(1);
                }
            }
            close(fd[1 - (i & 1)][1]);
            execlp(argv[i], argv[i], NULL);
            _exit(1);
        }

        close(fd[i & 1][0]);
        close(fd[i & 1][1]);
        wait(&status);
        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
            term(pids, i);
        }

        if (pipe(fd[i & 1]) == -1) {
            term(pids, i);
        }
    }

    return 0;
}
Программа почему-то не проходит по времени. Помогите, пожалуйста, разобраться, что не так
lovgager вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Конвейер микропроцессора Базиля Помощь студентам 11 08.07.2013 23:28
Реализовать smtp-клиента (unix shell) Iad Помощь студентам 0 01.05.2012 10:53
Конвейер рендеринга. Warn Gamedev - cоздание игр: Unity, OpenGL, DirectX 1 16.12.2011 09:51
Ленточный конвейер.... dj-Oleg Помощь студентам 2 03.11.2011 15:57
Shell на C(Конвейер) l1pton17 Общие вопросы C/C++ 0 01.11.2010 22:01