0

I am student developer and beginner in C programming language. I have a task and I did not find a clear solution according to my level. I want to run exec() function in child process. I created parent and child using fork(). It's OK. But my code is only running command like ls , pwd etc. If I want to write ls -l, it does not work command like that. What should I do ? Could you help me at this issue ?

My output for ls :

ls
a.out main.c
2006152 ms

My output for ls -l:

ls -l
Error exec: No such file or directory
3627824 ms

My code is :

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

#define N 100

void ChildProcess  ();  
void ParentProcess ();  

struct timeval start, end;

int main () {


    gettimeofday (&start, NULL);

    pid_t pid;
    pid = fork ();

    if (pid == 0){
        ChildProcess ();
    }
    else {
        wait (NULL);
        ParentProcess ();
    }

return 0;
}

void ChildProcess () {
    char input[N];
    scanf (" %[^\n]s", input);

    if (execlp (input, "", (char *) 0) < 0){
    perror ("Error exec");
    exit (0);}
} 

void ParentProcess () {
    gettimeofday (&end, NULL);
    printf ("%ld %s \n", ((end.tv_sec * 1000000 + end.tv_usec)-(start.tv_sec * 1000000 + start.tv_usec)), "ms");
} 
9
  • 2
    You're trying to run a program called ls -l, not a program called ls with an argument of -l. Commented Oct 19, 2019 at 23:15
  • BTW, why are you using (char *)0 instead of NULL? I mean, the C standard dictates that 0 (of any kind) and NULL will be evaluated the same, but I just find it to be a somewhat disputable practice. Commented Oct 19, 2019 at 23:16
  • regarding: scanf (" %[^\n]s", input); This is expecting a literal 's' in the input stdin Not what you want. Suggest: if( scanf( " %[^\n]", input ) != 1 ) { //handle error and exit } Commented Oct 20, 2019 at 4:00
  • regarding: if (pid == 0){ ChildProcess (); } else { wait (NULL); ParentProcess (); this, when fork() fails, will call wait() with no child process. This is a problem that you need to fix. Suggest using: switch( pid ) { case -1: perror( "fork failed: ); exit( EXIT_FAILURE ); break; case 0: ChildProcess(); break; default: wait(); ParentProcess(); break; } Commented Oct 20, 2019 at 4:05
  • OT: for ease of readability and understanding: 1) follow the axiom: only one statement per line and (at most) one variable declaration per statement. Commented Oct 20, 2019 at 4:07

1 Answer 1

2

Your problem is that all exec() family functions expect only the executable name as the first parameter (without any arguments). The arguments are then passed according to the exec function you decided to call. In the case of execlp(), all the arguments (including the executable name) are passed as a null-terminated list.

Essentially, you want to call your function in this way:

execlp ("ls", "ls", "-l", (char *) 0);

The way to do this is by splitting the input string on the space character (using strtok()) and saving the results in different variables.

If you would like to handle however cases of multiple arguments, then you cannot achieve it by using execlp(). Use execvp() instead with the according modifications. You can find the man page for all exec() functions here which will give you enough information.

Sign up to request clarification or add additional context in comments.

1 Comment

I understand. When I add it, my project runs ls -l . But I want to take an input value from user. What should I do ? How can I use inside your code sample ? Or is it possible ? @kyriakosSt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.