The UNIX and Linux Forums  

Go Back   The UNIX and Linux Forums > Top Forums > High Level Programming
Google UNIX.COM


High Level Programming Post questions about C, C++, Java, SQL, and other programming languages here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Can a child process return a specific value to a parent process ? Ametis1970 High Level Programming 8 04-09-2008 08:22 PM
Return code of background process c19h28O2 Shell Programming and Scripting 3 04-06-2008 08:46 AM
return code of a process filedeliver High Level Programming 1 04-18-2007 10:42 PM
return code of a process filedeliver UNIX for Advanced & Expert Users 1 04-18-2007 12:27 PM
background process return code Vikas Sood Shell Programming and Scripting 5 06-10-2006 06:25 AM

Reply
 
Submit Tools LinkBack Thread Tools Search this Thread Display Modes
  #1  
Old 08-09-2007
Registered User
 

Join Date: Aug 2007
Posts: 4
getting the return code of forked child process (ftp)

Hi,

From within my C++ program, I fork a child process and execl an ftp session (solaris), like this :

std::string szStartCmd = "ftp -i -n -v 192.168.149.31";

int nExecRes = execl("/bin/sh", "sh", "-c", szStartCmd.c_str(), (char *)0);

I use 2 pipes to communicate between my parent process and the ftp. But I'm not sure if it's possible to catch the output of the solaris ftp in a pipe, so that I can use it in my parent process. Until now I've only used uni-directional communication between parent and child process.
Getting commands from my parent to the ftp process works fine, but the ftp output is just printed on the screen. I would like to "catch" it in my parent process. Does anyone know if this is possible ?
Reply With Quote
Forum Sponsor
  #2  
Old 08-09-2007
...@...
 

Join Date: Feb 2004
Location: NM
Posts: 4,298
Call waitpid() using the pid of the child.

waitpid() will return an exit status that can be decoded by macros defined in sys/wait.h like WIFEXITED. Make sure your child returns an exit code from what you are trying to check - ftp. This means your child will have to learn about the return codes in RFC 959 and decide which ones are bad and which ones are okay. The ftp process itself doesn't usually return errors the way you would think, it displays return codes to stdout. And there are quite a few of them.
Reply With Quote
  #3  
Old 08-09-2007
blowtorch's Avatar
Supporter
 
Join Date: Dec 2004
Location: Singapore
Posts: 2,327
As jim mentioned, since ftp displays return codes on the stdout, you might want to think about using popen instead of execl to read the return codes straight off the child's stdout.
Reply With Quote
  #4  
Old 08-10-2007
Registered User
 

Join Date: Aug 2007
Posts: 4
Hello,

Thank you for the answers.
So, now I'm sure it's not something "impossible" that I'm trying to do.

But I'm not there yet. I've copied what I've got so far below.
With this piece of code, I can send ftp commands and get the response on standard output. But how do I catch it now ?

I thought read(fd[0],receive,strlen(receive)); would do this.
Maybe something is wrong with the close and dup'ing in the child process ?

I haven't tried the popen yet, because I have the idea that I'm very close with what I have now.

Does anyone see what's still wrong ?


int fd[2], nStatus;
pid_t pid;

pipe(&fd[0]); //create pipe
if ((pid=fork()) != 0) {
// parent
close(fd[0]);
//close(STD_OUTPUT);
//dup(fd[1]); // sets stdout to this pipe end
//close(fd[1]); // don’t need fd anymore

std::cout << "I'm the parent. I'm a child process of : " << getppid() << ", my pid is " << getpid() << std::endl;

} else {
// child
close(fd[1]);
close(STD_INPUT);
dup(fd[0]); // replace stdin
close(fd[0]);

std::cout << "I'm the child. I'm a child process of : " << getppid() << ", my pid is " << getpid() << std::endl;

std::string szStartCmd = "ftp -i -n -v 192.168.149.31";

int nExecRes = execl("/bin/sh", "sh", "-c", szStartCmd.c_str(), (char *)0);

}

