For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > December 2006 > managing tcp fd between parent and child process.









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author managing tcp fd between parent and child process.
vijay_kh_2000@yahoo.com

2006-12-16, 7:06 pm

Hi,

I need to develop a tcp server which takes and validate the information
from clients. Upon the validation, I need to create/replace the parent
with child process which would process the further request from client
without breaking the tcp connection.
How do I pass the FD to in case of execlp ?(probably by passing as
input argument)
How about if I use fork () ? (probably using the same FD as parent is
using)

which is the best approach for this problem. How do I handle exit,
closing of the FDs.

Thanks,
vj

Jens Thoms Toerring

2006-12-16, 7:06 pm

vijay_kh_2000@yahoo.com wrote:
> I need to develop a tcp server which takes and validate the information
> from clients. Upon the validation, I need to create/replace the parent
> with child process which would process the further request from client
> without breaking the tcp connection.
> How do I pass the FD to in case of execlp ?(probably by passing as
> input argument)


You can't pass a file descriptor as one of the argument - it's just
an integer number that has no meaning in the exec-ed program. There's
some way to pass an open file descriptor to an unrelated process
but I have never tried it and it is probably too complicated for
your case.

> How about if I use fork () ? (probably using the same FD as parent is
> using)


> which is the best approach for this problem. How do I handle exit,
> closing of the FDs.


Unless something else forces you to I would go with the fork()
approach. The child "inherits" the file descriptor and does it's
work with it while the parent just closes it immediately (no harm
done that way since the child has it still open). Once the child
is done with the file descriptor it also closes it (either expli-
citely or by simply by exiting), thereby closing the connection.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
vijay_kh_2000@yahoo.com

2006-12-16, 7:06 pm

Thanks Jens,

Even if I use the fork(), I have to use execlp to load the respective
child image. This doesn't solve the problem of passing the FD to child
process. Is it send_fd /recv_fd functions that we need to use ? It
seems even these functions will work in proper parent/child relations.
I'm not sure if execlp is treated as proper child. I will have to try
these tricks. let me know if you have additional information.

Thanks,
-vj
Jens Thoms Toerring wrote:
> vijay_kh_2000@yahoo.com wrote:
>
> You can't pass a file descriptor as one of the argument - it's just
> an integer number that has no meaning in the exec-ed program. There's
> some way to pass an open file descriptor to an unrelated process
> but I have never tried it and it is probably too complicated for
> your case.
>
>
>
> Unless something else forces you to I would go with the fork()
> approach. The child "inherits" the file descriptor and does it's
> work with it while the parent just closes it immediately (no harm
> done that way since the child has it still open). Once the child
> is done with the file descriptor it also closes it (either expli-
> citely or by simply by exiting), thereby closing the connection.
>
> Regards, Jens
> --
> \ Jens Thoms Toerring ___ jt@toerring.de
> \__________________________ http://toerring.de


Jens Thoms Toerring

2006-12-16, 7:06 pm

vijay_kh_2000@yahoo.com wrote:
> Even if I use the fork(), I have to use execlp to load the respective
> child image.


That's unfortunate - quite often servers that have to deal with
several connections at once contain both the code for waiting
for an incoming connection as well as the one for dealing with
the connection, where the parent does the waiting, and when a
new connection comes in, fork()'s and then lets the child run
the code for dealing with whatever the other side requires
while the parent goes back to waiting for the next connection.

> This doesn't solve the problem of passing the FD to child
> process. Is it send_fd /recv_fd functions that we need to use ? It
> seems even these functions will work in proper parent/child relations.


