3

I've done a lot of research on how to redirect stdout to a variable in C but no success. All I see is redirection of stdout to a file using dup2 and freopen which is not what I need. I want to know if is it even possible to redirect it to a variable without redirecting it first to a file?

Im using ubuntu and C to create the code. Im uaing GCC 4.7.3 as the compiler.

I did use dup2 and freopen and tried to do some work around but after some time. I realized that redirecting it to a file first then to variable is a bad idea (because of the data that will be written to it). I used freopen, but it's not working, maybe because gcc 4.7.3 doesn't have the library that contains that.

Is it possible to redirect stdout to a variable? if yes, how? if you dont know exactly how. Kindly give me an idea and I'll be the one to research on that.

Edit the post to add my code

As i've mentioned above, I did use dup2 and redirect stdout to a file. The code below shows how I managed to do it. It;s working but I realized saving the data to a file should not be an option. If its possible to change just a portion of my code, what can I do to to be able to redirect the stdout to a variable?

Here's the code..

char com1[] = "sudo mmm\n"; 

if (execCom!=NULL)  
{
    fp=popen(com1,"w");

    com = strtok(execCom, "\n");

    // walk through other commands that is separated by \n 
    while( com != NULL ) 
    {
        strcpy(comR,"\0");
        strcat(comR,com);
        strcat(comR,"\n");
        fwrite(comR, 1, strlen(comR),fp);
        com = strtok(NULL, "\n");
    }

    pclose(fp);
    fclose(out);
}
user3714598
  • 1,733
  • 5
  • 28
  • 45
  • grep and change `printf` to `sprintf` ... – M.M Aug 15 '14 at 11:52
  • possible duplicate of [popen simultaneous read and write](http://stackoverflow.com/questions/6171552/popen-simultaneous-read-and-write) – hyde Aug 17 '14 at 13:27
  • Could you please describe your real problem? That is, not this specific implementation issue, but the end problem you are trying to solve. – wkz Aug 18 '14 at 13:13

3 Answers3

3

Yes it is possible.

You will need to test this code as I do not have a compiler

It goes along the lines

#include <stdio.h>
#include <unistd.h>

int main()
{
       int fd[2];
       pipe(fd);
       if (fork() == 0) {
              dup2(fd[1], STDOUT_FILENO);
              execlp("ls","ls",NULL);
       } else {
              char buffer[1000];
              ssize_t size = read(fd[0], buffer, 1000);
              if ( (size>0) && (size<sizeof(buffer)) )
              {
                     buffer[size]='\0';
                     printf("%s\n", buffer);
              }
       }
}

Of course you need to put in error checking and also possibly having a loop in reading into the buffer.

I guess you need to read the manual pages

mpromonet
  • 11,326
  • 43
  • 62
  • 91
Ed Heal
  • 59,252
  • 17
  • 87
  • 127
2

Think this should be possible with fmemopen.

#include <stdio.h>

char buf[4096] = { 0 };

int main(void) {
    fclose(stdout);
    stdout = fmemopen(buf, sizeof(buf), "w");
    setbuf(stdout, NULL);

    printf("foo");

    return strncmp(buf, "foo", 3);
}

This program returns 0 on my machine, BUT there are a few things to beware of here:

  1. Using stdout as an lvalue is undefined as far as I know.
  2. Replacing printf with puts, for example, does not work, possibly due to (1).
wkz
  • 2,203
  • 1
  • 15
  • 21
  • Huh? This changes *your* `stdout` to a memory buffer, but the OP wants the output of *a different process* into a memory buffer in his process. – unwind Aug 15 '14 at 13:35
  • @unwind where does it say anything about another process? – wkz Aug 15 '14 at 13:36
  • hi @wkz actually it's a series of commands. I need to run "sudo -passsword" first and then run the commands.. I already modified my post. Thanks – user3714598 Aug 17 '14 at 13:27
  • 1
    newbie here -- I see that stdout is changed to point to a memory buffer, aren't we supposed to revert it back too ? – bhavs Mar 30 '16 at 08:55
2

This is simple as long as you have a POSIX system, you simply need to use

int shm_open(const char *name, int oflag, mode_t mode);

to open a shared memory block. This can then be mmaped into your memory space and a variable pointed to it. Finally you run your program, redirecting its stdout into the file descriptor given by the shared memory call.

Vality
  • 6,577
  • 3
  • 27
  • 48