1

If we execute gcc to compile a source file through the system() function, how can I capture the gcc output in a string ?


I tried with popen which works as long as it reads something like "PAUSE", but did not work with gcc as it runs a new child process.

DeltaProxy
  • 208
  • 1
  • 2
  • 7

2 Answers2

1

There are many ways.

Simple way: Redirect the output to a temporary file and read the temporary file into a string.

You can use pipes. In the child process, redirect the output to pipe and read from the other end of the pipe into a string. See man pipe

//In the parent process
int fd[2]
pipes(fd);

//Use fork+execv instead of system to launch child process.
if (fork()==0) {
    //Redirect output to fd[0]
   dup2(fileno(fd[0]), STDOUT_FILENO);
   dup2(fileno(fd[0]), STDERR_FILENO);
   //Use execv function to load gcc with arguments.

} else {
  //read from the other end fd[1]
}

See thread at http://ubuntuforums.org/archive/index.php/t-1627614.html.

Also see In C how do you redirect stdin/stdout/stderr to files when making an execvp() or similar call?

For Windows, this link might help you. https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499%28v=vs.85%29.aspx Flow is almost same as Linux. Syntax and primitives might be different. Here, idea is to use Pipe and redirect process output files to your pipe file.

Community
  • 1
  • 1
doptimusprime
  • 9,115
  • 6
  • 52
  • 90
0

If you are attempting to read the error messages produced by gcc, you need to remember that they are sent to stderr, not stdout. popen captures stdout but does not redirect stderr.

If system on Windows provides a standard posix shell, you could redirect stderr to stdout in the command line you provide to popen, by adding the redirection 2>&1.

rici
  • 234,347
  • 28
  • 237
  • 341
  • OH. Good remark. That makes sense and also makes it harder to be accomplished indeed. – DeltaProxy Mar 24 '15 at 03:47
  • @DeltaProxy: On Unix, it would be trivial; you'd just do `popen("gcc -o a.out file.c 2>&1", "r");` or something of that form. Maybe that will work in your environment. – rici Mar 24 '15 at 03:51
  • It worked.. on a way. Partially. It redirected the symbol `^` as well as some space. But it must redirect the backslash for the directory of the source file, which means it will be read as an escape sequence and this follows to be a problem. – DeltaProxy Mar 24 '15 at 04:01
  • @DeltaProxy: Why would it be read as an escape? `fread` (or `fgets`) just reads the bytes which are in the file. (Except for end-of-line translation for non-binary files on Windows.) – rici Mar 24 '15 at 04:04
  • @DeltaProxy: Also, if you have a surprisingly recent version of gcc, you should investigate the option `-fno-diagnostics-show-caret` – rici Mar 24 '15 at 04:05
  • I am printing the output buffer with printf. `-fno-diagnostics-show-caret` couldn't be fount even in google. – DeltaProxy Mar 24 '15 at 04:06
  • @DeltaProxy: Don't do that. Or if you do that, use a format. Otherwise, you're in ready-to-be-pwned land – rici Mar 24 '15 at 04:06
  • then how would I print them? (I am also using gtk and gtksourceview) Was hopefully expecting the way to be compatible with printing the result in a `GtkTextView` – DeltaProxy Mar 24 '15 at 04:08
  • @DeltaProxy: `printf("%s", buffer)` or `fputs(buffer, stdout)` are two good ways. Never ever ever write `printf(buffer);`. Whenever you see that line, think "danger". – rici Mar 24 '15 at 04:14
  • Oh, and why use google when the [gcc manual](https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Language-Independent-Options.html#index-fdiagnostics-show-caret-264) is online? – rici Mar 24 '15 at 04:16
  • I am not a `gcc` master, unfortunately and I don't get what does `-fno-diagnostics-show-caret` has to do with the problem. (Not a native speaker as well). Yes I am using `g_print("[%s]", buffer);` which is the analogue of `printf`. But I am still receiving the output of `^` and spaces. – DeltaProxy Mar 24 '15 at 04:21
  • @DeltaProxy: Recent versions of gcc show you where the error occurred by outputting a line containing a single ^ which points at the error position (by having enough spaces before it so that it is in the right place.) That's easier for human beings than a column number. Programs which understand column numbers can avoid the ^ (which is called a caret, and not just in English) by telling gcc "don't use carets in diagnostics", i.e. `-fno-diagnostics-show-caret`. The caret pointers also don't work if you use a proportionally-spaced font instead of a fixed-space font. – rici Mar 24 '15 at 04:27
  • The font of the console is monotype. Yes I receive the error in the console containing ^ at the line of the error. Adding this argument to the list of compiler arguments doesn't occur to change the the thing. – DeltaProxy Mar 24 '15 at 04:30
  • Screenshot after the invoking of `popen` to compile a file with the adding: http://screencast.com/t/4uFUUj6G It seem to redirect properly only the `^` ? – DeltaProxy Mar 24 '15 at 04:38
  • @DeltaProxy: You got me. Maybe the redirect doesn't work properly on Windows. Maybe there's a bug in your program. The fact that the ^ line seems to be written twice is suspicious, and needs some investigation. I'd start by writing a simple program which writes to stderr and see if you can get that to work. It wouldn't surprise me if it were a windows oddity, but I have zero windows experience so I can't offer much experience. – rici Mar 24 '15 at 05:00
  • Would you start a chat room? You can offer much. I was never to system programming. – DeltaProxy Mar 24 '15 at 05:02