0

I just learned C and fascinates with pointers. Recently I discovered C function system(). I am able to get return values from a program I executed via system ("program.exe"). Eg, program.c:

#include <stdio.h>

int main(){
    printf("hello world\n");

    return 123;
}

and this code calls program.exe, called call.c

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

int main(){
    int a;
    printf("calling program.exe:\n");
    a=system("program.exe");
    printf("program.exe returned %d at exit\n",a);

    return 0;
}

When I execute call.exe, I get this

calling program.exe:
hello world
pm returned 123 at exit

I was like, wow! This return value and system() function thing is like a new way to interprocess communication for me. But my question is, can I get a string return from the system() function?

Ii tried changing program.c "int main()" to "char * main()", and return 123 to return "bohemian rhapsody" and change "int a;" to "char *a;", printf format %d to %s in call.c, but I only get funny characters when I execute call.exe. I wonder what's wrong?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
coffeeground
  • 139
  • 8
  • i think my question is totally unique because im asking about returning string using return statement in C (returning and reading string exit code). – coffeeground Jul 24 '18 at 05:03
  • I'm not convinced this is a duplicate either. Certainly, the answer to the linked question explains how to get around the fact that what the OP wants can't be done, but IMHO, this question addresses why it's not possible in the first place. – dgnuff Jul 24 '18 at 19:36

2 Answers2

2

No you can't return a string from system(), and indeed a program under most modern desktop operating systems can only "return" an integer exit code when it terminates.

If you do want to get a string back from the executed program, one way would be to use popen() to invoke the program, and then have that program write the string to stdout.

dgnuff
  • 3,195
  • 2
  • 18
  • 32
  • thankyou for the answer. im aware of popen() function. but what im trying to achieve is, i trying to use exit code to return a string which can be read by caller (using system() function). is it possible to do? – coffeeground Jul 24 '18 at 05:07
  • 1
    No. As noted in my first paragraph, for all environments I'm aware of, a program can only "return" a single numeric value. This is most likely an operating system issue: the data marshalling that would be required to return something like a string represents a significant increase in complexity for little to no gain. ... – dgnuff Jul 24 '18 at 05:12
  • 1
    ... Worse yet. Suppose your `call.c` is compiled as a 32 bit program, and your `program.c` is compiled as 64 bit, and returns a string 5 billion bytes long. 64 bit programs could in theory do that. There isn't enough space in the address space of a 32 bit program to hold the entire returned string. What happens in that case? – dgnuff Jul 24 '18 at 05:12
  • whoa.. now i understood. many thanks dgnuff for your response! :) – coffeeground Jul 24 '18 at 06:04
1

The program that you call 'call.c' calls system(3), which does the following,

  • suspends the current process,
  • starts a child process,
  • and waits for the child process to complete

The return value from the called process, 'program.c/exe' is an integer (size is system dependent usually 16-bit), and what is happening behind the scenes is that the system(3) call uses the wait(2) call to (blocking) suspend execution until the child process returns.

Note that the string is not returned, but the child process prints to stdout. See the popen(3) call if you want to obtain the string (or binary) output from the child process.

See the manual page for wait(3) to see how to process the results returned by the called program, e.g. 'man -s2 wait',

WAIT(2)                     System Calls Manual                    WAIT(2)

NAME
     wait, wait3, wait4, waitpid -- wait for process termination

SYNOPSIS
     #include <sys/wait.h>

     pid_t
     wait(int *stat_loc);

     pid_t
     wait3(int *stat_loc, int options, struct rusage *rusage);

     pid_t
     wait4(pid_t pid, int *stat_loc, int options, struct rusage *rusage);

     pid_t
     waitpid(pid_t pid, int *stat_loc, int options);
ChuckCottrill
  • 4,360
  • 2
  • 24
  • 42