Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watnot!watmath!clyde!bellcore!faline!ulysses!gatech!lll-lcc!seismo!mimsy!chris From: chris@mimsy.UUCP Newsgroups: comp.unix.wizards Subject: Re: Of csh & filepointers & fopen calls ... Message-ID: <5429@mimsy.UUCP> Date: Fri, 13-Feb-87 06:57:50 EST Article-I.D.: mimsy.5429 Posted: Fri Feb 13 06:57:50 1987 Date-Received: Tue, 17-Feb-87 21:34:22 EST References: <638@rtech.UUCP> <828@wjvax.wjvax.UUCP> <176@quacky.mips.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 71 In article <176@quacky.mips.UUCP> dce@mips.UUCP (David Elliott) writes: >I believe that what csh does with the extra file descriptors is to use >them to save the values of the standard file descriptors when redirection >and pipes are done. Without this, you have to fork each time you do >redirection or pipes, which can cause problems when it involves control >structures (if, while, foreach, etc.). Indeed, csh salts away copies of its stdin, stdout, and stderr in `high numbered' file descriptors. In 4.1BSD these were 17, 18, and 19, as NOFILE was 20, making [0..20) legal file descriptor values. These were arranged to be closed on exec() by, as I recall, FIOCLEX ioctls on the *old* descriptors. Dup2 originally carried this attribute over to the new descriptors. This behaviour was deemed bogus, and dropped in 4.2. It seems, however, that the 4.2 csh was converted by a process best described as `tweak it until it works'. No one noticed that the extra descriptors were left behind. I thought all this had been straightened out in 4.3BSD, but it is possible it was overlooked. Csh is one large series of bugs, and desperately needs a complete overhaul. But I do not promise to do it. Incidentally, it really is not necessary to move stdin &c out of the way for redirection of internal commands. A possible data structure to demonstrate: struct cnode { /* command node */ int cn_type; /* type of this node */ char **cn_cmd; /* argv */ struct redir *cn_redir;/* I/O redirections */ caddr_t cn_data; /* type-dependent data (if any) */ }; /* * There may be many command nodes pointing at some particular * redirection node. In particular, a redirected loop construct * will have all its subcommands pointing to the same redir * (unless those subcommands have also been redirected). */ struct redir { /* redirection node */ int r_refcnt; /* reference count */ struct redir *r_next; /* linked list */ int r_type; /* type: TIE<, TIE>; <, <<, >, >>; | */ union { char *r_fname; /* file name for < > >> */ int r_hereis; /* hereis file for << */ /* * A `tied' redirect lists an actual fd * (owned by this process) and a desired * or `pretend' fd, so that >'d shell * constructs will list an acutal fd of * whatever the shell opened, with a * desired fd of 1, e.g. * * Tied fd's are also used as back links in * pipes. */ struct { int rt_realfd; /* actual fd */ int rt_desfd; /* desired fd */ } r_tie; struct cnode *r_pipe; /* link in pipe */ } r_redir; }; (How is that for convoluted? :-) It could well be wrong, too; I just now made it up.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) UUCP: seismo!mimsy!chris ARPA/CSNet: chris@mimsy.umd.edu