dhesi@bsu-cs.bsu.edu (Rahul Dhesi) (04/22/89)
Here is a puzzle. First read the question and answer. Then solve the puzzle that follows. Question: Why does COMMAND.COM allow redirection of standard input and standard output, but not standard error? Answer: MS-DOS, unlike UNIX, doesn't have a fork() system call; therefore the MS-DOS command interpreter, unlike the UNIX shell, can't redirect standard error. THE PUZZLE. Does the above make any sense? If it does, why? If it does not, what is the real answer to the question? I have an answer already, which I will post after a while. -- Rahul Dhesi <dhesi@bsu-cs.bsu.edu> UUCP: ...!{iuvax,pur-ee}!bsu-cs!dhesi
mbb@cbnewsh.ATT.COM (martin.b.brilliant) (04/22/89)
From article <6893@bsu-cs.bsu.edu>, by dhesi@bsu-cs.bsu.edu (Rahul Dhesi): > Question: Why does COMMAND.COM allow redirection of standard > input and standard output, but not standard error? > > Answer: MS-DOS, unlike UNIX, doesn't have a fork() system call; > therefore the MS-DOS command interpreter, unlike the > UNIX shell, can't redirect standard error. > > THE PUZZLE. Does the above make any sense? If it does, why? If it > does not, what is the real answer to the question? No, it does not make any sense. In the first place, there is no such thing as "UNIX". UNIX(R) is a trademark of AT&T. There are UNIX systems. MS-DOS is not a UNIX system and never was one. If MS-DOS can redirect standard input and standard output without fork(), it could also redirect standard error if the designers of MS-DOS wanted it to. The real answer to the question is that the designers of MS-DOS thought it would be good to allow redirection of standard input and standard output, but that error messages should always go to the screen. So they wrote MS-DOS to direct all error messages to the screen. M. B. Brilliant Marty AT&T-BL HO 3D-520 (201) 949-1858 Holmdel, NJ 07733 att!cbnewsh!mbb or mbb@cbnewsh.ATT.COM Disclaimer: Opinions stated herein are mine unless and until my employer explicitly claims them; then I lose all rights to them.
lfk@mbio.med.upenn.edu (Lee Kolakowski) (04/22/89)
mbb@cbnewsh.ATT.COM (martin.b.brilliant) writes: > From article <6893@bsu-cs.bsu.edu>, by dhesi@bsu-cs.bsu.edu (Rahul Dhesi): > > Question: Why does COMMAND.COM allow redirection of standard > > input and standard output, but not standard error? > > > > Answer: MS-DOS, unlike UNIX, doesn't have a fork() system call; > > therefore the MS-DOS command interpreter, unlike the > > UNIX shell, can't redirect standard error. > > > > THE PUZZLE. Does the above make any sense? If it does, why? If it > > does not, what is the real answer to the question? > No, it does not make any sense. In the first place, there is no such > thing as "UNIX". UNIX(R) is a trademark of AT&T. > > The real answer to the question is that the designers of MS-DOS thought > it would be good to allow redirection of standard input and standard > output, but that error messages should always go to the screen. So > they wrote MS-DOS to direct all error messages to the screen. First off, what filehandles are redirectable is just a matter of what mechanisms the shell provides. It has nothing to do with MS-DOS the underlying operating system, but instead with the most common shell "command.com". I know of at least two replacement shells which allow you to redirect any file handle. MKS does it well with their shell, and Command-Plus also allows this to happen. Command.com's authors did not create redirectable filenos other than 0 and 1. All you have to do is, given a command to redirect a file number somewhere, dup that fileno to somewhere else. Seems resonable to me. If you need that capablity, don't argue that it can't be done, use the product that does it. -- Frank Kolakowski ===================================================================== |lfk@mbio.med.upenn.edu || Lee F. Kolakowski | |kolakowski@mscf.med.upenn. || Univ. of Penna. | |c/o jes@eniac.seas.upenn.edu || Dept of Chemistry | |kolakowski@c.chem.upenn.edu || 231 South 34th St. | |bcooperman.kolakowski@bionet-20.arpa || Phila, PA 19104 | |AT&T: 1-215-898-2927 ||--------------------------| |#include <litigate.h> || One-Liner Here! | =====================================================================
vg55611@ihuxy.ATT.COM (Gopal) (04/23/89)
In article <6893@bsu-cs.bsu.edu> dhesi@bsu-cs.bsu.edu (Rahul Dhesi) writes: > Question: Why does COMMAND.COM allow redirection of standard > input and standard output, but not standard error? I think the question really should be - why does MS-DOS allow stdin/stdout redirection but not stderr ? Command.com simply goes through DOS to do the redirection (by playing with the filehandles etc.) > Answer: MS-DOS, unlike UNIX, doesn't have a fork() system call; > therefore the MS-DOS command interpreter, unlike the > UNIX shell, can't redirect standard error. I don't think MS-DOS has stderr defined. I think at one point, a very early point (DOS 1.00 ?), it didn't even have stdin and stdout defined, you only had keyboard / display services. Later, stdin and stdout were defined, and the keyboard/display services were mapped to these. At that time, they could have added stderr services, but they didn't. If application programs and compilers seem to have stderr, I am quite sure that it is because they bypass DOS and use BIOS to write to the display directly. >THE PUZZLE. Does the above make any sense? If it does, why? If it >does not, what is the real answer to the question? Venu P. Gopal UUCP: att!ihuxy!vg55611 Internet: vg55611@ihuxy.att.com BITNET: com%"vg55611@ihuxy.att.com" or com%"vg55611%ihuxy@research.att.com" Silence those silent letters and save the world 500 million keystrokes a day.
rose@shorty.CS.WISC.EDU (Scott Rose) (04/23/89)
The lack of redirectability of standard error is indeed an unfortunate feature of command.com. For those times when it is desirable to perform this redirection, Microsoft provides the "errout" command. It comes with MSC 5.x. It is fairly trival to write your own version of this command, by the by, by making use of the spawn() and dup2() library functions or the underlying MSDOS services. Simply use dup2() to connect standard error to standard output before spawning argv[1], with argv[2]...argv[argc-1] as the argument vector. This gives your executed program a little bit less memory than it would have if you ran it right from the primary command processor, but that's the only significant downside. Keep the name of the new command short and you won't sacrifice much command line length.
vg55611@ihuxy.ATT.COM (Gopal) (04/23/89)
In article <2936@ihuxy.ATT.COM> I (rather hastily) wrote: >> Question: Why does COMMAND.COM allow redirection of standard >> input and standard output, but not standard error? >I think the question really should be - why does MS-DOS allow stdin/stdout >redirection but not stderr ? Command.com simply goes through DOS to do >the redirection (by playing with the filehandles etc.) I have to eat my own words, for Norton's book says that stderr is defined in DOS (filehandle of 2) and he's usually right. Perhaps redirection of stderr was simply not implemented in command.com. I wonder, though, if applications really write to DOS stderr and not to BIOS. I would still guess that if stdin, stdout, stdprn etc. can be re-directed, stderr should also be possible. Venu P. Gopal UUCP: att!ihuxy!vg55611 Internet: vg55611@ihuxy.att.com BITNET: com%"vg55611@ihuxy.att.com" or com%"vg55611%ihuxy@research.att.com" Silence those silent letters and save the world 500 million keystrokes a day.
emb978@leah.Albany.Edu (Eric M. Boehm) (04/23/89)
It doesn't make any sense to me. It just happens that some unix shells provide a consruction like ">&2" to redirect stderr. (Note that this is a problem in csh). Command.com just doesn't happen to provide such a construction. I can't see any reason why a substitute shell (a previous response to this question mentioned 2 such shells) or a program couldn't redirect stderr by using appropriate file descriptors (handles). Eric M. Boehm EMB978@ALBNY1VX.BITNET EMB978@LEAH.ALBANY.EDU
cs3b3aj@maccs.McMaster.CA (Stephen M. Dunn) (04/23/89)
In article <6893@bsu-cs.bsu.edu> dhesi@bsu-cs.bsu.edu (Rahul Dhesi) writes: > Question: Why does COMMAND.COM allow redirection of standard > input and standard output, but not standard error? As I understand it, when you say "<", MS-DOS closes file handle 0 (STDIN) and then opens the file you specified. Since it uses the lowest available handle, it ends up redirecting STDIN. Ditto for STDOUT redirection. (This explanation condensed from _Advanced MS-DOS_, Ray Duncan, Microsoft Press). Why can't you redirect STDERR (or, for that matter, STDAUX or STDPRN)? Because they didn't write in a facility as in *NIX so that you could specify the handle number to be redirected. Why? Probably because they (read the powers that be at Microsoft, not the guys who coded it) figured there wasn't enough demand for this feature to justify writing it. I can't see that it would take that much extra code to implement *NIX- style redirection of any handle, but to be honest, I've never needed to redirect anything other than STDIN or STDOUT (I'm not saying there's no need to do so, just that I've never needed to do so). -- ====================================================================== ! Stephen M. Dunn, cs3b3aj@maccs.McMaster.CA ! DISCLAIMER: ! ! Goddamn exams! I hate them! I hate them! ! I'm only an undergrad ! ======================================================================
nelson@sun.soe.clarkson.edu (Russ Nelson) (04/23/89)
In article <2936@ihuxy.ATT.COM> vg55611@ihuxy.ATT.COM (Gopal) writes: In article <6893@bsu-cs.bsu.edu> dhesi@bsu-cs.bsu.edu (Rahul Dhesi) writes: > Question: Why does COMMAND.COM allow redirection of standard > input and standard output, but not standard error? I think the question really should be - why does MS-DOS allow stdin/stdout redirection but not stderr ? Command.com simply goes through DOS to do the redirection (by playing with the filehandles etc.) In some sense you are right. However, when command.com gets control via a critical error interrupt, it fiddles with the undocumented Process Handle Table at offset $18 in the Program Header. So I would say that, because command.com also does critial error handling, it does *not* go through DOS. -- --russ (nelson@clutx [.bitnet | .clarkson.edu]) America -- Socialism for the rich people, Capitalism for the rest of us. -- Michael Harrington, Co-Chair, Democratic Socialists of America
Ralf.Brown@B.GP.CS.CMU.EDU (04/23/89)
In article <2936@ihuxy.ATT.COM>, vg55611@ihuxy.ATT.COM (Gopal) writes: }I don't think MS-DOS has stderr defined. I think at one point, a very early }point (DOS 1.00 ?), it didn't even have stdin and stdout defined, you only }had keyboard / display services. Later, stdin and stdout were defined, and }the keyboard/display services were mapped to these. At that time, they }could have added stderr services, but they didn't. There is indeed a stderr. MSDOS opens five standard handles for a process: 0 is stdin (default CON) 1 is stdout (default CON) 2 is stderr (default CON) 3 is stdaux (default AUX or COM1) 4 is stdprn (default PRN or LPT1) Whoever was responsible for COMMAND.COM simply decided not to implement stderr, stdaux, or stdprn redirection. stdaux is useless, though, since it uses the unusable ROM BIOS serial port "services". }If application programs and compilers seem to have stderr, I am quite sure }that it is because they bypass DOS and use BIOS to write to the display }directly. No, they can use file handle 2, just like under Un*x. I use stderr all the time for error messages. -- UUCP: {ucbvax,harvard}!cs.cmu.edu!ralf -=-=-=- Voice: (412) 268-3053 (school) ARPA: ralf@cs.cmu.edu BIT: ralf%cs.cmu.edu@CMUCCVMA FIDO: Ralf Brown 1:129/31 Disclaimer? I claimed something? You cannot achieve the impossible without attempting the absurd.
cs3b3aj@maccs.McMaster.CA (Three More Exams) (04/24/89)
In article <2936@ihuxy.ATT.COM> vg55611@ihuxy.UUCP (55421-Gopal,V.P.) writes: >I don't think MS-DOS has stderr defined. I think at one point, a very early >point (DOS 1.00 ?), it didn't even have stdin and stdout defined, you only >had keyboard / display services. Later, stdin and stdout were defined, and >the keyboard/display services were mapped to these. At that time, they >could have added stderr services, but they didn't. >If application programs and compilers seem to have stderr, I am quite sure >that it is because they bypass DOS and use BIOS to write to the display >directly. Some correct points, some incorrect ones. Dos 1.* did not support any form of redirection (it didn't have the "handle" concept at that point ... all file I/O was done with file control blocks, and I/O to the console, AUX, etc. was done with specific DOS calls cloned from CP/M). DOS 2.* and up added file handle support, and define five handles which your program automatically receives: 0: Standard input, CON by default 1: Standard output, CON by default 2: Standard error, always connected to CON 3: Auxiliary, usually connected to COM1 4: List device (PRN), usually connected to LPT1 So DOS _does_ have stderr, and if you write a C program which outputs to stderr it will work without the compiler having to translate your output statements into BIOS calls. -- ====================================================================== ! Stephen M. Dunn, cs3b3aj@maccs.McMaster.CA ! DISCLAIMER: ! ! I always wanted to be a lumberjack! - M.P. ! I'm only an undergrad ! ======================================================================
tjr@cbnewsc.ATT.COM (thomas.j.roberts) (04/24/89)
From article <238@cbnewsh.ATT.COM>, by mbb@cbnewsh.ATT.COM (martin.b.brilliant): > From article <6893@bsu-cs.bsu.edu>, by dhesi@bsu-cs.bsu.edu (Rahul Dhesi): >> Question: Why does COMMAND.COM allow redirection of standard >> input and standard output, but not standard error? >> >> Answer: MS-DOS, unlike UNIX, doesn't have a fork() system call; >> therefore the MS-DOS command interpreter, unlike the >> UNIX shell, can't redirect standard error. > > The real answer to the question is that the designers of MS-DOS thought > it would be good to allow redirection of standard input and standard > output, but that error messages should always go to the screen. So > they wrote MS-DOS to direct all error messages to the screen. It's even worse than that (!) - you CAN redirect file-descriptor 2 in a program that then EXECs another program. Unfortunately, some programs put error messages onto file-descriptor 2, and some put them directly onto the screen. The "designers" (:-^) of MS-DOS decided NOT to standardize how error messages are presented. [IMHO that was a very arrogant attitude on their part, and is merely one instance of why MS-DOS is so difficult to do serious applications in (e.g. look at the TSR mess)]. Tom Roberts att!ihnet!tjr
davidr@hplsla.HP.COM (David M. Reed) (04/25/89)
I do not know why MicroSoft did not implement filehandle re-direction so that the user could re-direct I/O other than stdin and stdout. To me it is another example of MS-DOS being brain-dead, and one of the reasons I prefer to use the MKS Korn-shell. Recently we had need (again) for this capability of directing stderr to a file. The program a user was running here would encounter an error, write the message to stdout, and then the program would end with a clear screen action! Insufficient time to read the message. (One really had to be watching the screen to even see that what looked like an error message had been flashed to the screen. And since this program was typically auto-running for about 45 minutes of number crunching before it go to the error, the user was not typically watching the screen.) So I started up the program for him under the MKS shell with stderr being sent to a file, and, wonder of wonders, the next time the program aborted we had the error message neatly captured in a file!
psfales@ihlpb.ATT.COM (Fales) (04/25/89)
In article <2535@maccs.McMaster.CA>, cs3b3aj@maccs.McMaster.CA (Three More Exams) writes: > > DOS 2.* and up added file handle support, and define five handles which > your program automatically receives: > 0: Standard input, CON by default > 1: Standard output, CON by default > 2: Standard error, always connected to CON > 3: Auxiliary, usually connected to COM1 > 4: List device (PRN), usually connected to LPT1 > > So DOS _does_ have stderr, and if you write a C program which outputs > to stderr it will work without the compiler having to translate your output > statements into BIOS calls. Score one more for the MKS toolkit. I never realized that it could do this, until someone pointed it out recently, but I just tried it and it works: you can redirect stderr, stdprn (and presumably stdaux) from the MKS shell, using exactly the the same syntax you would on a *NIX system. i n e w s f i l l -- Peter Fales AT&T, Room 5B-414 2000 N. Naperville Rd. UUCP: ...att!ihlpb!psfales Naperville, IL 60566 Domain: psfales@ihlpb.att.com work: (312) 979-8031
feg@clyde.ATT.COM (Forrest Gehrke) (04/25/89)
In article <552@cbnewsc.ATT.COM>, tjr@cbnewsc.ATT.COM (thomas.j.roberts) writes: > > [IMHO that was a very arrogant attitude on their part, and is merely > one instance of why MS-DOS is so difficult to do serious applications > in (e.g. look at the TSR mess)]. To what extent Microsoft is responsible for the "TSR mess", I can not say. They have a very good and full explanation of how to program TSR's in their Encylopedia. However, most of the what you call the TSR mess is due to poor programming. Forrest Gehrke
alex@mks.UUCP (Alex White) (04/26/89)
In article <10309@ihlpb.ATT.COM> psfales@ihlpb.ATT.COM (Fales) writes: >In article <2535@maccs.McMaster.CA>, cs3b3aj@maccs.McMaster.CA (Three More Exams) writes: >Score one more for the MKS toolkit. I never realized that it could do this, >until someone pointed it out recently, but I just tried it and it works: >you can redirect stderr, stdprn (and presumably stdaux) from the MKS shell, >using exactly the the same syntax you would on a *NIX system. Actually, you can even better than this. Since nobody actually ever uses, or cares about stdprn or stdaux, my profile.ksh file starts with: exec 3<&- exec 4<&- which CLOSES stdprn and stdaux, leaving all programs with an extra 2 file descriptors. Yes, I agree, its a grotesque non-intuitive command to use. However, it is useful. You can also do things like exec 2>errors and then all error messages after that point would go to the file `errors'.
lfk@mbio.med.upenn.edu (Lee Kolakowski) (04/27/89)
Also you can install a device driver for say a tektronics emulation, such as PC plot. I made this device driver named TEK. Then you can say exec < CON > TEK And then from then on you are using the TEK device for your console driver -- Frank Kolakowski ===================================================================== |lfk@mbio.med.upenn.edu || Lee F. Kolakowski | |kolakowski@mscf.med.upenn. || Univ. of Penna. | |c/o jes@eniac.seas.upenn.edu || Dept of Chemistry | |kolakowski@c.chem.upenn.edu || 231 South 34th St. | |bcooperman.kolakowski@bionet-20.arpa || Phila, PA 19104 | |AT&T: 1-215-898-2927 ||--------------------------| |#include <litigate.h> || One-Liner Here! | =====================================================================
ralf@b.gp.cs.cmu.edu (Ralf Brown) (04/27/89)
In article <45133@clyde.ATT.COM> feg@clyde.ATT.COM (Forrest Gehrke) writes: }To what extent Microsoft is responsible for the "TSR mess", I can }not say. They have a very good and full explanation of how to }program TSR's in their Encylopedia. However, most of the what }you call the TSR mess is due to poor programming. Except that you are forgetting that people were writing TSRs for about five years before the MS-DOS Encyclopedia (non-buggy version) was available. If MS had started right out with documentation such as the Encyclopedia, and pushing for a standard (such as TeSseRact, which is used by a number of programs such as Borland's THELP.COM), things would be a lot less messy. -- {harvard,uunet,ucbvax}!b.gp.cs.cmu.edu!ralf -=-=- AT&T: (412)268-3053 (school) ARPA: RALF@B.GP.CS.CMU.EDU |"Tolerance means excusing the mistakes others make. FIDO: Ralf Brown at 129/31 | Tact means not noticing them." --Arthur Schnitzler BITnet: RALF%B.GP.CS.CMU.EDU@CMUCCVMA -=-=- DISCLAIMER? I claimed something? --
dhesi@bsu-cs.bsu.edu (Rahul Dhesi) (07/11/89)
In article <6893@bsu-cs.bsu.edu> a long time ago I wrote: >Here is a puzzle. First read the question and answer. Then solve >the puzzle that follows. > > Question: Why does COMMAND.COM allow redirection of standard > input and standard output, but not standard error? > > Answer: MS-DOS, unlike UNIX, doesn't have a fork() system call; > therefore the MS-DOS command interpreter, unlike the > UNIX shell, can't redirect standard error. > >THE PUZZLE. Does the above make any sense? If it does, why? If it >does not, what is the real answer to the question? > >I have an answer already, which I will post after a while. Here is my answer, which I am posting "after a while" as promised. Yes, the answer above does make a little sense. It may not be the complete reason why the MS-DOS command interpreter will redirect standard output but not standard error. If you have a fork() system call, you can redirect I/O as follows (some details omitted): pid = fork(); if (pid == 0) { /* child */ redirect file descriptors as needed; execute new program; } else { /* parent */ wait for child to exit; } In the above scheme, only the file descriptors of the child process are ever redirected. The parent's fds are left completely untouched. The MS-DOS command interpreter can't use fork(). In order to redirect a file descriptor for a child process, it must redirect its own file descriptor before the EXEC, and save the old file descriptor somewhere. One way of doing this is to use dup2() to create a duplicate high-numbered fd. So for example, it could save the current standard output fd (normally 1) as fd number 15, then close fd 1 and reopen it attached to a file for output, and it has redirected standard output to go to a file. Then the command interpreter executes the command as a subprocess using the EXEC system call. After the subprocess returns, it can do another dup2() to get a duplicate of fd 15 into fd 1. This restores the original standard output. But if it does this, then the new process has an extra open file handle available to it, since EXEC duplicates all open files. (MS-DOS has no close-on-exec flag.) This is risky. A badly-designed program could write garbage to fd 15 (which was not really supposed to be open at all). Perhaps the COMMAND.COM designer felt that enough was enough. Even if he had to supply extra fds to a subprocess that might mess with them without knowing they were open, he wasn't about to let standard error (which you absolutely HAVE to have to print error messages) get messed up by a rogue subprocess. There is another possibility. Maybe COMMAND.COM uses some undocumented feature of the MS-DOS kernel to redirect standard output. Maybe they only had enough bits left over in the PSP two handle two redirected fds but not three. It could be, for example, that COMMAND.COM first loads the new program, then changes its PSP to the new PSP using an "undocumented" system call, does the I/O redirection, and then jumps to the new program. For some undocumented reason, redirection of standard error doesn't work (a bug in the undocumented system call, which is why instead of documenting it in a later version, Microsoft created a new one instead?). The final possibility is that the COMMAND.COM designer didn't want to take the risk of the standard error stream suddenly freezing. When you initially open a device for output, it is in a mode in which it stops accepting any further writes as soon as it sees a control Z. (The original objective was apparently to prevent trailing garbage in CP/M files showing up at odd times.) It wouldn't do to let the standard error stream freeze up like this, for then where would you print error messages like "Stream frozen due to control-Z -- System Halted"?? On earlier MS-DOS versions, the command echo ^Z (that's a real control Z) produces an odd error message (try it). It wouldn't do to not be able to print this odd message in case somebody did something like echo 2>&1 ^Z instead. The above speculation may or may not be based on many facts, but it *is* based surely on *one* important fact: If it weren't for the absence of fork(), we wouldn't even have to wonder why COMMAND.COM won't redirect standard error. -- Rahul Dhesi <dhesi@bsu-cs.bsu.edu> UUCP: ...!{iuvax,pur-ee}!bsu-cs!dhesi
richard@calvin.EE.CORNELL.EDU (Richard Brittain) (07/11/89)
In article <8167@bsu-cs.bsu.edu> dhesi@bsu-cs.bsu.edu (Rahul Dhesi) writes: > >In article <6893@bsu-cs.bsu.edu> a long time ago I wrote: >> Question: Why does COMMAND.COM allow redirection of standard >> input and standard output, but not standard error? >> >> Answer: MS-DOS, unlike UNIX, doesn't have a fork() system call; >> therefore the MS-DOS command interpreter, unlike the >> UNIX shell, can't redirect standard error. >> >>THE PUZZLE. Does the above make any sense? If it does, why? If it >>does not, what is the real answer to the question? ...... >The MS-DOS command interpreter can't use fork(). In order to redirect >a file descriptor for a child process, it must redirect its own file >descriptor before the EXEC, and save the old file descriptor >somewhere. One way of doing this is to use dup2() to create a >duplicate high-numbered fd. ...... >But if it does this, then the new process has an extra open file handle >available to it, since EXEC duplicates all open files. (MS-DOS has no >close-on-exec flag.) This is risky. A badly-designed program could >write garbage to fd 15 (which was not really supposed to be open at >all). ...... >Rahul Dhesi <dhesi@bsu-cs.bsu.edu> >UUCP: ...!{iuvax,pur-ee}!bsu-cs!dhesi This sounds like a C programmer thinking only in terms of the standard way to handle things in C. Since stderr defaults to the console every time control returns to COMMAND.COM, why bother preserving the state with a dup'd file handle - just reopen it to the redirected file, then later close and reopen to the console. Even if stderr were pointing at a file when you wanted to redirect it, you would only need to remember the file name and offset to retore later on - there is no need to keep a spare file handle open in the meantime. It seems to me to be purely a design decision not to allow stderr to be redirected by the "default" shell, although there is no reason why a replacement shell could not do so (like ksh in the MKS toolkit). I work on a non-unix system a lot of the time (Harris VOS) in which there is a definite design decision to make it very hard (though not quite impossible) to redirect stderr. Also, note that the latest DOS has a child inherit/not inherit attribute on handles if sharing is used, so actually the dup method could then be used safely. Richard Brittain, School of Elect. Eng., Upson Hall Cornell University, Ithaca, NY 14853 ARPA: richard@calvin.spp.cornell.edu UUCP: {uunet,uw-beaver,rochester,cmcl2}!cornell!calvin!richard
ho@fergvax.unl.edu (Michael Ho) (07/11/89)
From article <8167@bsu-cs.bsu.edu>, by dhesi@bsu-cs.bsu.edu (Rahul Dhesi): > > In article <6893@bsu-cs.bsu.edu> a long time ago I wrote: >> >> Question: Why does COMMAND.COM allow redirection of standard >> input and standard output, but not standard error? >> >> Answer: MS-DOS, unlike UNIX, doesn't have a fork() system call; >> therefore the MS-DOS command interpreter, unlike the >> UNIX shell, can't redirect standard error. >> >>THE PUZZLE. Does the above make any sense? If it does, why? If it >>does not, what is the real answer to the question? >> Why can't MS-DOS just redirect all three file handles, and after the command is complete, do this: close(2); open ("CON", O_WRITE); { this could be wrong; I haven't done fdup (2, 1); medium-level I/O in a while } close (0); open ("CON", O_READ); After all, CON is like /dev/tty in Unix, isn't it? It's always there, and never goes away. Any program which wants a piece of the terminal can open CON, so why not COMMAND? Or am I just being naive? --- ... Michael Ho, University of Nebraska <ho@fergvax.unl.edu>
dhesi@bsu-cs.bsu.edu (Rahul Dhesi) (07/12/89)
In article <1171@calvin.EE.CORNELL.EDU> richard@calvin.spp.cornell.edu (Richard Brittain) writes: >Since stderr defaults to the console every time >control returns to COMMAND.COM, why bother preserving the state with a dup'd >file handle... Ah, but the reason why stderr defaults to the console every time is precisely because currently stderr cannot be redirected. Consider the following hypothetical command in a new enhanced MS-DOS, which allows redirection of stderr with the >* notation: command >* errors.out < commands.txt We are invoking a new copy of COMMAND.COM and making its stderr go to the file errors.out. This new COMMAND.COM cannot just reopen the console for its standard error stream. -- Rahul Dhesi <dhesi@bsu-cs.bsu.edu> UUCP: ...!{iuvax,pur-ee}!bsu-cs!dhesi
ralf@b.gp.cs.cmu.edu (Ralf Brown) (07/12/89)
In article <1171@calvin.EE.CORNELL.EDU> richard@calvin.spp.cornell.edu (Richard Brittain) writes: }In article <8167@bsu-cs.bsu.edu> dhesi@bsu-cs.bsu.edu (Rahul Dhesi) writes: }> }>In article <6893@bsu-cs.bsu.edu> a long time ago I wrote: }>> Question: Why does COMMAND.COM allow redirection of standard }>> input and standard output, but not standard error? }>> }>> Answer: MS-DOS, unlike UNIX, doesn't have a fork() system call; }>> therefore the MS-DOS command interpreter, unlike the }>> UNIX shell, can't redirect standard error. } ...... }>The MS-DOS command interpreter can't use fork(). In order to redirect }>a file descriptor for a child process, it must redirect its own file }>descriptor before the EXEC, and save the old file descriptor }>somewhere. One way of doing this is to use dup2() to create a }>duplicate high-numbered fd. } ...... }>But if it does this, then the new process has an extra open file handle }>available to it, since EXEC duplicates all open files. (MS-DOS has no }>close-on-exec flag.) This is risky. A badly-designed program could }>write garbage to fd 15 (which was not really supposed to be open at }>all). } ...... } This sounds like a C programmer thinking only in terms of the standard }way to handle things in C. Since stderr defaults to the console every time }control returns to COMMAND.COM, why bother preserving the state with a dup'd }file handle - just reopen it to the redirected file, then later close and }reopen to the console. Even if stderr were pointing at a file when you }wanted to redirect it, you would only need to remember the file name and }offset to retore later on - there is no need to keep a spare file handle }open in the meantime. . First, stderr does not necesarily refer to the console--I have a program to redirect standard error, and if I use it to run COMMAND.COM on a batch file, having COMMAND unilaterally change stderr to the console after executing a command with redirection would defeat this (same thing goes for stdin and stdout--you can run a COMMAND with them redirected and re-redirect them in a batch file). Secondly, the file name is not necesarily available. If another program did the redirection before spawning COMMAND, the name will be inaccessible. Note that the CTTY command is functionally equivalent to running another copy of COMMAND.COM with both input and output redirected to the specified device. CTTY COM1 <==> COMMAND <COM1 >COM2 . } Also, note that the latest DOS has a child inherit/not inherit attribute }on handles if sharing is used, so actually the dup method could then be }used safely. But note that setting the attribute is only available on OPEN, not on DUP or DUP2.... Unless the program redirecting std{in,out,err} opens the un-redirected handle to begin with, it can't make the file uninheritable. And if it did make it uninheritable, un-redirected output would require a DUP anyway, since the original handle couldn't be passed to the child. What can be done, however, (and this works for DOS 2 and up), is to copy the appropriate entries in the Process File Table in the PSP, zap them to FFh (unused), do the EXEC, and then restore the entries. While the child will then get the same handle number on opening a file, it will refer to a different file (the above is what the no-inherit attribute does, anyway--it zaps the uninheritable handles in the child's PFT to FFh). -- {harvard,uunet,ucbvax}!b.gp.cs.cmu.edu!ralf -=-=- AT&T: (412)268-3053 (school) ARPA: RALF@CS.CMU.EDU |"The optimist is the kind of person who believes a FIDO: Ralf Brown 1:129/46 | housefly is looking for a way out."--Geo.J.Nathan BITnet: RALF%CS.CMU.EDU@CMUCCVMA -=-=-=-=-=- DISCLAIMER? I claimed something?
toma@tekgvs.LABS.TEK.COM (Tom Almy) (07/13/89)
In article <5486@pt.cs.cmu.edu> ralf@b.gp.cs.cmu.edu (Ralf Brown) writes: >What can be done, however, (and this works for DOS 2 and up), is to copy the >appropriate entries in the Process File Table in the PSP, zap them to FFh >(unused), do the EXEC, and then restore the entries. While the child will >then get the same handle number on opening a file, it will refer to a >different file (the above is what the no-inherit attribute does, anyway--it >zaps the uninheritable handles in the child's PFT to FFh). Right on! I was working on a large programming environment that needed to EXEC arbitrary programs (or a DOS shell), with the ability to redirect stdin, stdout, and stderr. I did a variation of Ralf's scheme: 1. Save entire PFT (it's not that big!) 2. Set entries above the std* ones to FFh (effectively temprarily closes my programs files, without DOS overhead, but requiring a larger FILES= spec in config.sys). 3. Set to 0FFh and then open each redirected std*, one at a time. Since the open command uses the lowest numbered free descriptor, this works well. 4. EXEC the program 5. Do a close on each redirected std*. 6. Restore PFT from saved copy. Was that easy enough? Much simpler than the contortions in UNIX with those DUP2s! There certainly is no reason COMMAND.COM couldn't do it. And fork() has nothing to do with it. Tom Almy toma@tekgvs.labs.tek.com Standard Disclaimers Apply
maa@nbires.nbi.com (Mark Armbrust) (07/15/89)
In article <5565@tekgvs.LABS.TEK.COM> toma@tekgvs.LABS.TEK.COM (Tom Almy) writes: >In article <5486@pt.cs.cmu.edu> ralf@b.gp.cs.cmu.edu (Ralf Brown) writes: >>What can be done, however, (and this works for DOS 2 and up), is to copy the >>appropriate entries in the Process File Table in the PSP, zap them to FFh > >1. Save entire PFT (it's not that big!) >2. Set entries above the std* ones to FFh (effectively temprarily closes > >Was that easy enough? Much simpler than the contortions in UNIX with >those DUP2s! There certainly is no reason COMMAND.COM couldn't >do it. And fork() has nothing to do with it. I prefer to use the dos calls to do the job since there is a dos version dependancy when mucking directly with the jfn_table in the pdb. Starting with some version of dos between 2.11 and 3.2 (I only have these two handy to look at), jfn_table_length and jfn_table_pointer have been added to the pdb. pdb + 32h: jfn_table_len dw ? ; length of jfn table pdb + 34h: jfn_table_ptr dd ? ; FAR pointer to jfn table These are initialized to point to the jfn_table in the pdb, but can be changed by an application to point to a larger jfn_table. Starting in dos 3.3, there is a documented dos call (int 21h, ah=67h) to do this! -- Mark Armbrust maa@nbires.nbi.com maa@nbires.UUCP