0

Everytime this code is run, 0's and a null are passed in as the arguments for my child process. I know its something to do with pointers, but I cant seem to populate my array and pass the arguments along. I've looked at it too long and I'm hoping someone can spot a dumb mistake.

/* 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;
}
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • Maybe you can add what your desired behavior look like to help others help you. – xiamx Oct 07 '15 at 21:47
  • 1
    Read the man page for [execl](http://linux.die.net/man/3/execl). It clearly states that each of the args after the path need to be "null-terminated strings that represent the argument list". You are passing a mix of pointers to integers and integers, not null-terminated strings. – kaylum Oct 07 '15 at 22:16

1 Answers1

0

Here's the declaration for execl:

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

And here's the description for arg and ...:

   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.

So in your code, you pass procpath and procname which are correct, but your use of input is incorrect, execl does not take pointers to int, but pointer to null-terminated strings.

You need to change input to be char *input[size], then allocate memory for each entry in input before writing your arguments into it as a string, something like this:

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);
Andrew
  • 3,770
  • 15
  • 22
  • The args are already in `argv`. Wouldn't it be better to advise OP to use that rather than go through the hoops of converting it to an int, allocate new buffers and converting it back to a string? – kaylum Oct 07 '15 at 22:25