2015-10-07 3 views
0

Каждый раз, когда этот код запущен, 0 и нуль передаются в качестве аргументов для моего дочернего процесса. Я знаю, что это связано с указателями, но я не могу заполнить свой массив и передать аргументы. Я слишком долго смотрел на него, и я надеюсь, что кто-то может заметить тупую ошибку.Проблема с указателями и дочерними процессами в C

/* exec example * 
* for CS-350 */ 

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <unistd.h> 

int main(int argc, char *argv[]) 
{ 
    int pid,i; 
    int sum; 
    int total = 0; 
    char *procpath = "slave"; 
    char *procname = "slave"; 

    int size = argc-1; 

    int input[size]; 


    int k; 
    for (k = 0; k < size; k++) 
    { 
     int m = (strtol(argv[k + 1], NULL, 10)); 
     // printf("%d", m); 
     input[k] = m; 
     printf("%d", input[k]); 
    } 
    // size = (size + 1)/2; 
    int count = 0; 

    while (size > 1) 
    { 

     for (i = 0; i < size; i = i + 2) 
     { 
      // create a child process 
      pid = fork(); 
      if (pid == 0) 
      { 

       // child process execution code--shows exec family calls 
       if (i < argc - 1) 
       { 
        execl(procpath, procname, &input[i], &input[i + 1], pid,(char *) 0); 
       } 
       else 
       { 
        execl(procpath, procname, &input[i], 0, pid, (char *) 0); 
       } 
       // execvp(procname,argv); 
       // if exec returns, means the call has failed. 
       perror("execl failed to run slave program"); 
       exit(1); 
      } 
      else if (pid > 0) 
      { 
       // print out command line arguments 
       waitpid(-1, &sum); 
      } 
      else 
      { 
       printf("call to fork failed, no child\n"); 
       exit(-1); 
      } 
      sum = WEXITSTATUS(sum); 

      printf("MASTER: partial sum = %d, and the pid of my slave =  %d\n\n",sum,pid); 

      int l; 
      for (l = 0 ; l < sizeof(input)/sizeof(input[0]) ; l ++) 
      { 
       printf("\n%d\n", input[l]); 
      } 
      // printf("%d", input[i/2]); 
      input[(i + 1)/2] = sum; 
      // printf("%d", input[i/2]); 
     } 
     size = (size + 1)/2; 
    } 
    printf("MASTER: total sum = %d\n",input[0]); 
    exit(0); 
} 

/* exec example-- slave * 
* for CS-350   */ 

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 

int main(int argc, char *argv[]) 
{ 
    printf("hey whats up %s",argv[1]); 
    int f = strtol(argv[1], NULL, 10); 
    int s = strtol(argv[2],NULL,10); 
    int sum = f + s; 
    printf("I'm the slave my pid is %s\n",argv[3]); 
    printf("SLAVE: first argumement = %d, second argument = %d, sum = %d\n", f, s, sum); 

    return sum; 
} 
+0

Может быть, вы можете добавить, что ваш желаемый вид поведения как помочь другим помочь вам. – xiamx

+1

Прочтите страницу man для [execl] (http://linux.die.net/man/3/execl). В нем четко указано, что каждый из аргументов после пути должен быть «строк с нулевым завершением, которые представляют список аргументов». Вы передаете смесь указателей на целые и целые числа, а не на строки с нулевым завершением. – kaylum

ответ

0

Вот декларация execl:

int execl(const char *path, const char *arg, ...); 

А вот описание arg и ...:

The const char *arg and subsequent ellipses in the execl(), execlp(), 
    and execle() functions can be thought of as arg0, arg1, ..., argn. 
    Together they describe a list of one or more pointers to null-termi‐ 
    nated strings that represent the argument list available to the exe‐ 
    cuted program. The first argument, by convention, should point to the 
    filename associated with the file being executed. The list of argu‐ 
    ments must be terminated by a null pointer, and, since these are vari‐ 
    adic functions, this pointer must be cast (char *) NULL. 

Так что в вашем коде, вы передаете procpath и procname которые являются правильными, но ваше использование input неверно, execl не принимает точку ers для int, но указатель на строки с нулевым завершением.

Вы должны изменить input быть char *input[size], а затем выделить память для каждой записи в input, прежде чем писать свои аргументы в него в виде строки, что-то вроде этого:

char *input [size]; 
/* .... */ 
int bytes = snprintf (NULL, 0, "%d", m); 
input [k] = malloc (bytes + 1); 
assert (input [k] != NULL); 
snprintf (input [k], bytes + 1, "%d", m); 
+0

Аргенты уже находятся в 'argv'. Не лучше ли было бы рекомендовать OP использовать это, а не проходить через обручи преобразования его в int, выделять новые буферы и преобразовывать их обратно в строку? – kaylum

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