Search code examples
clinuxsystem

C code - trying to return an integer value with system() call


I'm facing an issue in my C code where my system call not triggering an if statement. My code is trying to detect if LKSCTP is loaded or not.

When LKSCTP is not loaded into the kernel, "/sbin/lsmod | grep sctp | wc -l" will return 0. The program should exit in this case with 2 lines of output.

If it is loaded, a non-zero number is returned, and the program should continue.

However, in both cases the number of lines from "wc -l" is being printed(?) and not correctly compared to 0, and the program is exiting.

First Attempt:

if ( system("/sbin/lsmod |grep sctp |wc -l") == 0 )
{
    /* no output, sctp is not loaded */
    ULCM_MSG("'/sbin/lsmod |grep sctp' failed! LKSCTP cannot be loaded.");
    ULCM_MSG("LKSCTP not installed or black-listed.");
    exit(1);
}

Output:

4 Sep 25 14:45:34.648 '/sbin/lsmod |grep sctp' failed! LKSCTP cannot be loaded. Sep 25 14:45:34.648 LKSCTP not installed or black-listed.

Second Attempt (tried casting the return to an integer):

int check = -1;

check = system("/sbin/lsmod |grep sctp |wc -l");
if(check == 0)
{
    /* no output, sctp is not loaded */
    ULCM_MSG("'/sbin/lsmod |grep sctp' failed! LKSCTP cannot be loaded.");
    ULCM_MSG("LKSCTP not installed or black-listed.");
    exit(1);
}

Output: Same as above.

I tried casting the system() return to an integer. I need to be able to check the "lsmod|grep sctp|wc -l" value for a zero/non-zero value for pass/fail.


Solution

  • wc -l always returns success (exit code 0) as long as it was able to read from the pipe and all. Try it in your shell: Both echo -n '' | wc -l; echo $? and echo hello | wc -l; echo $? will print 0 at the end. Regardless of whether there were lines to count or not. I feel like you are confusing the exit code with the value printed to stdout.

    However, I think you are already going too complicated a way - you can remove the wc -l and simply check if the exit code of grep is nonzero, because grep will give you a nonzero exit code (indicating failure) when the pattern was not found (again, check your shell: echo foo | grep hi; echo $? shows 1 while echo hi | grep hi; echo $? shows 0).

    Furthermore, as user zwol pointed out in the comments, you can use the -q argument to grep to suppress the output of the line(s) that it found to stdout because you are not interested in it anyway. The exit code will still be set.

    if ( system("/sbin/lsmod | grep -q sctp") != 0 )
    

    You could even get rid of the != 0 now but I left it in for clarity.