I'm thinking about different ways of program organization, and in
some ways having one executable is nicer than having several of
them. So I thought that maybe I should avoid exec and just fork
my process and let one branch return, while the other branch
executes another function (instead of execing another image).
The problem: file descriptors. I certainly don't want my forked
process to hang on too files the other process opened, and
close-on-exec is nice, but doesn't apply to fork without exec.
What's the Unix practice here? Do people generally avoid fork
without exec? (Then I wonder why fork exists, instead of having
something like spawn_process(image, params, ...))
Or do they keep a global list of open file descriptors and close
these after the fork?
Well, maybe this style of programming is really crying for threads
instead of processes, I don't know. So far I like the messaging
approach of write/select/read and really want to save myself the
hassle of shared-memory, fun-with-debugging-and-synchronization
threads.
--
XML is a prime example of retarded innovation.
-- Erik Meijer and Peter Drayton, Microsoft Corporation
|
|
0
|
|
|
|
Reply
|
Ulrich
|
7/19/2005 8:01:48 AM |
|
"Ulrich Hobelmann" <u.hobelmann@web.de> wrote in message
news:3k3qbcFslaerU1@individual.net...
> I'm thinking about different ways of program organization, and in some
> ways having one executable is nicer than having several of them. So I
> thought that maybe I should avoid exec and just fork my process and let
> one branch return, while the other branch executes another function
> (instead of execing another image).
That's not unreasonable.
> The problem: file descriptors. I certainly don't want my forked process
> to hang on too files the other process opened, and close-on-exec is nice,
> but doesn't apply to fork without exec.
Close all file descriptors you don't want.
> What's the Unix practice here? Do people generally avoid fork without
> exec? (Then I wonder why fork exists, instead of having something like
> spawn_process(image, params, ...))
There are a lot of reasons that 'fork' and 'exec' are two functions. One
is some people want to 'fork' without 'exec'ing. Another is that you often
need to do things in-between the 'fork' and the 'exec'.
> Or do they keep a global list of open file descriptors and close these
> after the fork?
You don't need a global list, just close every descriptor you don't
want. You can call 'getdtablesize' to get the limit. Then just loop and
close every one you aren't going to use.
> Well, maybe this style of programming is really crying for threads instead
> of processes, I don't know. So far I like the messaging approach of
> write/select/read and really want to save myself the hassle of
> shared-memory, fun-with-debugging-and-synchronization threads.
If you don't share things across threads, you don't need to do anything
special in them just because your process has multiple threads. However, you
will take some penalties in things like 'malloc'.
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/19/2005 8:31:03 AM
|
|
David Schwartz wrote:
> You don't need a global list, just close every descriptor you don't
> want. You can call 'getdtablesize' to get the limit. Then just loop and
> close every one you aren't going to use.
Hm, and that just works? I thought that getdtablesize gives you
the size of the table, not necessarily how many files there are
open (and I don't want to loop through 1000s of entries ;) ), and
that close() gives an error if you don't pass it an open file (so
while that works, it's not really clean style, and makes lots of
unneeded system calls).
> If you don't share things across threads, you don't need to do anything
> special in them just because your process has multiple threads. However, you
> will take some penalties in things like 'malloc'.
Hm, maybe that would be time to dig my own malloc out again, and
port it to use mmap()... :)
--
XML is a prime example of retarded innovation.
-- Erik Meijer and Peter Drayton, Microsoft Corporation
|
|
0
|
|
|
|
Reply
|
Ulrich
|
7/19/2005 8:43:46 AM
|
|
"Ulrich Hobelmann" <u.hobelmann@web.de> wrote in message
news:3k3sq2FsgdqcU1@individual.net...
> David Schwartz wrote:
>> You don't need a global list, just close every descriptor you don't
>> want. You can call 'getdtablesize' to get the limit. Then just loop and
>> close every one you aren't going to use.
> Hm, and that just works? I thought that getdtablesize gives you the size
> of the table, not necessarily how many files there are open (and I don't
> want to loop through 1000s of entries ;) ), and that close() gives an
> error if you don't pass it an open file (so while that works, it's not
> really clean style, and makes lots of unneeded system calls).
It's not elegant, but there's no alternative. The system calls are
needed.
>> If you don't share things across threads, you don't need to do
>> anything special in them just because your process has multiple threads.
>> However, you will take some penalties in things like 'malloc'.
> Hm, maybe that would be time to dig my own malloc out again, and port it
> to use mmap()... :)
If you need a high-performance multi-threaded malloc, hoard is out
there.
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/19/2005 10:00:09 AM
|
|
Ulrich Hobelmann <u.hobelmann@web.de> writes:
>David Schwartz wrote:
>> You don't need a global list, just close every descriptor you don't
>> want. You can call 'getdtablesize' to get the limit. Then just loop and
>> close every one you aren't going to use.
>Hm, and that just works? I thought that getdtablesize gives you
>the size of the table, not necessarily how many files there are
>open (and I don't want to loop through 1000s of entries ;) ), and
>that close() gives an error if you don't pass it an open file (so
>while that works, it's not really clean style, and makes lots of
>unneeded system calls).
It's what people used to do when the number of fds was small;
now that apps can have thousands, this is not always feasible.
Solaris now has "closefrom()" which efficiently closes all
descriptors above a certain number and fdwalk which gives you
a callback for each open fd.
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.
|
|
0
|
|
|
|
Reply
|
Casper
|
7/19/2005 3:36:26 PM
|
|
In article <3k3sq2FsgdqcU1@individual.net>,
Ulrich Hobelmann <u.hobelmann@web.de> wrote:
> David Schwartz wrote:
> > You don't need a global list, just close every descriptor you don't
> > want. You can call 'getdtablesize' to get the limit. Then just loop and
> > close every one you aren't going to use.
>
> Hm, and that just works? I thought that getdtablesize gives you
> the size of the table, not necessarily how many files there are
> open (and I don't want to loop through 1000s of entries ;) ), and
> that close() gives an error if you don't pass it an open file (so
> while that works, it's not really clean style, and makes lots of
> unneeded system calls).
You basically have two choices: keep a list of all the files that were
opened so you know specifically which ones to close, or just try to
close everything and ignore the errors.
There's no "close-on-fork" flag, as you pointed out, so there's no way
for the system to automatically tell which desciptors you want to share
between the parent and child and which you don't, so it can't automate
this for you.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
|
|
0
|
|
|
|
Reply
|
Barry
|
7/20/2005 4:31:44 AM
|
|
David Schwartz wrote:
> "Ulrich Hobelmann" <u.hobelmann@web.de> wrote in message
> news:3k3qbcFslaerU1@individual.net...
....
>>The problem: file descriptors. I certainly don't want my forked process
>>to hang on too files the other process opened, and close-on-exec is nice,
>>but doesn't apply to fork without exec.
>
>
> Close all file descriptors you don't want.
>
As I recently learned and was discussed in the the thread
"password (& host?) file lookups, daemons and stray descriptors"
<42bb3ac4$0$5702$9a6e19ea@news.newshosting.com> (June 26),
some library routines such as getpwuid() open descriptors and
leave them open, with static references to them in the library.
When you fork, the reference in the library is duplicated too.
Reusing the fd that the library still thinks it has can cause
trouble.
The common wisdom of indiscriminately closing all fds you
don't care about after a fork (as shown in many examples of
how to start a daemon) seems wrong. The only place you can get
away with this is at the start of your freshly exec'd program,
or just prior to exec'ing another program.
--
Clem
"If you push something hard enough, it will fall over."
- Fudd's first law of opposition
|
|
0
|
|
|
|
Reply
|
Mr
|
7/20/2005 12:56:00 PM
|
|
"Mr. Uh Clem" <uhclem@DutchElmSt.invalid> wrote in message
news:42de4972$0$10990$9a6e19ea@news.newshosting.com...
>> Close all file descriptors you don't want.
> As I recently learned and was discussed in the the thread
> "password (& host?) file lookups, daemons and stray descriptors"
> <42bb3ac4$0$5702$9a6e19ea@news.newshosting.com> (June 26),
> some library routines such as getpwuid() open descriptors and
> leave them open, with static references to them in the library.
> When you fork, the reference in the library is duplicated too.
> Reusing the fd that the library still thinks it has can cause
> trouble.
You can't call functions like 'getpwuid' after you 'fork'.
> The common wisdom of indiscriminately closing all fds you
> don't care about after a fork (as shown in many examples of
> how to start a daemon) seems wrong. The only place you can get
> away with this is at the start of your freshly exec'd program,
> or just prior to exec'ing another program.
What would you suggest?
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/20/2005 7:42:03 PM
|
|
>>> Close all file descriptors you don't want.
>
>> As I recently learned and was discussed in the the thread
>> "password (& host?) file lookups, daemons and stray descriptors"
>> <42bb3ac4$0$5702$9a6e19ea@news.newshosting.com> (June 26),
>> some library routines such as getpwuid() open descriptors and
>> leave them open, with static references to them in the library.
>> When you fork, the reference in the library is duplicated too.
>> Reusing the fd that the library still thinks it has can cause
>> trouble.
>
> You can't call functions like 'getpwuid' after you 'fork'.
What functions are "like getpwuid"? How do I identify them? Any
function that leaves files open? Does that include fopen() and
open()? It seems to me that "like getpwuid" depends too much on
internal implementation and not on the interface or documentation.
Gordon L. Burditt
|
|
0
|
|
|
|
Reply
|
gordonb
|
7/20/2005 8:34:27 PM
|
|
"Gordon Burditt" <gordonb.e5b7l@burditt.org> wrote in message
news:11dtdajr9cb16ac@corp.supernews.com...
>>>> Close all file descriptors you don't want.
>> You can't call functions like 'getpwuid' after you 'fork'.
> What functions are "like getpwuid"? How do I identify them? Any
> function that leaves files open? Does that include fopen() and
> open()? It seems to me that "like getpwuid" depends too much on
> internal implementation and not on the interface or documentation.
Any function that is not known to be safe between 'fork' and 'exec' must
not be called. You are very limited in what you can safely do between a
'fork' and an 'exec', just as you are in many other contexts such as signal
handlers. If, after a 'fork', neither process calls 'exec', you have a lot
of potential problems with shared structures. That's just a fact.
Sorry. I wish it wasn't so.
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/20/2005 11:59:57 PM
|
|
In article <dbmohv$jj8$1@nntp.webmaster.com>,
"David Schwartz" <davids@webmaster.com> wrote:
> "Gordon Burditt" <gordonb.e5b7l@burditt.org> wrote in message
> news:11dtdajr9cb16ac@corp.supernews.com...
>
> >>>> Close all file descriptors you don't want.
>
> >> You can't call functions like 'getpwuid' after you 'fork'.
>
> > What functions are "like getpwuid"? How do I identify them? Any
> > function that leaves files open? Does that include fopen() and
> > open()? It seems to me that "like getpwuid" depends too much on
> > internal implementation and not on the interface or documentation.
>
> Any function that is not known to be safe between 'fork' and 'exec' must
> not be called. You are very limited in what you can safely do between a
> 'fork' and an 'exec', just as you are in many other contexts such as signal
> handlers. If, after a 'fork', neither process calls 'exec', you have a lot
> of potential problems with shared structures. That's just a fact.
But what if you never exec()? I think you're confusing fork() with
vfork(). The latter is only supposed to be used if you plan on calling
exec() almost immediately.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
|
|
0
|
|
|
|
Reply
|
Barry
|
7/21/2005 1:11:03 AM
|
|
>>>>> Close all file descriptors you don't want.
>
>>> You can't call functions like 'getpwuid' after you 'fork'.
>
>> What functions are "like getpwuid"? How do I identify them? Any
>> function that leaves files open? Does that include fopen() and
>> open()? It seems to me that "like getpwuid" depends too much on
>> internal implementation and not on the interface or documentation.
>
> Any function that is not known to be safe between 'fork' and 'exec' must
>not be called. You are very limited in what you can safely do between a
>'fork' and an 'exec', just as you are in many other contexts such as signal
>handlers. If, after a 'fork', neither process calls 'exec', you have a lot
>of potential problems with shared structures. That's just a fact.
What "shared structures"? The problem with getpwuid() is a problem
with shared file descriptors (which share a common file pointer),
or with closing a library routine's file descriptor behind it's back.
Where does fork() create memory sharing? It makes COPIES, logically,
anyway. It doesn't create shared memory where a write by one is seen
by the other process (copy-on-write, if used, tears down the sharing
when one process writes).
Gordon L. Burditt
|
|
0
|
|
|
|
Reply
|
gordonb
|
7/21/2005 1:57:01 AM
|
|
"Barry Margolin" <barmar@alum.mit.edu> wrote in message
news:barmar-62331C.21110320072005@comcast.dca.giganews.com...
> But what if you never exec()?
If you never 'exec' and keep running in both processes, there are quite
a few things you can't (portably, with guaranteed safety) do.
> I think you're confusing fork() with
> vfork(). The latter is only supposed to be used if you plan on calling
> exec() almost immediately.
There are more problems with 'vfork', but there are problems with 'fork'
as well. Consider DNS functions like 'gethostbyname' that might use a
socket. After 'fork', both processes are trying to use the same TCP
connection.
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/21/2005 4:31:08 AM
|
|
"Gordon Burditt" <gordonb.e57v2@burditt.org> wrote in message
news:11du07dfe7atv0c@corp.supernews.com...
> What "shared structures"? The problem with getpwuid() is a problem
> with shared file descriptors (which share a common file pointer),
> or with closing a library routine's file descriptor behind it's back.
The file descriptor table is a structure. After the 'fork' it is shared
(though modifications are not propogated).
> Where does fork() create memory sharing? It makes COPIES, logically,
> anyway. It doesn't create shared memory where a write by one is seen
> by the other process (copy-on-write, if used, tears down the sharing
> when one process writes).
I didn't say it created memory sharing. I said that after a fork there
are shared structures. One of them is the table of file descriptors.
The problem is that everything should be copy on write after the 'fork'.
But some thing can't be copy on write, like file descriptors. And some
things that could be copy on write might not be so simply because the
underlying libraries don't realize, like a client identifier (issued by a
server, generated randomly, or whatever) that's expected to be unique for
each client.
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/21/2005 4:33:17 AM
|
|
In article <dbn8e9$pan$1@nntp.webmaster.com>,
"David Schwartz" <davids@webmaster.com> wrote:
> "Barry Margolin" <barmar@alum.mit.edu> wrote in message
> news:barmar-62331C.21110320072005@comcast.dca.giganews.com...
>
> > But what if you never exec()?
>
> If you never 'exec' and keep running in both processes, there are quite
> a few things you can't (portably, with guaranteed safety) do.
>
> > I think you're confusing fork() with
> > vfork(). The latter is only supposed to be used if you plan on calling
> > exec() almost immediately.
>
> There are more problems with 'vfork', but there are problems with 'fork'
> as well. Consider DNS functions like 'gethostbyname' that might use a
> socket. After 'fork', both processes are trying to use the same TCP
> connection.
Good point. Unfortunately, there's no list of "fork-safe" functions,
it's totally implementation dependent.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
|
|
0
|
|
|
|
Reply
|
Barry
|
7/21/2005 6:51:05 AM
|
|
On Thu, 21 Jul 2005 01:57:01 -0000,
Gordon Burditt <gordonb.e57v2@burditt.org> wrote:
>
> What "shared structures"? The problem with getpwuid() is a problem
> with shared file descriptors (which share a common file pointer),
> or with closing a library routine's file descriptor behind it's back.
>
If you call endpwent() when you are done reading password file the
file is closed. If need be you can then re-open the password file
after fork.
Same for calling endhostent() after gethostbyxxx() and about a handfull
of other endxxxent() functions.
Villy
|
|
0
|
|
|
|
Reply
|
Villy
|
7/21/2005 7:48:35 AM
|
|
David Schwartz wrote:
> There are more problems with 'vfork', but there are problems with 'fork'
> as well. Consider DNS functions like 'gethostbyname' that might use a
> socket. After 'fork', both processes are trying to use the same TCP
> connection.
True, but you've changed the rules in the middle of the game. Your
previous statement was about what can be done "between fork and exec",
i.e. *after* the fork. Now you're talking about creating a resource
*before* a fork and the problems associated with using it after.
--
Henry Townsend
|
|
0
|
|
|
|
Reply
|
Henry
|
7/21/2005 1:24:10 PM
|
|
"Henry Townsend" <henry.townsend@not.here> wrote in message
news:TdGdnf-y6u9mPELfRVn-qA@comcast.com...
> David Schwartz wrote:
>> There are more problems with 'vfork', but there are problems with
>> 'fork' as well. Consider DNS functions like 'gethostbyname' that might
>> use a socket. After 'fork', both processes are trying to use the same TCP
>> connection.
> True, but you've changed the rules in the middle of the game. Your
> previous statement was about what can be done "between fork and exec",
> i.e. *after* the fork. Now you're talking about creating a resource
> *before* a fork and the problems associated with using it after.
Huh?
The presumption is that you have a program that's been running and doing
all kinds of things. Now you want to 'fork' and have neither have call
'exec'. You expect each of the two processes to be able to continue doing
things normally without having a problem.
My point is that many library functions may not work right if you do
this.
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/21/2005 4:34:01 PM
|
|
>> What "shared structures"? The problem with getpwuid() is a problem
>> with shared file descriptors (which share a common file pointer),
>> or with closing a library routine's file descriptor behind it's back.
>
> The file descriptor table is a structure.
It's not a structure in the user's program, and you're assuming things
about the implementation of the OS that are not necessarily true,
although that is a fairly obvious implementation.
>After the 'fork' it is shared
>(though modifications are not propogated).
In the case of the file position indicator for shared file descriptors,
modifications *ARE* propogated, and this can cause problems. (For
example, after the fork(), both processes do a sequential scan of
the password file using getpwent(). They are likely to stomp all
over each other, especially if the library is actually using a flat
file for its lookups. Although if the seeking is done in dbm files,
the problems could be just as bad.)
>> Where does fork() create memory sharing? It makes COPIES, logically,
>> anyway. It doesn't create shared memory where a write by one is seen
>> by the other process (copy-on-write, if used, tears down the sharing
>> when one process writes).
>
> I didn't say it created memory sharing. I said that after a fork there
>are shared structures. One of them is the table of file descriptors.
>
> The problem is that everything should be copy on write after the 'fork'.
>But some thing can't be copy on write, like file descriptors. And some
>things that could be copy on write might not be so simply because the
>underlying libraries don't realize, like a client identifier (issued by a
>server, generated randomly, or whatever) that's expected to be unique for
>each client.
So far, it seems all the problems come from unexpected file descriptor
sharing (which includes sockets connected to servers).
Gordon L. Burditt
|
|
0
|
|
|
|
Reply
|
gordonb
|
7/21/2005 5:22:42 PM
|
|
"Gordon Burditt" <gordonb.wm5xl@burditt.org> wrote in message
news:11dvmf2lvrme89c@corp.supernews.com...
>>> What "shared structures"? The problem with getpwuid() is a problem
>>> with shared file descriptors (which share a common file pointer),
>>> or with closing a library routine's file descriptor behind it's back.
>> The file descriptor table is a structure.
> It's not a structure in the user's program, and you're assuming things
> about the implementation of the OS that are not necessarily true,
> although that is a fairly obvious implementation.
Huh? By definition the file descriptor table is a structure. A table of
things is a type of structure.
>>After the 'fork' it is shared
>>(though modifications are not propogated).
> In the case of the file position indicator for shared file descriptors,
> modifications *ARE* propogated, and this can cause problems. (For
> example, after the fork(), both processes do a sequential scan of
> the password file using getpwent(). They are likely to stomp all
> over each other, especially if the library is actually using a flat
> file for its lookups. Although if the seeking is done in dbm files,
> the problems could be just as bad.)
Right.
>> The problem is that everything should be copy on write after the
>> 'fork'.
>>But some thing can't be copy on write, like file descriptors. And some
>>things that could be copy on write might not be so simply because the
>>underlying libraries don't realize, like a client identifier (issued by a
>>server, generated randomly, or whatever) that's expected to be unique for
>>each client.
> So far, it seems all the problems come from unexpected file descriptor
> sharing (which includes sockets connected to servers).
That is far from the only problem. Another example of a type of problem
is PID caching.
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/21/2005 8:59:05 PM
|
|
>>>> What "shared structures"? The problem with getpwuid() is a problem
>>>> with shared file descriptors (which share a common file pointer),
>>>> or with closing a library routine's file descriptor behind it's back.
>
>>> The file descriptor table is a structure.
>
>> It's not a structure in the user's program, and you're assuming things
>> about the implementation of the OS that are not necessarily true,
>> although that is a fairly obvious implementation.
>
> Huh? By definition the file descriptor table is a structure.
Unless, of course, it's NOT a table, but it's a file descriptor SQL
database, or a file descriptor linked list, or a file descriptor
btree, or whatever. Where are you guaranteed that there *IS* a "file
descriptor table"? In any case, it's not part of the user's program.
>A table of
>things is a type of structure.
I'd think a table of things is a type of ARRAY. Possibly, even
usually, an array of structures.
Gordon L. Burditt
|
|
0
|
|
|
|
Reply
|
gordonb
|
7/21/2005 9:14:14 PM
|
|
In article <11e0416gm3jfed9@corp.supernews.com>,
gordonb.y2z4b@burditt.org (Gordon Burditt) wrote:
> >>>> What "shared structures"? The problem with getpwuid() is a problem
> >>>> with shared file descriptors (which share a common file pointer),
> >>>> or with closing a library routine's file descriptor behind it's back.
> >
> >>> The file descriptor table is a structure.
> >
> >> It's not a structure in the user's program, and you're assuming things
> >> about the implementation of the OS that are not necessarily true,
> >> although that is a fairly obvious implementation.
> >
> > Huh? By definition the file descriptor table is a structure.
>
> Unless, of course, it's NOT a table, but it's a file descriptor SQL
> database, or a file descriptor linked list, or a file descriptor
> btree, or whatever. Where are you guaranteed that there *IS* a "file
> descriptor table"? In any case, it's not part of the user's program.
All those are types of structures, in the general sense of the word.
They're not "C structs", but that's irrelevant.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
|
|
0
|
|
|
|
Reply
|
Barry
|
7/22/2005 12:46:41 AM
|
|
"Barry Margolin" <barmar@alum.mit.edu> wrote in message
news:barmar-249662.20464121072005@comcast.dca.giganews.com...
>> Unless, of course, it's NOT a table, but it's a file descriptor SQL
>> database, or a file descriptor linked list, or a file descriptor
>> btree, or whatever. Where are you guaranteed that there *IS* a "file
>> descriptor table"? In any case, it's not part of the user's program.
> All those are types of structures, in the general sense of the word.
> They're not "C structs", but that's irrelevant.
And though the file descriptor table is not part of the program in the
sense of the executable itself, it is part of the program in the sense of
the running instance of the program.
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/22/2005 1:04:43 AM
|
|
"David Schwartz" <davids@webmaster.com> writes:
> "Gordon Burditt" <gordonb.wm5xl@burditt.org> wrote in message
> news:11dvmf2lvrme89c@corp.supernews.com...
> > So far, it seems all the problems come from unexpected file
> > descriptor sharing (which includes sockets connected to servers).
>
> That is far from the only problem. Another example of a type of
> problem is PID caching.
We have our disagreements, but I mostly agree with you in this thread
except that I think you stated your position a little too strongly
when you said "You can't call functions like 'getpwuid' after you
'fork'".
Surely you can, if you know what to do first. It's perfectly
reasonable to call fork() without calling exec(), and do some pretty
non-trivial stuff. The trick is knowing how things work on the
platform being used. That could be said of most things in
programming.
Joe
|
|
0
|
|
|
|
Reply
|
joe
|
7/22/2005 1:08:23 AM
|
|
In article <m3irz3k5q0.fsf@localhost.localdomain>, joe@invalid.address
wrote:
> Surely you can, if you know what to do first. It's perfectly
> reasonable to call fork() without calling exec(), and do some pretty
> non-trivial stuff. The trick is knowing how things work on the
> platform being used. That could be said of most things in
> programming.
The problem is that it can be difficult to perform this trick, since the
issues that have been brought up are almost universally undocumented.
As a result, they're also subject to change from release to release.
Furthermore, POSIX programming is supposed to be portable. Does POSIX
ever suggest that there's a problem calling any of these functions
across forks? This is a pretty annoying gotcha.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
|
|
0
|
|
|
|
Reply
|
Barry
|
7/22/2005 1:31:39 AM
|
|
<joe@invalid.address> wrote in message
news:m3irz3k5q0.fsf@localhost.localdomain...
>> That is far from the only problem. Another example of a type of
>> problem is PID caching.
> Surely you can, if you know what to do first. It's perfectly
> reasonable to call fork() without calling exec(), and do some pretty
> non-trivial stuff. The trick is knowing how things work on the
> platform being used. That could be said of most things in
> programming.
When I say "you can't", I mean portably.
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/22/2005 2:32:09 AM
|
|
"David Schwartz" <davids@webmaster.com> writes:
> <joe@invalid.address> wrote in message
> news:m3irz3k5q0.fsf@localhost.localdomain...
>
> >> That is far from the only problem. Another example of a type of
> >> problem is PID caching.
>
> > Surely you can, if you know what to do first. It's perfectly
> > reasonable to call fork() without calling exec(), and do some
> > pretty non-trivial stuff. The trick is knowing how things work on
> > the platform being used. That could be said of most things in
> > programming.
>
> When I say "you can't", I mean portably.
I don't see how the two are equivalent.
Joe
|
|
0
|
|
|
|
Reply
|
joe
|
7/22/2005 3:00:41 AM
|
|
Barry Margolin <barmar@alum.mit.edu> writes:
> In article <m3irz3k5q0.fsf@localhost.localdomain>, joe@invalid.address
> wrote:
>
> > Surely you can, if you know what to do first. It's perfectly
> > reasonable to call fork() without calling exec(), and do some
> > pretty non-trivial stuff. The trick is knowing how things work on
> > the platform being used. That could be said of most things in
> > programming.
>
> The problem is that it can be difficult to perform this trick, since
> the issues that have been brought up are almost universally
> undocumented. As a result, they're also subject to change from
> release to release.
>
> Furthermore, POSIX programming is supposed to be portable. Does
> POSIX ever suggest that there's a problem calling any of these
> functions across forks? This is a pretty annoying gotcha.
I think that's not the only annoying gotcha in the POSIX, but that's
what defect reports are for.
Be that as it may, as I understand it, apache does pretty much what
we're talking about here. The program that originally gets run opens a
listening port and then forks a bunch of child processes which all
call accept() to handle incoming client connections, letting the
system do some of the load balancing. If I've got that right it seems
to be doable.
I'm not trying to say it's easy to accomplish, only that I think
"can't" is too strong a word for it.
Joe
|
|
0
|
|
|
|
Reply
|
joe
|
7/22/2005 3:05:03 AM
|
|
<joe@invalid.address> wrote in message
news:m38xzzk0iu.fsf@localhost.localdomain...
> "David Schwartz" <davids@webmaster.com> writes:
>> When I say "you can't", I mean portably.
> I don't see how the two are equivalent.
I'm presuming people want to be assured their code will work, even if
it's run on a different system, even when the next version of the library
comes out. Otherwise, what's the point?
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/22/2005 11:01:58 AM
|
|
In article <m38xzzk0iu.fsf@localhost.localdomain>,
<joe@invalid.address> wrote:
>"David Schwartz" <davids@webmaster.com> writes:
>
>> <joe@invalid.address> wrote in message
>> news:m3irz3k5q0.fsf@localhost.localdomain...
>>
>> >> That is far from the only problem. Another example of a type of
>> >> problem is PID caching.
>>
>> > Surely you can, if you know what to do first. It's perfectly
>> > reasonable to call fork() without calling exec(), and do some
>> > pretty non-trivial stuff. The trick is knowing how things work on
>> > the platform being used. That could be said of most things in
>> > programming.
>>
>> When I say "you can't", I mean portably.
>
>I don't see how the two are equivalent.
Welcome to the Humpty Dumpty world of Usenet, wherein people define terms
as they like (and assume, as HD did, that as long as they are consistent in
their usage, they're good-to-go). Try hanging around comp.lang.c for
a while and you'll see it in spades.
|
|
0
|
|
|
|
Reply
|
gazelle
|
7/22/2005 1:16:02 PM
|
|
"David Schwartz" <davids@webmaster.com> writes:
> <joe@invalid.address> wrote in message
> news:m38xzzk0iu.fsf@localhost.localdomain...
>
> > "David Schwartz" <davids@webmaster.com> writes:
>
> >> When I say "you can't", I mean portably.
>
> > I don't see how the two are equivalent.
>
> I'm presuming people want to be assured their code will work,
> even if it's run on a different system, even when the next version
> of the library comes out. Otherwise, what's the point?
Lots of people don't need that assurance.
But the point I was trying to make is that you can call getpwuid after
a fork portably, that's what the preprocessor is for. If I had to
choose between the standard and autoconf I'd probably pick autoconf.
Joe
|
|
0
|
|
|
|
Reply
|
joe
|
7/22/2005 5:47:34 PM
|
|
"Kenny McCormack" <gazelle@yin.interaccess.com> wrote in message
news:dbqrh5$m6g$1@yin.interaccess.com...
>>> When I say "you can't", I mean portably.
>>I don't see how the two are equivalent.
> Welcome to the Humpty Dumpty world of Usenet, wherein people define terms
> as they like (and assume, as HD did, that as long as they are consistent
> in
> their usage, they're good-to-go). Try hanging around comp.lang.c for
> a while and you'll see it in spades.
The standard says what you can and can't do. That's its purpose. We're
talking about a function that is standardized by posix.
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/22/2005 11:09:34 PM
|
|
In article <dbrubg$ft6$1@nntp.webmaster.com>,
David Schwartz <davids@webmaster.com> wrote:
>
>"Kenny McCormack" <gazelle@yin.interaccess.com> wrote in message
>news:dbqrh5$m6g$1@yin.interaccess.com...
>
>>>> When I say "you can't", I mean portably.
>
>>>I don't see how the two are equivalent.
>
>> Welcome to the Humpty Dumpty world of Usenet, wherein people define terms
>> as they like (and assume, as HD did, that as long as they are consistent
>> in
>> their usage, they're good-to-go). Try hanging around comp.lang.c for
>> a while and you'll see it in spades.
>
> The standard says what you can and can't do. That's its purpose. We're
>talking about a function that is standardized by posix.
I will grant that you, Humpty Dumpty, Tweedledee, and Tweedledum are.
The rest of us will just get on with our lives, thankyouverymuch.
|
|
0
|
|
|
|
Reply
|
gazelle
|
7/23/2005 3:05:39 AM
|
|
Villy Kruse wrote:
> On Thu, 21 Jul 2005 01:57:01 -0000,
> Gordon Burditt <gordonb.e57v2@burditt.org> wrote:
>
>
>
>>What "shared structures"? The problem with getpwuid() is a problem
>>with shared file descriptors (which share a common file pointer),
>>or with closing a library routine's file descriptor behind it's back.
>>
>
>
> If you call endpwent() when you are done reading password file the
> file is closed. If need be you can then re-open the password file
> after fork.
>
> Same for calling endhostent() after gethostbyxxx() and about a handfull
> of other endxxxent() functions.
>
> Villy
Unfortunately, endpwent() did not close the socket opened by
getpwuid(). (Having the endxxxxent() functions do such a
clean-up would be a rather rational thing to do.)
--
Clem
"If you push something hard enough, it will fall over."
- Fudd's first law of opposition
|
|
0
|
|
|
|
Reply
|
Mr
|
7/23/2005 10:45:23 PM
|
|
In article <42e2c80b$0$11011$9a6e19ea@news.newshosting.com>,
"Mr. Uh Clem" <uhclem@DutchElmSt.invalid> wrote:
> Villy Kruse wrote:
>
> > On Thu, 21 Jul 2005 01:57:01 -0000,
> > Gordon Burditt <gordonb.e57v2@burditt.org> wrote:
> >
> >
> >
> >>What "shared structures"? The problem with getpwuid() is a problem
> >>with shared file descriptors (which share a common file pointer),
> >>or with closing a library routine's file descriptor behind it's back.
> >>
> >
> >
> > If you call endpwent() when you are done reading password file the
> > file is closed. If need be you can then re-open the password file
> > after fork.
> >
> > Same for calling endhostent() after gethostbyxxx() and about a handfull
> > of other endxxxent() functions.
> >
> > Villy
>
> Unfortunately, endpwent() did not close the socket opened by
> getpwuid(). (Having the endxxxxent() functions do such a
> clean-up would be a rather rational thing to do.)
The problem is probably that it's using NIS, and there's no call to tell
NIS that it should close its socket.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
|
|
0
|
|
|
|
Reply
|
Barry
|
8/2/2005 5:33:37 AM
|
|
|
34 Replies
240 Views
(page loaded in 1.11 seconds)
Similiar Articles: Practice of using fork() - comp.unix.programmerI'm thinking about different ways of program organization, and in some ways having one executable is nicer than having several of them. So I though... how to debug forked child in eclipse CDT - comp.unix.programmer ...Practice of using fork() - comp.unix.programmer I certainly don't want my forked process to hang on too ... opens a listening port and then forks a bunch of child ... comp ... fork communication between parent & child - comp.unix.programmer ...Practice of using fork() - comp.unix.programmer Another is that you often need to do things in-between the 'fork' and the 'exec'. ... to automatically tell which ... Could not fork: Not enough space - comp.sys.hp.hpuxPractice of using fork() - comp.unix.programmer And some things that could be copy on write might not be so simply because the ... like a judicious use of funds to me ... Spawn process: No such file or directory - comp.parallel.mpi ...Practice of using fork() - comp.unix.programmer Spawn process: No such file or directory - comp.parallel.mpi ... Common practice is to use the user's home directories ... Synchronization between AD and Sun One Directory Server... - comp ...Practice of using fork() - comp.unix.programmer... of program organization, and in some ways having one ... realize, like a client identifier (issued by a server ... tcp push-flag - comp.unix.solarisPractice of using fork() - comp.unix.programmer There's no "close-on-fork" flag, as you pointed out, so ... -- Clem "If you push something hard enough, it will fall over." Way to avoid having to type sudo password each time? - comp.sys ...Practice of using fork() - comp.unix.programmer... ways of program organization, and in some ways having one ... So I thought that maybe I should avoid exec and just ... Adding prefix and suffix - comp.unix.shellPractice of using fork() - comp.unix.programmer Adding prefix and suffix - comp.unix.shell... optimally unless there's other factors >force use of a ... used by >>some ... implementation question (Java): Timestamp - comp.protocols.time ...Practice of using fork() - comp.unix.programmer... like getpwuid" depends too much on internal implementation ... alum.mit.edu Arlington, MA *** PLEASE post questions in ... File descriptor suddenly goes bad - comp.unix.programmer ...Practice of using fork() - comp.unix.programmer The problem: file descriptors. I certainly don't want my forked ... done in dbm files, the problems could be just as bad ... Limiting file system caching on RH Linux version 5 - comp ...Practice of using fork() - comp.unix.programmer The problem: file descriptors. I certainly ... example of a type of problem is PID caching ... work, even if it's run on a ... Bad File Descriptor - comp.protocols.time.ntpPractice of using fork() - comp.unix.programmer The problem: file descriptors. I certainly don't want my forked process to hang on too ... if the seeking is done in dbm ... GAWK: A fix for "missing file is a fatal error" - comp.lang.awk ...... 13:34, Aharon Robbins wrote: > Kenny: You are, of course, welcome to fork ... In practice, what I do is use getline to take control of this process instead of passing the ... Encapsulation in VPN - comp.dcom.sys.ciscoThe PPTP is using for client to server. IPSec can be ... if you look at how IPsec is used in practice for "non ... closed off, then it would be a simple matter to fork ... Practice of using fork() - comp.unix.programmer | Computer GroupI'm thinking about different ways of program organization, and in some ways having one executable is nicer than having several of them. So I though... Java theory and practice: Stick a fork in it, Part 1Java theory and practice: Stick a fork in it, Part 1. Learn how to exploit fine-grained parallelism using the fork-join framework coming in Java 7 7/20/2012 4:51:46 PM
|