2017-01-15 6 views
0

Мне нужно написать код для следующей опции «--command».Многопроцессорность языка C execvp()

execvp() терпит неудачу, когда я бегу:

./program --command 1 2 3 кошки test.txt

--command МОР CMD арг Выполнение команды со стандартным параметром я, стандартный выход o и стандартная ошибка e; эти значения должны соответствовать более ранним параметрам файла или трубы. Исполняемый файл для команды - cmd и имеет аргументы аргументов 0 или более аргументов. Ни один из операндов cmd и args не начинается с двух символов «-».

Часть кода, который должен сделать execvp() выглядит следующим образом:

 if(optarg){ 
int fd; 
int i = 0; 
char *arg[20]; 
int index; 
for(index = optind-1; index < argc && *argv[index] != '-'; index++, i++){ 
    switch(i){ 
    case 0: 
    fd = atoi(argv[index]); 
    break; 
    case 1: 
    fd = atoi(argv[index]); 
    break; 
    case 2: 
    fd = atoi(argv[index]); 
    break; 
    default: 
    arg[i - 3] = (char *)malloc(100 * sizeof(char)); 
    strcpy(arg[i - 3], argv[index]); 
    } 
} 
int j; 
for(j = 0; j < i - 3; j++) 
    printf("%s\t", arg[j]); 
printf("\n\n"); 
execvp(*arg, arg); 
    } 

Любая помощь высоко ценится.

+1

0 Вы не упомянули, что характер неудачи, что затрудняет вам помощь. Использование '1 2 3' для in, out и err очень странно (stdin - fd 0, а не 1), но поскольку вы, похоже, ничего не делаете с аргументами tjod, я не думаю, что это связано. Копирование строк, а не просто предоставление правильного смещения в массив args неэффективно и сложно, но я должен работать, если вы правильно завершаете нуль. Если вы настаиваете на копировании строк, используйте strlen для определения необходимого размера (или просто вызовите strdup, а не malloc + strcpy). – rici

+0

Спасибо, я использую strdup() сейчас. Проблема заключается в размере массива. так как в моем тесте я пропускаю только два argumeny cat test.txt, поэтому char ** arg должен иметь только две строки, тогда как я объявил 20 (char * arg [20]). Как я могу динамически добавлять размер char ** arg. Я не знаю, сколько аргументов пройдет, поэтому я взял номер болота, но execvp() не удалось из-за мусора в моем большом массиве. – user3050866

+1

Создайте MCVE ([MCVE]) - он не должен быть намного больше, чем вы показываете, но ему нужно воспроизвести вашу проблему, и нам нужно уметь ее компилировать и запускать (и видеть проблему). –

ответ

0

Вот функция, которую я написал и использует много, что может быть полезно; написанный на C++, а целевой ОС - Linux; вы можете проверить и скорректировать код для C:

#define MAX_PARMS 100 //crazy 
#define MAX_PARM_SIZE 5120 //make it 5K ///max is command-line-max (4096) i think too lazy to check 
#define SPACE_CHAR 32 
bool is_valid_space(const std::string s, int pos) 
{ 
    if (s[pos]!=SPACE_CHAR) return false; 
    if (!pos) return true; 
    if (s[pos-1]=='\\') return false; 
    return true; 
} 
void RunApp(const std::string sApp, const std::string sParm) 
{ 
    if (!isextant(sApp)) return; 
    int n=0,i=0; 
    while (i < (int)sParm.length()) { if (is_valid_space(sParm, i)) n++; i++; } 
    if ((n>=(MAX_PARMS-1)) || ((sApp.length() + sParm.length() + 1) > MAX_PARM_SIZE)) return; 
    pid_t pID = fork(); 
    if (pID == 0) 
    { //child.. 
     if (sParm.length()!=0) 
     { 
      static char *arsz[MAX_PARMS]; //pointers to offsets in sz[]-buffer 
      static char sz[MAX_PARM_SIZE]; 
      int p=1,t=0,i=0,n; 
      n = sApp.length(); //copy app into sz[] as first parm 
      while (i<n) { sz[i]=sApp.at(i); i++; } 
      sz[i] = 0; 
      t = i+1; 
      arsz[0] = sz; 
      n = sParm.length(); 
      i=0; 
      while (i<n) 
      { 
       if (is_valid_space(sParm, i)) i++; 
       if ((i<n) && (!is_valid_space(sParm, i))) 
       { 
        arsz[p] = sz+t; p++; 
        while ((i<n) && (!is_valid_space(sParm, i))) 
        { 
         sz[t]=sParm.at(i); 
         t++; 
         i++; 
        } 
        sz[t]=0; t++; 
       } 
      } 
      sz[t]=0; //double null at end 
      execvp(sApp.c_str(), arsz); 
     } //NB: here-be-zombies: must waitpid in caller 
     else execlp(sApp.c_str(), sApp.c_str(), (char*)0); 
     exit(0); //only if exec..-error 
    } 
} 
+0

Код OP - это C, а ваш код использует C++ –

Смежные вопросы