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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> fork exec 
V
    Опции темы
Ak47black
  Дата 28.9.2010, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

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



Здравствуйте.
Есть вот такой вот код
Код

//---------------------------------------------------------------------------

#pragma hdrstop

#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>

void parseA(char* input);
void parseB(char* input);
void parseC(char* input);
void parseD(char* input);











const char* cmdlist[20][20] = {NULL};
int block = 0;
int cmd = 0;

void parseA(char* input)
{
    while (input[0] != 0)
    {
        cmd = 0;
        const char* delim = strchr(input, '|');
        if (delim)
        {
            int len = delim-input;
            char* subcmd = (char*)malloc(len);
            strncpy(subcmd, input, len);
            subcmd[len] = '\0';

            parseB(subcmd);
            block++;
            strcpy(input, delim+1);
        }
        else
        {
            parseB(input);
            return;
        }
    }
}

void parseB(char* input)
{
    while (input[0] != 0)
    {
        char* delim = strchr(input, '&');
        if (delim)
        {
            int len = delim-input;
            char* subcmd = (char*)malloc(len);
            strncpy(subcmd, input, len);
            subcmd[len] = '\0';
            parseC(subcmd);
            cmd++;
            strcpy(input, delim+1);
        }
        else
        {
            parseC(input);
            return;
        }
    }
}

void parseC(char* input)
{
   while (input[0] == ' ') strcpy(input, input+1);
   while (input[strlen(input)-1] == ' ') input[strlen(input)-1] = '\0';
   cmdlist[block][cmd] = input;
}




//---------------------------------------------------------------------------

int main(int argc, char* argv[])
{
    //char input[] = "a1 param1 | a2 param1 param2 | a3 param1 & a4 & a5 | a6 param1\0";
    char input[] = "ls -l & ls | cut -c 44-56\0"; //Чтото для теста. Возможно можно придумать вариант полутьше.
    parseA(input); //Тут мы парсим и получает эту строку ввиде массива cmdlist[отделенённые с |][отделенённые с &]

    int ppipes[2]; // Трубы для соединения всех приложений. Нужно-ли мне их больше?
    int ids[20]; //всем id fork'нутыъ приложений
    //Перебираем все команды
    int i = 0;
    int e = 0;
    while (cmdlist[i][e] != NULL)
    {
        while (cmdlist[i][e] != NULL)
        {
            printf("%s\n", cmdlist[i][e]);
            e++;
        }
        i++;
        e = 0;
    }

    getchar();
    return 0;
}
//---------------------------------------------------------------------------

Мне нужно сделать что-бы строка input запустилась и выполнилась так-же как и в bash оболочке.
Парсер у меня работает нормально.
Осталось понять как быть с трубами, их соединением, как правильно запускать приложения в моём случае и следует-ли их ждать с waitid?
Очень хочу узнать с чего начать подход и как и в каком порядке нужно всё это дело сделать.

Добавлено через 3 минуты и 36 секунд
Есть у меня ещё вот такой пример
Код

#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <netinet/in.h>
#include <resolv.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
/*
 *
 */
int main (int argv, char** argc)
{
    int pfildes[2];
    pid_t pid;
 
    if (pipe(pfildes) == -1)    {perror("error creating pipe"); exit(1);}
    if ((pid = fork()) == -1)   {perror("error creating child process"); exit(1);}
    else if (pid == 0) {        /* child:                      */
          close(pfildes[0]);    /* close read end of pipe               */
          dup2(pfildes[1], 1);   /* make 1 same as write-to end of pipe  */
          close(pfildes[1]);    /* close excess fildes                  */
          execlp("ls", "ls", "-1", NULL);
          perror("error executing child process");       /* still around?  exec failed           */
          _exit(1);             /* no flush                             */
        }
    else {                      /* parent:               */
          close(pfildes[1]);    /* close write end of pipe              */
          dup2(pfildes[0],0);   /* make 0 same as read-from end of pipe */
          close(pfildes[0]);    /* close excess fildes                  */
          execlp("cut", "cut", "-c", "44-56", NULL);
          perror("error executing child process");       /* still around?  exec failed           */
          exit(1);            
        }

}

который выполняет "ls -1 | cut -c 44-56"
Мне вот по нему совсем непонятно как быть с трубами.
И ещё у меня все команды идут с параметрами, тоетсь prog param1 param2 ... , то какую exec функцию нужно взять и как мне использовать?
PM MAIL   Вверх
Ak47black
Дата 28.9.2010, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

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



