I can run the following command
xwd -root | xwdtopnm | pnmtojpeg > screen.jpg
in a terminal under linux and it will produce a screenshot of my current screen.
I try to do the following with the code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fpipe;
char *command="xwd -root | xwdtopnm | pnmtojpeg";
char line[256];
if ( !(fpipe = (FILE*)popen(command,"r")) )
{ // If fpipe is NULL
perror("Problems with pipe");
exit(1);
}
while ( fgets( line, sizeof line, fpipe))
{
//printf("%s", line);
puts(line);
}
pclose(fpipe);
}
then I compile and run the program ./popen > screen.jpg
but the resulting file screen.jpg is unrecongizable. How can I do this so that I can pipe through my program correctly?
The functions
fgets
andputs
aren't intended to be used with binary data like image files. They should only be used with strings of text. In C, strings end with a null byte ('\0'
). Since that's really just a zero, it might appear anywhere in a binary file. Let's say thatline[]
is filled with 256 characters of data. When you callputs
, the function reads the array until it encounters a null byte then assumes it has reached the end of the string and stops. Since in a binary file a null byte might appear anywhere (and not just at the end of the array), theputs
function could easily fail to print out sections of your data.If I were you, I'd research the
fread
andfwrite
functions and use them instead. On a Linux machine, you should just be able to typeman 3 fread
to read documentation for both functions.Without testing your code I hav doubts that "xwd -root | xwdtopnm | pnmtojpeg" works as an argument for a C - Pipe.
I wouldn't use a C program anyway for such a problem. Use a simple Bash script instead.
You shouldn't use
fgets
andputs
for dealing with binary data.fgets
will stop whenever it sees a newline. Worse,puts
will output extra newlines and it will also stop whenever it runs into a \0. Usefread
andfwrite
instead.For those having this same problem, I ended up finally getting it working by using the Unix read/write system calls: