Итак, я новичок в функциях семейства exec на языке C и задавался вопросом, почему cal возвращает

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

При передаче в execve (); ниже

    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" );
    }

Тогда как, когда я звоню "cal 4 1980" вручную через терминал, я получаю распечатку?

          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
1
Anon451 21 Ноя 2019 в 07:58
Относительно: execve( "/usr/bin/cal", myArgv, myEnv) ; Это было бы гораздо лучше записать как: execve( "/usr/bin/cal", myArgv, myEnv) ; perror( "execve failed" ); exit( EXIT_FAILURE );
 – 
user3629249
21 Ноя 2019 в 09:04
Относительно: printf("parent process waiting for execve complete \n" ); должно сопровождаться: waitpid( pid, NULL, 0 );
 – 
user3629249
21 Ноя 2019 в 09:06
Примечание: опубликованный код не может проверить сбой функции: fork() Помните, что fork() имеет три типа возврата: 1) <0 означает, что произошла ошибка 2) == 0 означает в дочернем процесс 3)> 0 означает в родительском процессе
 – 
user3629249
21 Ноя 2019 в 09:08
1
Может быть, он запутается, когда вы затираете всю среду, но HOME?
 – 
ikegami
21 Ноя 2019 в 09:27

2 ответа

Таким образом, похоже, что причина, по которой программа не печатала календарь, заключалась в том, что я не завершил NULL массив символов myArgv в строке 3 должным образом, а вместо этого завершил массив с помощью "NULL" с кавычками, вместо этого Я должен был завершить работу с помощью NULL без кавычек.

2
Anon451 21 Ноя 2019 в 09:55

Следующий предложенный код:

  1. чисто компилируется
  2. выполняет желаемую функциональность
  3. правильно проверяет на ошибки

Примечание: необходимость выполнения /bin/bash -c для выполнения программы из среды

А теперь предлагаемый код:

#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;
    }           
}

Запуск программы приводит к:

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  
0
user3629249 21 Ноя 2019 в 09:48