Сгущайте, может кто знает.
Нельзя-ли сделать что-бы команды можно было запускать одной строкой со всеми параметрами сразу
Тоесть чтото на подобии
Код

exec("ls -l \0")

а не 
Код

execp("ls", "ls", "-l", NULL);

?
PM MAIL   Вверх
Void
Дата 28.9.2010, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Цитата(Ak47black @  28.9.2010,  14:23 Найти цитируемый пост)
Нельзя-ли сделать что-бы команды можно было запускать одной строкой со всеми параметрами сразу

Отдать разбор командной строки шеллу.
Код
execl("/bin/sh", "sh", "-c", "command -opt1 -opt2 arg1 arg2", NULL);



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Ak47black
Дата 28.9.2010, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

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



А не так мне нельзя, у меня задание сделать свой шелл.

Добавлено через 1 минуту и 33 секунды
Застрял я вообщем на таком коде
Код

//---------------------------------------------------------------------------

#pragma hdrstop

#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <process.h>

void parseA(char* input);
void parseB(char* input);
void parseC(char* input);
void parseD(char* input);







char* cmdnames[20][20] = {NULL};
char* cmdparams[20][20][20] = {NULL};
int block = 0;
int cmd = 0;
int param = 0;

void parseA(char* input)
{
    while (input[0] != 0)
    {
        cmd = 0;
        const char* delim = strchr(input, '|');
        if (delim)
        {
            int len = delim-input;
            char* subcmd = (char*)malloc(len);
            strncpy(subcmd, input, len);
            subcmd[len] = '\0';

            parseB(subcmd);
            block++;
            strcpy(input, delim+1);
        }
        else
        {
            parseB(input);
            return;
        }
    }
}

void parseB(char* input)
{
    while (input[0] != 0)
    {
        param = 0;
        char* delim = strchr(input, '&');
        if (delim)
        {
            int len = delim-input;
            char* subcmd = (char*)malloc(len);
            strncpy(subcmd, input, len);
            subcmd[len] = '\0';
            parseC(subcmd);
            cmd++;
            strcpy(input, delim+1);
        }
        else
        {
            parseC(input);
            return;
        }
    }
}

void parseC(char* input)
{
   while (input[0] == ' ') strcpy(input, input+1);
   while (input[strlen(input)-1] == ' ') input[strlen(input)-1] = '\0';

   while (input[0] != 0)
   {
        char* delim = strchr(input, ' ');
        if (delim)
        {
            int len = delim-input;
            char* subcmd = (char*)malloc(len);
            strncpy(subcmd, input, len);
            subcmd[len] = '\0';
            parseD(subcmd);
            param++;
            strcpy(input, delim+1);
        }
        else
        {
            parseD(input);
            return;
        }
   }
   
}

void parseD(char* input)
{
    if (param == 0)
        cmdnames[block][cmd] = input;
    else
        cmdparams[block][cmd][param-1] = input;

}




//---------------------------------------------------------------------------

int main(int argc, char* argv[])
{
    char input[] = "g++ main.cpp -o test \0";
    parseA(input); //Тут мы парсим и получает эту строку ввиде массива cmdparams[отделенённые с |][отделенённые с &]

    int ppipes[2]; // Трубы для соединения всех приложений. Нужно-ли мне их больше?
    int ids[20]; //всем id fork'нутыъ приложений
    //Перебираем все команды
    int i = 0;
    int e = 0;
    while (cmdnames[i][e] != NULL)
    {
        while (cmdnames[i][e] != NULL)
        {
            if (cmdnames[i][e] != NULL)
            {
                execvp(cmdnames[i][e], cmdparams[i][e]);
            }            



            e++;
        }
        i++;
        e = 0;
    }

    getchar();
    return 0;
}
//---------------------------------------------------------------------------

g++ вроде запускается, но вижу странный текст
Цитата

main.cpp: no input files


Добавлено через 2 минуты и 43 секунды
Тут я запускаю
Код

execvp(cmdnames[i][e], cmdparams[i][e]);

вроде всё передаю правильно.
PM MAIL   Вверх
Ak47black
Дата 28.9.2010, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

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



Этот код так-же пока ещё работает на Windows

Добавлено через 4 минуты и 17 секунд
Вот тут документация по exec
Код

void main(int argc,char **argv)
{
    printf("Запуск CHILD с arg1, arg2 ...\n");
    execvp("CHILD.EXE",argv);
    perror("Ошибка EXEC");
    exit(1);
}


Чем-то похоже на мой код, только тут char **
А как мне быть?  smile 
PM MAIL   Вверх
Ak47black
Дата 28.9.2010, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

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



