user2551700
user2551700

Reputation: 89

Obtaining an integer (greater than 255) from the system function in C++

I have a relatively simple problem which I cannot seem to do. What I need to do is retrieve an integer from a bash script using the system function in a C++ program. My understanding is that system by default returns an integer, so I should be bale to do something like

int returnedVal = system ("myscript");

however the main problem is bash scripts do not have return values, just a flag between 0 and 255 for whether they were successful or not. I have tried doing something like writing to a text file in the script and then reading in a file, however this caused some issues and I would like to avoid that if possible. Does anyone know the easiest way to do this? Thanks very much in advance.

Upvotes: 1

Views: 524

Answers (3)

Jean-Baptiste Yunès
Jean-Baptiste Yunès

Reputation: 36401

POSIX exit(3) says:

The value of status may be 0, EXIT_SUCCESS, EXIT_FAILURE, [CX] [Option Start] or any other value, though only the least significant 8 bits (that is, status & 0377) shall be available to a waiting parent process.

This means that no value greater than what is possible to represent with 8 bits can exit from a normal process termination via call to exit then parent can't catch more.

More on this. Don't use returned value to transmit some data, it is primarily intended to represent a success or failure status. 0 value represent successful, any other a failure.

If you want your processes to communicate something, then you need some communication channel (file, pipe, etc).

Upvotes: 3

If myscript -like many scripts or programs- write(2)-s something (e.g. some numbers or strings) on its stdout, you might use (on POSIX) popen(3) in your program. When successful popen would give a FILE* stream for <stdio.h> routines (that you could read with fscanf etc).

(I am guessing that you are using some Linux or POSIX system)

But system(3) catches the exit(3) status (actually also other terminations, e.g. signal(7)-s, see waitpid(2)) of myscript. It don't care about the output of myscript which gets inserted in the standard output of your program.

Don't forget to use pclose(3) (not fclose) to close that popen-ed stream. Read also pipe(7).

For example, this code reads the number from the output of the wc -l /etc/fstab command

FILE*p = popen("wc -l /etc/fstab", "r");
if (!p) { perror("popen"); exit(EXIT_FAILURE); };
int n= 0;
if (fscanf(p,"%d", &n)<=0) { perror("fscanf"); exit(EXIT_FAILURE; };
if (pclose(p)>0) /*wc failed*/ exit(EXIT_FAILURE);
printf("your fstab has %d lines\n", n);

You should read Advanced Linux Programming (freely downloadable). You may want to use other things (e.g. some system calls like fork(2), execve(2), waitpid(2), pipe(2), dup2(2); see syscalls(2)).

There are many other ways of doing some Inter-Process Communication, including fifo(7)-s and socket(7)-s.

Beware of code injection when running, with popen or system, some computed string containing a command.

Some libraries (notably Qt or POCO for C++) offer other ways of running programs and communicating with them.

Upvotes: 1

Peter - Reinstate Monica
Peter - Reinstate Monica

Reputation: 16026

The system man page says, after discussing all kinds of failures:

If all system calls succeed, then the return value is the termination status of the child shell used to execute command. (The termination status of a shell is the termination status of the last command it executes.)

For clarity one could add that the shell's exit value is either the numerical argument to the exit command, or — if none is encountered — the exit status of the last command which was executed, i.e. the value of $?. That exit value is passed by the operating system to the shell's parent (which may be another shell) via the waitpid() function. That way the exit status of the "leaf" process is propagated until it reaches system, and finally your program.

I do not see why what you want to do should not be possible.

Upvotes: 0

Related Questions