Frank Ponte
Frank Ponte

Reputation: 145

Troubles passing arguments through execlp function - C

i'm using a given md5 function who calculates a file hash when you feed it with a file address. Thing is that i need to execute this program using fork() and then load it using any exe...() function(im trying with execlp()) but when i do it and i pass the single argument i need to calculate the hash it fails. I tried running md5 program manually with the exact argument i use in execlp and it doesn't fail so i'm just assuming it must be something wrong with execlp parameters. Here's an example i made to explain the scenario:

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

int main(){
  pid_t cpid;int status;
  cpid = fork();
  if(cpid < 0){
    printf("Error fork\n");
    exit (EXIT_FAILURE);
  }else if (!cpid){
        if (execlp("./hashMD5/me/md5","md5","testfile.a",(char*)NULL) == -1){
          printf("Error: Loading process\n");
          exit(EXIT_FAILURE);
        }
  }else{
    waitpid(cpid,&status,0);
  }
    exit (EXIT_SUCCESS);
}

when i use this i got an error in terminal:

$testfile.a can't be opened

but if i manually execute the md5 program with the exactly same argument i got the correct execution.

What's wrong? Help!

Upvotes: 0

Views: 1240

Answers (2)

Frank Ponte
Frank Ponte

Reputation: 145

I finally solved the problem. I appreciate the improvements people gave me, i'm always happy to learn new things!

The problem was with the argument itself: Even when you use execlp to create a brand new process the path of the argument remains relative to parent process, that's why was not working. After several headaches i finally realized that. Thanks to everyone!

Upvotes: 0

user3629249
user3629249

Reputation: 16540

the following proposed code:

  1. cleanly compiles
  2. documents why each header file is included
  3. uses a proper call to execl() rather than execlp() because execl() expects the first parameter to be a complete path while execlp() expects the first parameter to be just a file name.
  4. properly formats the code, for ease of readability and understanding
  5. properly handles calling execl() and possible failure of that call
  6. properly passes error messages to stderr rather than stdout, using perror(), so the reason the system thinks the error occurred is also displayed on stderr.

And now, the proposed code:

#include <stdio.h>   // perror()
#include <sys/types.h>
#include <stdlib.h>   // exit(), EXIT_FAILURE, EXIT_SUCCESS
#include <unistd.h>   // fork(), execlp()
#include <sys/wait.h> // waitpid()

int main( void )
{
    pid_t cpid;int status;
    cpid = fork();

    if(cpid < 0)
    { // error
        perror("Error fork\n");
        exit (EXIT_FAILURE);
    }

    else if (!cpid)
    { // child
        execl("./hashMD5/me/md5","md5","testfile.a", NULL);

        perror("Error: Loading process\n");
        exit(EXIT_FAILURE);
    }

    else
    { // parent
        waitpid(cpid,&status,0);
    }

    exit (EXIT_SUCCESS);
}

Upvotes: 2

Related Questions