That are the ones I have read about (Stevens' APUE). I am not sure how
common these functions are - on my Linux system I couldn't find them
in the man pages or in any of the include files and also the SUSv3
(POSIX) standard doesn't seem to know about them. So you may have to
write them yourself - there are some examples to be found on the net,
if they are correct I can't tell.

> I'm not sure if execlp is treated as proper child. I will have to try
> these tricks. let me know if you have additional information.


The execlp()-ed process is definitely still child of the process that
called fork(). But I am unfamiliar with the term "proper child", so I
don't know if that counts.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
loic-dev@gmx.net

2006-12-16, 7:06 pm

Good Evening vj,

> Even if I use the fork(), I have to use execlp to load the respective
> child image. This doesn't solve the problem of passing the FD to child
> process. Is it send_fd /recv_fd functions that we need to use ? It
> seems even these functions will work in proper parent/child relations.
> I'm not sure if execlp is treated as proper child. I will have to try
> these tricks. let me know if you have additional information.


You may even not need to /fork()/ actually, if there is no need to keep
the parent. Doing so looks however suspicious; since this would mean
that your server can accept only one connection... That's why a
classical design consists to have a process for the listening part that
forks a child at each new connection.

Anyway, speaking of the execv* family, SUSv3 tells us:
<quote>
File descriptors open in the calling process image shall remain open in
the new process image, except for those whose close-on- exec flag
FD_CLOEXEC is set. For those file descriptors that remain open, all
attributes of the open file description remain unchanged
</quote>

So that means: you basically keep the fd corresponding to the TCP
opened. The /exec()/'ed process shall then "inherit" this descriptor,
and can continue to "dialog" with the remote end of the TCP connection
as usual over that fd...

You could even go a step further. In the child, you can close all
descriptors other than the socket corresponding to the TCP connection,
dup that descriptor to 0,1,2 and close the socket. Then you /exec()/
your program. Doing so as the advantage that the /exec()/'ed program
isn't aware that is talking over a TCP connection: it just reads input
from stdin, write to stdout and stderr as it normally does. That's
basically how the inetd superserver works.

HTH,
Loic.

Jens Thoms Toerring

2006-12-16, 7:06 pm

loic-dev@gmx.net wrote:
> Anyway, speaking of the execv* family, SUSv3 tells us:
> <quote>
> File descriptors open in the calling process image shall remain open in
> the new process image, except for those whose close-on- exec flag
> FD_CLOEXEC is set. For those file descriptors that remain open, all
> attributes of the open file description remain unchanged
> </quote>


> So that means: you basically keep the fd corresponding to the TCP
> opened. The /exec()/'ed process shall then "inherit" this descriptor,
> and can continue to "dialog" with the remote end of the TCP connection
> as usual over that fd...


Thanks for reminding me about that, so it's rather simple for the OP.
But one question: how does the exec()-ed process know which fd to use?
Is it guaranteed to have the same number as before the exec() (so you
can pass it along in argv[])? Or, if you had only 0, 1 and 2 beside
the socket open before the exec() but the socket fd was e.g. 5 (e.g.
because two other files were open when the connection was made, but
which got closed before exec() was called), will it become 3? Or
will you have to use dup() before the exec() if you want to achieve
that?
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
vijay_kh_2000@yahoo.com

2006-12-16, 7:06 pm

Good Evening loic,
Thanks for your reply. I guess you got my requirement. But I'm not
looking for rich featured server. Presently even one client connection
will work for me. Also I feel it is better to go for classical design
with fork. See my reply inline.

loic-dev@gmx.net wrote:
> Good Evening vj,
>
>
> You may even not need to /fork()/ actually, if there is no need to keep
> the parent. Doing so looks however suspicious; since this would mean
> that your server can accept only one connection... That's why a
> classical design consists to have a process for the listening part that
> forks a child at each new connection.
>

Now I will go for classical design with fork to support multiple
clients.

> Anyway, speaking of the execv* family, SUSv3 tells us:
> <quote>
> File descriptors open in the calling process image shall remain open in
> the new process image, except for those whose close-on- exec flag
> FD_CLOEXEC is set. For those file descriptors that remain open, all
> attributes of the open file description remain unchanged
> </quote>
>
> So that means: you basically keep the fd corresponding to the TCP
> opened. The /exec()/'ed process shall then "inherit" this descriptor,
> and can continue to "dialog" with the remote end of the TCP connection
> as usual over that fd...


To use the same fd by exec'd process, the process needs to know which
fd/socket (value)
it should read/write. So I was thinking to pass the fd as an input
argument to execlp call.

>
> You could even go a step further. In the child, you can close all
> descriptors other than the socket corresponding to the TCP connection,
> dup that descriptor to 0,1,2 and close the socket. Then you /exec()/
> your program. Doing so as the advantage that the /exec()/'ed program
> isn't aware that is talking over a TCP connection: it just reads input
> from stdin, write to stdout and stderr as it normally does. That's
> basically how the inetd superserver works.

You meant in this case I need not to pass even the fd to exec'd
process. The exec'd process should always read/write to stdin/stdout
which will be redirected to socket.
Is this correct?
>
> HTH,
> Loic.

-vj

loic-dev@gmx.net

2006-12-16, 7:06 pm

Guten Abend Jens,

I guess, a new day has for us begun...

>
>
> Thanks for reminding me about that, so it's rather simple for the OP.
> But one question: how does the exec()-ed process know which fd to use?
> Is it guaranteed to have the same number as before the exec() (so you
> can pass it along in argv[])?


Yes, the file descriptor will have the same number as before the
/exec()/. As you guessed, one possibility is to pass that descriptor's
number as argument to the /exec()/'ed process.

Another possibility, mentioned in my previous post, could be to use
/dup2()/ + /close()/ to make sure that the descriptor has a well known
number (e.g. 3) before /exec()/'ing the process. That's basically the
technique used by inetd, which uses fd 0,1,2 as well known descriptors.

Cheers,
Loic.

loic-dev@gmx.net

2006-12-16, 7:06 pm

Hello Vijay,

>
> To use the same fd by exec'd process, the process needs to know which
> fd/socket (value)
> it should read/write. So I was thinking to pass the fd as an input
> argument to execlp call.


Yes that's one possibility: pass the file descriptor number to the
/exec()/'ed process. See my last post in reply to Jens for more
details.


>
> You meant in this case I need not to pass even the fd to exec'd
> process. The exec'd process should always read/write to stdin/stdout
> which will be redirected to socket.
> Is this correct?


Exactly. Isn't UNIX a nice, well designed operating system :-D

Doing so may simplify the code for the exec'd process. You may want
however to stick to your original idea, if your process needs to
somehow knows that it is dealing with a TCP connection...

Cheers,
Loic.

Casper H.S. Dik

2006-12-17, 4:10 am

jt@toerring.de (Jens Thoms Toerring) writes:

>You can't pass a file descriptor as one of the argument - it's just
>an integer number that has no meaning in the exec-ed program. There's
>some way to pass an open file descriptor to an unrelated process
>but I have never tried it and it is probably too complicated for
>your case.


The "integer" has precisely the same meaning in the exec'ed process
as in the original process; but you will have to tell the exec'ed process
on which fd the TCP connection is, generally by way of a commandline
argument, though an environment variable would also work.

Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
Casper H.S. Dik

2006-12-17, 8:06 am

vijay_kh_2000@yahoo.com writes:

>Even if I use the fork(), I have to use execlp to load the respective
>child image. This doesn't solve the problem of passing the FD to child
>process. Is it send_fd /recv_fd functions that we need to use ? It
>seems even these functions will work in proper parent/child relations.
>I'm not sure if execlp is treated as proper child. I will have to try
>these tricks. let me know if you have additional information.


The exec'ed process has all the original program's file descriptors,
except for those marked close-on-exec (which is something you need
to deliberately set).

Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
Alex Fraser

2006-12-17, 7:04 pm

"Casper H.S. Dik" <Casper.Dik@Sun.COM> wrote in message
news:4585174a$0$326$e4fe514c@news.xs4all.nl...
> jt@toerring.de (Jens Thoms Toerring) writes:
>
> The "integer" has precisely the same meaning in the exec'ed process
> as in the original process; but you will have to tell the exec'ed process
> on which fd the TCP connection is, generally by way of a commandline
> argument, though an environment variable would also work.


Is there a reason to favour this over doing it "by agreement"? That is, as
Loic suggested, dup2() to specified descriptor(s) such as 0-2 (like inetd)
or 3.

Alex


loic-dev@gmx.net

2006-12-17, 7:04 pm

Hi Alex,

> "Casper H.S. Dik" <Casper.Dik@Sun.COM> wrote in message
> news:4585174a$0$326$e4fe514c@news.xs4all.nl...
>
> Is there a reason to favour this over doing it "by agreement"? That is, as
> Loic suggested, dup2() to specified descriptor(s) such as 0-2 (like inetd)
> or 3.


Guess, it's a matter of taste...

Cheers,
Loic.

Casper H.S. Dik

2006-12-18, 8:06 am

"Alex Fraser" <me@privacy.net> writes:

>Is there a reason to favour this over doing it "by agreement"? That is, as
>Loic suggested, dup2() to specified descriptor(s) such as 0-2 (like inetd)
>or 3.


It all depens on the circumstances; (multiple files need passing or
just the one).

dup2() a pre-arranged fd should work just fine.

Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
vijay_kh_2000@yahoo.com

2006-12-24, 10:04 pm

Casper,

I can't use dup2 here because child process sometimes put the debug
printfs which goes to stdout. If stdout is redirected/duped to socket,
it gives unexpected results. So I opted for passing fd to execlp.

-Vijay
Casper H.S. Dik wrote:
> "Alex Fraser" <me@privacy.net> writes:
>
>
> It all depens on the circumstances; (multiple files need passing or
> just the one).
>
> dup2() a pre-arranged fd should work just fine.
>
> Casper
> --
> Expressed in this posting are my opinions. They are in no way related
> to opinions held by my employer, Sun Microsystems.
> Statements on Sun products included here are not gospel and may
> be fiction rather than truth.


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com