Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Программирование для Linux, Программирование для Linux 
:(
    Опции темы
GGoga
Дата 1.5.2007, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 1.5.2007
Где: Харьков

Репутация: нет
Всего: нет



Здравствуйте, люди разбирающиеся в программировании для Linux. Помогите начинающему программисту разобраться в одной проблемке. Как можно программно реализовать задание, где необходимо вызвать системные команды используя execv, dup2. Примером является команда:
                            
tr -d "[0-9]" < a.txt | sort | uniq > b.txt 
Причем каждый системный вызов должен вызываться отдельно, т.е. execv("tr",{"tr","-d","[0-9]"}), затем execv("sort",{"sort"}) и execv("uniq",{"uniq"}). Но вот только эти три вызова должны работать на один результат, а именно, чтобы программа давала такой же результат, что и такая команда введенная в терминале.
И вообще, возможно ли так сделать??? Просто, я не пойму, как можно выполнить взаимодействие между разными процессами вызванными с execv, если они сами по себе не могут быть синхронизированы...
А с помощью одной команды execv делать нельзя по условию...

Люди, подскажите, кто хоть что-нибудь знает. Заранее ОГРОМНОЕ СПАСИБО smile

PM MAIL ICQ Skype   Вверх
X-3R1
Дата 1.5.2007, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 28.4.2007

Репутация: нет
Всего: 2



С одним exec всё работает, а с несколькими ...хех. Вообщем если найдёшь решение отпишись здесь, мне тоже интересно ;)
PM MAIL   Вверх
MAKCim
Дата 1.5.2007, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



все просто, вот примерный алгоритм
Код

/*
 * @cmds: pointer to array of commands
 * @count: count of elements in `cmds'
 */
static int make_task(const char* cmds[], size_t count) {
    pid_t pids[MAX_PROCESSES_COUNT];
    size_t index;
    char *path;
    int pipe_fd[2] = {-1, -1},
         fd = -1;
    for (index = 0; index < count; ++index) {
        fd = *pipe_fd;
        pipe(pipe_fd); /* no error check */
        pids[index] = fork();
        if (pids[index] == 0) {
            if (fd < 0) {
                if ((path = parse(cmds[index], GET_IN_FILE)) != NULL)
                    fd = open(path, O_RDONLY); /* no error check */
                else goto output;
            }
            dup2(fd, STDIN_FILENO);
output:
            fd = -1;
            if (index < count - 1)
                fd = *(pipe_fd + 1);
            else if ((path = parse(cmds[index], GET_OUT_FILE)) != NULL)
                fd = open(path, O_WRONLY | O_CREAT | O_EXCL); /* no error check */
            dup2(fd, STDOUT_FILENO);
            pause(); /* wait for SIGUSR1 */
            /* make 'exec' for command with index `index' */
        } else if (pids[index] < 0) {
            /* error by creating process */
        }
        if (fd >= 0) close(fd);
        close(*(pipe_fd + 1));
    }
    while (count--)
        kill(pids[count], SIGUSR1); /* send SIGUSR1 to all created processes */
    return 0;
}


Это сообщение отредактировал(а) MAKCim - 1.5.2007, 15:44


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
GGoga
Дата 2.5.2007, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 1.5.2007
Где: Харьков

Репутация: нет
Всего: нет



Спасибо за примерчик!!! Ща буду разбираться smile
PM MAIL ICQ Skype   Вверх
GGoga
Дата 6.5.2007, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 1.5.2007
Где: Харьков

Репутация: нет
Всего: нет



Цитата(MAKCim @ 1.5.2007,  15:43)
все просто, вот примерный алгоритм
Код

/*
 * @cmds: pointer to array of commands
 * @count: count of elements in `cmds'
 */
static int make_task(const char* cmds[], size_t count) {
    pid_t pids[MAX_PROCESSES_COUNT];
    size_t index;
    char *path;
    int pipe_fd[2] = {-1, -1},
         fd = -1;
    for (index = 0; index < count; ++index) {
        fd = *pipe_fd;
        pipe(pipe_fd); /* no error check */
        pids[index] = fork();
        if (pids[index] == 0) {
            if (fd < 0) {
                if ((path = parse(cmds[index], GET_IN_FILE)) != NULL)
                    fd = open(path, O_RDONLY); /* no error check */
                else goto output;
            }
            dup2(fd, STDIN_FILENO);
output:
            fd = -1;
            if (index < count - 1)
                fd = *(pipe_fd + 1);
            else if ((path = parse(cmds[index], GET_OUT_FILE)) != NULL)
                fd = open(path, O_WRONLY | O_CREAT | O_EXCL); /* no error check */
            dup2(fd, STDOUT_FILENO);
            pause(); /* wait for SIGUSR1 */
            /* make 'exec' for command with index `index' */
        } else if (pids[index] < 0) {
            /* error by creating process */
        }
        if (fd >= 0) close(fd);
        close(*(pipe_fd + 1));
    }
    while (count--)
        kill(pids[count], SIGUSR1); /* send SIGUSR1 to all created processes */
    return 0;
}

