LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
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
 
Thread Tools
Old 11-05-2009, 12:34 AM   #1
nagendrar
Member
 
Registered: Apr 2008
Location: HYD, INDIA.
Posts: 40
Thanked: 0
examples with 2 pipes+fork+handling error,output in different files


[Log in to get rid of this advertisement]
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-05-2009 at 12:38 AM..
linux nagendrar is offline     Reply With Quote
Old 11-05-2009, 05:58 PM   #2
pixellany
Moderator
 
Registered: Nov 2005
Location: Pasadena, CA
Distribution: Arch
Posts: 13,173
Thanked: 285
Please provide some context. If this is homework, tell us more about the class, what books you are usig etc.
linux pixellany is offline     Reply With Quote


Old 11-06-2009, 12:04 AM   #3
nagendrar
Member
 
Registered: Apr 2008
Location: HYD, INDIA.
Posts: 40
Thanked: 0

Original Poster
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]);
};
}
linux nagendrar is offline     Reply With Quote


Old 11-06-2009, 01:15 AM   #4
chrism01
Guru
 
Registered: Aug 2004
Location: Brisbane
Distribution: Centos 5.4
Posts: 7,429
Thanked: 326
I recommend you ask the Mods (via the Report button) to move this to the Programming forum.
windows_xp_2003 chrism01 is offline     Reply With Quote


Old 11-06-2009, 07:36 AM   #5
pixellany
Moderator
 
Registered: Nov 2005
Location: Pasadena, CA
Distribution: Arch
Posts: 13,173
Thanked: 285
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....
linux pixellany is offline     Reply With Quote



Reply

Bookmarks


Thread Tools

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 01:10 PM
Sed gives output in pipes only when buffer is full jahvascriptmaniac Linux - Software 2 08-31-2006 06:57 PM
interrupt handling - fork - exec help!! James Scrymgeour Programming 0 06-15-2006 11:34 AM
Need help w/ shell handling 3 commands/2 pipes sptchamp Programming 3 07-15-2004 10:37 PM


All times are GMT -5. The time now is 10:28 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
RSS2  LQ Podcast
RSS2  LQ Radio
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration