cprintfcommand-execution

C program executing command before being told to


I have started looking into command processing with C but I have hit a problem with this C program. It is executing the ls command before it is intended.

Gcc info:

gcc version 6.2.1 20161124 (Debian 6.2.1-5)

This is the code:

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

int main()
{
    int i;

    printf("Is command processor available?\n");
    if (system(NULL))
    {
        printf("Command processor available!\n");
    }
    else
    {
        printf("Command processor not available!\n");
        exit(1);
    }

    printf("Executing command ls");
    i=system("ls");

    printf("Returned value is: %d.\n",i);
    return 0;
}

The piece of code I am speaking about is this specific line:

    printf("Executing command: ls");

If the program is ran with that piece of code the output is:

Is command processor available?
Command processor is available
systemProcessing  systemProcessing.c
Executing command: lsReturned value is: 0.

It executes the command before actually being told to

But when I finish the code off with a new line '\n', its output is as expected:

Is command processor available?
Command processor is available
Executing command: ls
systemProcessing  systemProcessing.c
Returned value is: 0.

Why is it that with the newline added to the string the code prints what it is about to do before executing, but without it it executes and then prints that is is going to execute?


Solution

  • It's a buffering issue. You need to do:

    printf("Executing command ls");
    fflush(stdout); //<<
    i=system("ls");
    

    or, if your output is a line-buffered terminal and you're OK with adding a line instead of an explicit fflush(stdout) call:

    printf("Executing command ls\n"); 
    

    stdio 101:

    Small read/writes to the OS are inefficient, so stdio IO (by default) associates each file handle/descriptor with an input buffer and an output buffer. stdio output calls output into the appropriate FILE's (in this case, it's stdout) output buffer (by memcpying the string), and only when the (large) buffer is full will a system call to write the whole buffer be made (problem solved).

    An explicit flush of an output buffer may be elicited with the fflush() function. Additionally, if stdio detects an output FILE is a terminal, it will use line buffering which means it will call fflush() whenever it encounters a newline in the output.

    The buffering mode of an stdio FILE may also be explicitly manipulated with the setvbuf() function. See the manpage in the link to learn how it can be used.