Anon451
Anon451

Reputation: 43

Why does execve return differently than user

So Im rather new to the C language exec family functions and was wondering why cal returns

usage: cal [-13smjyV] [[[day] month] year]

When passed to execve(); below

    pid = fork( ) ;
    if ( pid == 0 )  {
            char *myArgv[ ] = { "cal", "4", "1980", "NULL"};
            char *myEnv[ ] = { "HOME=/usr/bin", NULL}  ;
            execve( "/usr/bin/cal", myArgv, myEnv) ;
    } else {
            printf("parent process waiting for execve complete \n" );
    }

whereas when I call 'cal 4 1980' manually through my terminal I get an actual printout?

          April 1980     
     Su Mo Tu We Th Fr Sa
            1  2  3  4  5
      6  7  8  9 10 11 12
     13 14 15 16 17 18 19
     20 21 22 23 24 25 26
     27 28 29 30

Upvotes: 1

Views: 80

Answers (2)

Anon451
Anon451

Reputation: 43

So it looks like the reason the program wasn't printing the calendar was because I didn't NULL terminate the myArgv char array on line 3 properly and instead ended the array with "NULL" with quotes, instead I should have terminated with just NULL without quotes.

Upvotes: 2

user3629249
user3629249

Reputation: 16550

the following proposed code:

  1. cleanly compiles
  2. performs the desired functionality
  3. properly checks for errors

Note: the need to execute /bin/bash -c to execute a program from the environment

and now the proposed code:

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

int main( void )
{
    pid_t pid = fork( );
    switch( pid )
    {
        case -1:
            perror( "fork failed" );
            exit( EXIT_FAILURE );
            break;

        case 0:
            // in child process
            {
                //char *myArgv[ ] = { "-c", "/usr/bin/cal", "4", "1980", "NULL"};
                //char *myEnv[ ] = { "HOME=/usr/bin", NULL}  ;
                execlp( "/bin/bash", "bash", "-c", "/usr/bin/cal", "-S", "4", "1980", NULL) ;
                perror( "execve failed" );
                exit( EXIT_FAILURE );
            }
            break;

        default:
            // in parent process
            printf("parent process waiting for execlp>>bash>>cal to complete \n" );
            waitpid( pid, NULL, 0 );
            break;
    }           
}

a run of the program results in:

parent process waiting for execlp>>bash>>cal to complete 
   November 2019      
Su Mo Tu We Th Fr Sa  
                1  2  
 3  4  5  6  7  8  9  
10 11 12 13 14 15 16  
17 18 19 20 21 22 23  
24 25 26 27 28 29 30  

Upvotes: 0

Related Questions