148 / 118 / 37
Регистрация: 27.10.2011
Сообщений: 690
1

Пустые строки в файле с использованием pipe, fork, exec, dup

20.04.2016, 14:45. Показов 1455. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет, для написания сабжа задумал использовать такую команду :
Bash
1
grep -e '^$' argv[1] | wc --lines
По факту, мне нужно ручками написать перенаправление, которое создаёт знак '|'
Накидал такой код:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <unistd.h>
 
//"grep -e '^$' argv[1] | wc --lines"
 
int main(int argc, char *argv[])
{
    int commandsPipe[2];
    
    if (argc < 2)
    {
        fprintf(stderr, "Error : Not enough parameters\n");
        return 1;
    }
    if (pipe(commandsPipe) != 0)
    {
        perror("pipe call");
        return 2;
    }
    
    switch (fork())
    {
        case -1:
        {
            perror("fork call");
            close(commandsPipe[0]);
            close(commandsPipe[1]);
            return 3;
        }
        case 0:
        {
            close(commandsPipe[1]);
           
            if (dup2(commandsPipe[0], fileno(stdin)) != -1)
            { 
                execlp("wc", "wc", "--lines", NULL);
            }
            
            close(commandsPipe[0]);
            perror(NULL);
            
            return 4;
        }
        default:
        {
            close(commandsPipe[0]);
 
            if (dup2(commandsPipe[1], fileno(stdout)) != -1)
            {    
                execlp("grep", "grep", "-e", "'^$'", argv[1], NULL);       
            }
            
            close(commandsPipe[1]);
            perror(NULL);
            
            return 5;
        }
    }
    
    return 6;
}
Для абсолютно любого файла (например, пустой, или состоящий только из пустых строк, или состоящий из нескольких пустых строк и нескольких непустых), задаваемого в argv[1], программа выводит 0. В чём ошибка?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.04.2016, 14:45
Ответы с готовыми решениями:

Сортировка строки, используя fork() и pipe
Дали задание используя системный вызов fork() и pipe. Решить какую-то задачу. Я решил сделать...

Pipe, fork, shared memory
Доброго времени суток. Помогите пожалуйста написать программу: Процесс читает с клавиатуры и пишет...

Быстрая сортировка fork и pipe
помогите переделать данный код в быструю сортировку #include &lt;stdio.h&gt; #include &lt;unistd.h&gt;...

Pipe и exec
Задание: модифицировать программу для связи между собой двух родственных процессов, исполняющих...

3
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
21.04.2016, 12:11 2
Похоже, вы грепу шаблон не тот дали.
Заменил строки, начиная с вашей 21 до конца мейна.
C
1
2
3
4
5
6
7
8
    int pn= fork() > 0;
    close(commandsPipe[(pn+1)%2]);
 
    if (dup2(commandsPipe[pn], pn) != -1)
    {
      if (pn)  execlp("grep", "grep", "-e", "^$", argv[1], NULL);    
      else execlp("wc", "wc", "--lines", NULL);
    }
Количество нулевых строк выводит, вроде бы, правильно.
Прим. По уму нужно делать два форка, а родителю ждать завершения обоих.
1
148 / 118 / 37
Регистрация: 27.10.2011
Сообщений: 690
21.04.2016, 14:26  [ТС] 3
gng, спасибо большое, дело действительно оказалось в шаблоне grep'а - убрал одинарные кавычки и всё заработало

Цитата Сообщение от gng Посмотреть сообщение
Прим. По уму нужно делать два форка, а родителю ждать завершения обоих.
Можете пояснить, какие проблемы сулит один форк? Я понимаю, что процессы независимо друг от друга исполняются и делают это в неопределённом порядке, но по коду не могу найти "опасных" моментов
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
21.04.2016, 17:59 4
Цитата Сообщение от Nikitko_Cent Посмотреть сообщение
Можете пояснить, какие проблемы сулит один форк?
Самое банальное - родитель может завершиться раньше потомка, постав ему сигнал принудительного завершения.
Второе, потомок завершившись на какое-то време может стать зомби - процессом, завершения которого никто не ждал.

В нулевем приближении с двумя форками получится что-то такое (проверка кодов возвращиеня опущена для краткоси).
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
 
int main(int argc, char *argv[])
{   
    int pd[2];
    pipe(pd);
 
    int pn;
    for (pn= 0; pn<2; pn++) if (!fork()) break;
    if (pn < 2) {
        close(pd[(pn+1)%2]);
        dup2(pd[pn], pn);
        if (pn)  execlp("grep", "grep", "-e", "^$", argv[1], 0);   
        else execlp("wc", "wc", "--lines", 0);
    }
    for (pn= 1; pn>=0; pn--) {
      close(pd[pn]);
      wait(0);
    }
}
0
21.04.2016, 17:59
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.04.2016, 17:59
Помогаю со студенческими работами здесь

Особенности использования fork и exec
Подскажите пожалуйста, если мы используем в программе вызов fork, а потом exec, или просто сразу...

fork / exec - как запустить внешнюю программу?
Здравствуйте. Я вот скомпилил программу, написанную на Си, допустим test.exe Как ее запустить из...

Работа с процесса. Fork и exec. Не могу понять программу
Всем доброго времени суток. В общем, у меня есть программа, которая создаёт процессы с помощью fork...

Распараллелить задачу, ипользуя при системный вызов fork (), и трубу pipe
Дали задание распараллелить какую то задачу, ипользуя при этом системный вызов fork(), и трубу...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru