Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!orchid!clyde!rutgers!lll-lcc!pyramid!prls!mips!dce From: dce@mips.UUCP Newsgroups: comp.unix.questions Subject: Re: A couple questions Message-ID: <304@quacky.mips.UUCP> Date: Tue, 14-Apr-87 23:03:10 EST Article-I.D.: quacky.304 Posted: Tue Apr 14 23:03:10 1987 Date-Received: Fri, 17-Apr-87 05:06:51 EST References: <3164@jade.BERKELEY.EDU> Reply-To: dce@quacky.UUCP (David Elliott) Organization: MIPS Computer Systems, Sunnyvale, CA Lines: 66 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. (This question > came up when a bunch of people started accidentally sending > executables to a line printer, and I was trying to figure > out a way to filter out the execs from the texts). In standard 4.2/4.3 systems, more, vi, and file all have "magic numbers" (numbers found at the beginning of special files like object files) coded in them. In System V-based systems (and some BSD-based commercial systems), the file command uses a file (/etc/magic) that contains magic number information. Tektronix's UTek even supplies a libc subroutine that interfaces to /etc/magic. In any event, you probably want to make your filter check for nulls and high bits ((x & 0200) != 0), since not all "garbage files" are known to vi and more. >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, > 'cause I can do it with a line like: > > system("cat textfile &"); > > This won't work, however, if I try to "more" the file instead. > What determines what can be put in the background and what can't? > Is there some way to run a program from within a program, and have > it return upon completion to the original program besides "system"? > (The execl series, of course, doesn't return.) The more command works funny if you try to put it in the background because it works very closely with the tty. As for there being a way to execute subprograms other than with system(), there is a way (remember: the shell is just another command as far as Unix is concerned). The idea is something like: pid = fork(); if (pid < 0) { perror("fork"); return; } if (pid == 0) { /* child */ execlp(command, command, arg1, arg2, ..., 0); perror(command); _exit(127); } while ((wpid = wait(0)) != pid) { if (wpid < 0) { break; } } Note that the last loop is important (this is due to the way pipes work, and the lack of this loop used to cause a bug to show up in the crypt command). The above code is effectively what system() does, but if you don't need any of the special shell features (redirection, pipes, variables, etc.) or want to do things like redirection yourself (see fpopen(3s)), this saves you from forking a shell. -- David Elliott {decvax,ucbvax,ihnp4}!decwrl!mips!dce