Тут проблема не и изза массива
Вот такой код тоже не работает
Код

char *cmd[] = { "main.cpp", "-o", "test", (char *)0 };
execvp("g++", cmd);

 smile 

Я взял его отсюда
http://www.opengroup.org/onlinepubs/009695...tions/exec.html
Не понимаю вообще ничего почему это всё не работает  smile

Добавлено через 5 минут и 18 секунд
А в линуксе вот такой код работает
Код

#include <unistd.h>

/*
 *
 */
int main (int argv, char** argc)
{
    int ret;
    char *cmd[] = { "ls", "-l", (char *)0 };
    ret = execvp ("ls", cmd);


}

 smile
PM MAIL   Вверх
Ak47black
Дата 28.9.2010, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

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



Но вот такой код в UNIX, тоже не работает правильно
Код

//---------------------------------------------------------------------------

#pragma hdrstop

#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <netinet/in.h>
#include <resolv.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void parseA(char* input);
void parseB(char* input);
void parseC(char* input);
void parseD(char* input);







char* cmdnames[20][20] = {NULL};
char* cmdparams[20][20][20] = {NULL};
int block = 0;
int cmd = 0;
int param = 0;

void parseA(char* input)
{
    while (input[0] != 0)
    {
        cmd = 0;
        const char* delim = strchr(input, '|');
        if (delim)
        {
            int len = delim-input;
            char* subcmd = (char*)malloc(len);
            strncpy(subcmd, input, len);
            subcmd[len] = '\0';

            parseB(subcmd);
            block++;
            strcpy(input, delim+1);
        }
        else
        {
            parseB(input);
            return;
        }
    }
}

void parseB(char* input)
{
    while (input[0] != 0)
    {
        param = 0;
        char* delim = strchr(input, '&');
        if (delim)
        {
            int len = delim-input;
            char* subcmd = (char*)malloc(len);
            strncpy(subcmd, input, len);
            subcmd[len] = '\0';
            parseC(subcmd);
            cmd++;
            strcpy(input, delim+1);
        }
        else
        {
            parseC(input);
            return;
        }
    }
}

void parseC(char* input)
{
   while (input[0] == ' ') strcpy(input, input+1);
   while (input[strlen(input)-1] == ' ') input[strlen(input)-1] = '\0';

   while (input[0] != 0)
   {
        char* delim = strchr(input, ' ');
        if (delim)
        {
            int len = delim-input;
            char* subcmd = (char*)malloc(len);
            strncpy(subcmd, input, len);
            subcmd[len] = '\0';
            parseD(subcmd);
            param++;
            strcpy(input, delim+1);
        }
        else
        {
            parseD(input);
            return;
        }
   }
   
}

void parseD(char* input)
{
    if (param == 0)
        cmdnames[block][cmd] = input;
    else
        cmdparams[block][cmd][param-1] = input;

}




//---------------------------------------------------------------------------

int main(int argc, char* argv[])
{
    char input[] = "ls -l\0";
    parseA(input); //Тут мы парсим и получает эту строку ввиде массива cmdparams[отделенённые с |][отделенённые с &]

    int ppipes[2]; // Трубы для соединения всех приложений. Нужно-ли мне их больше?
    int ids[20]; //всем id fork'нутыъ приложений
    //Перебираем все команды
    int i = 0;
    int e = 0;
    while (cmdnames[i][e] != NULL)
    {
        while (cmdnames[i][e] != NULL)
        {
            if (cmdnames[i][e] != NULL)
            {
                execvp(cmdnames[i][e], cmdparams[i][e]);
                
            }            



            e++;
        }
        i++;
        e = 0;
    }

    getchar();
    return 0;
}
//---------------------------------------------------------------------------


Добавлено через 24 секунды
Может тут дело из-за
Код

[]

???
PM MAIL   Вверх
Ak47black
Дата 28.9.2010, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

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



Ура нашел ошибку smile !!!!!
Надо было в параметрах указывать ещё и параметр - имя программы.
Немогу понять до конца для чего его нужно указывать два раза, но главное работает  smile 
PM MAIL   Вверх
Void
Дата 28.9.2010, 19:35 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Цитата(Ak47black @  28.9.2010,  19:54 Найти цитируемый пост)
Немогу понять до конца для чего его нужно указывать два раза, но главное работает 

Потому что список параметров загружаемая программа получает как есть, без всякой обработки. А argv[0] у нас что? Вот.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

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

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


 




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


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

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