Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!lll-lcc!styx!ptsfa!hoptoad!academ!killer!jfh From: jfh@killer.UUCP (John Haugh) Newsgroups: comp.unix.questions Subject: Re: A couple questions Message-ID: <816@killer.UUCP> Date: Wed, 29-Apr-87 12:04:11 EDT Article-I.D.: killer.816 Posted: Wed Apr 29 12:04:11 1987 Date-Received: Thu, 7-May-87 06:11:50 EDT References: <3164@jade.BERKELEY.EDU> <2382@ncoast.UUCP> <1752@dg_rtp.UUCP> Organization: The Unix(tm) Connection, Dallas, Texas Lines: 145 Summary: Try again ... I love people who don't know what they are talking about, which is why I always say - 'Read the documentation whether you know it or not'. Disinformation correction in progress ... MUNCH ... MUNCH ... MUNCH In article <1752@dg_rtp.UUCP>, goudreau@dg_rtp.UUCP (Bob Goudreau) writes: > In article <2382@ncoast.UUCP> robertd@ncoast.UUCP (Rob DeMarco) writes: > >In article <3164@jade.BERKELEY.EDU> marcp@beryl.berkeley.edu (Marc M. Pack) writes: > >>Hello! I've a couple of questions in UNIX 4.2. > >> > >>1. How do programs like "more" distinguish between text files and > >> executable files? Hopefully, there's something surer than > >> just taking a sample of a file and testing it. [ More stuff ] > > > > I would believe that a pretty sure > >method would be to test the file > >permisions, if an "x" accours in the > >file permisions, then it is executable, > >other wise its text. > > > > This isn't such a good idea, for three reasons: [ Dumb comment about shell scripts being executable and printable ... ] [ Dumb comment about .o's not being executable. Of course, the question sent this guy in that direction. ] [ Misinfomation Alert ] > 3) Finally, pr can accept redirected input. How is it supposed to do > a stat() on stdin? Try the originally suggested idea. It does work, and see what file(1) says " ... If an argument appears to be ASCII, _file_ examines the first 512 bytes and tries to guess its language. ... " - Quoted from "Plexus Sys5 UNIX User's Reference Manual". Read 512 bytes (or 1024 if you want to be surer) and check to see if all of the characters are printable. How about using something like ctypes(3). The two macros isspace() and isprint() should do the trick. Then, to make things real robust (remember that word from Comp-Sci 101 :-) print character not in isspace() || isprint() with some special convention. Now for alittle disinformation correction. (I knew the manual would get a big workout today. From stat(2), I read "Similaryly, _fstat_ obtains information about an open file known by the file descriptor _filedes_, ..." - Quoted from "Plexus Sys5 UNIX Programmer's Reference Manual". Any file descriptor can be stat(2)'d, including 0, 1, and 2 which were opened long, long ago. If you wanted to, you could even find out the name of the file that was connected to the descriptor. (It is _not_ easy :-( ) > > A better filter would be a program that looks for indications that the > file is an object or a.out (program) file. This is in fact what more > does; it checks for for a "magic number" at the beginning of a file > indicating that the file is a program or object file. > No, this is a stupid idea. The problem with printouts screwing up printers is not because they are _object_ files, it is because they contain characters that screw up the printer. Look for those characters. What happens if your users decide to print core dumps, directories, /etc/wtmp and the like. A well thought out approach, or even the one I suggested (it took me about 12 seconds to come up with it.) will find out if the file can be printed. > > >>2. Is it possible to, while in a C program, call another program and > >> put it into the background? Actually, I know it's possible, [ And he tells us why (system ("command &");) ] > > > > My guess is that more accepts input, > >since you have to press to go > >on. Since it is in background, it > >doesn't wait for it to complete before > >going on, therefor , getting input is > >imposible, because it doesn't check for > >input. [ I can't even follow what this poster wants to say ... ] > > This is along the right lines, but not correct. > Consider the following program: > > main() > { > system ("more /etc/termcap &"); > for (;;) ; > } > > This will work, (try it) because only one process (the more) is trying to read > its stdin. (The system() does a fork() and the child process inherits identical > copies of its parent's file descriptors, including stdin). > No, once again you are wrong, wrong, wrong. The system may do a fork(2), but the child does an exec(2) of the sh(1), which says "If a command is followed by & the default standard input for the command is the empty file _/dev/null_. ..." -Quoted from "Plexus Sys5 UNIX User's Reference Manual". The shell closes file descriptor 0 and open(2)'s /dev/null, with the consequence that the file descriptor that is returned is 0. So it don't get the same file descriptor. And besides, _stdin_ is NOT a file descriptor. Try using it in a place where one is needed. > The place where you will run into trouble is when your main program is > also trying to read stdin at the same time; the two processes will > fight over the input. The same is true of stdout and stderr -- you will get > jumbled-together output. > Different problem with standard error and standard output. If you look at what the book's got to say, it tells you that with two processes reading from a terminal, the system flips a coin to decide which process gets it. It actually lets the two processes beat each other in the head for it. (I have seen the code for coinflip() an clobber() in the kernel with my own to eyes :-) :-) :-). > The moral is, Be careful of what child processes do with file descriptors > inherited from the parent. If the child is going to open its own files, > go right ahead and use system(foo &) to put it in the background. > You may want to become familiar with the fork() system call, since it > allows you to bypass some of the overhead of the system() lib function. > You could always close them and not worry about it if that is such a big deal. More(1) will still grab you because it doesn't use stdin to get the commands from the keyboard!!! Try 'cat /etc/passwd | more'. This works pretty much the same as 'more /etc/passwd'. If it didn't, the man(1) command wouldn't work for those of us that have, or added a more(1) in the output pipeline. Since the 'cat /etc/passwd |' is the standard input, it can't be reading from there. I can't find strings(1) on this machine so I can't tell you that more(1) is opening /dev/tty, BUT - the last more(1) clone I wrote did just that. Unless the output wasn't a file or pipe or somthing other that a tty (remember isatty(2)?). You of course, might want to become familiar with the manuals. Of course, you can always get had and say stupid things about system calls they just added in the newest release. But that is a different brand of stupidity. The moral of the story is - don't just say 'This is a nice article, I think I'll reply' unless you want to contribute some real information. Also, not everyone has the time to research or the knowelege to contribute a worth while reply, so don't feel bad if you can't. (But you still ought to read the manuals anyway.) - John. (jfh@killer.UUCP) Disclaimer: No disclaimer. Whatcha gonna do, sue me?