tags:

views:

71

answers:

3

Hello

Suppose I do a system("ps-C nautilus"); how do I return the result of this function in char* ?

Thank you.

+7  A: 

You don't. Not sure what platform you're on, but have a look at the popen function instead. You'll get a bidirectional pipe this way, which you can do file operations on, like reading to get a string out of it.

jer
The asker could combine `popen` with a loop which read from it until it completed, adding whatever was read to a dynamically resizable string and converting back to `char*` at the end. However this is in general a risky proposition; the output from the sub-process might consume all available memory.
crazyscot
I did stumble across a portable popen() type API that a friend wrote some years ago after I posted this answer, but I'm not sure what licensing terms he would put on it. If I can get in contact with him, I'll ask about it and update here with a source code link. It's really slick.
jer
A: 

The simplest solution is probably something like this:

system("ps-C nautilus > /tmp/data.txt");

then open the file and read in the contents.

Update Obviously you would not use a hard-coded file name. In the above code I was just illustrating the technique. There are many ways to ensure that your file name is unique.

Michael J
This is a bad idea on a multi-user system, what if that file is already there or being used by some other process?
crazyscot
I'd downvote if i wasn't out of votes for the day -- seriously this is a very bad idea. You don't know if that file exists beforehand, you have no idea if the shell that system() is invoking supports pipes, you have no idea if that file exists, or if some process is actively reading or writing to it at the time. Fraught with peril.
jer
+1  A: 

If your compiler supports some variant of popen() you can redirect the output fairly easily.

Caveats:

  1. The code below was written on a Windows box, which uses _popen() instead of popen(). It is not hard to convert for *nix.
  2. The code below has no error handling. It is just intended to illustrate the technique. You must add error checking before using it in production.
  3. This all runs in one thread. If the program was likely to run for a long time, you might need to use a second thread to read its output while it runs.
  4. I think popen() is POSIX, which means it will work on most *nix boxes, but it is not standard C, so should not be considered portable.
char *RunProg(const char *szCmdLine)
{
  size_t nSize=512;
  size_t nUsed=0;
  char *szOut = malloc(nSize);
  FILE *fp = _popen(szCmdLine, "r");
  char szBuff[128];
  while( !feof( fp ) )
  {
      if( fgets( szBuff, sizeof(szBuff), fp ) != NULL )
      {
          nUsed += strlen(szBuff);
          if (nUsed >= nSize)
          {
              nSize += nUsed;
              szOut = realloc(szOut, nSize);
          }
          strcat(szOut, szBuff);
      }
  }
  _pclose(fp);
  return szOut;
}
Michael J