LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 11-04-2009, 11:34 PM   #1
nagendrar
Member
 
Registered: Apr 2008
Location: HYD, INDIA.
Posts: 141

Rep: Reputation: 15
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

Last edited by nagendrar; 11-04-2009 at 11:38 PM.
 
Old 11-05-2009, 04:58 PM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728
Please provide some context. If this is homework, tell us more about the class, what books you are usig etc.
 
Old 11-05-2009, 11:04 PM   #3
nagendrar
Member
 
Registered: Apr 2008
Location: HYD, INDIA.
Posts: 141

Original Poster
Rep: Reputation: 15
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]);
};
}
 
Old 11-06-2009, 12:15 AM   #4
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,246

Rep: Reputation: 2025Reputation: 2025Reputation: 2025Reputation: 2025Reputation: 2025Reputation: 2025Reputation: 2025Reputation: 2025Reputation: 2025Reputation: 2025Reputation: 2025
I recommend you ask the Mods (via the Report button) to move this to the Programming forum.
 
Old 11-06-2009, 06:36 AM   #5
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728
Quote:
Originally Posted by chrism01 View Post
I recommend you ask the Mods (via the Report button) to move this to the Programming forum.
Done....
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Using Bash To Feed Command Output To A While Loop Without Using Pipes! LXer Syndicated Linux News 0 08-06-2008 12:10 PM
Sed gives output in pipes only when buffer is full jahvascriptmaniac Linux - Software 2 08-31-2006 05:57 PM
interrupt handling - fork - exec help!! James Scrymgeour Programming 0 06-15-2006 10:34 AM
Need help w/ shell handling 3 commands/2 pipes sptchamp Programming 3 07-15-2004 09:37 PM


All times are GMT -5. The time now is 06:07 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration