guy@gorodish.UUCP (06/08/87)
> I am currently working on my research using C concurrent programming > technique of fork & join and pipe. This isn't a C technique, it's a UNIX technique. I'm redirecting further discussion to comp.unix.questions/INFO-UNIX. > Are there any other ways of creating more than one child at a time. > The method I am using is read in the number of processes and use > this variable to determine the number of children to fork using > a simple FOR loop in C. No, there is no way in UNIX to create processes other than "fork", and that only creates one at a time. > Are there any books on these topics. There are lots of books on programming under UNIX, some of which will discuss this. There's a book by Brian Kernighan and Rob Pike, titled "The UNIX Programming Environment", which has been highly recommended by many people. (I don't know if it discusses this or not.) There is also a document called "UNIX Programming", by Kernighan and Ritchie, that comes with various versions of UNIX. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
mikep@ism780c.UUCP (06/10/87)
In article <20616@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes: > >No, there is no way in UNIX to create processes other than "fork", >and that only creates one at a time. > >> Are there any books on these topics. > >There are lots of books on programming under UNIX, some of which will >discuss this. There's a book by Brian Kernighan and Rob Pike, titled >"The UNIX Programming Environment", which has been highly recommended >by many people. (I don't know if it discusses this or not.) There >is also a document called "UNIX Programming", by Kernighan and >Ritchie, that comes with various versions of UNIX. There is another book that is much better than "The UNIX Programming Environment" for this and it is called, "Advanced UNIX Programming" by Marc J. Rochkind. This book is also put out by Prentice Hall, and describes the UNIX System call level more thoroughly than any other book I've seen. It's also very interesting bathroom reading... ------------------------------------------------------------------------------- The company and all my associates and friends and ESPECIALLY the government put me up to say all this useless trash. |=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=|=| MikeP sdcrdcf!\ "Some of my best friends are Bigots..." >-- ism780c!mikep seismo!/
mj@elmgate.UUCP (06/15/87)
> Are there any books on these topics.
Yet another good book on UNIX (although probably too advanced for the
fork/join/pipe questions) is THE DESIGN OF THE UNIX OPERATING SYSTEM
by Maurice Bach, c. 1986, Bell Telephone Laboratories (Prentice-Hall
software series). In this book, Bach describes the internal data
structures and algorithms of the kernel, and details how
these support the user interface. As a Unix programmer who
understands most of the system calls fairly well and would like
to begin digging at the kernel, I have found this books to be
complete and informative. The Advanced UNIX Programming book
mentioned earlier is also very good.
-------------------------------------------------------------------------------
Mark A Johnson - Eastman Kodak Co. - Dept 646 - KEEPS - Rochester, NY 14650
The opinions expressed above are not necessarily those of Eastman Kodak Company
and are entirely my responsibility.
guy%gorodish@Sun.COM (Guy Harris) (06/22/87)
(Again, we redirect this to comp.unix.questions/INFO-UNIX.) > If vfork is much faster (as opposed to slightly faster) than fork, it is > time to complain to the supplier of your Unix, asking why he hasn't > implemented fork efficiently. Even Berkeley *intended* to fix this, as > witness the comments on the vfork manual page. Sensible vendors have > long since implemented copy-on-write fork, which eliminates most of the > copying involved in fork, thus eliminating most of the reason to use the > ugly and brain-damaged vfork. Or, at least, sensible vendors that are implementing on hardware that provides the ability to specify, with a relatively small granularity, regions of a process' address space such that attempts to modify them will cause traps. If, for example, you are stuck with write-protecting the entire data or stack segment, copy-on-write may not buy you much. Fortunately, most machines don't impose obnoxious restrictions of that flavor. The only remaining reason to use vfork is that one has written ugly and brain-damaged code that depends on the semantics of "vfork". Such code does, unfortunately, exist; one of the pre-releases of 4.3BSD used this crock in "find", but it was fixed before 4.3BSD went out the door in its final form. If anybody has written code of this sort, they should hang their head in shame and then go out and fix it NOW. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
lm@cottage.WISC.EDU (Larry McVoy) (06/22/87)
In article <21685@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes:
$ The only remaining reason to use vfork is that one has written ugly
$ and brain-damaged code that depends on the semantics of "vfork".
Well, now, I'm not quite sure I agree with this. I'll admit that taking
advantage of the semantics of a doomed system call is ugly. But suppose
I were to phrase it like this: I wasn't taking advantage of vfork, I
just had a need for shared memory. Then it's probably ok, right?
Everyone thinks shm is great, n'est pas? (So when are we going to see
shm in 4.x? Hmm?)
Don't misunderstand me - I'm not telling you to use vfork - I'm just
pointing out that code that uses the semantics of vfork is not
necessarily "ugly and brain-damaged."
Larry McVoy lm@cottage.wisc.edu or uwvax!mcvoy
guy%gorodish@Sun.COM (Guy Harris) (06/22/87)
> Well, now, I'm not quite sure I agree with this. I'll admit that taking > advantage of the semantics of a doomed system call is ugly. But suppose > I were to phrase it like this: I wasn't taking advantage of vfork, I > just had a need for shared memory. Then it's probably ok, right? No! For one thing, the system call *is* doomed, and future implementations of "vfork" may not *give* you shared memory; in that case, your program will silently stop working. For another, you don't necessarily get *useful* shared memory - after a "vfork", the parent is blocked until the child either exits or does an "exec", releasing the shared memory. > Everyone thinks shm is great, n'est pas? Yes, shared memory is nice, but "vfork" *isn't* a mechanism for getting shared memory. > (So when are we going to see shm in 4.x? Hmm?) Don't ask me, I'm not responsible for 4.x. > Don't misunderstand me - I'm not telling you to use vfork - I'm just > pointing out that code that uses the semantics of vfork is not > necessarily "ugly and brain-damaged." Yes, it is. There is very little you can do with the (temporarily) shared memory you get from "vfork", and in most, if not all, cases, you can do the same thing just as well without it. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
schoch@ames.arpa (Steve Schoch) (06/24/87)
In article <21731@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes: > There is very little you can do with the (temporarily) shared >memory you get from "vfork", and in most, if not all, cases, you can >do the same thing just as well without it. Try the built-in command "hashstat" in csh. It's to be used mostly for debugging, I assume, as it tells you how well the exec hash table is working. The way it counts a "miss" is by incrementing a variable everytime a exec fails. It has to do this in the child, and thus uses the vfork "shared memory". Steve
guy%gorodish@Sun.COM (Guy Harris) (06/24/87)
> Try the built-in command "hashstat" in csh. It's to be used mostly for > debugging, I assume, as it tells you how well the exec hash table is working. > The way it counts a "miss" is by incrementing a variable everytime a exec > fails. It has to do this in the child, and thus uses the vfork "shared > memory". It could also do this with a shared file; abusing "vfork"s shared memory may have been convenient, but it wasn't necessary. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
tytso@athena.mit.edu (Theodore Y. Ts'o) (06/25/87)
In article <21928@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes: >> Try the built-in command "hashstat" in csh. It's to be used mostly for >> debugging, I assume, as it tells you how well the exec hash table is working. >> The way it counts a "miss" is by incrementing a variable everytime a exec >> fails. It has to do this in the child, and thus uses the vfork "shared >> memory". > >It could also do this with a shared file; abusing "vfork"s shared memory >may have been convenient, but it wasn't necessary. What about the overhead to update said shared file every time you execute a command? I think I prefer the "abuse" of the shared memory. The main purpose of vfork was to enhance csh's effiency anyway. =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Theodore Ts'o | mit-eddie!mit-athena!tytso | M.I.T., tytso@athena.mit.edu | P.h.D., 3 Ames St., Cambridge, MA 02139 | M.O.N.E.Y.! | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
guy%gorodish@Sun.COM (Guy Harris) (06/25/87)
> What about the overhead to update said shared file every time you > execute a command? Try it first, see how much the overhead really is, then complain. Don't assume it'll have to be so large as to render abusing "vfork" acceptable; it may very well not be noticeable. > I think I prefer the "abuse" of the shared memory. I hope you also prefer explaining to somebody why the function that abuses "vfork" mysteriously fails under 4.nBSD, for some n > 3, or on some box with a VM system that uses copy-on-write and thus implements "vfork" as an alias for "fork" - and do so with NO complaints about such implementations, as those complaints are completely unjustified. I quote from the 4.3BSD manual page for "vfork": This system call will be eliminated when proper system sharing mechanisms are implemented. Users should not depend on the memory sharing semantics of "vfork" as it will, in that case, be made synonymous to "fork". Note especially the absence of the word "may" here - the word "will" appears twice, so one presumes they wanted people to take this warning seriously. However, somebody decided this didn't apply to them and went ahead and depended on those semantics anyway. > The main purpose of vfork was to enhance csh's effiency anyway. Yes, but the efficiency improvement due to eliminating a copy of the entire data and stack segment was large; I've seen no evidence that there would be any major efficiency improvement due to abusing "vfork". We're talking about a very small amount of data here (it should fit into one frag), and that data is modified only if an "exec" fails. "exec"s shouldn't fail, in general, especially given the C shell's path hashing. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
tytso@athena.mit.edu (Theodore Y. Ts'o) (06/26/87)
In article <22057@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes: >> I think I prefer the "abuse" of the shared memory. > >I hope you also prefer explaining to somebody why the function that >abuses "vfork" mysteriously fails under 4.nBSD, for some n > 3, or on >some box with a VM system that uses copy-on-write and thus implements >"vfork" as an alias for "fork" - and do so with NO complaints about >such implementations, as those complaints are completely unjustified. For some n>3, /bin/csh will presumably be updated when vfork changes. If some VM system implements a copy-on-write fork and changes vfork on NOW, they will break csh. >I quote from the 4.3BSD manual page for "vfork": > > This system call will be eliminated when proper system sharing > mechanisms are implemented. Users should not depend on the memory ^^^^^ > sharing semantics of "vfork" as it will, in that case, be made > synonymous to "fork". > /bin/csh is a system program. USERS can write such programs at their own risk. >> The main purpose of vfork was to enhance csh's effiency anyway. > >Yes, but the efficiency improvement due to eliminating a copy of the >entire data and stack segment was large; I've seen no evidence that >there would be any major efficiency improvement due to abusing >"vfork". We're talking about a very small amount of data here (it >should fit into one frag), and that data is modified only if an >"exec" fails. "exec"s shouldn't fail, in general, especially given >the C shell's path hashing. A hashstat on my workstaion shows 26%. Other hosts that I'm logged into show hit ratios of about 40%. Our environment requires relatively long search paths. =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Theodore Ts'o | mit-eddie!mit-athena!tytso | M.I.T., tytso@athena.mit.edu | P.h.D., 3 Ames St., Cambridge, MA 02139 | M.O.N.E.Y.! | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
guy%gorodish@Sun.COM (Guy Harris) (06/26/87)
> For some n>3, /bin/csh will presumably be updated when vfork changes. > If some VM system implements a copy-on-write fork and changes vfork on > NOW, they will break csh. No, they will NOT! They will merely reveal that "csh" is ALREADY broken by virtue of relying on something that was *explicitly documented* as a quirk of the implementation that was not to be relied on. It is perfectly legitimate to provide a system with vfork == fork, and any complaints from programmers whose improperly-written programs cease to work should be redirected to /dev/null. > /bin/csh is a system program. USERS can write such programs at their > own risk. The trouble is that many users would squeal anyway, despite the fact that they were explicitly told not to write this kind of program and that they do so at their own risk. (Consider the possibly-apocryphal story of the person who bought and wrecked a Ferrari, and then sued because (s)he wasn't told that it was a "high-performance car".) It appears that points such as this need to be reiterated over and over again to ensure that people are aware of them. Furthermore, the fact that "/bin/csh" is a system program doesn't change the fact that there is no indication that, if you change the semantics of "vfork", it breaks - if somebody ports 4BSD and implements a better VM system, and makes vfork == fork (which the manual at least implies should be possible with such a VM system), without changing "csh", "csh" won't work. > A hashstat on my workstaion shows 26%. Other hosts that I'm logged > into show hit ratios of about 40%. Our environment requires > relatively long search paths. OK, but you still haven't provided any evidence that there would be a major performance hit from using the file rather than abusing "vfork". Go implement it, test it, and *then* argue one way or the other about whether it's a good thing to ignore what the manual says about "vfork" or not. (The burden of proof here is on the person who argues that the manual's warning should be ignored.) Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
lm@cottage.WISC.EDU (Larry McVoy) (06/27/87)
In article <22181@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes:
$ > For some n>3, /bin/csh will presumably be updated when vfork changes.
$ > If some VM system implements a copy-on-write fork and changes vfork on
$ > NOW, they will break csh.
$
$ No, they will NOT! They will merely reveal that "csh" is ALREADY broken
$ by virtue of relying on something that was *explicitly documented* as
$ a quirk of the implementation that was not to be relied on.
Lighten up, Guy, you sound hysterical. Csh is not "broken", at least not
by any reasonable definition - it runs, does it not? Lots of people use
it every day.
Furthermore, do you realize how ridiculous it is to say that csh is broken
due to its use of vfork()? Correct me if I am wrong (I'm sure you will)
but I believe vfork() was implemented *specifically* for csh. Irregardless
of what the man page says (you listen to man pages? Use the force, read the
source) the definitive use of vfork() is how it is used in csh.
Larry McVoy lm@cottage.wisc.edu or uwvax!mcvoy
schoch@ames.arpa (Steve Schoch) (06/27/87)
In article <22181@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes: > ...if you change the >semantics of "vfork", it breaks - if somebody ports 4BSD and >implements a better VM system, and makes vfork == fork (which the >manual at least implies should be possible with such a VM system), >without changing "csh", "csh" won't work. Well, actually, it won't "break" csh, the "hashstat" built-in will just not print anything. It will still give (status == 0) and everything else will work as before. We found this out when we had a system where vfork didn't work yet, so it just called fork() in the kernel. The idea is that csh will use the "shared memory" feature of vfork while it's there, but won't complain if it's not. Of course, if some user gets used to typing "hashstat" and expects it to print something, he will complain. I don't know who uses that function anyway. Steve
guy%gorodish@Sun.COM (Guy Harris) (06/27/87)
> but I believe vfork() was implemented *specifically* for csh. "vfork" was implemented for the benefit of various programs, "csh" among them. However, the fact that the current implementations of "vfork" give you a limited form of shared memory was purely a consequence of the implementation; it was not a "feature" stuck in for the benefit of any program, and if it disappears *nobody* has the right to complain *at all*. Unfortunately, some person who decides that warnings in the manual page don't apply to them will use this feature anyway and complain bitterly that somebody "broke" vfork if it is reimplemented so as not to provide that sort of shared memory. The warnings about "vfork" have to be repeated simply in the hopes that some form of conditioned reflex will be established amongst most programmers so that they don't force implementors to provide this explicitly deprecated side-effect of "vfork". > Irregardless of what the man page says (you listen to man pages? Use > the force, read the source) the definitive use of vfork() is how it is > used in csh. Bullshit. First of all, the line "Use the force, read the source" is descriptive of a deficiency in UNIX, not of an advantage of UNIX. One is forced to read the source in some cases because the UNIX documentation is either 1) incorrect, 2) unclear, or 3) incomplete. The UNIX documentation *should* be correct, clear, and complete; the fact that it isn't merely means more work should be done on it. Second of all, in this particular case the UNIX documentation *is* correct, clear, and complete. It tells you that these semantics of "vfork" are a side-effect of the current implementation, not a deliberate feature of the interface. The fact that the source of a *particular* UNIX implementation indicates that those semantics are provided does not mean that those semantics are a characteristic of the interface, and the fact that some piece of code knows that the implementation works in this fashion does not mean that "vfork" is intended to work in this fashion. (The fact that some 4.1BSD code used NULL as the name of a null character string most definitely does not mean that NULL *is* the name of a null character string! That is an unfortunate characteristic of the VAX UNIX implementation; had it not been, a lot of people at a number of computer companies might have spent less time fixing other people's bugs.) Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
throopw@xyzzy.UUCP (Wayne A. Throop) (06/27/87)
> guy%gorodish@Sun.COM (Guy Harris) > The only remaining reason to use vfork is that one has written ugly > and brain-damaged code that depends on the semantics of "vfork". But fork() can *never* be as efficent as vfork(), and sometimes this efficency is crucial. Even if you can create copy-on-demand during fork(), the database needed to keep track of these pages consumes kernel (possibly virtual) memory space, and the creation and upkeep of this data consumes kernel CPU time. The vfork() is hinting to the kernel that an exec() is about to occur, and therefore the kernel is well-advised not to invest much in the correct copy of the address space. That said, I agree that vfork is a horrible kludge. What *should* have been coined is the ability to create a process running a new executable image in a single system call. This is the only way the kernel can be *assured* (rather than simply having it hinted at) that this process creation will not involve the copying of any memory from the parent process. The fork() operation is still interesting and necessary, and the exec() operation is still interesting and necessary, but so is the create_process() operation. If you think the operation is not interesting and common, note how many zillions of library routines use fork() or vfork() immediately followed by exec(), and provoke the kernel into doing all sorts of unnecessary work, even if that kernel implements copy-on-demand. The counterargument is that each system call should do only one thing, and they should be combined to make more complicated operations. In this sense, I agree that only fork() and exec() are needed. But engineers don't build out of nand-gates only, though that is all that is logically necessary. They use gates that more clearly convey intent, and thus can gain significant efficency. Similarly, create_process() guarantees the kernel important information about the programmer's intent that combinations of fork() and exec() do not, and in this case I think the practical benefits of create_process() outweigh the theoretical benefits of a "pure" "simple" set of system calls. To finish off, let's look at the capabilities of fork() and exec() layed out in a table: load image create process --------------------+--------------------------------- do nothing | no no fork() | no yes exec() | yes no create_process() | yes yes I think it is clear that there "ought" to be a create_process(), despite the fact that it can be created out of fork() followed by exec(), because despite all tricks, fork() needs to get a process memory image from somewhere, and this will always come at some cost. (Although, strangely enough, I will not argue that there ought to be a do_nothing() system call...) -- An operating system is a set of manual and automatic procesures that enable a group of people to share a computer installation efficently. --- Per Brinch Hansen -- Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw
throopw@xyzzy.UUCP (Wayne A. Throop) (06/27/87)
> throopw@xyzzy.UUCP (Wayne A. Throop) > [...] vfork is a horrible kludge. What *should* have > been coined is the ability to create a process running a new executable > image in a single system call. This is the only way the kernel can be > *assured* (rather than simply having it hinted at) that this process > creation will not involve the copying of any memory from the parent > process. Another way to reinforce this point just occured to me, and that is to point out a case where (I think) Berkeley got it right (though perhaps for other reasons). There is a close analogy to fork(), exec(), and create_process() in link(), unlink(), and rename(). Obviously, link() and unlink() in combination suffice to rename files. But some extra efficency (though, granted, I think efficency was not the major consideration) can be added by hinting to the kernel that an unlink() will follow the link() (avoiding the necessity to change the link count and so on) by introducing the system call vlink(). This would create a link() but not increment the link count, allowing the new link to "share" one of the existing ones, because one of them is about to go away. Happily, the Berkeley implementors didn't do that. They implemented rename() instead. And similarly, they should have implemented create_process() instead of vfork(). (Or did rename() come from NFS? Hmmmm. Now I'm confused. But the point remains valid in either event.) -- Adam and Eve had many advantages, but the principal one was, that they escaped teething. --- Pudd'nhead Wilson's Calendar (Mark Twain) -- Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw
tytso@athena.mit.edu (Theodore Y. Ts'o) (06/28/87)
In article <22241@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes: >> but I believe vfork() was implemented *specifically* for csh. > >"vfork" was implemented for the benefit of various programs, "csh" >among them. However, the fact that the current implementations of >"vfork" give you a limited form of shared memory was purely a >consequence of the implementation; it was not a "feature" stuck in >for the benefit of any program, and if it disappears *nobody* has the >right to complain *at all*. > >Unfortunately, some person who decides that warnings in the manual >page..... *WHAT* warnings in the man pages? The only thing coming close to what you're saying is the BUGS entry where it says that it "will be eliminated when proper system sharing mechanisms are implemented." This implies that future *VERSIONS* of BSD have the right to change the meaning of vfork, NOT future *IMPLEMENTATIONS*. Since /bin/csh is maintained by Berkeley, when they change vfork, I expect they will update /bin/csh as well. >Bullshit. First of all, the line "Use the force, read the source" is >descriptive of a deficiency in UNIX, not of an advantage of UNIX. >One is forced to read the source in some cases because the UNIX >documentation is either 1) incorrect, 2) unclear, or 3) incomplete. >The UNIX documentation *should* be correct, clear, and complete; the >fact that it isn't merely means more work should be done on it. It's been said that UNIX is a OS writen by, and for, systems programers. Systems programmers writing documentation? :-) Seriously, I know they should, but you may be expecting a little bit too much of human nature..... >Second of all, in this particular case the UNIX documentation *is* >correct, clear, and complete. It tells you that these semantics of >"vfork" are a side-effect of the current implementation, not a Where? See above. I think that you differ with everybody else on the interpretation of the man pages. But at least mine (BSD 4.3) says absolutely nothing about vfork being implementation dependant. You may be reading a little bit too much into the man page here. > [flames about how programs that know too much about the > implementation of UNIX and rely upon them are broken] Fine, but how do you know what is a "implementation detail" and what is a part of the system call standard interface. By placing a description of how vfork works in the man pages, that becomes part of the interface. If I write a program that uses vfork in a clever way, but one that is COMPLETELY DOCUMENTED IN THE MAN PAGES, I expect that it should work in any implementation of UNIX that claims to be BSD 4.3. If it doesn't work, it isn't 4.3. Sure it should have been made more portable. But when you have a program like /bin/csh, which is ditributed under the assumption that it will run only under 4.3, (since it's distributed with it :-8) it's perfectly justified, don't you think? > Guy Harris =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Theodore Ts'o | mit-eddie!mit-athena!tytso | M.I.T., tytso@athena.mit.edu | P.h.D., 3 Ames St., Cambridge, MA 02139 | M.O.N.E.Y.! | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
lm@cottage.WISC.EDU (Larry McVoy) (06/28/87)
In article <22241@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes:
$ > but I believe vfork() was implemented *specifically* for csh.
$
$ "vfork" was implemented for the benefit of various programs, "csh"
$ among them.
Sorry, Guy, but you are wrong. I suggest you do a little more background
reading. I did some digging and came up with the paper which says that
vfork() was for csh. The paper is "Converting a Swap based System to do
Paging in an Architecture Lacking Page-Reference Bits" by Babaoglu & Joy,
1981 ACM. They specifically state that "We found the vast majority (over
80%) of all forks executed in the system were due to the command interpreter
[ie, csh]." They go on to point out that they implemeted vfork() to get
around this problem. It's all there on page 81, check it and see.
To be sure that they were indeed talking about csh all one has to do is
% cd /usr/src/bin/sh
% fgrep vfork *.[ch]
Which I did. No vfork(). The bottom line is: vfork was put in for csh.
Specifically for csh. Not in part, not as a general tool, specifically for
csh.
$ > Irregardless of what the man page says (you listen to man pages? Use
$ > the force, read the source) the definitive use of vfork() is how it is
$ > used in csh.
$
$ Bullshit.
No Guy, not bullshit, true shit. Vfork() was put in specifically for
csh. Any way that it is used in that program should be looked upon as
a legitimate use of the system call. Saying otherwise is ridiculous.
$ First of all, the line "Use the force, read the source" is
$ descriptive of a deficiency in UNIX, not of an advantage of UNIX.
$ One is forced to read the source in some cases because the UNIX
$ documentation is either 1) incorrect, 2) unclear, or 3) incomplete.
$ The UNIX documentation *should* be correct, clear, and complete; the
$ fact that it isn't merely means more work should be done on it.
Yeah - and just when is that work scheduled for completion? Real soon
now, eh? This business about Unix documentation is a joke. Only trivial
things are documented well. Anything complicated is, as has been pointed
out before, addendumed by a lengthy bugs section or is just quiet.
Case in point- I couldn't get to source for a weekend and my work came
to screeching halt. I really hadn't realized how much I leaned on it
but I'd say I pop over and look a couple of times a day. And I'm writing
user level code. There's no excuse for that crap.
Larry McVoy lm@cottage.wisc.edu or uwvax!mcvoy
guy%gorodish@Sun.COM (Guy Harris) (06/28/87)
> *WHAT* warnings in the man pages? The only thing coming close to what > you're saying is the BUGS entry where it says that it "will be > eliminated when proper system sharing mechanisms are implemented." I quote from the manual, which you appear not to have read carefully: This system call will be eliminated when proper system sharing mechanisms are implemented. *Users should not depend on the memory sharing semantics of "vfork" as it will, in that case, be made synonymous to "fork".* ("italics" mine) Now, to me that says you shouldn't write code like the code in question. The fact that it may happen to work *now* does not mean that it is specifically *intended* to work that way. It didn't say "be prepared to change your code when 'vfork' changes", it said "don't do this". It says so quite clearly, and gives no exceptions. > It's been said that UNIX is a OS writen by, and for, systems > programers. Systems programmers writing documentation? :-) If UNIX is an OS written by and for systems programmers, it should have remained a laboratory curiosity. Very few programmers are systems programmers, and at this point very few computer users are programmers. UNIX is, however, no longer a laboratory curiosity. There is *no* excuse for shabby documentation any more. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
guy%gorodish@Sun.COM (Guy Harris) (06/28/87)
> Sorry, Guy, but you are wrong. I suggest you do a little more background > reading. Sorry, Larry, but you are, as usual, wrong. I suggest you look in the source directory for "make" and note that it also uses "vfork", then check out "find", which also uses it (and, in the alpha version, ABused it - that was fixed for the final version) and then look at the source to the "popen" routine - it also uses "vfork". It may have been put in to speed up "csh", but concluding from this that it was *not* indended to be used by anybody else is absurd. > No Guy, not bullshit, true shit. Vfork() was put in specifically for > csh. Any way that it is used in that program should be looked upon as > a legitimate use of the system call. Saying otherwise is ridiculous. No, saying what you just said is ridiculous, considering that the use of "vfork" in question is specifically recommended *against* by the manual! If they had intended that it be used in that fashion, they wouldn't have told you not to use it in that fashion. > Yeah - and just when is that work scheduled for completion? Real soon > now, eh? This business about Unix documentation is a joke. Only trivial > things are documented well. Anything complicated is, as has been pointed > out before, addendumed by a lengthy bugs section or is just quiet. This is true, but accepting it as "the way of the world" and doing nothing to fix it is asinine. Various vendors have done some good work on fixing the UNIX documentation. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.ltin
guy%gorodish@Sun.COM (Guy Harris) (06/28/87)
> But fork() can *never* be as efficent as vfork(), and sometimes this > efficency is crucial. Yes, there is a savings if you can avoid copying the VM data structures, but this savings will be less than the savings from not copying the pages themselves. I'm not convinced that this savings will necessarily be enough to justify "vfork". (TOPS-20, and I presume TENEX, had the equivalent of "fork" and "exec", and used copy-on-write, but didn't provide the equivalent of "vfork". I don't know if they just didn't bother or if they determined that it wouldn't be worth it. It may be that on systems other than 10s and 20s, or OSes other than TOPS-20/TENEX, the overhead of copying the VM data structures would be greater, due to larger address spaces, smaller page sizes, more complicated data structures, etc..) > If you think the operation is not interesting and common, note how many > zillions of library routines use fork() or vfork() immediately followed > by exec(), and provoke the kernel into doing all sorts of unnecessary > work, even if that kernel implements copy-on-demand. Sometimes "fork" or "vfork" is *not* immediately followed by "exec". If the program to be run in the new process is not to inherit its set of open files from its parent, the child process has to rearrange the file descriptors before doing an "exec". The "create_process" call would have to include options for closing descriptors, opening files, and moving descriptors around. (This is the approach taken in VMS; the SYS$CREPRC call includes options for redirecting various I/O channels.) It might also have to include options for manipulating signals. A lot of systems don't provide separate "fork" and "exec" calls, but do provide a call like "create_process". (BTW, "rename" had nothing to do with NFS; it appeared in 4.2BSD.) Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
tytso@athena.mit.edu (Theodore Y. Ts'o) (06/29/87)
In article <22253@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes: >I quote from the manual, which you appear not to have read carefully: > > This system call will be eliminated when proper system sharing > mechanisms are implemented. *Users should not depend on the ^^^^^^ > memory sharing semantics of "vfork" as it will, in that case, > be made synonymous to "fork".* ("italics" mine) You appear not to have read my *POSTING* carefully. To summarize yet again: 1) /bin/csh is a system program, not a user program. It never says that system programs distributed by BSD may not use this call, and the BUGS entry of programs that use this call do not consider the fact that they use vfork a bug. 2) The man page implies that future versions of *BSD* may change vfork. Nowhere in the man page does it say that it is IMPLEMENTATION dependant. 3) Since the man page specifcally goes into painful detail how vfork works, the schemamtics of vfork have become part of the BSD 4.3 system interface. Any implementation that changes the meaning of vfork is not "FULL" BSD 4.3. ------------------------- All of the sources that I (and other people) have consulted say that vfork was implemented specifically for /bin/csh. Your arguments simply point to the source code of various programs/routines, like make and popen. Which came first, the chicken or the egg? I (and several other people) have documentation that vfork was implemented specifically and originally for /bin/csh. Do us the favor of finding some documented evidence to the contrary if you believe otherwise. ---------------------------- This is beginning to turn into a religious war. When ad hominum attacks: > Sorry, xxxxx, but you are, as usual, wrong. ^^ ^^^^^ start creeping into the discussion, perhaps we should find something else to discuss, hmm? Unless one of us plans to write BSD 4.4, most of this becomes mostly pointless and moot anyway. =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Theodore Ts'o | mit-eddie!mit-athena!tytso | M.I.T., tytso@athena.mit.edu | P.h.D., 3 Ames St., Cambridge, MA 02139 | M.O.N.E.Y.! | =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
jpn@teddy.UUCP (John P. Nelson) (06/29/87)
>There is a close analogy to fork(), exec(), and create_process() in >link(), unlink(), and rename(). ... some extra efficency can be added >by hinting to the kernel that an unlink() will follow the link() >(avoiding the necessity to change the link count and so on) by >introducing the system call vlink(). The situations are NOT analogous. One of the most common operations done between an fork and an exec is the modifications of the file descriptors. Tell me, with create_process, just how would you create an inter-process pipe? The standard code is: pipe(fds) if (fork() == 0) { dup2(fds[1], 1); close(fds[0]); close(fds[1]); exec(...); } close(fds[0]); Unless create_process allows for modification of the file descriptors, it will be of limited utility.
ron@topaz.rutgers.edu (Ron Natalie) (06/29/87)
> But fork() can *never* be as efficent as vfork(), and sometimes this > efficency is crucial. Even if you can create copy-on-demand during > fork(), the database needed to keep track of these pages consumes kernel > (possibly virtual) memory space, and the creation and upkeep of this > data consumes kernel CPU time. Crap. No extra space is involved as there are already unused bits in the page tables in most implementations. The few systems that already do copy-on-write forking don't end up using any additional CPU time. The MMU is what keeps track of write references (it is already doing this for "references" without differentiating writes and reads). What extra CPU overhead is it for machines that have decent virtual memory. VFORK exists only for people who don't share memory well in hardware. Note that FORK-AND-EXEC won't solve any but the most simple cases. The csh needs to twiddle process groups and file descriptors after the fork as do popen and other library calls. -Ron
lm@cottage.WISC.EDU (Larry McVoy) (06/29/87)
Guy sez: vfork() was invented for all sorts of programs. I sez: Guy is wrong, since vfork() was invented for csh. On my side of the ring we have the words of Bill Joy and others in published docs. (Note- I never said that vfork() is only for csh, only that it was invented for csh.) Guy sez: Larry is wrong, 'cause make & popen use vfork(). And now I sez: [Are we having fun yet????] Guy, don't be an ass. We were talking about the *creation* of the system call. You know, the funny thing is that I agree in principle with what Guy said in the first place - vfork() users probably ought not to pook about in their parent's address space. What I didn't agree with, and what probably bothered other people, is Guy's statement that "All programs that use vfork in this manner are brain damaged". That's an awfully strong statement and is just about impossible to back up. All one has to do to disprove it is show one program for which that statement is false. And the funny thing is that the very first program to use vfork (csh) needed to be able to pook about in the parent's address space. So what's the big deal, Guy? Obviously, csh will have to be fixed when they throw out vfork(). But it won't be hard - they'll probably have shared memory by then and people can do it that way. Whatever fix is used for csh can also be applied to similar programs. So, I say - use vfork() anyway you like, just be prepared to support new VM models. I don't see a big problem. I mean, is all of Berkeley running around chewing their nails over this? Then why are we? 'Nuff said. I hope. Larry McVoy lm@cottage.wisc.edu or uwvax!mcvoy
guy@gorodish.UUCP (06/29/87)
> 1) /bin/csh is a system program, not a user program. It never says > that system programs distributed by BSD may not use this call, and the > BUGS entry of programs that use this call do not consider the fact that > they use vfork a bug. Dammit, nobody was saying that the fact that they use "vfork" *was* a bug! The fact that they abuse a side-effect of the implementation of "vfork", in a fashion that the manual page *explicitly says not to*, is the problem. > 2) The man page implies that future versions of *BSD* may change vfork. > Nowhere in the man page does it say that it is IMPLEMENTATION > dependant. It should be fairly clear from the manual page that the *intent* of "vfork" was NOT to permit sharing of address space between parent and child, but to reduce the ovehead of creating a child. > 3) Since the man page specifcally goes into painful detail how vfork > works, the schemamtics of vfork have become part of the BSD 4.3 system > interface. Any implementation that changes the meaning of vfork is not > "FULL" BSD 4.3. The manual page also specifically goes into detail about how you are NOT supposed to depend on those semantics; this would appear to indicate that the fact that the current 4BSD implementation of "vfork" causes the parent and child to temporarily share memory was most definitely NOT intended to be a feature of "vfork". Manual pages will sometimes describe implementation details without making them part of the specification. > All of the sources that I (and other people) have consulted say that > vfork was implemented specifically for /bin/csh. Your arguments simply > point to the source code of various programs/routines, like make and > popen. Which came first, the chicken or the egg? I (and several other > people) have documentation that vfork was implemented specifically and > originally for /bin/csh. Do us the favor of finding some documented > evidence to the contrary if you believe otherwise. What does "implemented specifically for '/bin/csh'" mean? Does it mean that it was not intended to be used by anybody else? Obviously not, since they documented it in enough detail for others to use (AND, I repeat, in enough detail to strongy discourage people from abusing the fact that the implementation caused the parent and the child to share portions of their data space!), and since it was used elsewhere. The only way in which it was "implemented specifically for '/bin/csh'" was that the program that caused them to *notice* that providing "vfork" would increase performance was "/bin/csh". Sigh. If anybody STILL thinks that it's OK to rely on the shared memory that the current "vfork" implementation provides, and that this shared memory is a feature of the specification, not a characteristic of the implementation, would they please explain why the manual page specifically tells you NOT to rely on this? All the people who seem eager to consider the implementation to be the specification have failed to address this point. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
guy%gorodish@Sun.COM (Guy Harris) (06/30/87)
> We were talking about the *creation* of the system call. Which is totally irrelevant. I see no evidence that they did not intend other code to use "vfork"; "csh" just happened to contain the code that suggested its creation. > And the funny thing is that the very first program to use vfork > (csh) needed to be able to pook about in the parent's address space. Some people have a very funny notion of the meaning of the word "need". I have seen no evidence that "hashstat" *required* that "vfork" be abused, merely that it happened to be convenient to do so. A heck of a lot of crocks are created in the name of convenience. There are entirely too many programmers out there who are quick to take advantage of characteristics of the way some function is implemented without considering whether this is really a good idea. It should be made clear that this is a Bad Idea, and justifiable ONLY if it is the lesser of two or more evils. Unfortunately, there seems to be a large segment of the UNIX community that sees little or nothing wrong with this. This causes enough problems with non-portable OSes (I'm sure there are stories about programs "broken" by changes to VMS, where the fault lies *entirely* with the authors of those programs, not with DEC, as the authors in question were relying on the system continuing to work the way they "knew" it worked), but can cause even more problems with UNIX, as there will be several different implementations of the *same* interface. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
jerry@oliveb.UUCP (Jerry F Aguirre) (06/30/87)
In article <113@xyzzy.UUCP> throopw@xyzzy.UUCP (Wayne A. Throop) writes: >That said, I agree that vfork is a horrible kludge. What *should* have >been coined is the ability to create a process running a new executable >image in a single system call. This is the only way the kernel can be >*assured* (rather than simply having it hinted at) that this process >creation will not involve the copying of any memory from the parent >process. The fork() operation is still interesting and necessary, and >the exec() operation is still interesting and necessary, but so is the >create_process() operation. If you think the operation is not >interesting and common, note how many zillions of library routines use >fork() or vfork() immediately followed by exec(), and provoke the kernel >into doing all sorts of unnecessary work, even if that kernel implements >copy-on-demand. I will have to go along with Guy on this one. I have programed on systems that that use a "creat_process" call and it is the most complex system call in the whole system. I have also scanned the Unix sources and I have NOT found many uses of "fork" immediately followed by exec. There is almost always some intermediate code between the two. Let's take the case of csh, the reason vfork was created. At the minimum the csh will change the process group of the new process. It will also frequently have to close and open files. Other programs "su" have to deal with changes to the real and effective user and group IDs. A more complete list would include: files resource limits (CPU and memory) environment umask priority alarms signals real and effective UID and GID process group directory I have probably missed some. One could make a case for a "create_process" with limited capabilities for optimizing the most common case. Except that the most common case is the most complex one. What options do you pass to the "create_process" call to tell it that fd 1 should be closed and replaced by a pipe shared with the parent? Whatever features you decide not to include will be the ones most desired by somebody else. And, just when you think you have all possible options built into your "create_process" call, someone will add a new process characteristic. You will then be faced with the prospect of how to extend the "create_process" call to include the new options. And of course you have to do this in a way that will be compatible with old programs! After looking at the parameters of "create_process" and the extended parameters, and the optional extended extended parameters I considered the fork exec of Unix a much cleaner and more elegant solution. Jerry Aguirre
nate@altos86.UUCP (Nathaniel Ingersoll) (06/30/87)
In article <113@xyzzy.UUCP> throopw@xyzzy.UUCP (Wayne A. Throop) writes: [deleted] >The counterargument is that each system call should do only one thing, >and they should be combined to make more complicated operations. In >this sense, I agree that only fork() and exec() are needed. But >engineers don't build out of nand-gates only, though that is all that is >logically necessary. They use gates that more clearly convey intent, >and thus can gain significant efficency. Similarly, create_process() >guarantees the kernel important information about the programmer's >intent that combinations of fork() and exec() do not, and in this case I >think the practical benefits of create_process() outweigh the >theoretical benefits of a "pure" "simple" set of system calls. >... >Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw I have seen, on what seemed to be an extended port of BSD 4.2 by Ridge, a system call called spawn(), which took arguments like execve(), if my memory serves me correctly. The idea was that it internally fork() execve(...args...) and therefore didn't have to bother with process copying. Anyone else seen this? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ < Nathaniel Ingersoll > < Altos Computer Systems > vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
blarson@castor.usc.edu (Bob Larson) (06/30/87)
In article <4146@teddy.UUCP> jpn@teddy.UUCP (John P. Nelson) writes: >The situations are NOT analogous. One of the most common operations >done between an fork and an exec is the modifications of the file >descriptors. Tell me, with create_process, just how would you create >an inter-process pipe? The standard code is: > > pipe(fds) > if (fork() == 0) > { > dup2(fds[1], 1); > close(fds[0]); > close(fds[1]); > exec(...); > } > close(fds[0]); On os9, which has the create_process os9fork() call rather than a unix-like fork (error checking omited for simplicity): pipe = open("/pipe", S_IREAD | S_IWRITE); temp = dup(1); close(1); dup(pipe); os9fork(...); close(1); dup(temp); close(temp); Not much harder than on on unix. Bob Larson Arpa: Blarson@Ecla.Usc.Edu Uucp: {sdcrdcf,seismo!cit-vax}!oberon!castor!blarson "How well do we use our freedom to choose the illusions we create?" -- Timbuk3
chris@mimsy.UUCP (Chris Torek) (07/01/87)
>>guy%gorodish@Sun.COM (Guy Harris) >>The only remaining reason to use vfork is that one has written ugly >>and brain-damaged code that depends on the semantics of "vfork". In article <113@xyzzy.UUCP> throopw@xyzzy.UUCP (Wayne A. Throop) writes: >But fork() can *never* be as efficent as vfork(), and sometimes this >efficency is crucial. I disagree with the first part of this statement. If you wish to claim that on a Vax or other conventional two-level page table architecture, fork() cannot be as efficient as vfork(), *that* I can believe. On the MIPS R2000, I think a copy-on-write fork() could be just as efficient. >Even if you can create copy-on-demand during fork(), the database >needed to keep track of these pages consumes kernel (possibly virtual) >memory space, and the creation and upkeep of this data consumes >kernel CPU time. What database? Obviously you are considering some particular implementation. There are no doubt others, in which this operation is almost free---costing about the same as vfork(). >The vfork() is hinting to the kernel that an exec() is about to >occur, and therefore the kernel is well-advised not to invest much >in the correct copy of the address space. True; but one could consider *all* forks a hint that an exec() is soon to occur, and arrange not to run the parent for several milliseconds while the child finishes its task and exec()s. In effect, you would be making all forks vforks, since vfork really works by suspending the parent, but you would do it without the unintentionally shared memory. (Vfork also avoids copying both pages and PTEs, whereas even copy-on-write fork must copy PTEs. But who says machines even *have* PTEs?) >That said, I agree that vfork is a horrible kludge. What *should* have >been coined is the ability to create a process running a new executable >image in a single system call. As others have said, the big problem here is the need to alter some of the per-process information before running the new image. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: seismo!mimsy!chris
throopw@xyzzy.UUCP (Wayne A. Throop) (07/02/87)
> guy%gorodish@Sun.COM (Guy Harris) >> throopw@xyzzy.UUCP (Wayne Throop) >> But fork() can *never* be as efficent as vfork(), and sometimes this >> efficency is crucial. > Yes, there is a savings if you can avoid copying the VM data > structures, but this savings will be less than the savings from not > copying the pages themselves. I'm not convinced that this savings > will necessarily be enough to justify "vfork". I wish to make clear that I'm not convinced of this either. Rather than defending vfork, I was attempting to suggest that the alternative of a create_process() operation was preferable. The justification for vfork is loosely that the fork of a command processor to create a child process is most often followed immediately by an exec, and thus a brain-damaged fork will do just fine for these cases. My answer is that it is better to glue the two together so that the brain-damage cannot possibly bite anyone. Guy does point out an interesting thing about the "gap" between the fork and the exec, however: > If the program to be run in the new process is not to inherit its set > of open files from its parent, the child process has to rearrange the > file descriptors before doing an "exec". Actually, this can all be done in the parent, for most common cases. The point is that create_process() would act like exec() in that the child process would close descriptors marked for close-on-exec, and most file-descriptor-twiddling is reversible, and hence *can* (at some quite small cost) be done in the parent and then reversed after the create_process(). Thus, the alternative of making the create_process() have every bell and whistle for file control duplicated as part of the call is not really necessary. And in those cases where it cannot be done in the parent because of the complication of the inter-fork()-exec() processing, well... you'll just have to pay the price of a fork, won't you? Many may be skeptical that the processing can be done in the parent. I can't afford this skepticism, since I participlated in coding many of the common cases with the file manipulation done in the parent process. In particular, in popen() and similar library routines, and in the two shells. The shells, of course, are the most difficult, and try to squeeze an indecent amount of processing into the space between the fork() and the exec(), which is probably why berkeley implementors chose to do vfork() rather than grit their teeth and gird their loins and perform all *kinds* of mental preparation via divers asceticisms and go in there and *fix* *the* *blasted* *shells*. I sympathize with this decision, but I regret the outcome, which is unclean vfork() instead of relatively (I emphasize: *relatively*) clean create_process(). (I realize that making changes in the parent and then reversing them opens a small window of vulnerability where asynchronous events can find the process with its pants down, but *that* is just a bug in the way asynchronous events (signals et al) are specified to work in Unix. But that's another story.) -- You find sometimes that a Thing which seemed very Thingish inside you is quite different when it gets into the open and has other people looking at it. --- A. A. Milne, Winnie-the-Pooh. -- Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw
jerry@oliveb.UUCP (Jerry F Aguirre) (07/03/87)
In article <3768@spool.WISC.EDU> lm@cottage.WISC.EDU (Larry McVoy) writes: > So what's the big deal, Guy? Obviously, csh will have to be fixed > when they throw out vfork(). But it won't be hard - they'll probably > have shared memory by then and people can do it that way. Whatever > fix is used for csh can also be applied to similar programs. So, > I say - use vfork() anyway you like, just be prepared to support > new VM models. I don't see a big problem. I mean, is all of > Berkeley running around chewing their nails over this? Then > why are we? I think what Guy is complaining about is that such code will not run on a port of Unix that implements vfork in a different way. This could be either a new (4.4) version of BSD Unix or a port of the existing versions to a new architecture. Guy is posting from Sun and they are the ones who are always having problems with null pointer dereferencing. Somebody writes code that runs fine on a Vax but core dumps on a sun. The customer's response is that Sun does not have a good port because the software ran perfectly on a Vax. Sun responds that the code is broken but the Vax just didn't catch it. Nobody is happy but DEC. If someone implements a copy on write version of fork for their port of 4.[23] Unix and makes vfork the same as fork then they will be faced with a number of programs that don't work correctly. First off, the csh. Naturally they would like to avoid this. My opinion is that they shouldn't have a vfork unless they can implement it in a way that is compatible. The memory sharing characteristic is a documented and demonstrably used feature of vfork. Either make a separate vfork call that does share memory, wait the parent until exec, etc. or don't claim to have vfork. It was my understanding that, after a COW fork was implemented, vfork would disappear, not be maintained as an alternate name for fork. Jerry Aguirre
guy%gorodish@Sun.COM (Guy Harris) (07/03/87)
> Guy is posting from Sun and they are the ones who are always having > problems with null pointer dereferencing. Somebody writes code that > runs fine on a Vax but core dumps on a sun. The customer's response is > that Sun does not have a good port because the software ran perfectly on > a Vax. Sun responds that the code is broken but the Vax just didn't > catch it. Nobody is happy but DEC. Plenty of other people have these problems as well. Code that makes a lot of invalid assumptions will run "perfectly" (or, at least, run without any *obvious* errors; there have been postings in comp.lang.c that indicate that some such programs do *not* run fine, they just don't drop core) on a VAX (running one of the common versions of VAX UNIX; a version done inside BTL disallowed null pointer dereferencing, and VMS does also) and blow up on any of a number of machines out there. The only way to get a machine that will run all the code that runs on your current VAX is to get another VAX of the same sort. No, just buying another VAX isn't good enough. Take a look at the "comet sucks" comment in the VAX 4BSD "doprnt.c" (which, despite the ".c" suffix, is assembler code). That was a case where the VAX architecture manual said "don't do this" but somebody went ahead and did it anyway, and sure enough it didn't work when it ran on a 750. When a document says "don't do this", like the "vfork" manual page does, you should take it seriously unless you have an EXTREMELY good reason not to and are prepared to take the consequences. In the case of null pointers, K&R says that null pointers are "distinguishable from a pointer to any object", which means there is no guarantee what you get when you dereference one; this should at least act as a suggestion not to use pointers if they might be NULL without checking first. (Fortunately, ANSI C is a bit more firm on this point, for the benefit of people who don't get the hint.) You may get a null string, you may get "f(", you may get something with "p&P6" in it (or whatever the PDP-11 UNIX C implementation stuffed down at location 0), or you may get a memory fault. The point here is that some of us have learned that "this program works on machine X with C compiler Y with version Z of operating system W under the circumstances we tried it on" is very different from "this program is correct", or even "this program is reasonably close to correct". It is extremely galling when developers blame *their* bugs on the vendor of a system just because that system doesn't have all the implementation quirks of the system they were using before: it's not (little|big)-endian, it doesn't have a zero byte at location zero, it doesn't allow odd-boundary references to datatypes longer than 1 byte, it doesn't have _NFILE in <stdio.h>, etc., etc., etc.. They *could* have gotten it right, but didn't. > My opinion is that they shouldn't have a vfork unless they can implement > it in a way that is compatible. The memory sharing characteristic is a > documented and demonstrably used feature of vfork. It is also a characteristic that the manual specifically says should NOT be used. > It was my understanding that, after a COW fork was implemented, vfork > would disappear, not be maintained as an alternate name for fork. I quote from the manual page: This system call will be eliminated when proper system sharing mechanisms are implemented. Users should not depend on the memory sharing semantics of "vfork" as it will, in that case, be made synonymous to "fork". This reads as if it were saying that the *mechanism* that implements "vfork" will go away, but that the *interface* will remain as a synonym for "fork", so that correctly-written programs will still work. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
allbery@ncoast.UUCP (Brandon Allbery) (07/03/87)
As quoted from <1028@bloom-beacon.MIT.EDU> by tytso@athena.mit.edu (Theodore Y. Ts'o): +--------------- | 2) The man page implies that future versions of *BSD* may change vfork. | Nowhere in the man page does it say that it is IMPLEMENTATION | dependant. +--------------- Nowhere does it say that it is VERSION dependent either, as you assert. If some machine implements copy-on-write, that implementation is assured by the man page to be able to make vfork() == fork(). +--------------- | 3) Since the man page specifcally goes into painful detail how vfork | works, the schemamtics of vfork have become part of the BSD 4.3 system | interface. Any implementation that changes the meaning of vfork is not | "FULL" BSD 4.3. +--------------- If an early version of a system call has a bug which is documented, that bug becomes part of the interface and may not be fixed in an update, eh? Plexus documents late-found bugs in the release notes; this OBVIOUSLY (by your reasoning) casts them in stone and makes them wholly unfixable. At this point, if Plexus did things that way, I would start looking for another computer company. (Thank the Witness, they don't!) Should copy-on-write then require a wfork() call? --and if it has semantics that are subject to change, the change should be made into zfork() for the people who don't pay attention to its being listed as subject to change? Sure. Why don't we change all the existing system calls to V6 compatible and add new ones for the BSD (or SV or etc.) features? That way we make all the people who write programs that depend on V6 semantics happy. Nonsense. "Let's halt progress or make it painful, that way we can hide our heads in the sand when it happens." Do it elsewhere; *I* won't put up with it. Also -- just because a system program uses a system call in a way which is frowned upon does NOT make that usage correct. If a program uses a feature in a way that is documented as not being correct, EVEN IF THAT PROGRAM IS WRITTEN BY THE IMPLEMENTORS OF THE FEATURE, that program is wrong. The fact that vfork() was developed specifivally for csh is irrelevant; the manual page released to the public makes it clear that it is now a general feature. Again, doing otherwise gets ridiculous -- "ok, let's add cshfork() and cshexec() and telnetselect() and myprogramread() and ... system calls". The fact is that vfork, whatever its origins, was made GENERAL. Otherwise it would be named csh_only_fork() or something; and as I said above, that just isn't right. Adding a new system call should only be done if it's possible to make the system call general; adding a system call specifically for a single program's use is wasteful. ++Brandon -- ---- Moderator for comp.sources.misc and comp.binaries.ibm.pc ---- Brandon S. Allbery <BACKBONE>!cbosgd!hal!ncoast!allbery ('til Aug. 1) aXcess Company {ames,mit-eddie,harvard,talcott}!necntc!ncoast!allbery 6615 Center St. #A1-105 {well,sun,pyramid,ihnp4}!hoptoad!ncoast!allbery Mentor, OH 44060-4101 necntc!ncoast!allbery@harvard.HARVARD.EDU (Internet) +01 216 974 9210 ncoast!allbery@CWRU.EDU (CSnet -- if you dare) NCOAST ADMIN GROUP Brandon Allbery on 157/504 (Fidonet/Matrix/whatever) * ncoast -- Public Access UN*X -- (216) 781-6201, 24 hrs., 300/1200/2400 baud * * ncoast is proud to be carrying alt.all -- contact me for more information *
jpn@teddy.UUCP (John P. Nelson) (07/06/87)
>On os9, which has the create_process os9fork() call rather than a unix-like >fork (error checking omited for simplicity): > >pipe = open("/pipe", S_IREAD | S_IWRITE); >temp = dup(1); >close(1); >dup(pipe); >os9fork(...); >close(1); >dup(temp); >close(temp); But this leaves extra file descriptors open in the child task! By my calculation, extra descriptors in the child task are "pipe", and "temp". You really want to CLOSE those descriptors in the child task, but not in the parent task. Obviously, there can be workarounds: CLOSE_ON_EXEC information on a per-descriptor basis, or a convention in all tasks to close all descriptors above 2 before calling main(). The fundamental point is unchanged, however, and that is that there is often a need to do some extra operations between the logical "fork" into two processes, and the "exec" of a new program image.
blarson@castor.usc.edu (Bob Larson) (07/08/87)
In article <4167@teddy.UUCP> jpn@teddy.UUCP (John P. Nelson) writes: >>On os9, which has the create_process os9fork() call rather than a unix-like >>fork (error checking omited for simplicity): [...] >But this leaves extra file descriptors open in the child task! By my >calculation, extra descriptors in the child task are "pipe", and >"temp". You really want to CLOSE those descriptors in the child task, >but not in the parent task. No it doesn't. Os9fork only passes file descriptors 0, 1 and 2. There is an os9forkc call that allows passing a specified number of file descriptors. >Obviously, there can be workarounds: CLOSE_ON_EXEC information on a >per-descriptor basis, or a convention in all tasks to close all >descriptors above 2 before calling main(). The fundamental point is >unchanged, however, and that is that there is often a need to do some >extra operations between the logical "fork" into two processes, and >the "exec" of a new program image. I have not found such a NEED on os9. It would make converting unix programs easier. (It would require extra hardware to implement a unix-style fork call.) Bob Larson Arpa: Blarson@Ecla.Usc.Edu Uucp: {sdcrdcf,seismo!cit-vax}!oberon!castor!blarson "How well do we use our freedom to choose the illusions we create?" -- Timbuk3
cudcv@daisy.warwick.ac.uk (Rob McMahon) (07/14/87)
In article <113@xyzzy.UUCP> throopw@xyzzy.UUCP (Wayne A. Throop) writes: >If you think the operation is not >interesting and common, note how many zillions of library routines use >fork() or vfork() immediately followed by exec(), and provoke the kernel >into doing all sorts of unnecessary work, even if that kernel implements >copy-on-demand. Searching through the sources yields libc/gen/popen .../system libU77/chmod popen needs to re-arrange all its file descriptors, so that leaves system, and Fortran's chmod. > >I think it is clear that there "ought" to be a create_process(), despite >the fact that it can be created out of fork() followed by exec(), >because despite all tricks, fork() needs to get a process memory image >from somewhere, and this will always come at some cost. > But this create_process() is going to have to let you rearrange file descriptors, and probably catch signals to be of any real use. I can just imagine the interface---I think I'd rather have fork/exec and make fork more efficient. Rob -- UUCP: ...!mcvax!ukc!warwick!cudcv PHONE: +44 203 523037 JANET: cudcv@uk.ac.warwick.daisy ARPA: cudcv@daisy.warwick.ac.uk Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England