UNIX processes using C/C++
  • 🍴The fork system call
  • ⌚The wait system call
  • 🆔Process ID
  • 🔌Signals in UNIX
    • 🗄️Signal Handlers
  • 🥃Executing system commands
  • 📁Sharing information between processes
    • 🕚Bidirectional pipe
  • 🖥️Applications
    • 💻Console Application 1
    • 💻Console Application 2
  • ⚽Named pipe FIFO
Powered by GitBook
On this page
  • Output
  • Output
  • Output

Executing system commands

In this section we shall see how to execute system commands using the exec functions

PreviousSignal HandlersNextSharing information between processes

Last updated 2 years ago

Before we begin

#include <errno.h>

int main(int argc, char* argv[], char* envp[]){

    // argc = argument count
    // argv = argument vector
    // envp = environment pointer
    
    // errno stores the error code (if any) of the process in which the main thread is running

    return errno;
}

Let's first create a program to add any number of integers that are passed as arguments.

add.c
#include <stdio.h>
#include <math.h>
#include <string.h>

int str_to_int(char* c){
    int x = 0;
    int n = strlen(c);
    for(int i=0;i<n;i++)
        x += (c[i] - 48)*pow(10,n-i-1);
    return x;
}

int main(int argc, char* argv[]){
    int sum = 0;
    for(int i=1;i<argc;i++)
        sum += str_to_int(argv[i]);
    printf("Sum = %d",sum);
    return 0;
}

Now let's execute this program using certain arguments that are specified within the program itself.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(){
    // this command is for compilation purpose only
    system("gcc add.c -o add -lm");

    // returns the status code of the process
    int exc = execl(
        "./add",  // path to the executable
        "./add",  // path to the executable (again)
        // now we pass all the arguments
        "11",
        "22",
        "7",
        "120",
        NULL  // don't forget to pass the NULL pointer (mandatory)
    );
    
    // if the exec function runs properly without any exceptions, then this line will not be executed and the program will terminate
    printf("Process finished with code %d\n",exc);
    return 0;
}

Output

Sum = 160

Note: We can't have more than one exec command in a program since the program will terminate on successful execution of the first exec function call that it encounters.

Another way we can do this is using the execvp function where we pass the list of arguments as an array.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(){
    // this command is for compilation purpose only
    system("gcc add.c -o add -lm");

    char* args[] = {"./add","11", "22", "7", "120", NULL};

    // returns the status code of the process
    int exc = execvp(
        "./add",  // path to the executable
        args  // now we pass all the arguments
    );
    
    // if the exec function runs properly without any exceptions, then this line will not be executed and the program will terminate
    printf("Process finished with code %d\n",exc);
    return 0;
}

Output

Sum = 160

In case we want to execute a program from a path stored in ENVIRONMENT variables, we can use the execvp function.

Example:

#include <stdio.h>
#include <unistd.h>

int main(){
    char* args[] = {"ping","google.com"};

    // returns the status code of the process
    int exc = execvp("ping",args);
    
    // if the exec function runs properly without any exceptions, then this line will not be executed and the program will terminate
    printf("Process finished with code %d\n",exc);
    return 0;
}

Or we can just use the execl function

#include <stdio.h>
#include <unistd.h>

int main(){
    int exc2 = execl(
        "/usr/bin/ping",
        "/usr/bin/ping",
        "google.com",
        NULL
    );
    printf("Process finished with code %d\n",exc2);
    return 0;
}

Output

In all cases the outputs are the same

PING google.com (172.217.166.78) 56(84) bytes of data.
64 bytes from bom05s15-in-f14.1e100.net (172.217.166.78): icmp_seq=1 ttl=112 time=48.9 ms
64 bytes from bom05s15-in-f14.1e100.net (172.217.166.78): icmp_seq=2 ttl=112 time=48.7 ms
64 bytes from bom05s15-in-f14.1e100.net (172.217.166.78): icmp_seq=3 ttl=112 time=49.5 ms
64 bytes from bom05s15-in-f14.1e100.net (172.217.166.78): icmp_seq=4 ttl=112 time=86.9 ms
^C
--- google.com ping statistics ---
11 packets transmitted, 11 received, 0% packet loss, time 10014ms
rtt min/avg/max/mdev = 48.659/56.520/91.104/15.352 ms
🥃
Link to exec function manual