Nemesis0815
asked on
Using a pipe to redirect output
hello,
i have the following problem:
im using this code to communicate to another program via command line interface:
char cmd[100] = "ccm set role";
char psBuffer [128];
FILE *tmp;
tmp = _popen(cmd, "rt"); // open pipe for reading in text mode and send command
while( !feof( tmp ) )
{
if( fgets( psBuffer, 128, tmp ) != NULL )
{
printf( psBuffer );
}
}
printf( "\nProcess returned %d\n", _pclose( tmp ) );
This returns only this:
Process returned 0
when i execute the command line stored in the cmd string with a call like this
system(cmd);
it returns the correct return value, a string like this:
developer
Now i know that the _popen command sends the correct command since the application i call by the cmd command string reacts correctly. Only thing that bothers me is that it seems i cannot get the command line return value back which i would normally get when i enter the cmd in the standard command line interpreter or by using the system() function.
Anybody knows how to get the result by using the popen directive ?
i have the following problem:
im using this code to communicate to another program via command line interface:
char cmd[100] = "ccm set role";
char psBuffer [128];
FILE *tmp;
tmp = _popen(cmd, "rt"); // open pipe for reading in text mode and send command
while( !feof( tmp ) )
{
if( fgets( psBuffer, 128, tmp ) != NULL )
{
printf( psBuffer );
}
}
printf( "\nProcess returned %d\n", _pclose( tmp ) );
This returns only this:
Process returned 0
when i execute the command line stored in the cmd string with a call like this
system(cmd);
it returns the correct return value, a string like this:
developer
Now i know that the _popen command sends the correct command since the application i call by the cmd command string reacts correctly. Only thing that bothers me is that it seems i cannot get the command line return value back which i would normally get when i enter the cmd in the standard command line interpreter or by using the system() function.
Anybody knows how to get the result by using the popen directive ?
while( !feof( tmp ) )
{
if( fgets( psBuffer, 128, tmp ) != NULL )
{
printf( psBuffer ); ----- %s ????
}
}
can be changed to
while( fgets( psBuffer, 128, tmp ) != NULL )
printf( "%s", psBuffer );
>>>>when i execute the command line stored in the cmd string with a call like this
system(cmd);
it returns the correct return value, a string like this:
developer
How can system return a string ? system () returns only an int and that will be the status returned
what platform are you working on ?
{
if( fgets( psBuffer, 128, tmp ) != NULL )
{
printf( psBuffer ); ----- %s ????
}
}
can be changed to
while( fgets( psBuffer, 128, tmp ) != NULL )
printf( "%s", psBuffer );
>>>>when i execute the command line stored in the cmd string with a call like this
system(cmd);
it returns the correct return value, a string like this:
developer
How can system return a string ? system () returns only an int and that will be the status returned
what platform are you working on ?
ASKER
nope sorry,
exactly the same result as before - no output
it seems that this if( fgets( psBuffer, 128, tmp ) != NULL ) actually returns NULL when i debug.
exactly the same result as before - no output
it seems that this if( fgets( psBuffer, 128, tmp ) != NULL ) actually returns NULL when i debug.
ASKER
sorry, with system returning something i was referring to the output in the command line interface window.
when i use popen i get no answer/result from the cmd i send in which should be printed by the printf("%s",psBuffer);
but it isnt.
im running WinNT btw.
i changed the code to this now:
tmp = _popen(cmd, "r"); // open pipe for reading in text mode and send command
while( !feof( tmp ) )
{
if( fgets( psBuffer, 128, tmp ) == NULL )
printf( "Error! \n");
else
printf("%s",psBuffer);
}
and it only returns me a single "Error!" in standard output.
when i use popen i get no answer/result from the cmd i send in which should be printed by the printf("%s",psBuffer);
but it isnt.
im running WinNT btw.
i changed the code to this now:
tmp = _popen(cmd, "r"); // open pipe for reading in text mode and send command
while( !feof( tmp ) )
{
if( fgets( psBuffer, 128, tmp ) == NULL )
printf( "Error! \n");
else
printf("%s",psBuffer);
}
and it only returns me a single "Error!" in standard output.
cygwin or VC++
ASKER
vc++
ASKER
maybe the ccm application ( configuration management software continuus synergy )
outputs not to stdout but to stderr ?
outputs not to stdout but to stderr ?
are you creating windows application ? If yes then _popen is broken
http://lists.trolltech.com/qt-interest/1999-09/thread00289-0.html
>>maybe the ccm application ( configuration management software continuus synergy )
>>outputs not to stdout but to stderr ?
try redirecting the results to a file while executing from command line
>>maybe the ccm application ( configuration management software continuus synergy )
>>outputs not to stdout but to stderr ?
try redirecting the results to a file while executing from command line
ASKER
redirecting with system( "ccm set role > tempfile.txt");
works fine
with popen and redirecting with > operator it says:
Command created: ccm query /name s_bgem_test.db /version uid08453 /type project
/f "%status" /u > tmpfile.txt
The handle could not be opened
during redirection of handle 1.
Error!
Process returned 1
works fine
with popen and redirecting with > operator it says:
Command created: ccm query /name s_bgem_test.db /version uid08453 /type project
/f "%status" /u > tmpfile.txt
The handle could not be opened
during redirection of handle 1.
Error!
Process returned 1
add another error check
tmp = _popen(cmd, "r");
if ( tmp == NULL )
printf (" error opening pipe\n");
tmp = _popen(cmd, "r");
if ( tmp == NULL )
printf (" error opening pipe\n");
ASKER
i guess this is the problem now ( popen bug with win app)
any other idea of how i could get the output of the application i call and redirect it to a variable so that i can use it in my program ? ( i want to avoid redirecting to a file )
some simple piping ? im not used to create and handle pipes in windows :)
any other idea of how i could get the output of the application i call and redirect it to a variable so that i can use it in my program ? ( i want to avoid redirecting to a file )
some simple piping ? im not used to create and handle pipes in windows :)
ASKER
added
if ( tmp == NULL )
printf (" error opening pipe\n");
does not return an error
if ( tmp == NULL )
printf (" error opening pipe\n");
does not return an error
ASKER
so this might be this invalid file handle problem ...
either you use fork with pipe
or
redirect to file and read from file
first is more elegant while second is slightly simpler
or
redirect to file and read from file
first is more elegant while second is slightly simpler
ASKER
is there a fork in windows ?
The UNIX and Windows process models are very different, and the major difference lies in the creation of processes. UNIX uses fork to create a new copy of a running process and exec to replace a process's executable file with a new one. Windows does not have a fork function. Instead, Windows creates processes in one step by using CreateProcess. While there is no need in Win32 to execute the process after its creation (as it will already by executing the new code), the standard exec functions are still available in Win32.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnucmg/html/ucmgch09.asp
I am happy I have to work with Linux
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnucmg/html/ucmgch09.asp
I am happy I have to work with Linux
ASKER
isnt there an easier way then creating 2 pipes?
i only need to read the output that is generated by the ccm process no need to go both directions
i only need to read the output that is generated by the ccm process no need to go both directions
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
hm
ASKER
any simplier example for this ? i dont quite get the msdn one.. :p
http://www.cs.cf.ac.uk/Dave/C/node23.html#SECTION002330000000000000000
its a unix example but things are pretty similar :-) once you get an idea of the concept, you will be able to code it on win
its a unix example but things are pretty similar :-) once you get an idea of the concept, you will be able to code it on win
ASKER
ok i did it now on my own... and thanx to alf for his help in the other thread:)
dunno why it works but it does :)
extern int PipeThis( LPTSTR CmdLine, char * result )
{
HANDLE rfd, wfd, myinput,myoutput,myerror;
SECURITY_ATTRIBUTES attr;
STARTUPINFO startinfo;
PROCESS_INFORMATION myproc;
char PipeBuffer[READBUFFER] ="";
int readbytes;
// ************************** *
// * Preparations *
// ************************** *
ZeroMemory( &myproc, sizeof(PROCESS_INFORMATION ) );
ZeroMemory( &startinfo, sizeof(STARTUPINFO) );
attr.nLength = sizeof(SECURITY_ATTRIBUTES );
attr.bInheritHandle = TRUE; // we want to be able to inherit this handle.
attr.lpSecurityDescriptor = NULL;
myinput = GetStdHandle(STD_INPUT_HAN DLE);
myoutput = GetStdHandle(STD_OUTPUT_HA NDLE); // save all IO handles to redirect them later on
myerror = GetStdHandle(STD_ERROR_HAN DLE);
startinfo.cb = sizeof(STARTUPINFO);
startinfo.dwFlags = STARTF_USESTDHANDLES;
// ************************** *
// * STEP 1: Create the pipe *
// ************************** *
if (CreatePipe(& rfd, & wfd, & attr, 0) == 0) {
fprintf(stderr,"\nError, CreatePipe failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
startinfo.hStdError = myerror;
startinfo.hStdInput = myinput;
startinfo.hStdOutput = wfd; // set the processe´s standard output to the write end of the pipe
// ************************** *
// * STEP 2: Create a process*
// ************************** *
if( CreateProcess( NULL, CmdLine, &attr, &attr, TRUE, NORMAL_PRIORITY_CLASS , NULL, NULL, &startinfo, &myproc ) == 0) {
fprintf(stderr,"\nError, CreateProcess failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
// ************************** *
// * STEP 3: Close Handle *
// ************************** *
if ( CloseHandle(wfd) == 0 ){
fprintf(stderr,"\nError, CloseHandle failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
// ************************** *
// * STEP 4: Read Pipe *
// ************************** *
if( ReadFile( rfd, PipeBuffer,READBUFFER, &readbytes, NULL) == 0){
fprintf(stderr,"\nError, ReadFile failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
//printf("\nSuccess: \n\n%s\n",PipeBuffer);
strcpy( result,PipeBuffer); // write resulting string
// ************************** *
// * STEP 5: Closing..... *
// ************************** *
if ( CloseHandle(rfd) == 0 ){
fprintf(stderr,"\nError, CloseHandle failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
if ( CloseHandle(myproc.hProces s) == 0){
fprintf(stderr,"\nError, CloseHandle failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
if ( CloseHandle(myproc.hThread ) == 0 ){
fprintf(stderr,"\nError, CloseHandle failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
return 0; // success
}
gonna give you sunnycoder the points caues you brought me on the light lane with this bug in the popen and pipes thing anyway :)
dunno why it works but it does :)
extern int PipeThis( LPTSTR CmdLine, char * result )
{
HANDLE rfd, wfd, myinput,myoutput,myerror;
SECURITY_ATTRIBUTES attr;
STARTUPINFO startinfo;
PROCESS_INFORMATION myproc;
char PipeBuffer[READBUFFER] ="";
int readbytes;
// **************************
// * Preparations *
// **************************
ZeroMemory( &myproc, sizeof(PROCESS_INFORMATION
ZeroMemory( &startinfo, sizeof(STARTUPINFO) );
attr.nLength = sizeof(SECURITY_ATTRIBUTES
attr.bInheritHandle = TRUE; // we want to be able to inherit this handle.
attr.lpSecurityDescriptor = NULL;
myinput = GetStdHandle(STD_INPUT_HAN
myoutput = GetStdHandle(STD_OUTPUT_HA
myerror = GetStdHandle(STD_ERROR_HAN
startinfo.cb = sizeof(STARTUPINFO);
startinfo.dwFlags = STARTF_USESTDHANDLES;
// **************************
// * STEP 1: Create the pipe *
// **************************
if (CreatePipe(& rfd, & wfd, & attr, 0) == 0) {
fprintf(stderr,"\nError, CreatePipe failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
startinfo.hStdError = myerror;
startinfo.hStdInput = myinput;
startinfo.hStdOutput = wfd; // set the processe´s standard output to the write end of the pipe
// **************************
// * STEP 2: Create a process*
// **************************
if( CreateProcess( NULL, CmdLine, &attr, &attr, TRUE, NORMAL_PRIORITY_CLASS , NULL, NULL, &startinfo, &myproc ) == 0) {
fprintf(stderr,"\nError, CreateProcess failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
// **************************
// * STEP 3: Close Handle *
// **************************
if ( CloseHandle(wfd) == 0 ){
fprintf(stderr,"\nError, CloseHandle failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
// **************************
// * STEP 4: Read Pipe *
// **************************
if( ReadFile( rfd, PipeBuffer,READBUFFER, &readbytes, NULL) == 0){
fprintf(stderr,"\nError, ReadFile failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
//printf("\nSuccess: \n\n%s\n",PipeBuffer);
strcpy( result,PipeBuffer); // write resulting string
// **************************
// * STEP 5: Closing..... *
// **************************
if ( CloseHandle(rfd) == 0 ){
fprintf(stderr,"\nError, CloseHandle failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
if ( CloseHandle(myproc.hProces
fprintf(stderr,"\nError, CloseHandle failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
if ( CloseHandle(myproc.hThread
fprintf(stderr,"\nError, CloseHandle failed ! Code: %ul - exiting... \n",GetLastError());
system("pause");
exit(1);
}
return 0; // success
}
gonna give you sunnycoder the points caues you brought me on the light lane with this bug in the popen and pipes thing anyway :)
tmp = popen(cmd, "r"); should serve your purpose