home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / sh.zoo / sh.1 < prev    next >
Encoding:
Text File  |  1990-02-21  |  78.9 KB  |  2,447 lines

  1.  
  2. #!/bin/sh
  3. # shar:    Shell Archiver  (v1.23)
  4. #
  5. # This is a shell archive, meaning:
  6. # 1. Remove everything above the #! /bin/sh line.
  7. # 2. Save the resulting text in a file.
  8. # 3. Execute the file with /bin/sh (not csh) to create the files.
  9. #
  10. #
  11. # This is part 1 of a multipart archive                                    
  12. # do not concatenate these parts, unpack them in order with /bin/sh        
  13. #
  14. #    The following text will create:
  15. #      Install
  16. #      MANIFEST
  17. #      Notes
  18. #      ReadMe
  19. #      sh.1
  20. #      include/Changes
  21. #      include/sys/dirent.h
  22. #      include/sys/proto.h
  23. #      include/dirent.h
  24. #      include/unistd.h
  25. #      include/ms_dio.h
  26. #      lib/ms_dio.c
  27. #      lib/director.c
  28. #      lib/popen.c
  29. #      lib/syserr.c
  30. #      lib/stdargv.c
  31. #      lib/pnmatch.c
  32. #      lib/getopt.c
  33. #      scripts/l
  34. #      scripts/extend.lst
  35. #      scripts/profile.sh
  36. #      shell/Makefile
  37. #      shell/sh1.c
  38. #      shell/sh2.c
  39. #      shell/sh3.c
  40. #      shell/sh4.c
  41. #      shell/sh5.c
  42. #      shell/sh6.c
  43. #      shell/sh7.c
  44. #      shell/sh8.c
  45. #      shell/sh9.c
  46. #      shell/sh10.c
  47. #      shell/sh0.asm
  48. #      shell/sh.h
  49. #
  50. if test -r s2_seq_.tmp
  51. then echo "Must unpack archives in sequence!"
  52.      next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
  53.      exit 1; fi
  54. for i in include include/sys lib scripts shell
  55. do
  56. echo "x - creating directory $i"
  57. mkdir $i
  58. done
  59. echo "x - extracting Install (Text)"
  60. sed 's/^X//' << 'SHAR_EOF' > Install &&
  61. X MS-DOS Shell Version 1.4    INSTALL                January 1990
  62. X
  63. X MS-DOS SHELL - Copyright (c) 1990 Data Logic Limited and Charles Forsyth
  64. X
  65. X This code is based on (in part) the shell program written by Charles
  66. X Forsyth and is subject to the following copyright restrictions:
  67. X
  68. X 1.  Redistribution and use in source and binary forms are permitted
  69. X     provided that the above copyright notice is duplicated in the
  70. X     source form and the copyright notice in file sh6.c is displayed
  71. X     on entry to the program.
  72. X
  73. X 2.  The sources (or parts thereof) or objects generated from the
  74. X     sources (or parts of sources) cannot be sold under any circumstances.
  75. X
  76. X    $Header: install 1.1 90/01/29 18:03:04 MS_user Exp $
  77. X
  78. X    $Log:    install $
  79. X# Revision 1.1  90/01/29  18:03:04  MS_user
  80. X# Initial revision
  81. X# 
  82. X________________________________________________________________________________
  83. X
  84. XTo rebuild and install the shell, you should follow the following the
  85. Xsteps:
  86. X
  87. X1)  Load the include files in the include directory into the standard
  88. X    location (\msc\include or equivalent).  Read CHANGES file for the
  89. X    additional definitions which are required in the standard Microsoft
  90. X    5 include files and edit them in to the appropriate files.
  91. X
  92. X    We have standardised our MSDOS and Unix include files such that
  93. X    the same include file exists our Unix system and MSDOS systems.
  94. X    This makes porting a lot easier.  If you don't want to edit the
  95. X    standard include files, you will have to generate an new include
  96. X    file for the shell and include it as the first include in all the
  97. X    C sources for the additional library functions and the Shell itself
  98. X
  99. X2)  Modify the library function open so that the O_NOINHERIT flag is
  100. X    passed to MSDOS by the library.  This is not strictly necessary.
  101. X    I did it using CodeView to see where the library function masks
  102. X    the bottom three bits, noted the bytes around this location,
  103. X    extracted the open function from the library, patched the mask
  104. X    to be 0x83 instead of 0x03, and then replaced the function in the
  105. X    library.
  106. X
  107. X3)  Compile the library files in the directory /lib in large model mode
  108. X    and add the objects to your large model library
  109. X
  110. X    cl -c -AL -Olt *.c
  111. X    <appropriate library commands>
  112. X
  113. X4)  Build the shell, either using make or
  114. X
  115. X    cl -c -AL -Olt *.c
  116. X    masm /Ml sh0.asm
  117. X    link sh0+sh1+sh2+sh3+sh4+sh5+sh6+sh7+sh8+sh9+sh10/noi, sh.exe;
  118. X
  119. X    Note that the order is important.  SH0.OBJ must be the first object
  120. X    file in the load line.
  121. X
  122. X    Install the shell in its correct location.
  123. X
  124. X5)  Modify the scripts as appropriate for your installation and install
  125. X    them in the correct directories.
  126. X
  127. X6)  Type "sh -0" and see what happens.
  128. SHAR_EOF
  129. chmod 0644 Install || echo "restore of Install fails"
  130. set `wc -c Install`;Sum=$1
  131. if test "$Sum" != "2694"
  132. then echo original size 2694, current size $Sum;fi
  133. echo "x - extracting MANIFEST (Text)"
  134. sed 's/^X//' << 'SHAR_EOF' > MANIFEST &&
  135. XInstall            | Installation instructions
  136. XMANIFEST        | This list
  137. XNotes            | Some addition notes
  138. XReadMe            | The Release Readme
  139. Xsh.1            | The Manual page in *roff format
  140. Xinclude/Changes        | Changes to standard include files
  141. Xinclude/dirent.h    | Directory (3) functions include
  142. Xinclude/unistd.h    | unistd for MSDOS
  143. Xinclude/ms_dio.h    | MSDOS raw disk/memory I/O include file
  144. Xinclude/sys/dirent.h    | Second part of directory (3) functions include file
  145. Xinclude/sys/proto.h    | Prototype definitions
  146. Xlib/ms_dio.c        | MSDOS raw disk/memory I/O functions
  147. Xlib/director.c        | POSIX directory (3) functions for MSDOS
  148. Xlib/popen.c        | popen/pclose for MSDOS
  149. Xlib/syserr.c        | Modified sys_errlist for MSDOS
  150. Xlib/stdargv.c        | Replacement command list processing for programes
  151. Xlib/pnmatch.c        | Pattern matching function
  152. Xlib/getopt.c        | getopt function
  153. Xscripts/l        | A sample shell script
  154. Xscripts/extend.lst    | A sample extended command line processing list
  155. Xscripts/profile.sh    | A sample start up shell script
  156. Xshell/Makefile        | Shell - makefile 
  157. Xshell/sh0.asm        | Shell - Swap functions
  158. Xshell/sh1.c        | Shell - Main program and memory control functions
  159. Xshell/sh2.c        | Shell - Parser functions
  160. Xshell/sh3.c        | Shell - Parse tree processing functions
  161. Xshell/sh4.c        | Shell - Word processing functions
  162. Xshell/sh5.c        | Shell - Filename expansion functions
  163. Xshell/sh6.c        | Shell - Global variables
  164. Xshell/sh7.c        | Shell - Built-in functions
  165. Xshell/sh8.c        | Shell - Unix I/O Emulation
  166. Xshell/sh9.c        | Shell - History processing functions
  167. Xshell/sh10.c        | Shell - Function print/save/delete functions
  168. Xshell/sh.h        | Shell - Header file
  169. SHAR_EOF
  170. chmod 0644 MANIFEST || echo "restore of MANIFEST fails"
  171. set `wc -c MANIFEST`;Sum=$1
  172. if test "$Sum" != "1578"
  173. then echo original size 1578, current size $Sum;fi
  174. echo "x - extracting Notes (Text)"
  175. sed 's/^X//' << 'SHAR_EOF' > Notes &&
  176. XThe following addition points are noted about the Shell.
  177. X
  178. X1)  EMS 3.2 or above is required if expanded memory is to be used.
  179. X
  180. X2)  It has been tested on MS-DOS 3.3 and 4.0 and under OS/2 in the
  181. X    DOS box.
  182. X
  183. X3)  Not all the addition library functions are required.  Some are
  184. X    just included for your interest.  Their functionality is
  185. X    briefly described below:
  186. X
  187. X    director.c (required)
  188. X
  189. X    MSDOS versions of the POSIX directory (3) functions (see
  190. X    POSIX standards and Unix manual pages for further information).
  191. X
  192. X    getopt.c (required)
  193. X
  194. X    The getopt function
  195. X
  196. X    stdargv.c (required)
  197. X
  198. X    A replacement for the standard Microsoft library stdargv.obj.
  199. X    This function tries to provide the wildcard expansion functionality
  200. X    normally provided by Unix.  *, ?, [] and \ are supported.
  201. X    Environment variables are expanded and the selection of files
  202. X    across wildcard drive letters is supported (ie *:*.c will
  203. X    expand to all the .c files in the current directory of all
  204. X    drives).
  205. X
  206. X    pnmatch.c (required)
  207. X
  208. X    A pattern match function used by stdargv
  209. X
  210. X    ms_dio.c
  211. X
  212. X    A set of functions to allow you to do raw disk and memory
  213. X    I/O.  The include file ms_dio has a set of macros to
  214. X    change the normal library calls so that they go via this
  215. X    package.
  216. X
  217. X    popen.c
  218. X
  219. X    A version of popen for MS-DOS
  220. X
  221. X    syserr.c
  222. X
  223. X    A modified version of the standard Microsoft error list.
  224. SHAR_EOF
  225. chmod 0644 Notes || echo "restore of Notes fails"
  226. set `wc -c Notes`;Sum=$1
  227. if test "$Sum" != "1334"
  228. then echo original size 1334, current size $Sum;fi
  229. echo "x - extracting ReadMe (Text)"
  230. sed 's/^X//' << 'SHAR_EOF' > ReadMe &&
  231. X MS-DOS Shell Version 1.4    README                January 1990
  232. X
  233. X MS-DOS SHELL - Copyright (c) 1990 Data Logic Limited and Charles Forsyth
  234. X
  235. X This code is based on (in part) the shell program written by Charles
  236. X Forsyth and is subject to the following copyright restrictions:
  237. X
  238. X 1.  Redistribution and use in source and binary forms are permitted
  239. X     provided that the above copyright notice is duplicated in the
  240. X     source form and the copyright notice in file sh6.c is displayed
  241. X     on entry to the program.
  242. X
  243. X 2.  The sources (or parts thereof) or objects generated from the
  244. X     sources (or parts of sources) cannot be sold under any circumstances.
  245. X
  246. X    $Header: readme 1.1 90/01/25 13:43:20 MS_user Exp $
  247. X
  248. X    $Log:    readme $
  249. X# Revision 1.1  90/01/25  13:43:20  MS_user
  250. X# Initial revision
  251. X# 
  252. X________________________________________________________________________________
  253. X
  254. XThis is an implementation of the Unix Shell for MSDOS.  As far as
  255. Xpossible it is compatible with the System V.3 program sh(1).  The
  256. Xfollowing differences are noted:
  257. X
  258. X1)  Background or asynchronous commands are not supported
  259. X
  260. X2)  Certain internal commands which have no equivalent MSDOS supported
  261. X    functionality support (ulimit, time etc) are not provided.
  262. X
  263. X3)  Command hashing and accounting are not supported.
  264. X
  265. X4)  The Shell uses all variables starting with a ~ (tilde) internally
  266. X    and will not allow you to display them.  I don't think this is a
  267. X    difference from the user's view, just internally.
  268. X
  269. X5)  8 bit character sets are not supported.
  270. X
  271. XThe following enhancements have been made for the MSDOS environment.
  272. XThese enhancements are described in the appropriate section of the
  273. Xmanual pages.
  274. X
  275. X1)  The Shell will swap itself out to one of the following:
  276. X
  277. X    - Expanded memory
  278. X    - Extended memory
  279. X    - Disk (this is the slowest)
  280. X
  281. X    The swapping is controlled by the shell internal command swap.  If
  282. X    swapping is enabled, the shell only uses 3K of memory whilst a
  283. X    child process is executing.
  284. X
  285. X    Note: Swapping to Extended memory is probably the most dangerous
  286. X      because there is no memory manager available for it.
  287. X
  288. X2)  History processing has been added.
  289. X
  290. X3)  Command line editing has been added.
  291. X
  292. X4)  The command line prompt can be programmed to display 'useful'
  293. X    information.
  294. X
  295. X5)  The shell uses Unix format file names (ie slashes and not
  296. X    backslashes) to delimit directories.  Some programs require certain
  297. X    environment variables to be in MS-DOS format (using backslashes).
  298. X    The msdos command allows these variables to be marked so that they
  299. X    are set correctly when the environment for a program is set up.
  300. X
  301. X6)  Extended command line processing is supported using the parameter
  302. X    @<filename> to a command.  Examples of this include the Microsoft
  303. X    Linker and Librarian and of course the Shell itself.  A version of
  304. X    stdargv.c which supports this format (and wildcards from a normal
  305. X    command line) is included.
  306. X
  307. X7)  Wild cards on drives (ie echo *:*.c will echo all the C files in 
  308. X    the current directories of each drive) are supported.
  309. X
  310. XIn order to rebuild this program, you need the DIRECTORY(3) functions
  311. Xfor MSDOS (also included) and the version of open in your library must
  312. Xpass the O_NOINHERIT bit on the MSDOS kernel.  The Microsoft C V5.1
  313. Xlibrary does not pass this bit on to the MSDOS open System call.  I
  314. Xfixed this using CodeView to find where the library function masks off
  315. Xthe bottom 2 bits.  Extracted the object from the library and patched
  316. Xmask from 0x03 to 0x83 in the object and reload into the library.  No
  317. XProblem.
  318. X
  319. XYou can do want you like with this software as long as you don't sell
  320. Xit or remove the Copyright notices in the sources or object.
  321. X
  322. XIf you have any problems or want to let me know about any enhancements
  323. Xyou have made (which could be included in a new general release), you
  324. Xcan contact me at
  325. X
  326. X    Data Logic Limited
  327. X    Queens House
  328. X    Greenhill Way
  329. X    Harrow
  330. X    Middlesex, HA1 1YR
  331. X    UK.
  332. X
  333. X    Phone : +44 1 863 0383
  334. X    E-Mail: istewart@datlog.co.uk or ukc!datlog!istewart
  335. X
  336. XNote:
  337. X    Unix is a registered trademark of AT&T Bell Laboratories
  338. X    Microsoft, MSDOS and CodeView are registered trademarks of Microsoft
  339. X    Corporation
  340. SHAR_EOF
  341. chmod 0644 ReadMe || echo "restore of ReadMe fails"
  342. set `wc -c ReadMe`;Sum=$1
  343. if test "$Sum" != "4188"
  344. then echo original size 4188, current size $Sum;fi
  345. echo "x - extracting sh.1 (Text)"
  346. sed 's/^X//' << 'SHAR_EOF' > sh.1 &&
  347. X.\"
  348. X.\" MS-DOS SHELL - Manual Page
  349. X.\"
  350. X.\" MS-DOS SHELL - Copyright (c) 1990 Data Logic Limited
  351. X.\"
  352. X.\" This code is subject to the following copyright restrictions:
  353. X.\"
  354. X.\" 1.  Redistribution and use in source and binary forms are permitted
  355. X.\"     provided that the above copyright notice is duplicated in the
  356. X.\"     source form and the copyright notice in file sh6.c is displayed
  357. X.\"     on entry to the program.
  358. X.\"
  359. X.\" 2.  The sources (or parts thereof) or objects generated from the sources
  360. X.\"     (or parts of sources) cannot be sold under any circumstances.
  361. X.\"
  362. X.\"    $Header: sh.1 1.1 90/01/24 14:17:00 MS_user Locked $
  363. X.\"
  364. X.\"    $Log:    sh.1 $
  365. X.\"    Revision 1.1  90/01/24  14:17:00  MS_user
  366. X.\"    Initial revision
  367. X.\"    
  368. X.\"
  369. X.\"
  370. X.ds OK [\|
  371. X.ds CK \|]
  372. X.TH SH 1L "Data Logic Limited" "MS-DOS Version 1.4"
  373. X.SH NAME
  374. Xsh, rsh - shell, the standard/restricted command programming language
  375. X.SH SYNOPSIS
  376. X\fBsh\fR [ \fB-acefhiknmrstuvx\fR ] [ args ]
  377. X.br
  378. X\fBrsh\fR [ \fB-acefhiknmrstuvx\fR ] [ args ]
  379. X.SH DESCRIPTION
  380. X\fISh\fR is a command programming language that executes commands read from a
  381. Xterminal or a file.  \fIRsh\fR is a restricted version of the standard command
  382. Xinterpreter \fIsh\fR; it is used to set up login names and execution
  383. Xenvironments whose capabilities are more controlled than those of the standard
  384. Xshell.  See \fIInvocation\fR below for the meaning of arguments to the shell.
  385. X.SS Definitions
  386. XA \fIblank\fR is a tab or a space.  A \fIname\fR is a sequence of letters,
  387. Xdigits, or underscores beginning with a letter or underscore.  A \fIparameter\fR
  388. Xis a name, a digit, or any of the characters \fB*\fR, \fB@\fR, \fB#\fR, \fB?\fR,
  389. X\fB-\fR, \fB$\fR, and \fB!\fR.
  390. X.SS Commands
  391. XA \fIsimple-command\fR is a sequence of non-blank \fIwords\fR separated by
  392. X\fIblanks\fR.  The first word specifies the name of the command to be executed.
  393. XExcept as specified below, the remaining words are passed as arguments to the
  394. Xinvoked command.  The command name is passed as argument 0 (see \fIexec\fR(2)).
  395. XThe \fIvalue\fR of a simple-command is its exit status if it terminates
  396. Xnormally, or (octal) 200+\fIstatus\fR if it terminates abnormally (see
  397. X\fIsignal\fR(2) for a list of status values).
  398. X.PP
  399. XA \fIpipeline\fR is a sequence of one or more \fIcommands\fR separated by
  400. X\fB\(bv\fR (or, for historical compatibility, by \fB^\fR).
  401. XThe standard output of each command but the last is connected by a \fIpipe\fR(2)
  402. Xto the standard input of the next command.  Each command is run as a separate
  403. Xprocess; the shell waits for the last command to terminate.  The exit status
  404. Xof a pipeline is the exit status of the last command.
  405. X.PP
  406. XA \fIlist\fR is a sequence of one or more pipelines separated by \fB;\fR,
  407. X\fB&&\fR, or \fB\(bv\(bv\fR, and optionally terminated by \fB;\fR.  Of these
  408. Xthree symbols, \fB;\fR has a lower precedence than that of \fB&&\fR and
  409. X\fB\(bv\(bv\fR.  The symbols \fB&&\fR and \fB\(bv\(bv\fR also have equal
  410. Xprecedence.  A semicolon (\fB;\fR) causes sequential execution of the
  411. Xpreceding pipeline.  The symbol \fB&&\fR (\fB\(bv\(bv\fR) causes the
  412. X\fIlist\fR following it to be executed only if the preceding pipeline returns
  413. Xa zero (non-zero) exit status.  An arbitrary number of new-lines may appear in a
  414. X\fIlist\fR, instead of semicolons, to delimit commands.
  415. X.PP
  416. XA \fIcommand\fR is either a simple-command or one of the following.  Unless
  417. Xotherwise stated, the value returned by a command is that of the last
  418. Xsimple-command executed in the command.
  419. X.PP
  420. X.PD 0
  421. X.TP
  422. X\fBfor \fIname\fR \*(OK \fBin \fIword\fR ... \*(CK \fBdo \fIlist \fBdone\fR
  423. XEach time a \fBfor\fR command is executed, \fIname\fR is set to the next
  424. X\fIword\fR taken from the \fBin\fR \fIword\fR list.  If \fBin\fI word\fR ...
  425. Xis omitted, then the \fBfor\fR command executes the \fBdo\fR
  426. X\fIlist\fR once for each positional parameter that is set (see \fIParameter
  427. XSubstitution\fR below).  Execution ends when there are no more words in the
  428. Xlist.
  429. X.TP
  430. X\fBcase \fIword \fBin\fR \*(OK \fIpattern\fR \*(OK \(br \
  431. X\fIpattern\fR \*(CK ... \fB) \fIlist \fB;;\fR \*(CK ... \fBesac\fR
  432. XA \fBcase\fR command executes the \fIlist\fR associated with the first
  433. X\fIpattern\fR that matches \fIword\fR.  The form of the patterns is the same
  434. Xas that used for file-name generation (see \fIFile Name Generation\fR) except
  435. Xthat a slash, a leading dot, or a dot immediately following a slash need not
  436. Xbe matched explicitly, and the match is case sensitive. 
  437. X.TP
  438. X\fBif \fIlist \fBthen \fIlist\fR \*(OK \fBelif \fIlist \fBthen \fIlist\fR \*(CK ... \*(OK \fBelse \fIlist\fR \*(CK \fBf\&i\fR
  439. XThe \fIlist\fR following \fBif\fR is executed and, if it returns a zero exit
  440. Xstatus, the \fIlist\fR following the first \fBthen\fR is executed.  Otherwise,
  441. Xthe \fIlist\fR following \fBelif\fR is executed and, if its value is zero, the
  442. X\fIlist\fR following the next \fBthen\fR is executed.  Failing that, the
  443. X\fBelse \fIlist\fR is executed.  If no \fBelse \fIlist\fR or \fBthen \fIlist\fR
  444. Xis executed, then the \fBif\fR command returns a zero exit status.
  445. X.TP
  446. X\fBwhile \fIlist \fBdo \fIlist \fBdone\fR
  447. XA \fBwhile\fR command repeatedly executes the \fBwhile \fIlist\fR and, if
  448. Xthe exit status of the last command in the list is zero, executes the
  449. X\fBdo \fIlist\fR; otherwise the loop terminates.  If no commands in the
  450. X\fBdo \fIlist\fR are executed, then the \fBwhile\fR command returns a zero
  451. Xexit status; \fBuntil\fR may be used in place of \fBwhile\fR to negate the
  452. Xloop termination test.
  453. X.TP
  454. X\fB(\fIlist\fB)\fR
  455. X.br
  456. XExecute \fIlist\fR in a sub-shell.  The shell creates a new environment in
  457. Xwhich to execute the \fIlist\fR, but does not fork a sub-shell as a Unix
  458. Xsystem would.  The original environment is restored on completion.
  459. X.TP
  460. X\fB{\fIlist\fB;}\fR
  461. X.br
  462. X\fIlist\fR is simply executed.
  463. X.TP
  464. X\fIname \fB() {\fIlist\fB;}\fR
  465. XDefine a function which is referenced by \fIname\fR.  The body of the function
  466. Xis the \fIlist\fR of commands between \fB{\fR and \fB}\fR.  Execution of
  467. Xfunctions is described below (see \fIExecution\fR).
  468. X.PD
  469. X.PP
  470. XThe following words are only recognized as the first word of a command and
  471. Xwhen not quoted:
  472. X.if t .RS
  473. X.PP
  474. X.B
  475. X.if n if then else elif fi case esac for while until do done { }
  476. X.if t if  then  else  elif  f\&i  case  esac  for  while  until  do  done  {  }
  477. X.if t .RE
  478. X.SS Comments
  479. XA word beginning with \fB#\fR causes that word and all the following
  480. Xcharacters up to a new-line to be ignored.
  481. X.SS Command Substitution
  482. XThe standard output from a command enclosed in a pair of grave accents
  483. X(\fB\(ga\(ga\fR) may be used as part or all of a word; trailing new-lines
  484. Xare removed.
  485. X.SS Parameter Substitution
  486. XThe character \fB$\fR is used to introduce substitutable \fIparameters\fR.
  487. XThere are two types of parameters, positional and keyword.  If \fIparameter\fR
  488. Xis a digit, it is a positional parameter.  Positional parameters may be
  489. Xassigned values by \fBset\fR.  Keyword parameters (also known as variables)
  490. Xmay be assigned values by writing:
  491. X.RS
  492. X.PP
  493. X\fIname \(eq value\fR \*(OK \fIname \(eq value\fR \*(CK ...
  494. X.RE
  495. X.PP
  496. XPattern-matching is not performed on \fIvalue\fR.  There cannot be a function
  497. Xand a variable with the same \fIname\fR.
  498. X.PP
  499. X.PD 0
  500. X.TP
  501. X\fB${\fIparameter\fB}\fR
  502. XThe value, if any, of the parameter is substituted.  The braces are required
  503. Xonly when \fIparameter\fR is followed by a letter, digit, or underscore that
  504. Xis not to be interpreted as part of its name.  If \fIparameter\fR is
  505. X\fB*\fR or \fB@\fR, all the positional parameters, starting with \fB$1\fR,
  506. Xare substituted (separated by spaces).  Parameter \fB$0\fR is set from argument
  507. Xzero when the shell is invoked.
  508. X.TP
  509. X\fB${\fIparameter\fB:-\fIword\fB}\fR
  510. XIf \fIparameter\fR is set and is non-null, substitute its value; otherwise
  511. Xsubstitute \fIword\fR.
  512. X.TP
  513. X\fB${\fIparameter\fB:\(eq\fIword\fB}\fR
  514. XIf \fIparameter\fR is not set or is null set it to \fIword\fR; the value of
  515. Xthe parameter is substituted.  Positional parameters may not be assigned to
  516. Xin this way.
  517. X.TP
  518. X\fB${\fIparameter\fB:?\fIword\fB}\fR
  519. XIf \fIparameter\fR is set and is non-null, substitute its value; otherwise,
  520. Xprint \fIword\fR and exit from the shell.  If \fIword\fR is omitted, the
  521. Xmessage \(ga\(gaparameter null or not set\(aa\(aa is printed.
  522. X.TP
  523. X\fB${\fIparameter\fB:+\fIword\fB}\fR
  524. XIf \fIparameter\fR is set and is non-null, substitute \fIword\fR; otherwise
  525. Xsubstitute nothing.
  526. X.PD
  527. X.PP
  528. XIn the above, \fIword\fR is not evaluated unless it is to be used as the
  529. Xsubstituted string, so that, in the following example, \fBpwd\fR is executed
  530. Xonly if \fBd\fR is not set or is null:
  531. X.RS
  532. X.PP
  533. Xecho ${d:-\(gapwd\(ga}
  534. X.RE
  535. X.PP
  536. XIf the colon (\fB:\fR) is omitted from the above expressions, the shell only
  537. Xchecks whether \fIparameter\fR is set or not (\fIIt is not clear what this
  538. Xmeans\fR).
  539. X.PP
  540. XThe following parameters are automatically set by the shell:
  541. X.RS
  542. X.PD 0
  543. X.TP
  544. X.B #
  545. XThe number of positional parameters in decimal.
  546. X.TP
  547. X.B \-
  548. XFlags supplied to the shell on invocation or by the \fBset\fR command.
  549. X.TP
  550. X.B ?
  551. XThe decimal value returned by the last synchronously executed command.
  552. X.TP
  553. X.B $
  554. XThe process number of this shell.
  555. X.TP
  556. X.B !
  557. XThe process number of the last background command invoked.
  558. X.TP
  559. X.B ~
  560. XThe shell reserves all variables beginning with a \fB~\fR for its own
  561. Xinternal use and these variables cannot be accessed by the user.
  562. X.PD
  563. X.RE
  564. X.PP
  565. XThe following parameters are used by the shell:
  566. X.RS
  567. X.PD 0
  568. X.TP
  569. X.B
  570. X.SM CDPATH
  571. XThe search path for the \fIcd\fR command.  (Note that becuase a colon is used
  572. Xby MSDOS to indicate a drive, a semi-colon is used to separate the path names
  573. Xinstead of a colon - this implies that the CDPATH variable must be set using
  574. Xsingle or double quotes to surround the value).
  575. X.TP
  576. X.B
  577. X.SM EXTENDED_LINE
  578. XThis parameter defines a file containing a list of command which can accept
  579. Xan Extended Command Line using the indirect command file character \fB@\fR.
  580. XWhen a command which can process the Extended Command Line finds a parameter
  581. Xstarting with a \fB@\fR in the command list, treats the rest of the parameter
  582. Xas a file and reads the parameters from that file.  Examples of this
  583. Xfunctionality include the Standard \fBLinker\fR and \fBLibrarian\fR.  The
  584. Xfilename defined by \fBEXTENDED_LINE\fR contains a list of command (including
  585. Xthe .exe or .com extension) separated by a newlines.   If the command is in
  586. Xupper case, the file name on the command line is set up with backslashes as
  587. Xthe directory separator.  Otherwise, slashes (Unix style) are used.  This
  588. Xfunctionality allows the user to get round the 127 byte command line length
  589. Xlimit of MSDOS.
  590. X.TP
  591. X.B
  592. X.SM HISTFILE
  593. XThe file where command history is saved across login sessions.  The default
  594. Xvalue is \fB\s-1$HOME\s+1/history.sh\fR.
  595. X.TP
  596. X.B
  597. X.SM HOME
  598. XThe default argument (home directory) for the \fIcd\fR command.
  599. X.TP
  600. X.B
  601. X.SM IFS
  602. XInternal field separators, normally \fBspace\fR, \fBtab\fR, and \fBnew-line\fR.
  603. X.TP
  604. X.B
  605. X.SM MAIL
  606. XIf this parameter is set to the name of a mail file \fIand\fR the
  607. X\fB\s-1MAILPATH\s+1\fR parameter is not set, the shell informs the user of
  608. Xthe arrival of mail in the specified file.
  609. X.TP
  610. X.B
  611. X.SM MAILCHECK
  612. XThis parameter specifies how often (in seconds) the shell will check for the
  613. Xarrival of mail in the files specified by the \fB\s-1MAILPATH\s+1\fR or
  614. X\fB\s-1MAIL\s+1\fR parameters.  If set to 0, the shell will check before each
  615. Xprompt.
  616. X.TP
  617. X.B
  618. X.SM MAILPATH
  619. XA colon (\fB:\fR) separated list of file names.  If this parameter is set,
  620. Xthe shell informs the user of the arrival of mail in any of the specified
  621. Xfiles. Each file name can be followed by \fB%\fR and a message that will be
  622. Xprinted when the modification time changes.  The default message is
  623. X\fI"you have mail"\fR.
  624. X.TP
  625. X.B
  626. X.SM PATH
  627. XThe search path for commands (see \fIExecution\fR below).  The user may not
  628. Xchange \fB\s-1PATH\s+1\fR if executing under \fIrsh\fR.  (Note that because a
  629. Xcolon is used by MSDOS to indicate a drive, a semi-colon is used to separate
  630. Xthe path names instead of a colon - this implies that the PATH variable must
  631. Xbe set using single or double quotes to surround the value).
  632. X.TP
  633. X.B
  634. X.SM PS1
  635. XPrimary prompt string, by default \(ga\(ga\fB$ \fR\(aa\(aa.  
  636. X.TP
  637. X.B
  638. X.SM PS2
  639. XSecondary prompt string, by default \(ga\(ga\fB> \fR\(aa\(aa. 
  640. X.TP
  641. X.B
  642. X.SM SHELL
  643. XWhen the shell is invoked, it scans the environment (see \fIEnvironment\fR
  644. Xbelow) for this name.  If it is found and there is an 'r' in the file name
  645. Xpart of its value, the shell becomes a restricted shell.
  646. X.TP
  647. X.B
  648. X.SM TMP
  649. XThe location of temporary files created by the shell.
  650. X.RE
  651. X.PP
  652. XThe shell gives default values to \fB\s-1PATH\s+1\fR, \fB\s-1PS1\s+1\fR,
  653. X\fB\s-1PS2\s+1\fR, \fB\s-1SHELL\s+1\fR, \fB\s-1HOME\s+1\fR and
  654. X\fB\s-1IFS\s+1\fR.
  655. X.SS Blank Interpretation
  656. XAfter parameter and command substitution, the results of substitution are
  657. Xscanned for internal field separator characters (those found in
  658. X\fB\s-1IFS\s+1\fR) and split into distinct arguments where such characters
  659. Xare found.  Explicit null arguments (\fB""\fR or \fB\(aa\(aa\fR) are retained.
  660. XImplicit null arguments (those resulting from \fIparameters\fR that have no
  661. Xvalues) are removed.
  662. X.SS File Name Generation
  663. XFollowing substitution, each command \fIword\fR is scanned for the characters
  664. X\fB*\fR, \fB?\fR and \fB\*(OK\fR.  If one of these characters appears the word
  665. Xis regarded as a \fIpattern\fR.  The word is replaced with alphabetically
  666. Xsorted file names that match the pattern.  If no file name is found that
  667. Xmatches the pattern, the word is left unchanged.  The character \fB.\fR at the
  668. Xstart of a file name or immediately following a \fB/\fR, as well as the
  669. Xcharacter \fB/\fR itself, must be matched explicitly.  When matching
  670. Xpatterns for file names, the shell ignores the case of the pattern and the
  671. Xfile directory entries.  Generated file names are always in lower case.
  672. X.PP
  673. X.PD 0
  674. X.RS
  675. X.TP
  676. X\fB*\fR
  677. XMatches any string, including the null string.
  678. X.TP
  679. X\fB?\fR
  680. XMatches any single character.
  681. X.TP
  682. X\fB\*(OK ... \*(CK\fR
  683. XMatches any one of the enclosed characters.  A pair of characters separated by
  684. X\fB-\fR matches any character lexically between the pair, inclusive.  If the
  685. Xfirst character following the opening \(ga\(ga\*(OK\(aa\(aa is a
  686. X\fB\(ga\(ga!\(aa\(aa\fR any character not enclosed is matched.
  687. X.PD
  688. X.RE
  689. X.SS Quoting
  690. XThe following characters have a special meaning to the shell and cause
  691. Xtermination of a word unless quoted:
  692. X.RS
  693. X.PP
  694. X\fB;  &  (  )  \(br  ^  <  >  new-line  space  tab\fR
  695. X.RE
  696. X.PP
  697. XA character may be \fIquoted\fR (i.e., made to stand for itself) by preceding
  698. Xit with a \fB\e\fR.  The pair \fB\enew-line\fR is ignored.  All characters
  699. Xenclosed between a pair of single quote marks (\fB\(aa\(aa\fR), except a
  700. Xsingle quote, are quoted.  Inside double quote marks (\fB""\fR), parameter
  701. Xand command substitution occurs and \fB\e\fR quotes the characters \fB\e\fR,
  702. X\fB\(ga\fR, \fB"\fR, and \fB$\fR. \fB"$*"\fR is equivalent to \fB"$1 $2 ..."\fR,
  703. Xwhereas \fB"$@"\fR is equivalent to \fB"$1" "$2" ...\fR.
  704. X.SS Prompting
  705. XWhen used interactively, the shell prompts with the value of \fBPS1\fR
  706. Xbefore reading a command.  If at any time a new-line is typed and further
  707. Xinput is needed to complete a command, the secondary prompt (i.e., the value
  708. Xof \fB\s-1PS2\s+1\fR) is issued.
  709. X.PP
  710. XMany people like to have the shell provide them with useful information in
  711. Xtheir prompt.  To accommodate this, the shell recognises special sequences of
  712. Xcharacters in the values of \fBPS1\fR and \fBPS2\fR, and substitutes the
  713. Xappropriate information for them.  The special sequences and what they signify
  714. Xare:
  715. X.RS
  716. X.TP
  717. X\fB%d\fR
  718. XPlace the current date, in the form \s-1DAY DD-MM-YY\s+1 into the prompt.
  719. X.TP
  720. X\fB%e\fR
  721. XPlace the current event number (as defined by the \fBhistory\fR command) into
  722. Xthe prompt.  If history evaluation has been turned off (via \fBhistory -d\fR),
  723. Xno number will be substituted in (i.e. the \fB%e\fR will be removed).
  724. X.TP
  725. X\fB%n\fR
  726. XPlace the current working drive into the prompt.
  727. X.TP
  728. X\fB%p\fR
  729. XPlace the current working directory into the prompt.
  730. X.TP
  731. X\fB%t\fR
  732. XPlace the current time of day, in the form \s-1HH:MM\s+1 into the prompt.
  733. XThe time is on a 24 hour clock, i.e. 1:30 in the afternoon will be 13:30.
  734. X.TP
  735. X\fB%v\fR
  736. XPlace the MSDOS version number, in the form \s-1 MSDOS MM:MM\s+1 into the
  737. Xprompt.
  738. X.TP
  739. X\fB%%\fR
  740. XPlace the character \fI%\fR into the prompt.
  741. X.TP
  742. X\fB\exxx\fR
  743. XPlace the character \fI\exxx\fR into the prompt.  The processing of escape
  744. Xsequences is the same as that for \fBecho\fR.
  745. X.RE
  746. X.PP
  747. XSome of these facilities are of more use than others.
  748. X.SS Input/Output
  749. XBefore a command is executed, its input and output may be redirected using a
  750. Xspecial notation interpreted by the shell.  The following may appear anywhere
  751. Xin a simple-command or may precede or follow a \fIcommand\fR and are \fInot\fR
  752. Xpassed on to the invoked command; substitution occurs before \fIword\fR or
  753. X\fIdigit\fR is used:
  754. X.PP
  755. X.PD 0
  756. X.TP 14
  757. X\fB<word\fR
  758. XUse file \fIword\fR as standard input (file descriptor 0).
  759. X.TP
  760. X\fB>word\fR
  761. XUse file \fIword\fR as standard output (file descriptor 1).  If the file does
  762. Xnot exist it is created; otherwise, it is truncated to zero length.
  763. X.TP
  764. X\fB>\h@-.3m@>word\fR
  765. XUse file \fIword\fR as standard output.  If the file exists output is appended
  766. Xto it (by first seeking to the end-of-file); otherwise, the file is created.
  767. X.TP
  768. X\fB<\h@-.3m@<\fR\*(OK\fB-\fR\*(CK\fBword\fR
  769. XThe shell input is read up to a line that is the same as \fIword\fR, or to an
  770. Xend-of-file.  The resulting document becomes the standard input.  If any
  771. Xcharacter of \fIword\fR is quoted, no interpretation is placed upon the
  772. Xcharacters of the document; otherwise, parameter and command substitution
  773. Xoccurs, (unescaped) \fB\enew-line\fR is ignored, and \fB\e\fR must be used to
  774. Xquote the characters \fB\e\fR, \fB$\fR, \fB\(ga\fR, and the first character of
  775. X\fIword\fR.  If \fB-\fR is appended to \fB<\h@-.3m@<\fR, all leading tabs are
  776. Xstripped from \fIword\fR and from the document.
  777. X.TP
  778. X\fB<\h@-.1m@&digit\fR
  779. XUse the file associated with file descriptor \fIdigit\fR as standard input.
  780. XSimilarly for the standard output using \fB>\h@-.1m@&digit\fR.
  781. X.TP
  782. X\fB<\h@-.1m@&\h@-.1m@\-\fR
  783. XThe standard input is closed.  Similarly for the standard output using
  784. X\fB>\h@-.1m@&\h@-.1m@\-\fR.
  785. X.PD
  786. X.PP
  787. XIf any of the above is preceded by a digit, the file descriptor which will be
  788. Xassociated with the file is that specified by the digit (instead of the
  789. Xdefault 0 or 1).  For example:
  790. X.RS
  791. X.PP
  792. X\&... 2>&1
  793. X.RE
  794. X.PP
  795. Xassociates file descriptor 2 with the file currently associated with file
  796. Xdescriptor 1.
  797. X.PP
  798. XThe order in which redirections are specified is significant.  The shell
  799. Xevaluates redirections left-to-right.  For example:
  800. X.RS
  801. X.PP
  802. X\&... 1>\fIxxx\fR 2>&1
  803. X.RE
  804. X.PP
  805. Xfirst associates file descriptor 1 with file \fIxxx\fR.  It associates file
  806. Xdescriptor 2 with the file associated with file descriptor 1 (i.e. \fIxxx\fR).
  807. XIf the order of redirections were reversed, file descriptor 2 would be
  808. Xassociated with the terminal (assuming file descriptor 1 had been) and file
  809. Xdescriptor 1 would be associated with file \fIxxx\fR .
  810. X.PP
  811. XThe environment for the execution of a command contains the file descriptors
  812. Xof the invoking shell as modified by input/output specifications.
  813. X.PP
  814. XRedirection of output is not allowed in the restricted shell.
  815. X.SS Environment
  816. XThe \fIenvironment\fR (see \fIenviron\fR(5)) is a list of name-value pairs
  817. Xthat is passed to an executed program in the same way as a normal argument
  818. Xlist.  The shell interacts with the environment in several ways.  On invocation,
  819. Xthe shell scans the environment and creates a parameter for each name found,
  820. Xgiving it the corresponding value.  If the user modifies the value of any of
  821. Xthese parameters or creates new parameters, none of these affects the
  822. Xenvironment unless the \fBexport\fR command is used to bind the shell's
  823. Xparameter to the environment (see also \fBset -a\fR).  A parameter may be
  824. Xremoved from the environment with the \fBunset\fR command.  The environment
  825. Xseen by any executed command is thus composed of any unmodified name-value
  826. Xpairs originally inherited by the shell, minus any pairs removed by \fBunset\fR,
  827. Xplus any modifications or additions, all of which must be noted in \fBexport\fR
  828. Xcommands.
  829. X.PP
  830. XThe environment for any \fIsimple-command\fR may be augmented by prefixing it
  831. Xwith one or more assignments to parameters.  Thus:
  832. X.RS
  833. X.PP
  834. X\s-1TERM\s+1\(eq450 cmd args            and
  835. X.br
  836. X(export \s-1TERM\s+1; \s-1TERM\s+1\(eq450; cmd args)
  837. X.RE
  838. X.PP
  839. Xare equivalent (as far as the execution of \fIcmd\fR is concerned).
  840. X.PP
  841. XIf the \fB-k\fR flag is set, \fIall\fR keyword arguments are placed in the
  842. Xenvironment, even if they occur after the command name.  The following first
  843. Xprints \fBa\(eqb c\fR and \fBc\fR:
  844. X.PP
  845. X.RS
  846. X.nf
  847. Xecho a\(eqb c
  848. Xset -k
  849. Xecho a\(eqb c
  850. X.fi
  851. X.RE
  852. X.SS Signals
  853. XThe \s-1INTERRUPT\s+1 and \s-1QUIT\s+1 signals for an invoked command are
  854. Xignored if the command is followed by \fB&\fR; otherwise signals have the
  855. Xvalues inherited by the shell from its parent, with the exception of signal 11
  856. X(but see also the \fBtrap\fR command below).
  857. X.SS History
  858. XWhen reading input from an interactive terminal, a \(ga\(ga!\(aa\(aa at the
  859. Xstart of a line signals to the shell that it should attempt to perform a history
  860. Xsubsitution.  A history subsitution is a short-hand method which allows the
  861. Xuser to recall a previous command for execution or editing.  The recalled
  862. Xcommand is placed in the command line for editing or passing to the rest of
  863. Xthe shell for normal processing.  A history substitution takes the form:
  864. X.RS
  865. X.PP
  866. X\fB!\fR \*(OK \fIstr\fR \(br \fInum\fR \*(CK \fIterminator\fR
  867. X.RE
  868. X.PP
  869. X\fB!\fInum\fR will place the history command with the specified number
  870. Xin the command line.  \fB!\fIstr\fR will find the most recent command
  871. Xline that started with the characters in \fIstr\fR.
  872. X.PP
  873. XThe \fIterminator\fR determines what action is performed after the history
  874. Xline has been found.  If the original history command is entered using the
  875. X\fB<return>\fR key, the new command line is passed directly to the shell.
  876. XIf the \fB<end>\fR key is pressed, the new command line can be edited in the
  877. Xmanner described below.
  878. X.SS Command Line Editing
  879. XWhen reading input from an interactive terminal, certain keystrokes allow
  880. Xthe current input line to be edited.  The following keystrokes are
  881. Xavailable:
  882. X.TP
  883. X.SM "Cursor Right"
  884. XMove the cursor right one character
  885. X.TP
  886. X.SM "Control-Cursor Right"
  887. XMove the cursor right one word
  888. X.TP
  889. X.SM "Cursor Left"
  890. XMove the cursor left one character
  891. X.TP
  892. X.SM "Control-Cursor Left"
  893. XMove the cursor left one word
  894. X.TP
  895. X.SM "Cursor Up"
  896. XGet the previous command from the history file
  897. X.TP
  898. X.SM "Cursor Down"
  899. XGet the next command from the history file
  900. X.TP
  901. X.SM "Insert"
  902. XToggle insert/overwrite mode
  903. X.TP
  904. X.SM "Delete"
  905. XDelete the current character
  906. X.TP
  907. X.SM "Home"
  908. XMove the cursor to the start of the command
  909. X.TP
  910. X.SM "End"
  911. XMove the cursor to the end of the command, unless the first character of
  912. Xthe command is a \fB!\fR, in which case the appropriate history search is
  913. Xdone.
  914. X.TP
  915. X.SM "Control-End"
  916. XDelete to the end of the line
  917. X.TP
  918. X.SM "Page-Up"
  919. XSearch backwards from the current history command for the next match against
  920. Xthe last history request.  This command can only be used after \fBEnd\fR has
  921. Xbeen used to select a history line.
  922. X.TP
  923. X.SM "Page-Down"
  924. XSearch forewards from the current history command for the next match against
  925. Xthe last history request.  This command can only be used after \fBEnd\fR has
  926. Xbeen used to select a history line.
  927. X.TP
  928. X.SM "Backspace"
  929. XMove the cursor back one character, erasing the current character.
  930. X.TP
  931. X.SM "Return"
  932. XExecute the command line, unless the first character of the command is a
  933. X\fB!\fR, in which case the appropriate history processing is done.
  934. X.PD
  935. X.RE
  936. X.SS Execution
  937. XEach time a command is executed, the above substitutions are carried out.  If
  938. Xthe command name matches one of the \fISpecial Commands\fR listed below, it
  939. Xis executed in the shell process.  If the command name does not match a
  940. X\fISpecial Command\fR, but matches the name of a defined function, the
  941. Xfunction is executed in the shell process (note how this differs from the
  942. Xexecution of shell procedures).  The positional parameters \fB$1\fR,
  943. X\fB$2\fR, ....  are set to the arguments of the function.  If the command
  944. Xname matches neither a \fISpecial Command\fR nor the name of a defined function,
  945. Xa new process is created and an attempt is made to execute the command via
  946. X\fIexec\fR(2).
  947. X.PP
  948. XThe shell parameter \fBPATH\fR defines the search path for the directory
  949. Xcontaining the command.  Alternative directory names are separated by a
  950. Xsemi-colon (\fB;\fR).  The default path is \fB;c:/bin;c:/usr/bin\fR (specifying
  951. Xthe current directory, \fBc:/bin\fR, and \fBc:/usr/bin\fR, in that order).
  952. XNote that the current directory is specified by a null path name, which can
  953. Xappear immediately after the equal sign or between the semi-colon delimiters
  954. Xanywhere else in the path list.  If the command name contains a \fB/\fR or
  955. Xstarts with \fBx:\fR (where x is a drive letter) the search path is not used;
  956. Xsuch commands will not be executed by the restricted shell.  Otherwise, each
  957. Xdirectory in the path is searched for an executable file.
  958. X.PP
  959. XIf the file does not have a .com or .exe extension, it is opened and the first
  960. X5 characters are read.  If the first 5 characters are the string
  961. X\fB#!sh\\n\fR it is assumed to be a file containing shell commands.  Note
  962. Xthat the shell will check the file and if that file does not exist or is not a
  963. Xscript, it will try the file with an extension of \fB.sh\fR.  If a \fB.sh\fR
  964. Xfile is found, that will be processed.  A sub-shell is spawned to read it.
  965. XA parenthesized command is also executed in a sub-shell.
  966. X.SS Special Commands
  967. XInput/output redirection is permitted for these commands.  File descriptor 1
  968. Xis the default output location.
  969. X.PP
  970. X.PD 0
  971. X.TP
  972. X\fB:\fR
  973. XNo effect; the command does nothing.  A zero exit code is returned.
  974. X.TP
  975. X\fIletter\fB:\fR
  976. XSelect the drive specified by \fIletter\fR.
  977. X.TP
  978. X\fB\&. \fIfile\fR
  979. XRead and execute commands from \fIfile\fR and return.  The search path
  980. Xspecified by \fBPATH\fR is used to find the directory containing \fIfile\fR.
  981. X.TP
  982. X\fBbreak\fR \*(OK \fIn\fR \*(CK
  983. XExit from the enclosing \fBfor\fR or \fBwhile\fR loop, if any.  If \fIn\fR is
  984. Xspecified, break \fIn\fR levels.
  985. X.TP
  986. X\fBcontinue\fR \*(OK \fIn\fR \*(CK
  987. XResume the next iteration of the enclosing \fBfor\fR or \fBwhile\fR loop.  If
  988. X\fIn\fR is specified, resume at the \fIn\fR-th enclosing loop.
  989. X.TP
  990. X\fBcd\fR \*(OK \fIarg\fR \*(CK
  991. XChange the current directory to \fIarg\fR.  The shell parameter \fBHOME\fR is
  992. Xthe default \fIarg\fR.  The shell parameter \fBCDPATH\fR defines the search
  993. Xpath for the directory containing \fIarg\fR.  Alternative directory names are
  994. Xseparated by a semi-colon (\fB;\fR).  The default path is \fB<null>\fR
  995. X(specifying the current directory).  Note that the current directory is
  996. Xspecified by a null path name, which can appear immediately after the equal
  997. Xsign or between the semi-colon delimiters anywhere else in the path list.
  998. XIf \fIarg\fR begins with a \fB/\fR or \fBx:\fR (where x is a drive letter),
  999. Xthe search path is not used.  Otherwise, each directory in the path is searched
  1000. Xfor \fIarg\fR.  The \fIcd\fR command may not be executed by \fIrsh\fR.
  1001. X.TP
  1002. X\fBecho\fR \*(OK \fIarg\fR ... \*(CK
  1003. XEcho arguments. \fBEcho\fR writes its arguments separated by blanks and
  1004. Xterminated by a new-line on the standard output.  It also understands C-like
  1005. Xescape conventions; beware of conflicts with the shell's use of \fB\e\fR:
  1006. X.PP
  1007. X.RS
  1008. X.PD 0
  1009. X.TP
  1010. X\fB\eb\fR
  1011. Xbackspace
  1012. X.TP
  1013. X\fB\ec\fR
  1014. Xprint line without new-line
  1015. X.TP
  1016. X\fB\ef\fR
  1017. Xform-feed
  1018. X.TP
  1019. X\fB\en\fR
  1020. Xnew-line
  1021. X.TP
  1022. X\fB\er\fR
  1023. Xcarriage return
  1024. X.TP
  1025. X\fB\et\fR
  1026. Xtab
  1027. X.TP
  1028. X\fB\ev\fR
  1029. Xvertical tab
  1030. X.TP
  1031. X\fB\e\e\fR
  1032. Xbackslash
  1033. X.TP
  1034. X\fB\e\fIn\fR
  1035. Xthe 8-bit character whose \s-1ASCII\s0 code is the 1-, 2- or 3-digit octal
  1036. Xnumber \fIn\fR, which must start with a zero.
  1037. X.PD
  1038. X.PP
  1039. X\fIEcho\fR is useful for producing diagnostics in command files and for
  1040. Xsending known data into a pipe.
  1041. X.RE
  1042. X.TP
  1043. X\fBeval\fR \*(OK \fIarg\fR ... \*(CK
  1044. XThe arguments are read as input to the shell and the resulting command(s)
  1045. Xexecuted.
  1046. X.TP
  1047. X\fBexec\fR \*(OK \fIarg\fR ... \*(CK
  1048. XThe command specified by the arguments is executed in place of this shell
  1049. Xwithout creating a new process.  Input/output arguments may appear and, if no
  1050. Xother arguments are given, cause the shell input/output to be modified.
  1051. X.TP
  1052. X\fBexit\fR \*(OK \fIn\fR \*(CK
  1053. XCauses a shell to exit with the exit status specified by \fIn\fR.
  1054. XIf \fIn\fR is omitted the exit status is that of the last command executed
  1055. X(an end-of-file will also cause the shell to exit.)
  1056. X.TP
  1057. X\fBexport\fR \*(OK \fIname\fR ... \*(CK
  1058. XThe given \fIname\fRs are marked for automatic export to the \fIenvironment\fR
  1059. Xof subsequently-executed commands.  If no arguments are given, a list of all
  1060. Xnames that are exported in this shell is printed.  Function names may \fInot\fR
  1061. Xbe exported.
  1062. X.TP
  1063. X\fBgetopt\fR \fIoptstring name\fR \*(OK \fIargs\fR ... \*(CK
  1064. XParse command options and write them to standard output.  \fBGetopt\fR is used
  1065. Xto break up options in command lines for easy parsing by shell procedures and
  1066. Xto check for legal options.  \fIOptstring\fR is a string of recognized option
  1067. Xletters (see \fIgetopt\fR(3C)); if a letter is followed by a colon, the option
  1068. Xis expected to have an argument which may or may not be separated from it by
  1069. Xwhite space.  The special option \fB\-\-\fP is used to delimit the end of the
  1070. Xoptions.  If it is used explicitly, \fBgetopt\fR will recognize it; otherwise,
  1071. X\fBgetopt\fR will generate it; in either case, \fBgetopt\fR will place it at
  1072. Xthe end of the options.  Each option is preceded by a \fB-\fR and is in its
  1073. Xown positional parameter; each option argument is also parsed into its own
  1074. Xpositional parameter.
  1075. X.sp
  1076. XThe following code fragment shows how one might process the arguments for a
  1077. Xcommand that can take the options \fBa\fR or \fBb\fR, as well as the option
  1078. X\fBo\fR, which requires an argument:
  1079. X.sp
  1080. X.RS
  1081. X.nf
  1082. X.ss 18
  1083. X.ta +.5i +1i
  1084. Xset -- \(gagetopt abo: $*\(ga
  1085. Xif [ $? !\(eq 0 ]
  1086. Xthen
  1087. X    echo $\s-1USAGE\s+1
  1088. X    exit 2
  1089. Xfi
  1090. Xfor i in $\(**
  1091. Xdo
  1092. X    case $i in
  1093. X    \-a \(bv \-b)    \s-1FLAG\s+1\(eq$i; shift;;
  1094. X    \-o)    \s-1OARG\s+1\(eq$2; shift 2;;
  1095. X    \-\-)    shift; break;;
  1096. X    esac
  1097. Xdone
  1098. X.fi
  1099. X.ta
  1100. X.ss 12
  1101. X.sp
  1102. XThis code will accept any of the following as equivalent:
  1103. X.sp
  1104. X.nf
  1105. X.ss 18
  1106. Xcmd \-aoarg file file
  1107. Xcmd \-a \-o arg file file
  1108. Xcmd \-oarg \-a file file
  1109. Xcmd \-a \-oarg \-\- file file
  1110. X.fi
  1111. X.ss 12
  1112. X.RE
  1113. X.TP
  1114. X\fBhistory\fR \*(OK \fB-dei\fR \*(CK
  1115. XThe \fBhistory\fR command, with no arguments, will print all the commands that
  1116. Xare currently saved in the shell's history buffers.  As new commands are
  1117. Xexecuted, and space in the buffers runs out, old commands will be deleted.  The
  1118. X\fBhistory\fR commands prints out the stored commands with sequence numbers.
  1119. XNegative numbered commands, through command number zero, are commands that were
  1120. Xretrieved from the saved history file.  Commands starting at one were entered
  1121. Xduring the current login session.  If a saved command contains embedded
  1122. Xnewlines, these will be printed out as the sequence \fB\en\fR, so that
  1123. Xindividual command stay on one line.
  1124. X.sp
  1125. XThe arguments changes the way the shell processes history information as
  1126. Xfollows:
  1127. X.RS
  1128. X.TP
  1129. X\fB-d\fR
  1130. XDisable the saving of commands in the history file.
  1131. X.TP
  1132. X\fB-e\fR
  1133. XEnable the saving of commands in the history file.
  1134. X.TP
  1135. X\fB-i\fR
  1136. XInitialise the history file.
  1137. X.RE
  1138. X.TP
  1139. X\fBmsdos\fR \*(OK \fIname\fR ... \*(CK
  1140. XThe given \fIname\fRs are marked \fImsdos\fR format and if the \fB-m\fR flag
  1141. Xis set, the values of the these \fIname\fRs are exported to child processes
  1142. Xwith the any slashes in the value replaced by backslashes.
  1143. X.TP
  1144. X\fBpwd\fR
  1145. XPrint the current working directory.  
  1146. X.TP
  1147. X\fBread\fR \*(OK \fIname\fR ... \*(CK
  1148. XOne line is read from the standard input and the first word is assigned to the
  1149. Xfirst \fIname\fR, the second word to the second \fIname\fR, etc., with leftover
  1150. Xwords assigned to the last \fIname\fR.  The return code is 0 unless an
  1151. Xend-of-file is encountered.
  1152. X.TP
  1153. X\fBreadonly\fR \*(OK \fIname\fR ... \*(CK
  1154. XThe given \fIname\fRs are marked \fIreadonly\fR and the values of the these
  1155. X\fIname\fRs may not be changed by subsequent assignment.  If no arguments are
  1156. Xgiven, a list of all \fIreadonly\fR names is printed.
  1157. X.TP
  1158. X\fBreturn\fR \*(OK \fIn\fR \*(CK
  1159. XCauses a function to exit with the return value specified by \fIn\fR.  If
  1160. X\fIn\fR is omitted, the return status is that of the last command executed.
  1161. X.TP
  1162. X\fBset\fR \*(OK \fB--aefkmntuvx\fR \*(OK \fIarg\fR ... \*(CK \*(CK
  1163. X.RS
  1164. X.TP
  1165. X\fB-a\fR
  1166. XMark variables which are modified or created for export.
  1167. X.TP
  1168. X\fB-e\fR
  1169. XExit immediately if a command exits with a non-zero exit status.
  1170. X.TP
  1171. X\fB-f\fR
  1172. XDisable file name generation
  1173. X.TP
  1174. X\fB-k\fR
  1175. XAll keyword arguments are placed in the environment for a command, not just
  1176. Xthose that precede the command name.
  1177. X.TP
  1178. X\fB-m\fR
  1179. XFor those variables marked as \fBmsdos\fR variables, the values are
  1180. Xexported to child processes with the slashes replaced by backslashes.  Most
  1181. XMSDOS utilities do not care if a file name contains a slash or backslash as
  1182. Xa directory separator.  However, some like the \fIlinker\fR require
  1183. Xbackslashes in the value of the \fBLIB\fR variable.
  1184. X.TP
  1185. X\fB-n\fR
  1186. XRead commands but do not execute them.
  1187. X.TP
  1188. X\fB-t\fR
  1189. XExit after reading and executing one command.
  1190. X.TP
  1191. X\fB-u\fR
  1192. XTreat unset variables as an error when substituting.
  1193. X.TP
  1194. X\fB-v\fR
  1195. XPrint shell input lines as they are read.
  1196. X.TP
  1197. X\fB-x\fR
  1198. XPrint commands and their arguments as they are executed.
  1199. X.TP
  1200. X\fB--\fR
  1201. XDo not change any of the flags; useful in setting \fB$1\fR to \fB\-\fR.
  1202. X.PP
  1203. XUsing \fB+\fR rather than \fB-\fR causes these flags to be turned off.  These
  1204. Xflags can also be used upon invocation of the shell.  The current set of flags
  1205. Xmay be found in \fB$-\fR.  The remaining arguments are positional parameters
  1206. Xand are assigned, in order, to \fB$1\fR, \fB$2\fR, ....  If no arguments
  1207. Xare given the values of all names are printed.
  1208. X.RE
  1209. X.TP
  1210. X\fBshift\fR \*(OK \fIn\fR \*(CK
  1211. X.br
  1212. XThe positional parameters from \fB$n+1\fR ...  are renamed \fB$1\fR ....  If
  1213. X\fIn\fR is not given, it is assumed to be 1.
  1214. X.TP
  1215. X\fBswap\fR \*(OK \fIoptions\fR \*(CK
  1216. XThis command defines how the shell will handle swapping.  The options are
  1217. X.RS
  1218. X.TP
  1219. X\fBoff\fR
  1220. XDisable swapping.  The shell remains in memory whilst the child is running
  1221. Xand reduces the available memory by about 200K (depending on the size of
  1222. Xthe environment and history).
  1223. X.TP
  1224. X\fBon\fR
  1225. XEnable all devices.  The shell will swap out to either expanded or extended
  1226. Xmemory or to disk, execute the command and then swap back in.  Whilest
  1227. Xswapped, the shell reduces the available memory by about 3K.
  1228. X.TP
  1229. X\fBexpand\fR
  1230. XEnable swapping to Expanded Memory.  The EMS drive must exist on your
  1231. Xsystem for this to work.
  1232. X.TP
  1233. X\fBextent\fR \*(OK \fIstart address\fR \*(CK
  1234. XEnable swapping to Extended Memory.  The optional start address defines the
  1235. Xbased address in the Extended Memory at which point the shell writes its
  1236. Xswap area.  The default location is \fI0x100000\fR.
  1237. X.TP
  1238. X\fBdisk\fR
  1239. XEnable swapping to disk.  The shell creates a temporary file and saves
  1240. Xitself in it.  On completion, the file is deleted.  This is the slowest method
  1241. Xof swapping.
  1242. X.PD
  1243. X.PP
  1244. XWith no options, the current swapping options are displayed.
  1245. X.RE
  1246. X.TP
  1247. X\fBtest \fIexpr\fR or \fB\*(OK \fIexpr\fB \*(CK\fR
  1248. XEvaluate conditional expressions.  \fBTest\fR evaluates the expression
  1249. X\fIexpr\fR and, if its value is true, returns a zero (true) exit status;
  1250. Xotherwise, a non-zero (false) exit status is returned; \fBtest\fR also returns
  1251. Xa non-zero exit status if there are no arguments.  The following primitives
  1252. Xare used to construct \fBexpr\fR:
  1253. X.RS
  1254. X.TP 12
  1255. X\fB-r \fIfile\fR
  1256. Xtrue if \fIfile\fR exists and is readable.
  1257. X.TP
  1258. X\fB-w \fIfile\fR
  1259. Xtrue if \fIfile\fR exists and is writable.
  1260. X.TP
  1261. X\fB-x \fIfile\fR
  1262. Xtrue if \fIfile\fR exists and is executable.
  1263. X.TP
  1264. X\fB-f \fIfile\fR
  1265. Xtrue if \fIfile\fR exists and is a regular file.
  1266. X.TP
  1267. X\fB-d \fIfile\fR
  1268. Xtrue if \fIfile\fR exists and is a directory.
  1269. X.TP
  1270. X\fB-c \fIfile\fR
  1271. Xtrue if \fIfile\fR exists and is a character special file.
  1272. X.TP
  1273. X\fB-b \fIfile\fR
  1274. Xtrue if \fIfile\fR exists and is a block special file.
  1275. X.TP
  1276. X\fB-s \fIfile\fR
  1277. Xtrue if \fIfile\fR exists and has a size greater than zero.
  1278. X.TP
  1279. X\fB-t\fR \*(OK \fIfildes\fR \*(CK
  1280. Xtrue if the open file whose file descriptor number is \fIfildes\fR (1 by
  1281. Xdefault) is associated with a terminal device.
  1282. X.TP
  1283. X\fB-n \fIs1\fR
  1284. Xtrue if the length of the string \fIs1\fR is zero.
  1285. X.TP
  1286. X\fB-n \fIs1\fR
  1287. Xtrue if the length of the string \fIs1\fR is non-zero.
  1288. X.TP
  1289. X\fIs1 \fB\(eq\fI s2\fR
  1290. Xtrue if strings \fIs1\fR and \fIs2\fR are identical.
  1291. X.TP
  1292. X\fIs1 \fB!\(eq\fI s2\fR
  1293. Xtrue if strings \fIs1\fR and \fIs2\fR are \fInot\fR identical.
  1294. X.TP
  1295. X\fIs1\fR
  1296. Xtrue if \fIs1\fR is \fInot\fR the null string.
  1297. X.TP
  1298. X\fIn1 \fB-eq \fIn2\fR
  1299. Xtrue if the integers \fIn1\fR and \fIn2\fR are algebraically equal.  Any of
  1300. Xthe comparisons \fB-ne\fR, \fB-gt\fR, \fB-ge\fR, \fB-lt\fR, and \fB-le\fR
  1301. Xmay be used in place of \fBR-eq\fR.
  1302. X.PP
  1303. XThese primaries may be combined with the following operators:
  1304. X.TP  12
  1305. X\fB!\fR
  1306. Xunary negation operator.
  1307. X.TP
  1308. X\fB-a\fR
  1309. Xbinary \fIand\fR operator.
  1310. X.TP
  1311. X\fB-o\fR
  1312. Xbinary \fIor\fR operator (\fB-a\fR has higher precedence than \fB-o\fR).
  1313. X.TP
  1314. X\fB(\fR expr \fB)\fR
  1315. Xparentheses for grouping.
  1316. X.PP
  1317. XNotice that all the operators and flags are separate arguments to \fBtest\fR.
  1318. XNotice also that parentheses are meaningful to the shell and, therefore,
  1319. Xmust be escaped.
  1320. X.RE
  1321. X.TP
  1322. X\fBtrap\fR \*(OK \fIarg\fR \*(CK \*(OK \fIn\fR \*(CK ...
  1323. XThe command \fIarg\fR is to be read and executed when the shell receives
  1324. Xsignal(s) \fIn\fR.  (Note that \fIarg\fR is scanned once when the trap is set
  1325. Xand once when the trap is taken.) Trap commands are executed in order of
  1326. Xsignal number.  Any attempt to set a trap on a signal that was ignored on
  1327. Xentry to the current shell is ineffective.  An attempt to trap on signal 11
  1328. X(memory fault) produces an error.  If \fIarg\fR is absent all trap(s) \fIn\fR
  1329. Xare reset to their original values.  If \fIarg\fR is the null string this
  1330. Xsignal is ignored by the shell and by the commands it invokes.  If \fIn\fR is
  1331. X0 the command \fIarg\fR is executed on exit from the shell.  The \fBtrap\fR
  1332. Xcommand with no arguments prints a list of commands associated with each
  1333. Xsignal number.
  1334. X.TP
  1335. X\fBtype\fR \*(OK \fIname\fR ... \*(CK
  1336. XFor each \fIname\fR, indicate how it would be interpreted if used as a command
  1337. Xname.
  1338. X.TP
  1339. X\fBumask\fR \*(OK \fInnn\fR \*(CK
  1340. XThe user file-creation mask is set to \fInnn\fR (see \fIumask\fR(2)).  If
  1341. X\fInnn\fR is omitted, the current value of the mask is printed.
  1342. X.TP
  1343. X\fBunset\fR \*(OK \fIname\fR ... \*(CK
  1344. XFor each \fIname\fR, remove the corresponding variable or function.  The
  1345. Xvariables \fB\s-1PATH\s+1\fR, \fB\s-1PS1\s+1\fR, \fB\s-1PS2\s+1\fR, and
  1346. X\fB\s-1IFS\s+1\fR cannot be unset.
  1347. X.TP
  1348. X\fBver\fR
  1349. XDisplay the current version of the shell.
  1350. X.PD
  1351. X.PP
  1352. X.SS Invocation
  1353. XIf the shell is invoked through \fIexec\fR(2) and the first character of
  1354. Xargument zero is \fB-\fR or the \fB-0\fR(zero) switch is in the invokation line,
  1355. Xcommands are initially read from \fB/etc/profile.sh\fR and from
  1356. X\fB\s-1$HOME\s+1/profile.sh\fR, if such files exist.  Thereafter, commands are
  1357. Xread as described below, which is also the case when the shell is invoked as
  1358. X\fB/bin/sh\fR.  The flags below are interpreted by the shell on invocation only;
  1359. XNote that unless the \fB-c\fR or \fB-s\fR flag is specified, the first argument
  1360. Xis assumed to be the name of a file containing commands, and the remaining
  1361. Xarguments are passed as positional parameters to that command file:
  1362. X.PP
  1363. X.PD 0
  1364. X.TP 10
  1365. X\fB-c\fR string
  1366. XIf the \fB-c\fR flag is present commands are read from \fIstring\fR.
  1367. X.TP
  1368. X\fB-s\fR
  1369. XIf the \fB-s\fR flag is present or if no arguments remain commands are read
  1370. Xfrom the standard input.  Any remaining arguments specify the positional
  1371. Xparameters.  Shell output (except for \fISpecial Commands\fR) is written to
  1372. Xfile descriptor 2.
  1373. X.TP
  1374. X\fB-i\fR
  1375. XIf the \fB-i\fR flag is present or if the shell input and output are attached
  1376. Xto a terminal, this shell is \fIinteractive\fR.  In this case, the
  1377. X\s-1TERMINATE\s+1 signal is ignored and the \s-1INTERRUPT\s+1 signal is caught
  1378. Xand ignored.  In all cases, the \s-1QUIT\s+1 signal is ignored by the shell.
  1379. X.TP
  1380. X\fB-r\fR
  1381. XIf the \fB-r\fR flag is present, the shell is a restricted shell.
  1382. X.TP
  1383. X\fB-0\fR(zero)
  1384. XIf the \fB-0\fR(zero) flag is present, this has the same effect as starting the
  1385. Xshell with the first character of argument zero as a \fB-\fR (see above).
  1386. X.PD
  1387. X.PP
  1388. XThe remaining flags and arguments are described under the \fBset\fR command
  1389. Xabove.
  1390. X.SS Rsh Only
  1391. X\fIRsh\fR is used to set up login names and execution environments whose
  1392. Xcapabilities are more controlled than those of the standard shell.  The
  1393. Xactions of \fIrsh\fR are identical to those of \fIsh\fR, except that the
  1394. Xfollowing are disallowed:
  1395. X.RS
  1396. X.PD 0
  1397. X.PP
  1398. Xchanging directory (see \fIcd\fR(1)),
  1399. X.br
  1400. Xsetting the value of \fB$PATH\fR
  1401. X.br
  1402. Xspecifying path or command names containing \fB/\fR,
  1403. X.br
  1404. Xredirecting output (\fB>\fR and \fB>>\fR).
  1405. X.PD
  1406. X.RE
  1407. X.PP
  1408. XThe restrictions above are enforced after \fBprofile.sh\fR is interpreted.
  1409. X.PP
  1410. XWhen a command to be executed is found to be a shell procedure, \fIrsh\fR
  1411. Xinvokes \fIsh\fR to execute it.  Thus, it is possible to provide to the
  1412. Xend-user shell procedures that have access to the full power of the standard
  1413. Xshell, while imposing a limited menu of commands; this scheme assumes that the
  1414. Xend-user does not have write and execute permissions in the same directory.
  1415. X.PP
  1416. XThe net effect of these rules is that the writer of the \fBprofile.sh\fR has
  1417. Xcomplete control over user actions, by performing guaranteed setup actions
  1418. Xand leaving the user in an appropriate directory (probably \fInot\fR the login
  1419. Xdirectory).
  1420. X.PP
  1421. XThe system administrator often sets up a directory of commands (i.e.,
  1422. X\fB/usr/rbin\fR) that can be safely invoked by \fIrsh\fR.  Some systems also
  1423. Xprovide a restricted editor \fIred\fR.
  1424. X.SH EXIT STATUS
  1425. XErrors detected by the shell, such as syntax errors, cause the shell to return
  1426. Xa non-zero exit status.  If the shell is being used non-interactively execution
  1427. Xof the shell file is abandoned.  Otherwise, the shell returns the exit status of
  1428. Xthe last command executed (see also the \fBexit\fR command above).
  1429. X.SH FILES
  1430. X/etc/profile.sh
  1431. X.br
  1432. X\s-1$HOME\s+1/profile.sh
  1433. X.br
  1434. X\s-1$TMP\s+1/sh\(**
  1435. X.SH LIMIITATIONS
  1436. XAny TSR (Terminate Stay Resident) programs must be loaded before loading
  1437. X\fISh\fR as the shell will overwrite the TSR when it reloads itself after
  1438. Xswapping out.
  1439. X.SH SEE ALSO
  1440. Xcd(1),
  1441. Xenv(1),
  1442. Xtest(1),
  1443. Xumask(1).
  1444. X.br
  1445. Xdup(2),
  1446. Xexec(2),
  1447. Xpipe(2),
  1448. Xsignal(2),
  1449. Xumask(2),
  1450. Xwait(2),
  1451. Xprofile(4),
  1452. Xenviron(5) in the
  1453. X\fI\s-1UNIX\s+1 System Programmer Reference Manual\fR.
  1454. SHAR_EOF
  1455. chmod 0644 sh.1 || echo "restore of sh.1 fails"
  1456. set `wc -c sh.1`;Sum=$1
  1457. if test "$Sum" != "42496"
  1458. then echo original size 42496, current size $Sum;fi
  1459. echo "x - extracting include/Changes (Text)"
  1460. sed 's/^X//' << 'SHAR_EOF' > include/Changes &&
  1461. XAdd to fcntl.h the following 2 lines
  1462. X
  1463. Xextern int _CDECL    open    (char *, int, ...);
  1464. Xextern int _CDECL    creat    (char *, int);
  1465. X
  1466. XAdd to limits.h the following 2 lines
  1467. X
  1468. X#define PATH_MAX    130        /* Maximum path length        */
  1469. X#define NAME_MAX    14        /* Maximum file name length    */
  1470. X
  1471. XAdd to stdio.h the following 2 lines
  1472. X
  1473. Xextern FILE * _CDECL    popen(char *, char *);
  1474. Xextern int _CDECL    pclose(FILE *);
  1475. X
  1476. XAdd to stdlib.h the following 8 lines
  1477. X
  1478. Xextern int _CDECL        optind;
  1479. Xextern int _CDECL        opterr;
  1480. Xextern int _CDECL        optind;
  1481. Xextern int _CDECL        optopt;
  1482. Xextern int _CDECL        optvar;
  1483. Xextern char * _CDECL        optarg;
  1484. Xextern int _CDECL        getopt    (int, char **, char *);
  1485. Xextern int _CDECL        pnmatch    (char *, char *, int);
  1486. X
  1487. XAdd to sys/stat.h the following 10 lines
  1488. X
  1489. X/* Tests for file types */
  1490. X
  1491. X#define    S_IFBLK        0060000        /* block special        */
  1492. X
  1493. X#define S_ISDIR(m)    ((((m) & S_IFMT) == S_IFDIR))
  1494. X#define S_ISCHR(m)    ((((m) & S_IFMT) == S_IFCHR))
  1495. X#define S_ISREG(m)    ((((m) & S_IFMT) == S_IFREG))
  1496. X#define S_ISBLK(m)    ((((m) & S_IFMT) == S_IFBLK))
  1497. Xextern int CDECL    chmod    (char *, int);
  1498. Xextern int CDECL    umask    (int);
  1499. X
  1500. XAdd to sys/types.h the following 32 lines
  1501. X
  1502. X#ifndef _USHORT_T_DEFINED
  1503. Xtypedef unsigned short    ushort;
  1504. X#define _USHORT_T_DEFINED
  1505. X#endif
  1506. X
  1507. X#ifndef _MODE_T_DEFINED
  1508. Xtypedef unsigned short    mode_t;
  1509. X#define _MODE_T_DEFINED
  1510. X#endif
  1511. X
  1512. X#ifndef _PID_T_DEFINED
  1513. Xtypedef int        pid_t;
  1514. X#define _PID_T_DEFINED
  1515. X#endif
  1516. X
  1517. X#ifndef _GID_T_DEFINED
  1518. Xtypedef int        gid_t;
  1519. X#define _GID_T_DEFINED
  1520. X#endif
  1521. X
  1522. X#ifndef _UID_T_DEFINED
  1523. Xtypedef int        uid_t;
  1524. X#define _UID_T_DEFINED
  1525. X#endif
  1526. X
  1527. X#ifndef _BOOL_T_DEFINED
  1528. Xtypedef char        bool;    /* Boolean: 0 = false, 1 = true        */
  1529. X#define FALSE    ((bool)0)    /* Boolean 'false'            */
  1530. X#define TRUE    ((bool)1)    /* Boolean 'true'            */
  1531. X#define _BOOL_T_DEFINED
  1532. X#endif
  1533. X
  1534. SHAR_EOF
  1535. chmod 0644 include/Changes || echo "restore of include/Changes fails"
  1536. set `wc -c include/Changes`;Sum=$1
  1537. if test "$Sum" != "1716"
  1538. then echo original size 1716, current size $Sum;fi
  1539. echo "x - extracting include/sys/dirent.h (Text)"
  1540. sed 's/^X//' << 'SHAR_EOF' > include/sys/dirent.h &&
  1541. X/* <sys/dirent.h> -- file system independent directory entry (SVR3) */
  1542. X#ifndef _SYS_DIRENT_H
  1543. X#define _SYS_DIRENT_H
  1544. X
  1545. X#ifndef MSDOS
  1546. X#define    MAXNAMLEN    512    /* maximum filename length        */
  1547. X#else
  1548. X#define    MAXNAMLEN    13    /* maximum filename length        */
  1549. X#endif
  1550. X
  1551. X#ifndef NAME_MAX
  1552. X#define    NAME_MAX    (MAXNAMLEN - 1)
  1553. X#endif
  1554. X
  1555. Xstruct dirent            /* data from getdents()/readdir()    */
  1556. X{
  1557. X    ino_t    d_ino;        /* inode number of entry        */
  1558. X    off_t    d_off;        /* offset of disk directory entry    */
  1559. X    ushort    d_reclen;    /* length of this record        */
  1560. X#ifndef MSDOS
  1561. X    char    d_name[1];    /* name of file                */
  1562. X#else
  1563. X    char    d_name[MAXNAMLEN + 1];
  1564. X#endif
  1565. X};
  1566. X
  1567. X#ifdef BSD_SYSV            /* (e.g., when compiling getdents.c)    */
  1568. Xextern struct dirent    __dirent;    /* (not actually used) */
  1569. X
  1570. X                /* The following is portable, although    */
  1571. X                /* rather silly.            */
  1572. X#define    DIRENTBASESIZ        (__dirent.d_name - (char *)&__dirent.d_ino)
  1573. X
  1574. X#else
  1575. X
  1576. X/* The following nonportable ugliness could have been avoided by defining
  1577. X * DIRENTSIZ and DIRENTBASESIZ to also have (struct dirent *) arguments.
  1578. X * There shouldn't be any problem if you avoid using the DIRENTSIZ() macro.
  1579. X */
  1580. X
  1581. X#define    DIRENTBASESIZ        (((struct dirent *)0)->d_name \
  1582. X                - (char *)&((struct dirent *)0)->d_ino)
  1583. X#endif
  1584. X
  1585. X#define    DIRENTSIZ(namlen)    ((DIRENTBASESIZ + sizeof(long) + (namlen)) \
  1586. X                / sizeof(long) * sizeof(long))
  1587. X
  1588. X#endif
  1589. SHAR_EOF
  1590. chmod 0644 include/sys/dirent.h || echo "restore of include/sys/dirent.h fails"
  1591. set `wc -c include/sys/dirent.h`;Sum=$1
  1592. if test "$Sum" != "1331"
  1593. then echo original size 1331, current size $Sum;fi
  1594. echo "x - extracting include/sys/proto.h (Text)"
  1595. sed 's/^X//' << 'SHAR_EOF' > include/sys/proto.h &&
  1596. X/*
  1597. X * Prototype definitions for Standard and Non-standard compilers
  1598. X */
  1599. X
  1600. X#undef _PROTO
  1601. X#undef _CDECL
  1602. X#undef _NEAR
  1603. X
  1604. X#ifdef MSDOS
  1605. X#  ifndef NO_EXT_KEYS                /* extensions enabled */
  1606. X#    define _CDECL    cdecl
  1607. X#    define _NEAR    near
  1608. X#  else 
  1609. X#    define _CDECL
  1610. X#    define _NEAR
  1611. X#  endif 
  1612. X#else
  1613. X#    define _CDECL
  1614. X#endif
  1615. X
  1616. X#ifdef __STDC__
  1617. X#  define _PROTO(p)    p
  1618. X#else
  1619. X#  define _PROTO(p)    ()
  1620. X#  undef  const
  1621. X#endif
  1622. SHAR_EOF
  1623. chmod 0644 include/sys/proto.h || echo "restore of include/sys/proto.h fails"
  1624. set `wc -c include/sys/proto.h`;Sum=$1
  1625. if test "$Sum" != "405"
  1626. then echo original size 405, current size $Sum;fi
  1627. echo "x - extracting include/dirent.h (Text)"
  1628. sed 's/^X//' << 'SHAR_EOF' > include/dirent.h &&
  1629. X/* <dirent.h> -- definitions for SVR3 directory access routines */
  1630. X#ifndef _DIRENT_H
  1631. X#define _DIRENT_H
  1632. X
  1633. X#include <sys/types.h>
  1634. X#include <limits.h>
  1635. X#include <sys/dirent.h>
  1636. X#include <sys/proto.h>
  1637. X
  1638. X#ifndef NULL
  1639. X#  ifdef MSDOS
  1640. X#    if (defined(M_I86SM) || defined(M_I86MM))
  1641. X#      define NULL    0
  1642. X#    else
  1643. X#      if (defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM))
  1644. X#        define NULL    0L
  1645. X#      endif
  1646. X#    endif
  1647. X#  else
  1648. X#    define NULL    0
  1649. X#  endif
  1650. X#endif
  1651. X
  1652. X#define    DIRBUF    8192        /* buffer size for fs-indep. dirs    */
  1653. X                /* must in general be larger than the    */
  1654. X                /* filesystem buffer size        */
  1655. X
  1656. X#ifndef MSDOS
  1657. Xtypedef struct
  1658. X{
  1659. X    int        dd_fd;        /* file descriptor            */
  1660. X    int        dd_loc;        /* offset in block            */
  1661. X    int        dd_size;    /* amount of valid data            */
  1662. X    char    *dd_buf;    /* -> directory block            */
  1663. X} DIR;                /* stream data from opendir()        */
  1664. X
  1665. X#else
  1666. X
  1667. X/* MSDOS versions */
  1668. X
  1669. Xstruct _dircontents {
  1670. X    char        *_d_entry;
  1671. X    struct _dircontents    *_d_next;
  1672. X};
  1673. X
  1674. Xtypedef struct _dirdesc {
  1675. X    int            dd_id;    /* uniquely identify each open directory */
  1676. X    long        dd_loc;    /* where we are in directory entry is this */
  1677. X    struct _dircontents    *dd_contents;    /* pointer to contents of dir    */
  1678. X    struct _dircontents    *dd_cp;        /* pointer to current position    */
  1679. X} DIR;
  1680. X#endif
  1681. X
  1682. X/* Functions */
  1683. X
  1684. Xextern DIR * _CDECL        opendir        _PROTO ((char *));
  1685. Xextern struct dirent * _CDECL    readdir        _PROTO ((DIR *));
  1686. Xextern void _CDECL        rewinddir    _PROTO ((DIR *));
  1687. Xextern int _CDECL        closedir    _PROTO ((DIR *));
  1688. Xextern void _CDECL        seekdir        _PROTO ((DIR *, off_t));
  1689. Xextern off_t _CDECL        telldir        _PROTO ((DIR *));
  1690. X
  1691. Xextern int _CDECL        chdir        _PROTO ((char *));
  1692. Xextern char * _CDECL        getcwd        _PROTO ((char *, int));
  1693. X#ifdef MSDOS
  1694. Xextern int _CDECL        mkdir        _PROTO ((char *));
  1695. X#else
  1696. Xextern int _CDECL        mkdir        _PROTO ((char *, mode_t));
  1697. X#endif
  1698. Xextern int _CDECL        rmdir        _PROTO ((char *));
  1699. Xextern int _CDECL        scandir        _PROTO ((char *, struct dirent ***, int (_CDECL *)(const void *, const void *), int (_CDECL *)(const void *, const void *)));
  1700. X#endif
  1701. SHAR_EOF
  1702. chmod 0644 include/dirent.h || echo "restore of include/dirent.h fails"
  1703. set `wc -c include/dirent.h`;Sum=$1
  1704. if test "$Sum" != "2014"
  1705. then echo original size 2014, current size $Sum;fi
  1706. echo "x - extracting include/unistd.h (Text)"
  1707. sed 's/^X//' << 'SHAR_EOF' > include/unistd.h &&
  1708. X#ifndef _UNISTD_H
  1709. X#define _UNISTD_H
  1710. X
  1711. X/*  unistd.h  */
  1712. X
  1713. X#include <sys/types.h>
  1714. X#include <sys/proto.h>
  1715. X
  1716. X/* Definition for NULL pointer */
  1717. X
  1718. X#ifndef NULL
  1719. X#  ifdef MSDOS
  1720. X#    if (defined(M_I86SM) || defined(M_I86MM))
  1721. X#      define NULL    0
  1722. X#    else
  1723. X#      if (defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM))
  1724. X#        define NULL    0L
  1725. X#      endif
  1726. X#    endif
  1727. X#  else
  1728. X#    define NULL    0
  1729. X#  endif
  1730. X#endif
  1731. X
  1732. X/*  for access(2)  */
  1733. X
  1734. X#define R_OK         4
  1735. X#define W_OK         2
  1736. X#define X_OK         1
  1737. X#define F_OK         0
  1738. X
  1739. X/*  for lockf()  */
  1740. X
  1741. X#define F_ULOCK        0
  1742. X#define F_LOCK        1
  1743. X#define F_TLOCK        2
  1744. X#define F_TEST        3
  1745. X
  1746. X/*  for lseek(2)  */
  1747. X
  1748. X#ifndef SEEK_SET
  1749. X#define SEEK_SET    0
  1750. X#endif
  1751. X
  1752. X#ifndef SEEK_CUR
  1753. X#define SEEK_CUR    1
  1754. X#endif
  1755. X
  1756. X#ifndef SEEK_END
  1757. X#define SEEK_END    2
  1758. X#endif
  1759. X
  1760. X/* STDIO definitions */
  1761. X
  1762. X#define    STDIN_FILENO    0
  1763. X#define    STDOUT_FILENO    1
  1764. X#define    STDERR_FILENO    2
  1765. X
  1766. X/* Standard paths */
  1767. X
  1768. X#define GF_PATH        "/etc/group"
  1769. X#define PF_PATH        "/etc/passwd"
  1770. X#define IF_PATH        "/usr/include"
  1771. X#define SF_PATH        "/etc/shadow"
  1772. X
  1773. X/* POSIX definitions */
  1774. X
  1775. X#define _POSIX_VERSION        198803L
  1776. X#undef    _POSIX_CHOWN_RESTRICTED
  1777. X#undef    _POSIX_JOB_CONTROL
  1778. X#define    _POSIX_NO_TRUNC        1
  1779. X#define _POSIX_SAVED_IDS    1
  1780. X#undef    _POSIX_VDISABLE
  1781. X/* #define _XOPEN_VERSION        */
  1782. X
  1783. X/* sysconf values */
  1784. X
  1785. X#define _SC_ARG_MAX        0
  1786. X#define _SC_CHILD_MAX        1
  1787. X#define _SC_CLK_TCK        2
  1788. X#define _SC_NGROUPS_MAX        3
  1789. X#define _SC_OPEN_MAX        4
  1790. X#define _SC_JOB_CONTROL        5
  1791. X#define _SC_SAVED_IDS        6
  1792. X#define _SC_VERSION        7
  1793. X#define _SC_PASS_MAX        8
  1794. X#define _SC_XOPEN_VERSION    9
  1795. X
  1796. X/* pathconf values */
  1797. X
  1798. X#define _PC_LINK_MAX        0
  1799. X#define _PC_MAX_CANON        1
  1800. X#define _PC_MAX_INPUT        2
  1801. X#define _PC_NAME_MAX        3
  1802. X#define _PC_PATH_MAX        4
  1803. X#define _PC_PIPE_BUF        5
  1804. X#define _PC_CHOWN_RESTRICTED    6
  1805. X#define _PC_NO_TRUNC        7
  1806. X#define _PC_VDISABLE        8
  1807. X
  1808. X/* confstring values */
  1809. X
  1810. X#define _CS_PATH        1
  1811. X
  1812. X/* Function declarations */
  1813. X
  1814. Xextern size_t _CDECL    confstring    _PROTO ((int, char *, size_t));
  1815. Xextern void _CDECL    abort        _PROTO ((void));
  1816. X#ifdef MSDOS
  1817. Xextern int _CDECL    chsize        _PROTO ((int, off_t));
  1818. X#else
  1819. Xextern int _CDECL    chsize        _PROTO ((char *, off_t));
  1820. X#endif
  1821. Xextern void _CDECL    sync        _PROTO ((void));
  1822. X
  1823. X/* --- Process creation and execution --- */
  1824. Xextern pid_t _CDECL    fork        _PROTO ((void));
  1825. Xextern pid_t _CDECL    vfork        _PROTO ((void));
  1826. Xextern int _CDECL    execl        _PROTO ((char *, char *, ...));
  1827. Xextern int _CDECL    execle        _PROTO ((char *, char *, ...));
  1828. Xextern int _CDECL    execlp        _PROTO ((char *, char *, ...));
  1829. Xextern int _CDECL    execlpe        _PROTO ((char *, char *, ...));
  1830. Xextern int _CDECL    execv        _PROTO ((char *, char **));
  1831. Xextern int _CDECL    execve        _PROTO ((char *, char **, char **));
  1832. Xextern int _CDECL    execvp        _PROTO ((char *, char **));
  1833. Xextern int _CDECL    execvpe        _PROTO ((char *, char **, char **));
  1834. X
  1835. X/* --- Process termination --- */
  1836. Xextern void _CDECL    _exit        _PROTO ((int));
  1837. Xextern void _CDECL    exit        _PROTO ((int));
  1838. X
  1839. X/* --- Timer operations --- */
  1840. Xextern unsigned int _CDECL    alarm    _PROTO ((unsigned int));
  1841. Xextern int _CDECL        pause    _PROTO ((void));
  1842. Xextern unsigned int _CDECL    sleep    _PROTO ((unsigned int));
  1843. X
  1844. X/* --- Process identification --- */
  1845. Xextern pid_t _CDECL    getpid        _PROTO ((void));
  1846. Xextern pid_t _CDECL    getppid        _PROTO ((void));
  1847. X
  1848. X/* --- User identification --- */
  1849. Xextern uid_t _CDECL    getuid        _PROTO ((void));
  1850. Xextern uid_t _CDECL    geteuid        _PROTO ((void));
  1851. Xextern gid_t _CDECL    getgid        _PROTO ((void));
  1852. Xextern gid_t _CDECL    getegid        _PROTO ((void));
  1853. Xextern int _CDECL    setuid        _PROTO ((uid_t));
  1854. Xextern int _CDECL    setgid        _PROTO ((gid_t));
  1855. Xextern int _CDECL    getgroups    _PROTO ((int, gid_t *));
  1856. Xextern char * _CDECL    getlogin    _PROTO ((void));
  1857. Xextern char * _CDECL    cuserid        _PROTO ((char *));
  1858. X
  1859. X/* --- Process groups --- */
  1860. Xextern pid_t _CDECL    getpgrp        _PROTO ((void));
  1861. Xextern pid_t _CDECL    setsid        _PROTO ((void));
  1862. Xextern int _CDECL    setpgid        _PROTO ((pid_t, pid_t));
  1863. X
  1864. X/* --- Terminal identification --- */
  1865. Xextern char * _CDECL    ctermid    _PROTO ((char *));
  1866. Xextern char * _CDECL    ttyname    _PROTO ((int));
  1867. Xextern int _CDECL    isatty        _PROTO ((int));
  1868. X
  1869. X/* --- Configurable system variables --- */
  1870. Xextern long _CDECL    sysconf        _PROTO ((int));
  1871. X
  1872. X/* --- Working directory --- */
  1873. Xextern int _CDECL    chdir        _PROTO ((char *));
  1874. Xextern char * _CDECL    getcwd        _PROTO ((char *, int));
  1875. X
  1876. X/* --- General file creation --- */
  1877. Xextern int _CDECL    link        _PROTO ((char *, char *));
  1878. Xextern int _CDECL    rename        _PROTO ((const char *, const char *));
  1879. Xextern char * _CDECL    mktemp        _PROTO ((char *));
  1880. X
  1881. X/* --- File removal --- */
  1882. Xextern int _CDECL    unlink        _PROTO ((const char *));
  1883. Xextern int _CDECL    remove        _PROTO ((const char *));
  1884. Xextern int _CDECL    rmdir        _PROTO ((char *));
  1885. X
  1886. X/* --- File characteristics --- */
  1887. Xextern int _CDECL    access        _PROTO ((char *, int));
  1888. Xextern int _CDECL    chown        _PROTO ((char *, uid_t, gid_t));
  1889. Xextern long _CDECL    tell         _PROTO ((int));
  1890. X
  1891. X/* --- Configurable pathname variables --- */
  1892. Xextern long _CDECL    pathconf    _PROTO ((char *, int));
  1893. Xextern long _CDECL    fpathconf    _PROTO ((int, int));
  1894. X
  1895. X/* --- Pipes --- */
  1896. Xextern int _CDECL    pipe        _PROTO ((int[2]));
  1897. X
  1898. X/* --- File descriptor manipulation --- */
  1899. Xextern int _CDECL    dup        _PROTO ((int));
  1900. Xextern int _CDECL    dup2        _PROTO ((int, int));
  1901. X
  1902. X/* --- File descriptor deassignment --- */
  1903. Xextern int _CDECL    close        _PROTO ((int));
  1904. X
  1905. X/* --- Input and output --- */
  1906. Xextern int _CDECL    read        _PROTO ((int, char *, unsigned int));
  1907. Xextern int _CDECL    write        _PROTO ((int, char *, unsigned int));
  1908. X
  1909. X/* --- Control operations on files --- */
  1910. Xextern off_t _CDECL    lseek        _PROTO ((int, off_t, int));
  1911. X#endif
  1912. SHAR_EOF
  1913. chmod 0644 include/unistd.h || echo "restore of include/unistd.h fails"
  1914. set `wc -c include/unistd.h`;Sum=$1
  1915. if test "$Sum" != "5401"
  1916. then echo original size 5401, current size $Sum;fi
  1917. echo "x - extracting include/ms_dio.h (Text)"
  1918. sed 's/^X//' << 'SHAR_EOF' > include/ms_dio.h &&
  1919. X/* ms_dio.h */
  1920. X#ifndef _MS_DIO_H
  1921. X#define _MS_DIO_H
  1922. X
  1923. X/*
  1924. X * This is only required under MSDOS
  1925. X */
  1926. X
  1927. X#ifdef MSDOS
  1928. X#include <sys/proto.h>
  1929. X
  1930. Xextern int _CDECL    dio_write    _PROTO ((int, char *, unsigned int));
  1931. Xextern int _CDECL    dio_read    _PROTO ((int, char *, unsigned int));
  1932. Xextern int _CDECL    dio_open    _PROTO ((char *, int, ...));
  1933. Xextern int _CDECL    dio_close    _PROTO ((int));
  1934. Xextern long _CDECL    dio_lseek    _PROTO ((int, long, int));
  1935. Xextern int _CDECL    dio_fstat    _PROTO ((int , struct stat *));
  1936. Xextern int _CDECL    dio_stat    _PROTO ((char *, struct stat *));
  1937. Xextern int _CDECL    dio_access    _PROTO ((char *, int));
  1938. Xextern int _CDECL    dio_chmod    _PROTO ((char *, int));
  1939. Xextern int _CDECL    dio_creat    _PROTO ((char *, int));
  1940. Xextern int _CDECL    dio_dup        _PROTO ((int));
  1941. Xextern int _CDECL    dio_isatty    _PROTO ((int));
  1942. Xextern long _CDECL    dio_tell    _PROTO ((int));
  1943. X
  1944. X#define open        dio_open
  1945. X#define close(a)    dio_close (a)
  1946. X#define read(a,b,c)    dio_read (a,b,c)
  1947. X#define write(a,b,c)    dio_write (a,b,c)
  1948. X#define lseek(a,b,c)    dio_lseek (a,b,c)
  1949. X#define fstat(a,b)    dio_fstat (a,b)
  1950. X#define stat(a,b)    dio_stat (a,b)
  1951. X#define access(a, b)    dio_access (a,b)
  1952. X#define chmod(a, b)    dio_chmod (a,b)
  1953. X#define creat(a, b)    dio_creat (a,b)
  1954. X#define dup(a)        dio_dup (a)
  1955. X#define isatty(a)    dio_isatty (a)
  1956. X#define tell(a)        dio_tell (a)
  1957. X#endif
  1958. X#endif
  1959. SHAR_EOF
  1960. chmod 0644 include/ms_dio.h || echo "restore of include/ms_dio.h fails"
  1961. set `wc -c include/ms_dio.h`;Sum=$1
  1962. if test "$Sum" != "1284"
  1963. then echo original size 1284, current size $Sum;fi
  1964. echo "x - extracting lib/ms_dio.c (Text)"
  1965. sed 's/^X//' << 'SHAR_EOF' > lib/ms_dio.c &&
  1966. X/* MS-DOS Direct Disk I/O
  1967. X *
  1968. X * MS-DOS Direct Disk I/O - Copyright (c) 1989 Data Logic Limited.
  1969. X *
  1970. X * dio_read and dio_write based on original code copyrighted (c) 1989
  1971. X * Harold G. Walters.
  1972. X *
  1973. X * The rest of the code has been written from scatch to support multiple disk
  1974. X * access and provide a consistant interface from normal I/O operations.
  1975. X *
  1976. X * The devices supported are:
  1977. X *
  1978. X *    /dev/hdxy    - Hard disk drive x parition y (x = 0 to 9, y =
  1979. X *              0 to 9, where 0 is the whole disk).
  1980. X *    /dev/fdx    - Floppy drive x (x = 0 to 9).
  1981. X *    /dev/kmem    - Memory driver
  1982. X *
  1983. X * It does its best to determine what type of disk you are reading.
  1984. X *
  1985. X * Redistribution and use in source and binary forms are permitted
  1986. X * provided that the above copyright notice is duplicated in the
  1987. X * source form.
  1988. X */
  1989. X
  1990. X#include <sys/types.h>
  1991. X#include <sys/stat.h>
  1992. X#include <stdio.h>
  1993. X#include <stdlib.h>
  1994. X#include <string.h>
  1995. X#include <errno.h>
  1996. X#include <dos.h>
  1997. X#include <fcntl.h>
  1998. X#include <ctype.h>
  1999. X#include <unistd.h>
  2000. X#include <time.h>
  2001. X#include <ms_dio.h>
  2002. X
  2003. X#undef open
  2004. X#undef close
  2005. X#undef read
  2006. X#undef write
  2007. X#undef lseek
  2008. X#undef fstat
  2009. X#undef stat
  2010. X#undef access
  2011. X#undef chmod
  2012. X#undef creat
  2013. X#undef dup
  2014. X#undef isatty
  2015. X#undef tell
  2016. X
  2017. X#define SECSIZ        512
  2018. X#define    MS_MODIFIER    30000
  2019. X#define BIOS_READ    0x2
  2020. X#define BIOS_WRITE    0x3
  2021. X#define HD_FLAG        0x80        /* Hard disk flag        */
  2022. X#define MEGABYTE    1048576L
  2023. X#define DRIVE_RAM    20
  2024. X
  2025. X#ifdef __STDC__
  2026. Xstatic int        dio_do (int, struct fs *, char *, long, unsigned int);
  2027. Xstatic struct fs    *dio_fpcheck (int);
  2028. Xstatic int        dio_fncheck (char *);
  2029. X#else
  2030. Xstatic int        dio_do ();
  2031. Xstatic struct fs    *dio_fpcheck ();
  2032. Xstatic int        dio_fncheck ();
  2033. X#endif
  2034. X
  2035. Xstatic struct fs {
  2036. X    int        mode;            /* Open mode            */
  2037. X    int        drive;
  2038. X    int        partition;        /* Hard disk partition number    */
  2039. X    off_t    location;        /* Current offset        */
  2040. X    long    m_start;        /* Offset for partition        */
  2041. X    long    m_cyl;            /* Max cylinders        */
  2042. X    int        m_head;            /* Max heads            */
  2043. X    int        m_sector;        /* Max sectors            */
  2044. X    long    m_scount;        /* Total sectors per disk    */
  2045. X} *MS_io_fs[_NFILE];
  2046. X
  2047. Xstruct partition {
  2048. X    long    f_type;            /* Type flags            */
  2049. X    long    f_status;        /* Status flags            */
  2050. X    long    offset;            /* Offset in sectors        */
  2051. X    long    size;            /* Size in sectors        */
  2052. X};
  2053. X
  2054. Xstatic int    fs_init = 0;
  2055. X
  2056. X/* Do the actual read/write to the disk.  This function is not used
  2057. X * for the RAM drive
  2058. X */
  2059. X
  2060. Xstatic int    dio_do (type, FP, buf, secnum, secknt)
  2061. Xint        type;
  2062. Xstruct fs    *FP;
  2063. Xchar        *buf;
  2064. Xlong        secnum;
  2065. Xunsigned int    secknt;
  2066. X{
  2067. X    int            i, j;
  2068. X    int            nsec, cyl;
  2069. X    long        asec;
  2070. X    union REGS        reg;
  2071. X#if defined(M_I86LM)
  2072. X    struct SREGS    sreg;
  2073. X#endif
  2074. X
  2075. X    for (j = 0; j < secknt; j += nsec, buf += (nsec * SECSIZ), secnum += nsec)
  2076. X    {
  2077. X
  2078. X/* Check for space - end of drive */
  2079. X
  2080. X    if (secnum > FP->m_scount)
  2081. X    {
  2082. X        errno = ENOSPC;
  2083. X        return j * SECSIZ;
  2084. X    }
  2085. X
  2086. X/* Calculate the number of sectors left on the track */
  2087. X
  2088. X    asec = FP->m_start + secnum;
  2089. X
  2090. X    if (((asec % FP->m_sector) + (secknt - j)) > FP->m_sector)
  2091. X        nsec = (int)(FP->m_sector - (asec % FP->m_sector));
  2092. X
  2093. X    else
  2094. X        nsec = secknt - j;
  2095. X
  2096. X/* Read/write it three times */
  2097. X
  2098. X    for (i = 0; i < 3; i++)
  2099. X    {
  2100. X        reg.h.ah = (unsigned char)type;
  2101. X        reg.h.al = (unsigned char)nsec;
  2102. X        reg.h.dl = (unsigned char)FP->drive;
  2103. X
  2104. X        cyl      = (int)(asec / (FP->m_head * FP->m_sector));
  2105. X        reg.h.cl = (unsigned char)((((asec % FP->m_sector) + 1) & 0x03f) |
  2106. X            ((cyl & 0x0300) >> 2));
  2107. X        reg.h.ch = (unsigned char)(cyl & 0xff);
  2108. X        reg.h.dh = (unsigned char)((asec % (FP->m_head * FP->m_sector)) / FP->m_sector);
  2109. X
  2110. X
  2111. X#if defined(M_I86LM)
  2112. X        reg.x.bx = FP_OFF(buf);
  2113. X        sreg.es = FP_SEG(buf);
  2114. X        int86x (0x13, ®, ®, &sreg);
  2115. X#else
  2116. X        reg.x.bx = (int) buf;
  2117. X        int86 (0x13, ®, ®);
  2118. X#endif
  2119. X
  2120. X        if (!reg.x.cflag)
  2121. X        break;
  2122. X    }
  2123. X
  2124. X/* Check for failure */
  2125. X
  2126. X    if (i == 3)
  2127. X    {
  2128. X        errno = EIO;
  2129. X        return -1;
  2130. X    }
  2131. X    }
  2132. X
  2133. X    return secknt * SECSIZ;
  2134. X}
  2135. X
  2136. X/* Write function */
  2137. X
  2138. Xint        dio_write (fp, from_buf, from_cnt)
  2139. Xint        fp;            /* File handler            */
  2140. Xchar        *from_buf;        /* Output buffer        */
  2141. Xunsigned int    from_cnt;        /* Number of bytes to write    */
  2142. X{
  2143. X    unsigned int    amt = 0;
  2144. X    unsigned int    err = 0;
  2145. X    long        fquo;
  2146. X    unsigned int    frem;
  2147. X    unsigned int    cquo = 0;
  2148. X    unsigned int    crem = 0;
  2149. X    struct fs        *FP;
  2150. X    char        buffer[SECSIZ];
  2151. X
  2152. X/* Direct IO or normal */
  2153. X
  2154. X    if (fp < MS_MODIFIER)
  2155. X    return write (fp, from_buf, from_cnt);
  2156. X
  2157. X    if (((FP = dio_fpcheck (fp)) == (struct fs *)NULL) ||
  2158. X    ((FP->mode & 0x03) == O_RDONLY))
  2159. X    {
  2160. X    errno = EBADF;
  2161. X    return -1;
  2162. X    }
  2163. X
  2164. X/* If RAM - just copy */
  2165. X
  2166. X    if (FP->drive == DRIVE_RAM)
  2167. X    {
  2168. X    char huge     *cp = (char huge *)from_buf;
  2169. X    char huge     *sp = (char huge *)(((FP->location & 0x0ffff0L) << 12L)
  2170. X                        | (FP->location & 0x0fL));
  2171. X
  2172. X    amt = from_cnt;
  2173. X    while (amt--)
  2174. X        *(sp++) = *(cp++);
  2175. X
  2176. X    return from_cnt;
  2177. X    }
  2178. X
  2179. X/* If the current location is not a sector boundary - read in the current
  2180. X * sector and write a bit at the end to move to the boundary
  2181. X */
  2182. X
  2183. X    fquo = FP->location / SECSIZ;
  2184. X    frem = (unsigned int) (FP->location % SECSIZ);
  2185. X
  2186. X    if (frem > 0)
  2187. X    {
  2188. X    if ((err = dio_do (BIOS_READ, FP, buffer, fquo, 1)) != SECSIZ)
  2189. X        return err;
  2190. X
  2191. X    if ((amt = SECSIZ - frem) > from_cnt)
  2192. X        amt = from_cnt;
  2193. X
  2194. X/* Update the buffer with the bit at the end */
  2195. X
  2196. X    memcpy (&buffer[frem], from_buf, amt);
  2197. X
  2198. X    if ((err = dio_do (BIOS_WRITE, FP, buffer, fquo, 1)) != SECSIZ)
  2199. X        return err;
  2200. X
  2201. X/* Increment the location */
  2202. X
  2203. X    FP->location += amt;
  2204. X
  2205. X    if (SECSIZ - frem <= from_cnt)
  2206. X        fquo++;
  2207. X
  2208. X    from_buf += amt;
  2209. X    from_cnt -= amt;
  2210. X    }
  2211. X
  2212. X/* Calculate the number of full sectors to process now we are on a sector
  2213. X * boundary
  2214. X */
  2215. X
  2216. X    cquo = from_cnt / SECSIZ;
  2217. X    crem = from_cnt % SECSIZ;
  2218. X
  2219. X    if (cquo > 0)
  2220. X    {
  2221. X    if ((err = dio_do (BIOS_WRITE, FP, from_buf, fquo, cquo)) !=
  2222. X        (cquo * SECSIZ))
  2223. X    {
  2224. X        if (err > 0)
  2225. X        FP->location += err;
  2226. X
  2227. X        return err;
  2228. X    }
  2229. X
  2230. X    amt += (cquo * SECSIZ);
  2231. X    FP->location += (cquo * SECSIZ);
  2232. X    fquo += cquo;
  2233. X    from_buf += (cquo * SECSIZ);
  2234. X    from_cnt -= (cquo * SECSIZ);
  2235. X    }
  2236. X
  2237. X/* Is there still more - read in the next sector, update first half and
  2238. X * re-write
  2239. X */
  2240. X
  2241. X    if (crem > 0)
  2242. X    {
  2243. X    if ((err = dio_do (BIOS_READ, FP, buffer, fquo, 1)) != SECSIZ)
  2244. X        return err;
  2245. X
  2246. X    memcpy (buffer, from_buf, crem);
  2247. X
  2248. X    if ((err = dio_do (BIOS_WRITE, FP, buffer, fquo, 1)) != SECSIZ)
  2249. X        return err;
  2250. X
  2251. X    amt += crem;
  2252. X    FP->location += crem;
  2253. X    }
  2254. X
  2255. X    return amt;
  2256. X}
  2257. X
  2258. X/* Read function */
  2259. X
  2260. Xint        dio_read (fp, to_buf, to_cnt)
  2261. Xint        fp;            /* File handler            */
  2262. Xchar        *to_buf;        /* Input buffer            */
  2263. Xunsigned int    to_cnt;            /* Number of bytes to read    */
  2264. X{
  2265. X    unsigned int    amt = 0;
  2266. X    unsigned int    err = 0;
  2267. X    long        fquo;
  2268. X    unsigned int    frem;
  2269. X    unsigned int    cquo = 0;
  2270. X    unsigned int    crem = 0;
  2271. X    struct fs        *FP;
  2272. X    char        buffer[SECSIZ];
  2273. X
  2274. X/* Direct IO or normal */
  2275. X
  2276. X    if (fp < MS_MODIFIER)
  2277. X    return read (fp, to_buf, to_cnt);
  2278. X
  2279. X    if (((FP = dio_fpcheck (fp)) == (struct fs *)NULL) ||
  2280. X    ((FP->mode & 0x03) == O_WRONLY))
  2281. X    {
  2282. X    errno = EBADF;
  2283. X    return -1;
  2284. X    }
  2285. X
  2286. X/* If RAM - just copy */
  2287. X
  2288. X    if (FP->drive == DRIVE_RAM)
  2289. X    {
  2290. X    char huge     *cp = (char huge *)to_buf;
  2291. X    char huge     *sp = (char huge *)(((FP->location & 0x0ffff0L) << 12L)
  2292. X                        | (FP->location & 0x0f));
  2293. X
  2294. X
  2295. X    amt = to_cnt;
  2296. X    while (amt--)
  2297. X        *(cp++) = *(sp++);
  2298. X
  2299. X    return to_cnt;
  2300. X    }
  2301. X
  2302. X    fquo = FP->location / SECSIZ;
  2303. X    frem = (unsigned int) (FP->location % SECSIZ);
  2304. X
  2305. X    if (frem > 0)
  2306. X    {
  2307. X    if ((err = dio_do (BIOS_READ, FP, buffer, fquo, 1)) != SECSIZ)
  2308. X        return err;
  2309. X
  2310. X    if ((amt = SECSIZ - frem) > to_cnt)
  2311. X        amt = to_cnt;
  2312. X
  2313. X    memcpy (to_buf, &buffer[frem], amt);
  2314. X
  2315. X    FP->location += amt;
  2316. X    if (SECSIZ - frem <= to_cnt)
  2317. X        fquo++;
  2318. X
  2319. X    to_buf += amt;
  2320. X    to_cnt -= amt;
  2321. X    }
  2322. X
  2323. X    cquo = to_cnt / SECSIZ;
  2324. X    crem = to_cnt % SECSIZ;
  2325. X
  2326. X    if (cquo > 0)
  2327. X    {
  2328. X    if ((err = dio_do (BIOS_READ, FP, to_buf, fquo, cquo)) !=
  2329. X        (cquo * SECSIZ))
  2330. X    {
  2331. X        if (err > 0)
  2332. X        FP->location += err;
  2333. X
  2334. X        return err;
  2335. X    }
  2336. X
  2337. X    amt += (cquo * SECSIZ);
  2338. X    FP->location += (cquo * SECSIZ);
  2339. X    fquo += cquo;
  2340. X    to_buf += (cquo * SECSIZ);
  2341. X    to_cnt -= (cquo * SECSIZ);
  2342. X    }
  2343. X
  2344. X/* Do we still need a partial sector ? */
  2345. X
  2346. X    if (crem > 0)
  2347. X    {
  2348. X    if ((err = dio_do (BIOS_READ, FP, buffer, fquo, 1)) != SECSIZ)
  2349. X        return err;
  2350. X
  2351. X    memcpy (to_buf, buffer, crem);
  2352. X    amt += crem;
  2353. X    FP->location += crem;
  2354. X    }
  2355. X
  2356. X    return (amt);
  2357. X}
  2358. X
  2359. Xint    dio_open (name, mode, permissions)
  2360. Xchar    *name;
  2361. Xint    mode;
  2362. Xmode_t    permissions;
  2363. X{
  2364. X    struct fs    *FP;
  2365. X    int        fp, i, j;
  2366. X    int        drive, ndrive;
  2367. X    union REGS    iregs;
  2368. X    char    buf[SECSIZ];
  2369. X
  2370. X/* Check for initialisation */
  2371. X
  2372. X    if (!(fs_init++))
  2373. X    memset (MS_io_fs, 0, sizeof (struct fs *) * _NFILE);
  2374. X
  2375. X/* Direct I/o file name */
  2376. X
  2377. X    if ((drive = dio_fncheck (name)) != -1)
  2378. X    {
  2379. X    for (fp = 0; (fp < _NFILE) && (MS_io_fs[fp] != (struct fs *)NULL); fp++)
  2380. X        ;
  2381. X
  2382. X/* Check for available entry and space */
  2383. X
  2384. X    if ((fp == _NFILE) ||
  2385. X        ((FP = (struct fs *)malloc (sizeof (struct fs))) == (struct fs *)NULL))
  2386. X    {
  2387. X        errno = ENFILE;
  2388. X        return -1;
  2389. X    }
  2390. X
  2391. X    FP->location = 0L;
  2392. X    FP->mode = mode;
  2393. X
  2394. X/* RAM access ? */
  2395. X
  2396. X    if (drive == DRIVE_RAM)
  2397. X    {
  2398. X        FP->drive    = drive;
  2399. X        MS_io_fs[fp] = FP;
  2400. X        return fp + MS_MODIFIER;
  2401. X    }
  2402. X
  2403. X    if (drive & HD_FLAG)
  2404. X    {
  2405. X        ndrive      = (drive & (~HD_FLAG));
  2406. X        FP->partition = ndrive % 10;
  2407. X        ndrive      /= 10;
  2408. X        FP->drive     = ndrive | HD_FLAG;
  2409. X        FP->m_start   = 0L;        /* Offset for partition        */
  2410. X    }
  2411. X
  2412. X    else
  2413. X    {
  2414. X        FP->drive     = drive;
  2415. X        ndrive        = drive;
  2416. X        FP->partition = 0;
  2417. X        FP->m_start   = 0L;        /* Offset for partition        */
  2418. X    }
  2419. X
  2420. X
  2421. X/* Reset the drive */
  2422. X
  2423. X    iregs.h.ah = 0;
  2424. X    iregs.h.dl = (unsigned char)FP->drive;
  2425. X    int86 (0x13, &iregs, &iregs);
  2426. X
  2427. X/* Get the drive parameters */
  2428. X
  2429. X    iregs.h.ah = 0x08;
  2430. X    iregs.h.dl = (unsigned char)FP->drive;
  2431. X    int86 (0x13, &iregs, &iregs);
  2432. X
  2433. X/* Check for hard disk */
  2434. SHAR_EOF
  2435. echo "End of part 1"
  2436. echo "File lib/ms_dio.c is continued in part 2"
  2437. echo "2" > s2_seq_.tmp
  2438. exit 0
  2439.  
  2440. -- 
  2441. Regards,
  2442.  
  2443. Ian Stewartson
  2444. Data Logic Ltd.
  2445.  
  2446.  
  2447.