sleep(1);


std::cout << "I'm a child process of : " << getppid() << ", my pid is " << getpid() << std::endl;


// Wait for the child process to end, but without blocking !
// If the child process exits immediately, we assume ftp couldn't be started -> return false
// else the child process is waited for later (it becomes a "zombie" process when ftp is closed,
// by calling waitpid, the zombie processes are cleared.
int nChildDied = waitpid(pid, &nStatus, WNOHANG);

if (nChildDied == 0)
{
// Child is not dead -> protocol analyser was started OK
std::cout << "ftp started, child not dead" << std::endl;

}
else if (nChildDied > 0)
{
// A child process died -> error starting protocol analyser
if (WIFEXITED(nStatus))
{
std::cout << "child process with pid = " << nChildDied << " died. Child WIFEXITED status = "
<< nChildDied << WEXITSTATUS(nStatus);
}
if (WIFSIGNALED(nStatus))
{
std::cout << "child process with pid = " << nChildDied << "died. Child WIFSIGNALED status = "
<< nChildDied << WTERMSIG(nStatus);
}

std::cout << "error starting ftp";

}
else if (nChildDied < 0)
{
// An error occured
if (errno == ECHILD)
{
std::cout << "no child process exists";
}
else if (errno == EINTR)
{
std::cout << "calling process interrupted by a signal";
}
else if (errno == EINVAL)
{
std::cout << "bad argument passed to waitpid";
}
}

char send[80], receive[80] = "initial value";

fprintf(stdout, "Ftp Command ? > "); fgets(send, 80, stdin);

write(fd[1],send,strlen(send));

read(fd[0],receive,strlen(receive));

std::cout << "response from ftp : " << receive << std::endl;

fprintf(stdout, "Ftp Command ? > "); fgets(send, 80, stdin);

write(fd[1],send,strlen(send));

...
Reply With Quote
  #5  
Old 08-10-2007
ilko_partizan's Avatar
Registered User
 

Join Date: Apr 2007
Location: EU, Bulgaria
Posts: 33
You can solve your problem with library functions - "popen", "pclose"

http://www.freebsd.org/cgi/man.cgi?q...SE&format=html

Best regards,
Iliyan Varshilov
Reply With Quote
  #6  
Old 08-18-2007
Registered User
 

Join Date: Jan 2005
Posts: 24
hi
i wrote a reply that took me about an half our or more (my english is not good). when i clicked the "submit request" button another login was requested an all i had written was lost.
therefore a short version of my post:
1. popen is not ansi c and you cannot both write and read from the pipe it creates, espesially not in solaris9 as the manual states.
2. in m.bach,The design of the UNIX operating system,ISBN:0-13-201799-7
one can find a description what one must do
3. i found to examples in the net which i do not check:
Mapping UNIX pipe descriptors to stdin and stdout in C
Simple popen2 implementation [c] [unix] [ipc] [popen] [popen2] [pipes]
4. in your program i am missing the second pipe. you correctly create one pipe and use the dup function to that the child's process stdin now is sent through the pipe. you must create another pipe for the stdout in the same manner
5. after exec the filehandles are inherited so your ftp-progrma will read from one pipe and write to the other. but everything in the program beinning with the line
sleep(1);
will never be executed by the child (but by the parent)

now i make a copy of this text befor i press the submit-button
mfg guenter
Reply With Quote
  #7  
Old 08-18-2007
reborg's Avatar
Administrator
 

Join Date: Mar 2005
Location: Ireland
Posts: 3,642
If you get another login screen and you then login, your operation will be completed, did you do this or did you press "back" on your browser?
Reply With Quote
Google The UNIX and Linux Forums
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes




All times are GMT -7. The time now is 06:02 PM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited.
The UNIX and Linux Forums Content Copyright ©1993-2008. All Rights Reserved.Ad Management by RedTyger Visit The Complex Event Processing Blog

Content Relevant URLs by vBSEO 3.2.0