передача аргументов командной строки дочернему процессу и их подсчет - PullRequest
4 голосов
/ 06 марта 2010

Я хочу, чтобы родительский процесс принимал аргументы функции main () и отправлял символы в них по одному дочернему процессу через канал, начинающийся с argv [1], и продолжал через остальные аргументы (один звоните, чтобы написать для каждого символа).

Я хочу, чтобы дочерний процесс подсчитал символы, отправленные ему родительским процессом, и распечатал количество символов, полученных от родительского процесса. Дочерний процесс никоим образом не должен использовать аргументы main ().

Что я делаю не так? мне нужно использовать exec ()?

неверный вывод:

    ~ $ gc a03
gcc -Wall -g a03.c -o a03
~ $ ./a03 abcd ef ghi

child: counted 12 characters
~ $

вот программа ..

#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[])
{

    int length = 0;
    int i, count;

    int     fdest[2];          // for pipe
    pid_t   pid;              //process IDs
    char    buffer[BUFSIZ];



    if (pipe(fdest) < 0)          /* attempt to create pipe */
        printf("pipe error");

    if ((pid = fork()) < 0)  /* attempt to create child / parent process */

    {
        printf("fork error");
    } 


    /* parent process */
    else if (pid > 0) {      
        close(fdest[0]);

        for(i = 1; i < argc; i++)    /* write to pipe */
        {
            write(fdest[1], argv[i], strlen(argv[1]));
        }

        wait(0);

    } else {   

        /* child Process */
        close(fdest[1]);

        for(i = 0; i < argc; i++)
        {
            length +=( strlen(argv[i])); /* get length of arguments */
        }

        count = read(fdest[0], buffer, length);
        printf("\nchild: counted %d characters\n", count);

    }

    exit(0);

}

Ответы [ 4 ]

3 голосов
/ 06 марта 2010

Вы сказали, что "дочерний процесс не должен каким-либо образом использовать аргументы для main ()". Однако я вижу, что ваш дочерний процесс использует argc. Разве это не побеждает ваше ограничение?

Вы также говорите, что хотите «один вызов написать для каждого символа». Ваша текущая реализация использует один вызов для записи для каждого аргумента, а не для каждого символа. Это была опечатка? Если нет, вы захотите использовать что-то вроде этого:

char nul='\0', endl='\n';
for (a=1; a < argc; ++a) {
    for (c=0; c < strlen(argv[a]); ++c) {
        write(fdest[1], &argv[a][c], 1);
    }
    write(fdest[1], &nul, 1);
}
write(fdest[1], &endl, 1);

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

Дочерний процесс просто должен быть циклом, который читает входящие байты один за другим и увеличивает счетчик, если байт не равен '\0' или '\n'. Когда он читает символ новой строки, он выходит из цикла обработки ввода и сообщает значение счетчика.

1 голос
/ 06 марта 2010

У вас есть ошибка здесь:

write(fdest[1], argv[i], strlen(argv[1]));

Вам лучше взять strlen(argv[i]), или вы говорите write(), чтобы прочитать за пределами argv [i] и вызвать неопределенное поведение.

Обратите внимание, что вы вызываете read () только один раз. К тому времени, когда вы вызываете read (), возможно, только один из argv [] был написан родителем. Или 2. Или любое их количество.

0 голосов
/ 06 марта 2010

Проблема здесь

write(fdest[1], argv[i], strlen(argv[1]));

Обратите внимание, что это значение равно argv[1], оно должно быть argv[i]. Вы на самом деле ссылаетесь на конец argv[2] и argv[3] в этом цикле

Вы эффективно пишете strlen ("abcd") * 3 символа, что составляет 12 символов

0 голосов
/ 06 марта 2010

Здесь:

for(i = 1; i < argc; i++)    /* write to pipe */  
{  
    write(fdest[1], argv[i], strlen(argv[1]));  
}

strlen(argv[1]) должно быть strlen(argv[i])

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...