lwall@netlabs.com (Larry Wall) (04/15/91)
Submitted-by: Larry Wall <lwall@netlabs.com> Posting-number: Volume 18, Issue 23 Archive-name: perl/part05 [There are 36 kits for perl version 4.0.] #! /bin/sh # Make a new directory for the perl sources, cd to it, and run kits 1 # thru 36 through sh. When all 36 kits have been run, read README. echo "This is perl 4.0 kit 5 (of 36). If kit 5 is complete, the line" echo '"'"End of kit 5 (of 36)"'" will echo at the end.' echo "" export PATH || (echo "You didn't use sh, you clunch." ; kill $$) mkdir 2>/dev/null echo Extracting perl.man:AB sed >perl.man:AB <<'!STUFFY!FUNK!' -e 's/X//' X''' X''' Revision 3.0.1.10 90/11/10 01:46:29 lwall X''' patch38: random cleanup X''' patch38: added alarm function X''' X''' Revision 3.0.1.9 90/10/15 18:17:37 lwall X''' patch29: added caller X''' patch29: index and substr now have optional 3rd args X''' patch29: added SysV IPC X''' X''' Revision 3.0.1.8 90/08/13 22:21:00 lwall X''' patch28: documented that you can't interpolate $) or $| in pattern X''' X''' Revision 3.0.1.7 90/08/09 04:27:04 lwall X''' patch19: added require operator X''' X''' Revision 3.0.1.6 90/08/03 11:15:29 lwall X''' patch19: Intermediate diffs for Randal X''' X''' Revision 3.0.1.5 90/03/27 16:15:17 lwall X''' patch16: MSDOS support X''' X''' Revision 3.0.1.4 90/03/12 16:46:02 lwall X''' patch13: documented behavior of @array = /noparens/ X''' X''' Revision 3.0.1.3 90/02/28 17:55:58 lwall X''' patch9: grep now returns number of items matched in scalar context X''' patch9: documented in-place modification capabilites of grep X''' X''' Revision 3.0.1.2 89/11/17 15:30:16 lwall X''' patch5: fixed some manual typos and indent problems X''' X''' Revision 3.0.1.1 89/11/11 04:43:10 lwall X''' patch2: made some line breaks depend on troff vs. nroff X''' patch2: example of unshift had args backwards X''' X''' Revision 3.0 89/10/18 15:21:37 lwall X''' 3.0 baseline X''' X''' X.PP XAlong with the literals and variables mentioned earlier, Xthe operations in the following section can serve as terms in an expression. XSome of these operations take a LIST as an argument. XSuch a list can consist of any combination of scalar arguments or array values; Xthe array values will be included in the list as if each individual element were Xinterpolated at that point in the list, forming a longer single-dimensional Xarray value. XElements of the LIST should be separated by commas. XIf an operation is listed both with and without parentheses around its Xarguments, it means you can either use it as a unary operator or Xas a function call. XTo use it as a function call, the next token on the same line must Xbe a left parenthesis. X(There may be intervening white space.) XSuch a function then has highest precedence, as you would expect from Xa function. XIf any token other than a left parenthesis follows, then it is a Xunary operator, with a precedence depending only on whether it is a LIST Xoperator or not. XLIST operators have lowest precedence. XAll other unary operators have a precedence greater than relational operators Xbut less than arithmetic operators. XSee the section on Precedence. X.Ip "/PATTERN/" 8 4 XSee m/PATTERN/. X.Ip "?PATTERN?" 8 4 XThis is just like the /pattern/ search, except that it matches only once between Xcalls to the X.I reset Xoperator. XThis is a useful optimization when you only want to see the first occurrence of Xsomething in each file of a set of files, for instance. XOnly ?? patterns local to the current package are reset. X.Ip "accept(NEWSOCKET,GENERICSOCKET)" 8 2 XDoes the same thing that the accept system call does. XReturns true if it succeeded, false otherwise. XSee example in section on Interprocess Communication. X.Ip "alarm(SECONDS)" 8 4 X.Ip "alarm SECONDS" 8 XArranges to have a SIGALRM delivered to this process after the specified number Xof seconds (minus 1, actually) have elapsed. Thus, alarm(15) will cause Xa SIGALRM at some point more than 14 seconds in the future. XOnly one timer may be counting at once. Each call disables the previous Xtimer, and an argument of 0 may be supplied to cancel the previous timer Xwithout starting a new one. XThe returned value is the amount of time remaining on the previous timer. X.Ip "atan2(Y,X)" 8 2 XReturns the arctangent of Y/X in the range X.if t \-\(*p to \(*p. X.if n \-PI to PI. X.Ip "bind(SOCKET,NAME)" 8 2 XDoes the same thing that the bind system call does. XReturns true if it succeeded, false otherwise. XNAME should be a packed address of the proper type for the socket. XSee example in section on Interprocess Communication. X.Ip "binmode(FILEHANDLE)" 8 4 X.Ip "binmode FILEHANDLE" 8 4 XArranges for the file to be read in \*(L"binary\*(R" mode in operating systems Xthat distinguish between binary and text files. XFiles that are not read in binary mode have CR LF sequences translated Xto LF on input and LF translated to CR LF on output. XBinmode has no effect under Unix. XIf FILEHANDLE is an expression, the value is taken as the name of Xthe filehandle. X.Ip "caller(EXPR)" X.Ip "caller" XReturns the context of the current subroutine call: X.nf X X ($package,$filename,$line) = caller; X X.fi XWith EXPR, returns some extra information that the debugger uses to print Xa stack trace. The value of EXPR indicates how many call frames to go Xback before the current one. X.Ip "chdir(EXPR)" 8 2 X.Ip "chdir EXPR" 8 2 XChanges the working directory to EXPR, if possible. XIf EXPR is omitted, changes to home directory. XReturns 1 upon success, 0 otherwise. XSee example under X.IR die . X.Ip "chmod(LIST)" 8 2 X.Ip "chmod LIST" 8 2 XChanges the permissions of a list of files. XThe first element of the list must be the numerical mode. XReturns the number of files successfully changed. X.nf X X.ne 2 X $cnt = chmod 0755, \'foo\', \'bar\'; X chmod 0755, @executables; X X.fi X.Ip "chop(LIST)" 8 7 X.Ip "chop(VARIABLE)" 8 X.Ip "chop VARIABLE" 8 X.Ip "chop" 8 XChops off the last character of a string and returns the character chopped. XIt's used primarily to remove the newline from the end of an input record, Xbut is much more efficient than s/\en// because it neither scans nor copies Xthe string. XIf VARIABLE is omitted, chops $_. XExample: X.nf X X.ne 5 X while (<>) { X chop; # avoid \en on last field X @array = split(/:/); X .\|.\|. X } X X.fi XYou can actually chop anything that's an lvalue, including an assignment: X.nf X X chop($cwd = \`pwd\`); X chop($answer = <STDIN>); X X.fi XIf you chop a list, each element is chopped. XOnly the value of the last chop is returned. X.Ip "chown(LIST)" 8 2 X.Ip "chown LIST" 8 2 XChanges the owner (and group) of a list of files. XThe first two elements of the list must be the NUMERICAL uid and gid, Xin that order. XReturns the number of files successfully changed. X.nf X X.ne 2 X $cnt = chown $uid, $gid, \'foo\', \'bar\'; X chown $uid, $gid, @filenames; X X.fi X.ne 23 XHere's an example of looking up non-numeric uids: X.nf X X print "User: "; X $user = <STDIN>; X chop($user); X print "Files: " X $pattern = <STDIN>; X chop($pattern); X.ie t \{\ X open(pass, \'/etc/passwd\') || die "Can't open passwd: $!\en"; X'br\} X.el \{\ X open(pass, \'/etc/passwd\') X || die "Can't open passwd: $!\en"; X'br\} X while (<pass>) { X ($login,$pass,$uid,$gid) = split(/:/); X $uid{$login} = $uid; X $gid{$login} = $gid; X } X @ary = <${pattern}>; # get filenames X if ($uid{$user} eq \'\') { X die "$user not in passwd file"; X } X else { X chown $uid{$user}, $gid{$user}, @ary; X } X X.fi X.Ip "chroot(FILENAME)" 8 5 X.Ip "chroot FILENAME" 8 XDoes the same as the system call of that name. XIf you don't know what it does, don't worry about it. XIf FILENAME is omitted, does chroot to $_. X.Ip "close(FILEHANDLE)" 8 5 X.Ip "close FILEHANDLE" 8 XCloses the file or pipe associated with the file handle. XYou don't have to close FILEHANDLE if you are immediately going to Xdo another open on it, since open will close it for you. X(See X.IR open .) XHowever, an explicit close on an input file resets the line counter ($.), while Xthe implicit close done by X.I open Xdoes not. XAlso, closing a pipe will wait for the process executing on the pipe to complete, Xin case you want to look at the output of the pipe afterwards. XClosing a pipe explicitly also puts the status value of the command into $?. XExample: X.nf X X.ne 4 X open(OUTPUT, \'|sort >foo\'); # pipe to sort X .\|.\|. # print stuff to output X close OUTPUT; # wait for sort to finish X open(INPUT, \'foo\'); # get sort's results X X.fi XFILEHANDLE may be an expression whose value gives the real filehandle name. X.Ip "closedir(DIRHANDLE)" 8 5 X.Ip "closedir DIRHANDLE" 8 XCloses a directory opened by opendir(). X.Ip "connect(SOCKET,NAME)" 8 2 XDoes the same thing that the connect system call does. XReturns true if it succeeded, false otherwise. XNAME should be a package address of the proper type for the socket. XSee example in section on Interprocess Communication. X.Ip "cos(EXPR)" 8 6 X.Ip "cos EXPR" 8 6 XReturns the cosine of EXPR (expressed in radians). XIf EXPR is omitted takes cosine of $_. X.Ip "crypt(PLAINTEXT,SALT)" 8 6 XEncrypts a string exactly like the crypt() function in the C library. XUseful for checking the password file for lousy passwords. XOnly the guys wearing white hats should do this. X.Ip "dbmclose(ASSOC_ARRAY)" 8 6 X.Ip "dbmclose ASSOC_ARRAY" 8 XBreaks the binding between a dbm file and an associative array. XThe values remaining in the associative array are meaningless unless Xyou happen to want to know what was in the cache for the dbm file. XThis function is only useful if you have ndbm. X.Ip "dbmopen(ASSOC,DBNAME,MODE)" 8 6 XThis binds a dbm or ndbm file to an associative array. XASSOC is the name of the associative array. X(Unlike normal open, the first argument is NOT a filehandle, even though Xit looks like one). XDBNAME is the name of the database (without the .dir or .pag extension). XIf the database does not exist, it is created with protection specified Xby MODE (as modified by the umask). XIf your system only supports the older dbm functions, you may only have one Xdbmopen in your program. XIf your system has neither dbm nor ndbm, calling dbmopen produces a fatal Xerror. X.Sp XValues assigned to the associative array prior to the dbmopen are lost. XA certain number of values from the dbm file are cached in memory. XBy default this number is 64, but you can increase it by preallocating Xthat number of garbage entries in the associative array before the dbmopen. XYou can flush the cache if necessary with the reset command. X.Sp XIf you don't have write access to the dbm file, you can only read Xassociative array variables, not set them. XIf you want to test whether you can write, either use file tests or Xtry setting a dummy array entry inside an eval, which will trap the error. X.Sp XNote that functions such as keys() and values() may return huge array values Xwhen used on large dbm files. XYou may prefer to use the each() function to iterate over large dbm files. XExample: X.nf X X.ne 6 X # print out history file offsets X dbmopen(HIST,'/usr/lib/news/history',0666); X while (($key,$val) = each %HIST) { X print $key, ' = ', unpack('L',$val), "\en"; X } X dbmclose(HIST); X X.fi X.Ip "defined(EXPR)" 8 6 X.Ip "defined EXPR" 8 XReturns a boolean value saying whether the lvalue EXPR has a real value Xor not. XMany operations return the undefined value under exceptional conditions, Xsuch as end of file, uninitialized variable, system error and such. XThis function allows you to distinguish between an undefined null string Xand a defined null string with operations that might return a real null Xstring, in particular referencing elements of an array. XYou may also check to see if arrays or subroutines exist. XUse on predefined variables is not guaranteed to produce intuitive results. XExamples: X.nf X X.ne 7 X print if defined $switch{'D'}; X print "$val\en" while defined($val = pop(@ary)); X die "Can't readlink $sym: $!" X unless defined($value = readlink $sym); X eval '@foo = ()' if defined(@foo); X die "No XYZ package defined" unless defined %_XYZ; X sub foo { defined &bar ? &bar(@_) : die "No bar"; } X X.fi XSee also undef. X.Ip "delete $ASSOC{KEY}" 8 6 XDeletes the specified value from the specified associative array. XReturns the deleted value, or the undefined value if nothing was deleted. XDeleting from $ENV{} modifies the environment. XDeleting from an array bound to a dbm file deletes the entry from the dbm Xfile. X.Sp XThe following deletes all the values of an associative array: X.nf X X.ne 3 X foreach $key (keys %ARRAY) { X delete $ARRAY{$key}; X } X X.fi X(But it would be faster to use the X.I reset Xcommand. XSaying undef %ARRAY is faster yet.) X.Ip "die(LIST)" 8 X.Ip "die LIST" 8 XOutside of an eval, prints the value of LIST to X.I STDERR Xand exits with the current value of $! X(errno). XIf $! is 0, exits with the value of ($? >> 8) (\`command\` status). XIf ($? >> 8) is 0, exits with 255. XInside an eval, the error message is stuffed into $@ and the eval is terminated Xwith the undefined value. X.Sp XEquivalent examples: X.nf X X.ne 3 X.ie t \{\ X die "Can't cd to spool: $!\en" unless chdir \'/usr/spool/news\'; X'br\} X.el \{\ X die "Can't cd to spool: $!\en" X unless chdir \'/usr/spool/news\'; X'br\} X X chdir \'/usr/spool/news\' || die "Can't cd to spool: $!\en" X X.fi X.Sp XIf the value of EXPR does not end in a newline, the current script line Xnumber and input line number (if any) are also printed, and a newline is Xsupplied. XHint: sometimes appending \*(L", stopped\*(R" to your message will cause it to make Xbetter sense when the string \*(L"at foo line 123\*(R" is appended. XSuppose you are running script \*(L"canasta\*(R". X.nf X X.ne 7 X die "/etc/games is no good"; X die "/etc/games is no good, stopped"; X Xproduce, respectively X X /etc/games is no good at canasta line 123. X /etc/games is no good, stopped at canasta line 123. X X.fi XSee also X.IR exit . X.Ip "do BLOCK" 8 4 XReturns the value of the last command in the sequence of commands indicated Xby BLOCK. XWhen modified by a loop modifier, executes the BLOCK once before testing the Xloop condition. X(On other statements the loop modifiers test the conditional first.) X.Ip "do SUBROUTINE (LIST)" 8 3 XExecutes a SUBROUTINE declared by a X.I sub Xdeclaration, and returns the value Xof the last expression evaluated in SUBROUTINE. XIf there is no subroutine by that name, produces a fatal error. X(You may use the \*(L"defined\*(R" operator to determine if a subroutine Xexists.) XIf you pass arrays as part of LIST you may wish to pass the length Xof the array in front of each array. X(See the section on subroutines later on.) XSUBROUTINE may be a scalar variable, in which case the variable contains Xthe name of the subroutine to execute. XThe parentheses are required to avoid confusion with the \*(L"do EXPR\*(R" Xform. X.Sp XAs an alternate form, you may call a subroutine by prefixing the name with Xan ampersand: &foo(@args). XIf you aren't passing any arguments, you don't have to use parentheses. XIf you omit the parentheses, no @_ array is passed to the subroutine. XThe & form is also used to specify subroutines to the defined and undef Xoperators. X.Ip "do EXPR" 8 3 XUses the value of EXPR as a filename and executes the contents of the file Xas a X.I perl Xscript. XIts primary use is to include subroutines from a X.I perl Xsubroutine library. X.nf X X do \'stat.pl\'; X Xis just like X X eval \`cat stat.pl\`; X X.fi Xexcept that it's more efficient, more concise, keeps track of the current Xfilename for error messages, and searches all the X.B \-I Xlibraries if the file Xisn't in the current directory (see also the @INC array in Predefined Names). XIt's the same, however, in that it does reparse the file every time you Xcall it, so if you are going to use the file inside a loop you might prefer Xto use \-P and #include, at the expense of a little more startup time. X(The main problem with #include is that cpp doesn't grok # comments\*(--a Xworkaround is to use \*(L";#\*(R" for standalone comments.) XNote that the following are NOT equivalent: X.nf X X.ne 2 X do $foo; # eval a file X do $foo(); # call a subroutine X X.fi XNote that inclusion of library routines is better done with Xthe \*(L"require\*(R" operator. X.Ip "dump LABEL" 8 6 XThis causes an immediate core dump. XPrimarily this is so that you can use the undump program to turn your Xcore dump into an executable binary after having initialized all your Xvariables at the beginning of the program. XWhen the new binary is executed it will begin by executing a "goto LABEL" X(with all the restrictions that goto suffers). XThink of it as a goto with an intervening core dump and reincarnation. XIf LABEL is omitted, restarts the program from the top. XWARNING: any files opened at the time of the dump will NOT be open any more Xwhen the program is reincarnated, with possible resulting confusion on the part Xof perl. XSee also \-u. X.Sp XExample: X.nf X X.ne 16 X #!/usr/bin/perl X require 'getopt.pl'; X require 'stat.pl'; X %days = ( X 'Sun',1, X 'Mon',2, X 'Tue',3, X 'Wed',4, X 'Thu',5, X 'Fri',6, X 'Sat',7); X X dump QUICKSTART if $ARGV[0] eq '-d'; X X QUICKSTART: X do Getopt('f'); X X.fi X.Ip "each(ASSOC_ARRAY)" 8 6 X.Ip "each ASSOC_ARRAY" 8 XReturns a 2 element array consisting of the key and value for the next Xvalue of an associative array, so that you can iterate over it. XEntries are returned in an apparently random order. XWhen the array is entirely read, a null array is returned (which when Xassigned produces a FALSE (0) value). XThe next call to each() after that will start iterating again. XThe iterator can be reset only by reading all the elements from the array. XYou must not modify the array while iterating over it. XThere is a single iterator for each associative array, shared by all Xeach(), keys() and values() function calls in the program. XThe following prints out your environment like the printenv program, only Xin a different order: X.nf X X.ne 3 X while (($key,$value) = each %ENV) { X print "$key=$value\en"; X } X X.fi XSee also keys() and values(). X.Ip "eof(FILEHANDLE)" 8 8 X.Ip "eof()" 8 X.Ip "eof" 8 XReturns 1 if the next read on FILEHANDLE will return end of file, or if XFILEHANDLE is not open. XFILEHANDLE may be an expression whose value gives the real filehandle name. X(Note that this function actually reads a character and then ungetc's it, Xso it is not very useful in an interactive context.) XAn eof without an argument returns the eof status for the last file read. XEmpty parentheses () may be used to indicate the pseudo file formed of the Xfiles listed on the command line, i.e. eof() is reasonable to use inside Xa while (<>) loop to detect the end of only the last file. XUse eof(ARGV) or eof without the parentheses to test EACH file in a while (<>) loop. XExamples: X.nf X X.ne 7 X # insert dashes just before last line of last file X while (<>) { X if (eof()) { X print "\-\|\-\|\-\|\-\|\-\|\-\|\-\|\-\|\-\|\-\|\-\|\-\|\-\|\-\en"; X } X print; X } X X.ne 7 X # reset line numbering on each input file X while (<>) { X print "$.\et$_"; X if (eof) { # Not eof(). X close(ARGV); X } X } X X.fi X.Ip "eval(EXPR)" 8 6 X.Ip "eval EXPR" 8 6 XEXPR is parsed and executed as if it were a little X.I perl Xprogram. XIt is executed in the context of the current X.I perl Xprogram, so that Xany variable settings, subroutine or format definitions remain afterwards. XThe value returned is the value of the last expression evaluated, just Xas with subroutines. XIf there is a syntax error or runtime error, or a die statement is Xexecuted, an undefined value is returned by Xeval, and $@ is set to the error message. XIf there was no error, $@ is guaranteed to be a null string. XIf EXPR is omitted, evaluates $_. XThe final semicolon, if any, may be omitted from the expression. X.Sp XNote that, since eval traps otherwise-fatal errors, it is useful for Xdetermining whether a particular feature X(such as dbmopen or symlink) is implemented. XIt is also Perl's exception trapping mechanism, where the die operator is Xused to raise exceptions. X.Ip "exec(LIST)" 8 8 X.Ip "exec LIST" 8 6 XIf there is more than one argument in LIST, or if LIST is an array with Xmore than one value, Xcalls execvp() with the arguments in LIST. XIf there is only one scalar argument, the argument is checked for shell metacharacters. XIf there are any, the entire argument is passed to \*(L"/bin/sh \-c\*(R" for parsing. XIf there are none, the argument is split into words and passed directly to Xexecvp(), which is more efficient. XNote: exec (and system) do not flush your output buffer, so you may need to Xset $| to avoid lost output. XExamples: X.nf X X exec \'/bin/echo\', \'Your arguments are: \', @ARGV; X exec "sort $outfile | uniq"; X X.fi X.Sp XIf you don't really want to execute the first argument, but want to lie Xto the program you are executing about its own name, you can specify Xthe program you actually want to run by assigning that to a variable and Xputting the name of the variable in front of the LIST without a comma. X(This always forces interpretation of the LIST as a multi-valued list, even Xif there is only a single scalar in the list.) XExample: X.nf X X.ne 2 X $shell = '/bin/csh'; X exec $shell '-sh'; # pretend it's a login shell X X.fi X.Ip "exit(EXPR)" 8 6 X.Ip "exit EXPR" 8 XEvaluates EXPR and exits immediately with that value. XExample: X.nf X X.ne 2 X $ans = <STDIN>; X exit 0 \|if \|$ans \|=~ \|/\|^[Xx]\|/\|; X X.fi XSee also X.IR die . XIf EXPR is omitted, exits with 0 status. X.Ip "exp(EXPR)" 8 3 X.Ip "exp EXPR" 8 XReturns X.I e Xto the power of EXPR. XIf EXPR is omitted, gives exp($_). X.Ip "fcntl(FILEHANDLE,FUNCTION,SCALAR)" 8 4 XImplements the fcntl(2) function. XYou'll probably have to say X.nf X X require "fcntl.ph"; # probably /usr/local/lib/perl/fcntl.ph X X.fi Xfirst to get the correct function definitions. XIf fcntl.ph doesn't exist or doesn't have the correct definitions Xyou'll have to roll Xyour own, based on your C header files such as <sys/fcntl.h>. X(There is a perl script called h2ph that comes with the perl kit Xwhich may help you in this.) XArgument processing and value return works just like ioctl below. XNote that fcntl will produce a fatal error if used on a machine that doesn't implement Xfcntl(2). X.Ip "fileno(FILEHANDLE)" 8 4 X.Ip "fileno FILEHANDLE" 8 4 XReturns the file descriptor for a filehandle. XUseful for constructing bitmaps for select(). XIf FILEHANDLE is an expression, the value is taken as the name of Xthe filehandle. X.Ip "flock(FILEHANDLE,OPERATION)" 8 4 XCalls flock(2) on FILEHANDLE. XSee manual page for flock(2) for definition of OPERATION. XReturns true for success, false on failure. XWill produce a fatal error if used on a machine that doesn't implement Xflock(2). XHere's a mailbox appender for BSD systems. X.nf X X.ne 20 X $LOCK_SH = 1; X $LOCK_EX = 2; X $LOCK_NB = 4; X $LOCK_UN = 8; X X sub lock { X flock(MBOX,$LOCK_EX); X # and, in case someone appended X # while we were waiting... X seek(MBOX, 0, 2); X } X X sub unlock { X flock(MBOX,$LOCK_UN); X } X X open(MBOX, ">>/usr/spool/mail/$ENV{'USER'}") X || die "Can't open mailbox: $!"; X X do lock(); X print MBOX $msg,"\en\en"; X do unlock(); X X.fi X.Ip "fork" 8 4 XDoes a fork() call. XReturns the child pid to the parent process and 0 to the child process. XNote: unflushed buffers remain unflushed in both processes, which means Xyou may need to set $| to avoid duplicate output. X.Ip "getc(FILEHANDLE)" 8 4 X.Ip "getc FILEHANDLE" 8 X.Ip "getc" 8 XReturns the next character from the input file attached to FILEHANDLE, or Xa null string at EOF. XIf FILEHANDLE is omitted, reads from STDIN. X.Ip "getlogin" 8 3 XReturns the current login from /etc/utmp, if any. XIf null, use getpwuid. X X $login = getlogin || (getpwuid($<))[0] || "Somebody"; X X.Ip "getpeername(SOCKET)" 8 3 XReturns the packed sockaddr address of other end of the SOCKET connection. X.nf X X.ne 4 X # An internet sockaddr X $sockaddr = 'S n a4 x8'; X $hersockaddr = getpeername(S); X.ie t \{\ X ($family, $port, $heraddr) = unpack($sockaddr,$hersockaddr); X'br\} X.el \{\ X ($family, $port, $heraddr) = X unpack($sockaddr,$hersockaddr); X'br\} X X.fi X.Ip "getpgrp(PID)" 8 4 X.Ip "getpgrp PID" 8 XReturns the current process group for the specified PID, 0 for the current Xprocess. XWill produce a fatal error if used on a machine that doesn't implement Xgetpgrp(2). XIf EXPR is omitted, returns process group of current process. X.Ip "getppid" 8 4 XReturns the process id of the parent process. X.Ip "getpriority(WHICH,WHO)" 8 4 XReturns the current priority for a process, a process group, or a user. X(See getpriority(2).) XWill produce a fatal error if used on a machine that doesn't implement Xgetpriority(2). X.Ip "getpwnam(NAME)" 8 X.Ip "getgrnam(NAME)" 8 X.Ip "gethostbyname(NAME)" 8 X.Ip "getnetbyname(NAME)" 8 X.Ip "getprotobyname(NAME)" 8 X.Ip "getpwuid(UID)" 8 X.Ip "getgrgid(GID)" 8 X.Ip "getservbyname(NAME,PROTO)" 8 X.Ip "gethostbyaddr(ADDR,ADDRTYPE)" 8 X.Ip "getnetbyaddr(ADDR,ADDRTYPE)" 8 X.Ip "getprotobynumber(NUMBER)" 8 X.Ip "getservbyport(PORT,PROTO)" 8 X.Ip "getpwent" 8 X.Ip "getgrent" 8 X.Ip "gethostent" 8 X.Ip "getnetent" 8 X.Ip "getprotoent" 8 X.Ip "getservent" 8 X.Ip "setpwent" 8 X.Ip "setgrent" 8 X.Ip "sethostent(STAYOPEN)" 8 X.Ip "setnetent(STAYOPEN)" 8 X.Ip "setprotoent(STAYOPEN)" 8 X.Ip "setservent(STAYOPEN)" 8 X.Ip "endpwent" 8 X.Ip "endgrent" 8 X.Ip "endhostent" 8 X.Ip "endnetent" 8 X.Ip "endprotoent" 8 X.Ip "endservent" 8 XThese routines perform the same functions as their counterparts in the Xsystem library. XThe return values from the various get routines are as follows: X.nf X X ($name,$passwd,$uid,$gid, X $quota,$comment,$gcos,$dir,$shell) = getpw.\|.\|. X ($name,$passwd,$gid,$members) = getgr.\|.\|. X ($name,$aliases,$addrtype,$length,@addrs) = gethost.\|.\|. X ($name,$aliases,$addrtype,$net) = getnet.\|.\|. X ($name,$aliases,$proto) = getproto.\|.\|. X ($name,$aliases,$port,$proto) = getserv.\|.\|. X X.fi XThe $members value returned by getgr.\|.\|. is a space separated list Xof the login names of the members of the group. X.Sp XThe @addrs value returned by the gethost.\|.\|. functions is a list of the Xraw addresses returned by the corresponding system library call. XIn the Internet domain, each address is four bytes long and you can unpack Xit by saying something like: X.nf X X ($a,$b,$c,$d) = unpack('C4',$addr[0]); X X.fi X.Ip "getsockname(SOCKET)" 8 3 XReturns the packed sockaddr address of this end of the SOCKET connection. X.nf X X.ne 4 X # An internet sockaddr X $sockaddr = 'S n a4 x8'; X $mysockaddr = getsockname(S); X.ie t \{\ X ($family, $port, $myaddr) = unpack($sockaddr,$mysockaddr); X'br\} X.el \{\ X ($family, $port, $myaddr) = X unpack($sockaddr,$mysockaddr); X'br\} X X.fi X.Ip "getsockopt(SOCKET,LEVEL,OPTNAME)" 8 3 XReturns the socket option requested, or undefined if there is an error. X.Ip "gmtime(EXPR)" 8 4 X.Ip "gmtime EXPR" 8 XConverts a time as returned by the time function to a 9-element array with Xthe time analyzed for the Greenwich timezone. XTypically used as follows: X.nf X X.ne 3 X.ie t \{\ X ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time); X'br\} X.el \{\ X ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = X gmtime(time); X'br\} X X.fi XAll array elements are numeric, and come straight out of a struct tm. XIn particular this means that $mon has the range 0.\|.11 and $wday has the Xrange 0.\|.6. XIf EXPR is omitted, does gmtime(time). X.Ip "goto LABEL" 8 6 XFinds the statement labeled with LABEL and resumes execution there. XCurrently you may only go to statements in the main body of the program Xthat are not nested inside a do {} construct. XThis statement is not implemented very efficiently, and is here only to make Xthe X.IR sed -to- perl Xtranslator easier. XI may change its semantics at any time, consistent with support for translated X.I sed Xscripts. XUse it at your own risk. XBetter yet, don't use it at all. X.Ip "grep(EXPR,LIST)" 8 4 XEvaluates EXPR for each element of LIST (locally setting $_ to each element) Xand returns the array value consisting of those elements for which the Xexpression evaluated to true. XIn a scalar context, returns the number of times the expression was true. X.nf X X @foo = grep(!/^#/, @bar); # weed out comments X X.fi XNote that, since $_ is a reference into the array value, it can be Xused to modify the elements of the array. XWhile this is useful and supported, it can cause bizarre results if Xthe LIST is not a named array. X.Ip "hex(EXPR)" 8 4 X.Ip "hex EXPR" 8 XReturns the decimal value of EXPR interpreted as an hex string. X(To interpret strings that might start with 0 or 0x see oct().) XIf EXPR is omitted, uses $_. X.Ip "index(STR,SUBSTR,POSITION)" 8 4 X.Ip "index(STR,SUBSTR)" 8 4 XReturns the position of the first occurrence of SUBSTR in STR at or after XPOSITION. XIf POSITION is omitted, starts searching from the beginning of the string. XThe return value is based at 0, or whatever you've Xset the $[ variable to. XIf the substring is not found, returns one less than the base, ordinarily \-1. X.Ip "int(EXPR)" 8 4 X.Ip "int EXPR" 8 XReturns the integer portion of EXPR. XIf EXPR is omitted, uses $_. X.Ip "ioctl(FILEHANDLE,FUNCTION,SCALAR)" 8 4 XImplements the ioctl(2) function. XYou'll probably have to say X.nf X X require "ioctl.ph"; # probably /usr/local/lib/perl/ioctl.ph X X.fi Xfirst to get the correct function definitions. XIf ioctl.ph doesn't exist or doesn't have the correct definitions Xyou'll have to roll Xyour own, based on your C header files such as <sys/ioctl.h>. X(There is a perl script called h2ph that comes with the perl kit Xwhich may help you in this.) XSCALAR will be read and/or written depending on the FUNCTION\*(--a pointer Xto the string value of SCALAR will be passed as the third argument of Xthe actual ioctl call. X(If SCALAR has no string value but does have a numeric value, that value Xwill be passed rather than a pointer to the string value. XTo guarantee this to be true, add a 0 to the scalar before using it.) XThe pack() and unpack() functions are useful for manipulating the values Xof structures used by ioctl(). XThe following example sets the erase character to DEL. X.nf X X.ne 9 X require 'ioctl.ph'; X $sgttyb_t = "ccccs"; # 4 chars and a short X if (ioctl(STDIN,$TIOCGETP,$sgttyb)) { X @ary = unpack($sgttyb_t,$sgttyb); X $ary[2] = 127; X $sgttyb = pack($sgttyb_t,@ary); X ioctl(STDIN,$TIOCSETP,$sgttyb) X || die "Can't ioctl: $!"; X } X X.fi XThe return value of ioctl (and fcntl) is as follows: X.nf X X.ne 4 X if OS returns:\h'|3i'perl returns: X -1\h'|3i' undefined value X 0\h'|3i' string "0 but true" X anything else\h'|3i' that number X X.fi XThus perl returns true on success and false on failure, yet you can still Xeasily determine the actual value returned by the operating system: X.nf X X ($retval = ioctl(...)) || ($retval = -1); X printf "System returned %d\en", $retval; X.fi X.Ip "join(EXPR,LIST)" 8 8 X.Ip "join(EXPR,ARRAY)" 8 XJoins the separate strings of LIST or ARRAY into a single string with fields Xseparated by the value of EXPR, and returns the string. XExample: X.nf X X.ie t \{\ X $_ = join(\|\':\', $login,$passwd,$uid,$gid,$gcos,$home,$shell); X'br\} X.el \{\ X $_ = join(\|\':\', X $login,$passwd,$uid,$gid,$gcos,$home,$shell); X'br\} X X.fi XSee X.IR split . X.Ip "keys(ASSOC_ARRAY)" 8 6 X.Ip "keys ASSOC_ARRAY" 8 XReturns a normal array consisting of all the keys of the named associative Xarray. XThe keys are returned in an apparently random order, but it is the same order Xas either the values() or each() function produces (given that the associative array Xhas not been modified). XHere is yet another way to print your environment: X.nf X X.ne 5 X @keys = keys %ENV; X @values = values %ENV; X while ($#keys >= 0) { X print pop(@keys), \'=\', pop(@values), "\en"; X } X Xor how about sorted by key: X X.ne 3 X foreach $key (sort(keys %ENV)) { X print $key, \'=\', $ENV{$key}, "\en"; X } X X.fi X.Ip "kill(LIST)" 8 8 X.Ip "kill LIST" 8 2 XSends a signal to a list of processes. XThe first element of the list must be the signal to send. XReturns the number of processes successfully signaled. X.nf X X $cnt = kill 1, $child1, $child2; X kill 9, @goners; X X.fi XIf the signal is negative, kills process groups instead of processes. X(On System V, a negative \fIprocess\fR number will also kill process groups, Xbut that's not portable.) XYou may use a signal name in quotes. X.Ip "last LABEL" 8 8 X.Ip "last" 8 XThe X.I last Xcommand is like the X.I break Xstatement in C (as used in loops); it immediately exits the loop in question. XIf the LABEL is omitted, the command refers to the innermost enclosing loop. XThe X.I continue Xblock, if any, is not executed: X.nf X X.ne 4 X line: while (<STDIN>) { X last line if /\|^$/; # exit when done with header X .\|.\|. X } X X.fi X.Ip "length(EXPR)" 8 4 X.Ip "length EXPR" 8 XReturns the length in characters of the value of EXPR. XIf EXPR is omitted, returns length of $_. X.Ip "link(OLDFILE,NEWFILE)" 8 2 XCreates a new filename linked to the old filename. XReturns 1 for success, 0 otherwise. X.Ip "listen(SOCKET,QUEUESIZE)" 8 2 XDoes the same thing that the listen system call does. XReturns true if it succeeded, false otherwise. XSee example in section on Interprocess Communication. X.Ip "local(LIST)" 8 4 XDeclares the listed variables to be local to the enclosing block, Xsubroutine, eval or \*(L"do\*(R". XAll the listed elements must be legal lvalues. XThis operator works by saving the current values of those variables in LIST Xon a hidden stack and restoring them upon exiting the block, subroutine or eval. XThis means that called subroutines can also reference the local variable, Xbut not the global one. XThe LIST may be assigned to if desired, which allows you to initialize Xyour local variables. X(If no initializer is given for a particular variable, it is created with Xan undefined value.) XCommonly this is used to name the parameters to a subroutine. XExamples: X.nf X X.ne 13 X sub RANGEVAL { X local($min, $max, $thunk) = @_; X local($result) = \'\'; X local($i); X X # Presumably $thunk makes reference to $i X X for ($i = $min; $i < $max; $i++) { X $result .= eval $thunk; X } X X $result; X } X X.ne 6 X if ($sw eq \'-v\') { X # init local array with global array X local(@ARGV) = @ARGV; X unshift(@ARGV,\'echo\'); X system @ARGV; X } X # @ARGV restored X X.ne 6 X # temporarily add to digits associative array X if ($base12) { X # (NOTE: not claiming this is efficient!) X local(%digits) = (%digits,'t',10,'e',11); X do parse_num(); X } X X.fi XNote that local() is a run-time command, and so gets executed every time Xthrough a loop, using up more stack storage each time until it's all Xreleased at once when the loop is exited. X.Ip "localtime(EXPR)" 8 4 X.Ip "localtime EXPR" 8 XConverts a time as returned by the time function to a 9-element array with Xthe time analyzed for the local timezone. XTypically used as follows: X.nf X X.ne 3 X.ie t \{\ X ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); X'br\} X.el \{\ X ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = X localtime(time); X'br\} X X.fi XAll array elements are numeric, and come straight out of a struct tm. XIn particular this means that $mon has the range 0.\|.11 and $wday has the Xrange 0.\|.6. XIf EXPR is omitted, does localtime(time). X.Ip "log(EXPR)" 8 4 X.Ip "log EXPR" 8 XReturns logarithm (base X.IR e ) Xof EXPR. XIf EXPR is omitted, returns log of $_. X.Ip "lstat(FILEHANDLE)" 8 6 X.Ip "lstat FILEHANDLE" 8 X.Ip "lstat(EXPR)" 8 X.Ip "lstat SCALARVARIABLE" 8 XDoes the same thing as the stat() function, but stats a symbolic link Xinstead of the file the symbolic link points to. XIf symbolic links are unimplemented on your system, a normal stat is done. X.Ip "m/PATTERN/io" 8 4 X.Ip "/PATTERN/io" 8 XSearches a string for a pattern match, and returns true (1) or false (\'\'). XIf no string is specified via the =~ or !~ operator, Xthe $_ string is searched. X(The string specified with =~ need not be an lvalue\*(--it may be the result of an expression evaluation, but remember the =~ binds rather tightly.) XSee also the section on regular expressions. X.Sp XIf / is the delimiter then the initial \*(L'm\*(R' is optional. XWith the \*(L'm\*(R' you can use any pair of non-alphanumeric characters Xas delimiters. XThis is particularly useful for matching Unix path names that contain \*(L'/\*(R'. XIf the final delimiter is followed by the optional letter \*(L'i\*(R', the matching is Xdone in a case-insensitive manner. XPATTERN may contain references to scalar variables, which will be interpolated X(and the pattern recompiled) every time the pattern search is evaluated. X(Note that $) and $| may not be interpolated because they look like end-of-string tests.) XIf you want such a pattern to be compiled only once, add an \*(L"o\*(R" after Xthe trailing delimiter. XThis avoids expensive run-time recompilations, and Xis useful when the value you are interpolating won't change over the Xlife of the script. XIf the PATTERN evaluates to a null string, the most recent successful Xregular expression is used instead. X.Sp XIf used in a context that requires an array value, a pattern match returns an Xarray consisting of the subexpressions matched by the parentheses in the Xpattern, Xi.e. ($1, $2, $3.\|.\|.). XIt does NOT actually set $1, $2, etc. in this case, nor does it set $+, $`, $& Xor $'. XIf the match fails, a null array is returned. XIf the match succeeds, but there were no parentheses, an array value of (1) Xis returned. X.Sp XExamples: X.nf X X.ne 4 X open(tty, \'/dev/tty\'); X <tty> \|=~ \|/\|^y\|/i \|&& \|do foo(\|); # do foo if desired X X if (/Version: \|*\|([0\-9.]*\|)\|/\|) { $version = $1; } X X next if m#^/usr/spool/uucp#; X X.ne 5 X # poor man's grep X $arg = shift; X while (<>) { X print if /$arg/o; # compile only once X } X X if (($F1, $F2, $Etc) = ($foo =~ /^(\eS+)\es+(\eS+)\es*(.*)/)) X X.fi XThis last example splits $foo into the first two words and the remainder Xof the line, and assigns those three fields to $F1, $F2 and $Etc. XThe conditional is true if any variables were assigned, i.e. if the pattern Xmatched. X.Ip "mkdir(FILENAME,MODE)" 8 3 XCreates the directory specified by FILENAME, with permissions specified by XMODE (as modified by umask). XIf it succeeds it returns 1, otherwise it returns 0 and sets $! (errno). X.Ip "msgctl(ID,CMD,ARG)" 8 4 XCalls the System V IPC function msgctl. If CMD is &IPC_STAT, then ARG Xmust be a variable which will hold the returned msqid_ds structure. XReturns like ioctl: the undefined value for error, "0 but true" for Xzero, or the actual return value otherwise. X.Ip "msgget(KEY,FLAGS)" 8 4 XCalls the System V IPC function msgget. Returns the message queue id, Xor the undefined value if there is an error. X.Ip "msgsnd(ID,MSG,FLAGS)" 8 4 XCalls the System V IPC function msgsnd to send the message MSG to the Xmessage queue ID. MSG must begin with the long integer message type, Xwhich may be created with pack("L", $type). Returns true if Xsuccessful, or false if there is an error. X.Ip "msgrcv(ID,VAR,SIZE,TYPE,FLAGS)" 8 4 XCalls the System V IPC function msgrcv to receive a message from Xmessage queue ID into variable VAR with a maximum message size of XSIZE. Note that if a message is received, the message type will be Xthe first thing in VAR, and the maximum length of VAR is SIZE plus the Xsize of the message type. Returns true if successful, or false if Xthere is an error. X''' Beginning of part 3 X''' $RCSfile: perl.man,v $$Revision: 4.0.1.1 $$Date: 91/04/11 17:50:44 $ X''' X''' $Log: perl.man,v $ X''' Revision 4.0.1.1 91/04/11 17:50:44 lwall X''' patch1: fixed some typos X''' X''' Revision 4.0 91/03/20 01:38:08 lwall X''' 4.0 baseline. X''' X''' Revision 3.0.1.12 91/01/11 18:18:15 lwall X''' patch42: added binary and hex pack/unpack options X''' X''' Revision 3.0.1.11 90/11/10 01:48:21 lwall X''' patch38: random cleanup X''' patch38: documented tr///cds X''' X''' Revision 3.0.1.10 90/10/20 02:15:17 lwall X''' patch37: patch37: fixed various typos in man page X''' X''' Revision 3.0.1.9 90/10/16 10:02:43 lwall X''' patch29: you can now read into the middle string X''' patch29: index and substr now have optional 3rd args X''' patch29: added scalar reverse X''' patch29: added scalar X''' patch29: added SysV IPC X''' patch29: added waitpid X''' patch29: added sysread and syswrite X''' X''' Revision 3.0.1.8 90/08/09 04:39:04 lwall X''' patch19: added require operator X''' patch19: added truncate operator X''' patch19: unpack can do checksumming X''' X''' Revision 3.0.1.7 90/08/03 11:15:42 lwall X''' patch19: Intermediate diffs for Randal X''' X''' Revision 3.0.1.6 90/03/27 16:17:56 lwall X''' patch16: MSDOS support X''' X''' Revision 3.0.1.5 90/03/12 16:52:21 lwall X''' patch13: documented that print $filehandle &foo is ambiguous X''' patch13: added splice operator: @oldelems = splice(@array,$offset,$len,LIST) X''' X''' Revision 3.0.1.4 90/02/28 18:00:09 lwall X''' patch9: added pipe function X''' patch9: documented how to handle arbitrary weird characters in filenames X''' patch9: documented the unflushed buffers problem on piped opens X''' patch9: documented how to force top of page X''' X''' Revision 3.0.1.3 89/12/21 20:10:12 lwall X''' patch7: documented that s`pat`repl` does command substitution on replacement X''' patch7: documented that $timeleft from select() is likely not implemented X''' X''' Revision 3.0.1.2 89/11/17 15:31:05 lwall X''' patch5: fixed some manual typos and indent problems X''' patch5: added warning about print making an array context X''' X''' Revision 3.0.1.1 89/11/11 04:45:06 lwall X''' patch2: made some line breaks depend on troff vs. nroff X''' X''' Revision 3.0 89/10/18 15:21:46 lwall X''' 3.0 baseline X''' X.Ip "next LABEL" 8 8 X.Ip "next" 8 XThe X.I next Xcommand is like the X.I continue Xstatement in C; it starts the next iteration of the loop: X.nf X X.ne 4 X line: while (<STDIN>) { X next line if /\|^#/; # discard comments X .\|.\|. X } X X.fi XNote that if there were a X.I continue Xblock on the above, it would get executed even on discarded lines. XIf the LABEL is omitted, the command refers to the innermost enclosing loop. X.Ip "oct(EXPR)" 8 4 X.Ip "oct EXPR" 8 XReturns the decimal value of EXPR interpreted as an octal string. X(If EXPR happens to start off with 0x, interprets it as a hex string instead.) XThe following will handle decimal, octal and hex in the standard notation: X.nf X X $val = oct($val) if $val =~ /^0/; X X.fi XIf EXPR is omitted, uses $_. X.Ip "open(FILEHANDLE,EXPR)" 8 8 X.Ip "open(FILEHANDLE)" 8 X.Ip "open FILEHANDLE" 8 XOpens the file whose filename is given by EXPR, and associates it with XFILEHANDLE. XIf FILEHANDLE is an expression, its value is used as the name of the Xreal filehandle wanted. XIf EXPR is omitted, the scalar variable of the same name as the FILEHANDLE Xcontains the filename. XIf the filename begins with \*(L"<\*(R" or nothing, the file is opened for Xinput. XIf the filename begins with \*(L">\*(R", the file is opened for output. XIf the filename begins with \*(L">>\*(R", the file is opened for appending. X(You can put a \'+\' in front of the \'>\' or \'<\' to indicate that you Xwant both read and write access to the file.) XIf the filename begins with \*(L"|\*(R", the filename is interpreted Xas a command to which output is to be piped, and if the filename ends Xwith a \*(L"|\*(R", the filename is interpreted as command which pipes Xinput to us. X(You may not have a command that pipes both in and out.) XOpening \'\-\' opens X.I STDIN Xand opening \'>\-\' opens X.IR STDOUT . XOpen returns non-zero upon success, the undefined value otherwise. XIf the open involved a pipe, the return value happens to be the pid Xof the subprocess. XExamples: X.nf X X.ne 3 X $article = 100; X open article || die "Can't find article $article: $!\en"; X while (<article>) {\|.\|.\|. X X.ie t \{\ X open(LOG, \'>>/usr/spool/news/twitlog\'\|); # (log is reserved) X'br\} X.el \{\ X open(LOG, \'>>/usr/spool/news/twitlog\'\|); X # (log is reserved) X'br\} X X.ie t \{\ X open(article, "caesar <$article |"\|); # decrypt article X'br\} X.el \{\ X open(article, "caesar <$article |"\|); X # decrypt article X'br\} X X.ie t \{\ X open(extract, "|sort >/tmp/Tmp$$"\|); # $$ is our process# X'br\} X.el \{\ X open(extract, "|sort >/tmp/Tmp$$"\|); X # $$ is our process# X'br\} X X.ne 7 X # process argument list of files along with any includes X X foreach $file (@ARGV) { X do process($file, \'fh00\'); # no pun intended X } X X sub process { X local($filename, $input) = @_; X $input++; # this is a string increment X unless (open($input, $filename)) { X print STDERR "Can't open $filename: $!\en"; X return; X } X.ie t \{\ X while (<$input>) { # note the use of indirection X'br\} X.el \{\ X while (<$input>) { # note use of indirection X'br\} X if (/^#include "(.*)"/) { X do process($1, $input); X next; X } X .\|.\|. # whatever X } X } X X.fi XYou may also, in the Bourne shell tradition, specify an EXPR beginning Xwith \*(L">&\*(R", in which case the rest of the string Xis interpreted as the name of a filehandle X(or file descriptor, if numeric) which is to be duped and opened. XYou may use & after >, >>, <, +>, +>> and +<. XThe mode you specify should match the mode of the original filehandle. XHere is a script that saves, redirects, and restores X.I STDOUT Xand X.IR STDERR : X.nf X X.ne 21 X #!/usr/bin/perl X open(SAVEOUT, ">&STDOUT"); X open(SAVEERR, ">&STDERR"); X X open(STDOUT, ">foo.out") || die "Can't redirect stdout"; X open(STDERR, ">&STDOUT") || die "Can't dup stdout"; X X select(STDERR); $| = 1; # make unbuffered X select(STDOUT); $| = 1; # make unbuffered X X print STDOUT "stdout 1\en"; # this works for X print STDERR "stderr 1\en"; # subprocesses too X X close(STDOUT); X close(STDERR); X X open(STDOUT, ">&SAVEOUT"); X open(STDERR, ">&SAVEERR"); X X print STDOUT "stdout 2\en"; X print STDERR "stderr 2\en"; X X.fi XIf you open a pipe on the command \*(L"\-\*(R", i.e. either \*(L"|\-\*(R" or \*(L"\-|\*(R", Xthen there is an implicit fork done, and the return value of open Xis the pid of the child within the parent process, and 0 within the child Xprocess. X(Use defined($pid) to determine if the open was successful.) XThe filehandle behaves normally for the parent, but i/o to that Xfilehandle is piped from/to the X.IR STDOUT / STDIN Xof the child process. XIn the child process the filehandle isn't opened\*(--i/o happens from/to Xthe new X.I STDOUT Xor X.IR STDIN . XTypically this is used like the normal piped open when you want to exercise Xmore control over just how the pipe command gets executed, such as when Xyou are running setuid, and don't want to have to scan shell commands Xfor metacharacters. XThe following pairs are more or less equivalent: X.nf X X.ne 5 X open(FOO, "|tr \'[a\-z]\' \'[A\-Z]\'"); X open(FOO, "|\-") || exec \'tr\', \'[a\-z]\', \'[A\-Z]\'; X X open(FOO, "cat \-n '$file'|"); X open(FOO, "\-|") || exec \'cat\', \'\-n\', $file; X X.fi XExplicitly closing any piped filehandle causes the parent process to wait for the Xchild to finish, and returns the status value in $?. XNote: on any operation which may do a fork, Xunflushed buffers remain unflushed in both Xprocesses, which means you may need to set $| to Xavoid duplicate output. X.Sp XThe filename that is passed to open will have leading and trailing Xwhitespace deleted. XIn order to open a file with arbitrary weird characters in it, it's necessary Xto protect any leading and trailing whitespace thusly: X.nf X X.ne 2 X $file =~ s#^(\es)#./$1#; X open(FOO, "< $file\e0"); X X.fi X.Ip "opendir(DIRHANDLE,EXPR)" 8 3 XOpens a directory named EXPR for processing by readdir(), telldir(), seekdir(), Xrewinddir() and closedir(). XReturns true if successful. XDIRHANDLEs have their own namespace separate from FILEHANDLEs. X.Ip "ord(EXPR)" 8 4 X.Ip "ord EXPR" 8 XReturns the numeric ascii value of the first character of EXPR. XIf EXPR is omitted, uses $_. X''' Comments on f & d by gnb@melba.bby.oz.au 22/11/89 X.Ip "pack(TEMPLATE,LIST)" 8 4 XTakes an array or list of values and packs it into a binary structure, Xreturning the string containing the structure. XThe TEMPLATE is a sequence of characters that give the order and type Xof values, as follows: X.nf X X A An ascii string, will be space padded. X a An ascii string, will be null padded. X c A signed char value. X C An unsigned char value. X s A signed short value. X S An unsigned short value. X i A signed integer value. X I An unsigned integer value. X l A signed long value. X L An unsigned long value. X n A short in \*(L"network\*(R" order. X N A long in \*(L"network\*(R" order. X f A single-precision float in the native format. X d A double-precision float in the native format. X p A pointer to a string. X x A null byte. X X Back up a byte. X @ Null fill to absolute position. X u A uuencoded string. X b A bit string (ascending bit order, like vec()). X B A bit string (descending bit order). X h A hex string (low nybble first). X H A hex string (high nybble first). X X.fi XEach letter may optionally be followed by a number which gives a repeat Xcount. XWith all types except "a", "A", "b", "B", "h" and "H", Xthe pack function will gobble up that many values Xfrom the LIST. XA * for the repeat count means to use however many items are left. XThe "a" and "A" types gobble just one value, but pack it as a string of length Xcount, !STUFFY!FUNK! echo " " echo "End of kit 5 (of 36)" cat /dev/null >kit5isdone run='' config='' for iskit in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36; do if test -f kit${iskit}isdone; then run="$run $iskit" else todo="$todo $iskit" fi done case $todo in '') echo "You have run all your kits. Please read README and then type Configure." for combo in *:AA; do if test -f "$combo"; then realfile=`basename $combo :AA` cat $realfile:[A-Z][A-Z] >$realfile rm -rf $realfile:[A-Z][A-Z] fi done rm -rf kit*isdone chmod 755 Configure ;; *) echo "You have run$run." echo "You still need to run$todo." ;; esac : Someone might mail this, so... exit exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.