← Back to Home

CITS2002 - Lecture 17
Command-line Arguments & Inter-Process Communication - Slides

Command-line Arguments

  • main(int arc, char *argv[])
    • argc number of command-line arguments
    • argv an array of strings (char pointers) holding the arguments
    • argv[0] always the program’s name

Parsing Command-line Arguments

  • Most applications support command switches that appear between a program’s name and the ‘true’ arguments
    • They all start with a hyphen (-) to indicate they are a switch
  • Command switches are accepted in any order:
    • ls -l -t -r is equivalent to ls -ltr
  • Switches are interpreted by the program, not the shell or OS

Here is an example of a switch implementation:

while (argc > 0 && (*argv)[0] == '-') {
    if ((*argv)[1] == 'd') dflag = true;
    --argc; ++argv;
}

-ddflag switch

Parsing with getopt()

  • As programs become more complicated, they often accept many command switches to define and constrain their execution
  • getopt() simplifies handling complex command-line options
    • From POSIX standard (not standard C library) but widely used
      Defined in <unistd.h> and <getopt.h>
int getopt(int argc, char * const argv[], const char *OPTLIST);
  • OPTLIST defines valid switches, e.g. {C#}"df:n:" means:
    • -d → no argument
    • -f → expects a string argument (optarg)
    • -n → expects a numeric argument (optarg)
#define OPTLIST "df:n:"
while ((opt = getopt(argc, argv, OPTLIST)) != -1) {
    if (opt == 'd') dflag = true;
    else if (opt == 'f') filename = strdup(optarg);
    else if (opt == 'n') value = atoi(optarg);
}
  • getopt() automatically:
    • Sets optarg to the switch’s argument
    • Sets optind to the index of the next unprocessed argument

Inter-Process Communication (IPC)

  • Programs can cooperate and exchange data using IPC mechanisms provided by the OS
    • This is useful as we want to always try employ functions and programs that already work well from 3rd parties
  • OS’s provide many IPC mechanisms
    • e.g. signals, pipes, shared memory blocks, etc.

Using Pipes in C

  • Pipes enable shells (or other programs) to connect the output of one program to the input of another
  • The system call pipe() is used to create a unidirectional communication buffer
  • A pipe is represented as an array of two integer file-descriptors
    • Writing data to array[0] adds the data to the pipe, and reading from array[1] removes that data

Creating a pipe:

#include <unistd.h>
int thepipe[2];
pipe(thepipe);
write(thepipe[1], data, size); // write end
read(thepipe[0], buffer, size); // read end
  • Pipes have a finite size, typically 4096 bytes long
  • A process trying to read an empty pipe will block until data arrives
  • A process writing to a full pipe will block until space frees up

CITS2002 - Lecture 19