Здравствуйте, MAKCim! Спасибо еще раз за Вашу помощь! Так как я начинающий программист и мне еще далеко не все понятно в программировании, у меня к Вам есть пару вопросов. Насколько я понимаю, в Вашем примере MAX_PROCESSES_COUNT, GET_IN_FILE и GET_OUT_FILE - это макроопределения или константы, скажите пожалуйста, чему они должны быть равны. А также, что делает функция parse? И последний вопрос, скажите пожалуйста, как правильно определить массив указателей, в котором будут храниться команды, т.е. елементом этого массива должна быть просто команда или команда с параметрами:
const char *cmds[] = {"tr", "-d \"[0-9]\"", "< a.txt", "sort", "uniq", "> b.txt"};
или
const char *cmds[] = {"tr -d \"[0-9]\" < a.txt", "sort", "uniq > b.txt"};
или как это должно быть правильно?

Заранее ОГРОМНОЕ СПАСИБО и извините за беспокойство!
PM MAIL ICQ Skype   Вверх
MAKCim
Дата 6.5.2007, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(GGoga @  6.5.2007,  14:42 Найти цитируемый пост)
что делает функция parse?

получает на вход команду и возвращает NULL, если перенаправления ввода/вывода нет (т. е отсутствуют > и <)
иначе возвращает имя файла, куда перенаправляется ввод/вывод
GET_IN_FILE - означает поиск < 
GET_OUT_FILE - означает поиск >
функцию эту тебе самому придется написать  smile 
константы GET_IN_FILE, GET_OUT_FILE тоже нужно определить самостоятельно
Цитата(GGoga @  6.5.2007,  14:42 Найти цитируемый пост)
И последний вопрос, скажите пожалуйста, как правильно определить массив указателей, в котором будут храниться команды

все, что между |
т. е например для задачи 
Цитата

tr -d "[0-9]" < a.txt | sort | uniq > b.txt 

Код

const char *cmds[] = {"tr -d \"[0-9]\" < a.txt", "sort", "uniq > b.txt"};


Это сообщение отредактировал(а) MAKCim - 6.5.2007, 16:02


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
GGoga
Дата 6.5.2007, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 1.5.2007
Где: Харьков

Репутация: нет
Всего: нет



Спасибо за подсказку! smile
PM MAIL ICQ Skype   Вверх
codelord
Дата 26.7.2007, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 777
Регистрация: 7.5.2005
Где: ты моя темноглаза я где?!

Репутация: нет
Всего: 39



Цитата(MAKCim @  1.5.2007,  11:43 Найти цитируемый пост)
все просто, вот примерный алгоритм

сори за занудство, но мне так goto здесь лишнее
можно хотябы так:
Код

static int make_task(const char* cmds[], size_t count) {
    pid_t pids[MAX_PROCESSES_COUNT];
    size_t index;
    char *path;
    int pipe_fd[2] = {-1, -1},
         fd = -1;
    for (index = 0; index < count; ++index) {
        fd = *pipe_fd;
        pipe(pipe_fd); /* no error check */
        pids[index] = fork();
        if (pids[index] == 0) {
            if (fd < 0 && ((path = parse(cmds[index], GET_IN_FILE)) != NULL ) ) 
               {
                    fd = open(path, O_RDONLY); /* no error check */
               }
       else if( (fd > =0)  && !((path = parse(cmds[index], GET_IN_FILE)) != NULL) ) 
        { 
                  dup2(fd, STDIN_FILENO); 
        }
            fd = -1;
            if (index < count - 1)
                fd = *(pipe_fd + 1);
            else if ((path = parse(cmds[index], GET_OUT_FILE)) != NULL)
                fd = open(path, O_WRONLY | O_CREAT | O_EXCL); /* no error check */
            dup2(fd, STDOUT_FILENO);
            pause(); /* wait for SIGUSR1 */
            /* make 'exec' for command with index `index' */
        } else if (pids[index] < 0) {
            /* error by creating process */
        }
        if (fd >= 0) close(fd);
        close(*(pipe_fd + 1));
    }
    while (count--)
        kill(pids[count], SIGUSR1); /* send SIGUSR1 to all created processes */
    return 0;

не проверял


--------------------
Доступен поиск по исходным кодам в GOOGLE.
http://www.google.com/codesearch
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0686 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.