LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   examples with 2 pipes+fork+handling error,output in different files (http://www.linuxquestions.org/questions/programming-9/examples-with-2-pipes-fork-handling-error-output-in-different-files-766970/)

nagendrar 11-04-2009 11:34 PM

examples with 2 pipes+fork+handling error,output in different files
 
Please provide examples in c or c++ if any one know which have following

By creating two pipes handling the output and error in two different pipes while running commands remotely by using plink.

ThanQ,
NAgendra R

pixellany 11-05-2009 04:58 PM

Please provide some context. If this is homework, tell us more about the class, what books you are usig etc.

nagendrar 11-05-2009 11:04 PM

Here the context is 'I want to run the scripts on remote system using plink. Here I am using pipes concept .I created two pipes And I want to handle the output and error in two different files.

If host key (available in /.putty/sshhostkeys file) is not available or is
not match then we will get "Store key in cache? (y/n)" message from child
process into error file.

If parent process reads this message then we will send "yes" if not then we
will continue to next step and parent process will wait until exit child
process .

In this bug case, host key did not match and response came late from child
process into error file and parent process took it as host key already
available and waiting for exit status of child process using waitpid(). But
here "yes" did not send for running commands and exit the child process.
Hence it is hanged at waitpid(). Please help me how to solve this issue.

I tried this in following way:

#include<stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <poll.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <stdlib.h>

void strtrimright(char * src, char trim) {
char * end = src;
while (*end) ++end;
--end;
while (end >= src && *end == trim)
*end-- = 0;
}

int talkToPlink(struct pollfd *waitfordata ,int read_stdout,int write_stdin,const char *passwd)
{
char buf[2048];
int pollRes=0;
unsigned long bread = 0;
while(1)
{
pollRes = poll(waitfordata,1,10*1000);

if(pollRes < 0)
{
printf("ReadWithTimeOut: Poll Error:%s",strerror(errno));
return -1; // pipe closed or other failure
}
memset(buf, 0, 2048);
bread = 0;

if(pollRes > 0)
{
if(waitfordata[0].revents > 0 ){
printf("======[%d]=====1\n",waitfordata[0].revents);
if(waitfordata[0].revents == POLLIN)
bread = read(read_stdout, buf, 2047);
else
{
struct stat filestat;
char errBuf[1024];
char *str =NULL;
if(stat("./outputFilename.txt", &filestat)==0){
sleep(8);
FILE *fpOut = fopen("./errFilename.txt", "r");
if(fpOut) {
fread(errBuf, 1, 1023, fpOut);
printf("errBuf[%s]\n",errBuf);

str= strstr(errBuf, "Store key in cache? (y/n) ");
if(str && *str) {

write(write_stdin,"y\n", strlen("y\n"));

sleep(1);
}
fclose(fpOut);
}

}

break;
}
}
}
}
return 1;
}

/* This waits until the child exits or untill timeouts */
int waitWithTimeOut(pid_t pid, int timeout,int &status)
{
time_t deadline = time(0) + timeout;
int state=0;
do {
waitpid(pid, &state,0);
if(WIFEXITED(state))
{
status=WEXITSTATUS(state);
kill(pid, SIGKILL);
waitpid(pid, 0, 0);
return 1;
}
sleep(1);

} while(time(0) < deadline);
kill(pid, SIGKILL);
waitpid(pid, 0, 0);
return -1;
}
//Connect to the host and run a command on it. Capture stdout to a file.
//Caller should close and delete the file afterward.
//Currently uses SSH only, but we could easily support Telnet too.
int main()
{
const char* host="10.0.15.187"; const char* user="all"; const char* passwd="e1q@";
const char* outputFilename="./outputFilename.txt";
const char *errorFilename="./errorFilename.txt"; char *errMesg;
const char *inputFilename="./findBootLoadPass.sh";
int status=0;
//format command
char command[1024]; memset(command, 0, 1024);
char exeName[1024];memset(exeName, 0, 1024);
snprintf(exeName , 1023, "./plink");
char port[16];memset(port,0,16);snprintf(port,15,"22");

char ppkFilePath[1024];
memset(ppkFilePath,0,1024);
char *argv[12] = {(char*)exeName,(char *)host,"-l",(char*)user,"-P", (char*)port,NULL};
argv[6] = "-pw"; argv[7] = (char*)passwd; argv[8] = "-m";
argv[9] = (char *)inputFilename; argv[10] = NULL;

bool ok = true;
int result=0,ret = 0;
int pid=0;
int write_stdin[2], read_stdout[2];
pipe(write_stdin);
pipe(read_stdout);

/* Fork the process */
pid = fork();

switch (pid) {
case 0: /* Child process */
close(write_stdin[1]);
close(read_stdout[0]);

/* Replace stdin and stdout with the new fds */
dup2(write_stdin[0], STDIN_FILENO);
dup2(read_stdout[1], STDERR_FILENO);

close(write_stdin[0]);
close(read_stdout[1]);

int f;
if ((f=creat("./outputFilename.txt", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1){
printf("failed at output file creation outputFilename");
}

int ferror;
if ((ferror=creat("./errFilename.txt", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1){
printf("failed at output file creation errputFilename");
}

dup2(f,STDOUT_FILENO);
dup2(ferror, STDERR_FILENO);


close(ferror); // original not needed after dup2
close(f); // original not needed after dup2

execvp(exeName, argv);
_exit(0);
break;

case -1: /* fork() error */
printf("Fork() error for host:%s, cmd:%s, user:%s", host,cmd,user);
return NULL;
break;

default: /* Parent process */
/* Close unneeded fds */
close(write_stdin[0]);
close(read_stdout[1]);
struct pollfd waitfordata[1];
waitfordata[0].fd=read_stdout[0];
waitfordata[0].events=POLLIN;
sleep(2);

//run the commands
result = talkToPlink(waitfordata,read_stdout[0], write_stdin[1],passwd);
if(result < 0){
kill(pid,SIGKILL);
waitpid(pid, 0, 0);
}
else{
waitWithTimeOut(pid, 300, status);
}
close(write_stdin[1]);
close(read_stdout[0]);
};
}

chrism01 11-06-2009 12:15 AM

I recommend you ask the Mods (via the Report button) to move this to the Programming forum.

pixellany 11-06-2009 06:36 AM

Quote:

Originally Posted by chrism01 (Post 3746632)
I recommend you ask the Mods (via the Report button) to move this to the Programming forum.

Done....


All times are GMT -5. The time now is 06:08 AM.