Redirecting standard output to a namedpiped
-
Friday, June 15, 2012 1:06 PM
Hello,
I know that with freopen() I can redirect the standard output to a file, now question is there anyway to use freopen() and give it a named pipe. This way instead of redirecting to a file I will redirect it to the named pipe.
cheers,
Ehsan
All Replies
-
Friday, June 15, 2012 1:24 PM
The technique of redirecting the input/output of a console process is very sample: The
CreateProcess()API through theSTARTUPINFOstructure enables us to redirect the standard handles of a child console based process. So we can set these handles to either a pipe handle, file handle, or any handle that we can read and write. The detail of this technique has been described clearly in MSDN: HOWTO: Spawn Console Processes with Redirected Standard Handles.
If you find this p☺st helpful please remember to hit <Vote As Helpful> √ 1. Whiter than the white is UV bright! 2. Eat your vegetables or you are going to turn in to blobs of lazy fat! 3. Fruits won't cut it 4 wheel drive with levers to lock differentials was a hack
-
Monday, June 18, 2012 10:34 AM
I would appreciate the answer as well. I am not aware of mechanism that can reroute all console IO. Even for above example it works for C++ conio commands, and I had never heard how to do it for C functions like printf.
I am exploring following option:
CMDLINE:
ProcessThatUsesConsole.exe > MyExeThatReceivesAndManagesConsoleInput.exe
where ">MyExeThatReceivesAndManagesConsoleInput.exe" is added to command line parameters
In case you are not familiar with syntax, I am talking [dir >listing.txt] where you will get output to file listing.txt
If you find this p☺st helpful please remember to hit <Vote As Helpful> √ 1. Whiter than the white is UV bright! 2. Eat your vegetables or you are going to turn in to blobs of lazy fat! 3. Fruits won't cut it 4 wheel drive with levers to lock differentials was a hack
- Edited by D3F84U Monday, June 18, 2012 10:34 AM
- Proposed As Answer by Jesse JiangMicrosoft Contingent Staff, Moderator Tuesday, June 19, 2012 9:20 AM
-
Monday, June 18, 2012 7:20 PM
On 6/15/2012 9:06 AM, ehsansad wrote:
I know that with freopen() I can redirect the standard output to a file, now question is there anyway to use freopen() and give it a named pipe. This way instead of redirecting to a file I will redirect it to the named pipe.
Try something like this:
HANDLE pipe = CreateNamedPipe(...);
int stream = _open_osfhandle(intptr_t(pipe), 0);
stdout = _fdopen(stream, "wt");
Igor Tandetnik
- Proposed As Answer by Jesse JiangMicrosoft Contingent Staff, Moderator Tuesday, June 19, 2012 9:20 AM
-
Tuesday, June 19, 2012 1:35 PM
I have been trying to make this work without any result, this is the code:
#include <windows.h> #include <process.h> #include <stdio.h> #include <stdlib.h> #include <io.h> int Buffer_out; int count,i; int stream; int old; LPCTSTR pipeName = "\\\\.\\pipe\\ehsan"; HANDLE hPipe; FILE *freOpenstream = NULL; FILE *test = NULL; int main(int argc, char* argv[]) { hPipe = CreateNamedPipe(pipeName, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, 10, 0, sizeof(Buffer_out), 10000, NULL); if(INVALID_HANDLE_VALUE == hPipe) { printf("Server Pipe not created\n"); exit(0); } else printf("Successful in creating server pipe\n"); old = _dup(1); if( old == -1 ) { perror( "_dup( 1 ) failure" ); exit( 1 ); } stream = _open_osfhandle((long)hPipe, 0); if(stream != -1) test = _fdopen(stream, "wt"); // stdout now refers to file "test" if(_dup2(_fileno( test), 1 ) == -1 ) { perror( "Can't _dup2 stdout" ); exit( 1 ); } /* if((freOpenstream = freopen(test, "w", stdout)) == NULL) exit(-1); */ // wait of a connection. while (!ConnectNamedPipe(hPipe, (LPOVERLAPPED) NULL)); printf("Client has connected\n"); for(Buffer_out=0;; Buffer_out++) { // printf("sending %d\n", Buffer_out); WriteFile(hPipe,&Buffer_out, sizeof(Buffer_out),(LPDWORD) &count, NULL); printf("sending printf to pipe\n"); Sleep(1000); } printf("press 'c' to quit\n"); while( toupper(getchar()) != 'C'); CloseHandle(hPipe); return 0; }the stdout = _fdopen(stream, "wt"); gave me a lvaue error. My problem here is that the printf("sending to pipe") which I thought would be sent to the pipe is not working, it's not going to the stdout or to the pipe.
so any suggestions?
with regards,
ehsan
-
Tuesday, June 19, 2012 11:12 PM
On 6/19/2012 9:35 AM, ehsansad wrote:
My problem here is that the printf("sending to pipe") which I thought
would be sent to the pipe is not working, it's not going to the stdout or to the pipe.
I bet the output gets buffered by the run-time. There's some magic in the CRT that detects whether the stream is attached to the console (as opposed to, say, being redirected to a file), and automatically disables buffering.
Try calling fflush() after printf, and/or use setvbuf to suppress buffering.
Igor Tandetnik
- Marked As Answer by ehsansad Wednesday, June 20, 2012 7:10 AM
-
Wednesday, June 20, 2012 3:21 AMModerator
Hello,
For addition, you should use multithread for write and read name pipe. Or you can use a named Pipe client to read. Please check these sample
Multithreaded Pipe Server
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365588(v=vs.85).aspx
Named Pipe Client
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365592(v=vs.85).aspx
Best regards,
Jesse
Jesse Jiang [MSFT]
MSDN Community Support | Feedback to us
-
Wednesday, June 20, 2012 7:13 AM
This is the changes to the code:
// stdout now refers to file "test" if(_dup2(_fileno( test), 1 ) == -1 ) { perror( "Can't _dup2 stdout" ); exit( 1 ); } setvbuf(stdout, NULL, _IONBF, 0); while (!ConnectNamedPipe(hPipe, (LPOVERLAPPED) NULL)); for(Buffer_out=0;; Buffer_out++) { printf("sending printf to pipe\n"); fflush(NULL); }
and its working, the client is receiving the printf() string in the for loop. NOW another question how safe is this code?
-ehsan
-
Wednesday, June 20, 2012 2:02 PM
It looks safe because you are not using single buffer or pointer to array. More interesting than server would be client.
I assume that last 6 lines of code are meant to be nonsense in terms it would fill endlessly fill the pipe with test message. They are still safe.
If you find this p☺st helpful please remember to hit <Vote As Helpful> √ 1. Whiter than the white is UV bright! 2. Eat your vegetables or you are going to turn in to blobs of lazy fat! 3. Fruits won't cut it 4 wheel drive with levers to lock differentials was a hack
- Edited by D3F84U Wednesday, June 20, 2012 2:07 PM
-
Wednesday, June 20, 2012 2:31 PM
The client is a standard client#include <windows.h> #include <process.h> #include <stdio.h> HANDLE hPipe; const int BUFSIZE = 10; int Buffer_in; int count; int main(int argc, char* argv[]) { hPipe = CreateFile("\\\\.\\pipe\\ehsan", // this machine GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if(INVALID_HANDLE_VALUE == hPipe) { printf("Server Pipe not found\n"); goto done; } else printf("Successful in finding server pipe\n"); for (;;) { ReadFile(hPipe,(LPVOID) &Buffer_in, (DWORD) sizeof(Buffer_in), (LPDWORD) &count, (LPOVERLAPPED) NULL); if (Buffer_in != '\n') printf("%c", Buffer_in); else printf("\n"); } CloseHandle(hPipe); return 0; } -
Wednesday, June 20, 2012 5:24 PM
-
Wednesday, June 20, 2012 6:35 PM
ReadFile(hPipe,(LPVOID) &Buffer_in, (DWORD) sizeof(Buffer_in),
is potential threat. Since you are not using any arrays, and you write fixed size that is determined from variable it self, you can't cause buffer overrun. Your code seems safe from managed vs. native perspective.
I hope I understood your question correctly.
If you find this p☺st helpful please remember to hit <Vote As Helpful> √ 1. Whiter than the white is UV bright! 2. Eat your vegetables or you are going to turn in to blobs of lazy fat! 3. Fruits won't cut it 4 wheel drive with levers to lock differentials was a hack
-
Thursday, June 21, 2012 2:05 PMI was just thinking if the whole system will collapse or not, based on this code.
-
Thursday, June 21, 2012 7:32 PM
-
Friday, June 22, 2012 7:25 AMThanks for the help.

