Re: pipe data form windows program to cygwin program
Hi bob thanks for your help, i solve the problem bny using only windows functions to have a pipe and that is working well. It seems that posix and windows doesn't work well together. bertrand Le ven 29/10/2004 04:18, Bob Byrnes a crit : | Are you *sure* that you have closed *all* of the write handles to the pipe? | If any write handles remain open, then EOF won't be delivered to the | read side of the pipe. i think i did, but even if i didn't the fact that the program exit normally will close all open handles under windows, won't it ? It's true that all open handles for the parent process will be closed on exit. However, if handles for the write side of the pipe were passed to the child process, and any of them remain open, then that's a problem. This appears to be the case for your sample program. Here are some suggestions: -- If you only need to write out some compressed data, try linking with zlib and calling one of the gzip functions: some examples are provided with the zlib source distribution. This is simple (no pipes or subprocesses), efficient, and effective. -- If you really do need a pipe to a subprocess, consider using popen(), which does all of the work for you. -- If for some reason you need to do all of the pipe and process creation stuff yourself, be sure to close all of the unneeded file descriptors in the child process as well as in the parent process. The usual technique looks something like this: int pfds[2];// pipe file descriptors pipe(pfds); // make the pipe if (fork() == 0) { // child // connect stdin to read side of pipe dup2(pfds[0], STDIN_FILENO); // close unneeded pipe descriptors close(pfds[0]); close(pfds[1]); execlp(gzip, ...); } else { // parent // connect stdout to write side of pipe dup2(pfds[1], STDOUT_FILENO); // close unneeded pipe descriptors close(pfds[0]); close(pfds[1]); // write to stdout // close stdout, or exit } Alternately, the parent could just write to pfds[1], the write side of the pipe, if you don't want or need to mess with stdout. But it's still important to close pfds[0], the read side of the pipe, in the parent process. Either way, there are no stray open file descriptors for the pipe in any process, so when the parent closes the write side of the pipe, the child should see EOF on the read side. One final suggestion: I'd try to avoid mixing the win32 and posix APIs. Life is complicated enough without trying to deal with win32 HANDLEs and posix (int) file descriptors at the same time, or using functions like DuplicateHandle() and dup2() in the same program. HTH ... -- Bob -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: pipe data form windows program to cygwin program
Le mer 27/10/2004 21:37, Bob Byrnes a crit : I'm writing a program which need to send data to a cygwin program using a pipe on the stdin (actually data to compress using gzip). All is working well but at the end of the program when i close the pipe it seems that gzip doesn't see that the pipe has been closed and so it stay open. Are you *sure* that you have closed *all* of the write handles to the pipe? If any write handles remain open, then EOF won't be delivered to the read side of the pipe. i think i did, but even if i didn't the fact that the program exit normally will close all open handles under windows,won't it ? I kind of think there must be something with windows-cygwin EOF but i can't find out what. Is anyone has an idea ? If you can provide a (very) simple test case that exhibits allegedly incorrect behavior, that would be helpful. i will try to do this as soon as possible, thanks for help bertrand -- Bob -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: pipe data form windows program to cygwin program
hi again, i join to this mail an example. This must be compiled with mingw compiler. the program is going great but at the end gzip( or you can try with cat to see that data is in output file) stay open. bertrand Le mer 27/10/2004 21:37, Bob Byrnes a crit : I'm writing a program which need to send data to a cygwin program using a pipe on the stdin (actually data to compress using gzip). All is working well but at the end of the program when i close the pipe it seems that gzip doesn't see that the pipe has been closed and so it stay open. Are you *sure* that you have closed *all* of the write handles to the pipe? If any write handles remain open, then EOF won't be delivered to the read side of the pipe. I kind of think there must be something with windows-cygwin EOF but i can't find out what. Is anyone has an idea ? If you can provide a (very) simple test case that exhibits allegedly incorrect behavior, that would be helpful. -- Bob -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ #include stdio.h #include windows.h #include fcntl.h #include process.h main() { HANDLE newstdout,newstdin,parent,handles[2]; int phandles[2],compressor_pid,archivefd; /*open a file to put data on*/ archivefd = open(test.gz, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY,0666 ~umask(0)); /*save current handles*/ parent=GetCurrentProcess (); handles[0] = GetStdHandle (STD_INPUT_HANDLE); handles[1] = GetStdHandle (STD_OUTPUT_HANDLE); /*create a new pipe*/ _pipe(phandles,0,O_BINARY); /*set pipe of stdin of process form our stdout*/ DuplicateHandle (parent, (HANDLE) _get_osfhandle (archivefd), parent, newstdout, 0, TRUE, DUPLICATE_SAME_ACCESS); /*set pipe of stdout of process to open file*/ DuplicateHandle (parent, (HANDLE) _get_osfhandle (phandles[0]), parent, newstdin, 0, TRUE, DUPLICATE_SAME_ACCESS); /*replace standard handles*/ SetStdHandle (STD_INPUT_HANDLE, newstdin); SetStdHandle (STD_OUTPUT_HANDLE, newstdout); /*start process*/ compressor_pid= spawnlpe(_P_NOWAIT,cat,NULL, NULL); /*restore standard handles*/ CloseHandle (GetStdHandle (STD_INPUT_HANDLE)); CloseHandle (GetStdHandle (STD_OUTPUT_HANDLE)); SetStdHandle (STD_INPUT_HANDLE, handles[0]); SetStdHandle (STD_OUTPUT_HANDLE, handles[1]); /*close pipe unneeded and duplicate pipe input to archivefd*/ dup2(phandles[1], archivefd); close(phandles[0]); close(phandles[1]); /*output data to gzip*/ write(archivefd,abcdefghijklmnopqrstuvwxyz,26); /*close our handles*/ close(archivefd); /*exit*/ exit(0); } -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: pipe data form windows program to cygwin program
| Are you *sure* that you have closed *all* of the write handles to the pipe? | If any write handles remain open, then EOF won't be delivered to the | read side of the pipe. i think i did, but even if i didn't the fact that the program exit normally will close all open handles under windows, won't it ? It's true that all open handles for the parent process will be closed on exit. However, if handles for the write side of the pipe were passed to the child process, and any of them remain open, then that's a problem. This appears to be the case for your sample program. Here are some suggestions: -- If you only need to write out some compressed data, try linking with zlib and calling one of the gzip functions: some examples are provided with the zlib source distribution. This is simple (no pipes or subprocesses), efficient, and effective. -- If you really do need a pipe to a subprocess, consider using popen(), which does all of the work for you. -- If for some reason you need to do all of the pipe and process creation stuff yourself, be sure to close all of the unneeded file descriptors in the child process as well as in the parent process. The usual technique looks something like this: int pfds[2];// pipe file descriptors pipe(pfds); // make the pipe if (fork() == 0) { // child // connect stdin to read side of pipe dup2(pfds[0], STDIN_FILENO); // close unneeded pipe descriptors close(pfds[0]); close(pfds[1]); execlp(gzip, ...); } else { // parent // connect stdout to write side of pipe dup2(pfds[1], STDOUT_FILENO); // close unneeded pipe descriptors close(pfds[0]); close(pfds[1]); // write to stdout // close stdout, or exit } Alternately, the parent could just write to pfds[1], the write side of the pipe, if you don't want or need to mess with stdout. But it's still important to close pfds[0], the read side of the pipe, in the parent process. Either way, there are no stray open file descriptors for the pipe in any process, so when the parent closes the write side of the pipe, the child should see EOF on the read side. One final suggestion: I'd try to avoid mixing the win32 and posix APIs. Life is complicated enough without trying to deal with win32 HANDLEs and posix (int) file descriptors at the same time, or using functions like DuplicateHandle() and dup2() in the same program. HTH ... -- Bob -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
pipe data form windows program to cygwin program
Hi, I'm writing a program which need to send data to a cygwin program using a pipe on the stdin (actually data to compress using gzip). All is working well but at the end of the program when i close the pipe it seems that gzip doesn't see that the pipe has been closed and so it stay open. I kind of think there must be something with windows-cygwin EOF but i can't find out what. Is anyone has an idea ? thanks Bertrand -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: pipe data form windows program to cygwin program
I'm writing a program which need to send data to a cygwin program using a pipe on the stdin (actually data to compress using gzip). All is working well but at the end of the program when i close the pipe it seems that gzip doesn't see that the pipe has been closed and so it stay open. Are you *sure* that you have closed *all* of the write handles to the pipe? If any write handles remain open, then EOF won't be delivered to the read side of the pipe. I kind of think there must be something with windows-cygwin EOF but i can't find out what. Is anyone has an idea ? If you can provide a (very) simple test case that exhibits allegedly incorrect behavior, that would be helpful. -- Bob -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/