gno-docs/refs.aug96/gnokernelref-95.doc

1421 lines
265 KiB
Plaintext

{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f4\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Times;}{\f5\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Helvetica{\*\falt Arial};}{\f6\fmodern\fcharset0\fprq1{\*\panose 00000000000000000000}Courier;}{\f7\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Geneva{\*\falt Arial};}{\f8\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Tms Rmn;}{\f9\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Helv;}{\f10\froman\fcharset0\fprq2{\*\panose 00000000000000000000}MS Serif;}{\f11\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}MS Sans Serif;}{\f12\froman\fcharset0\fprq2{\*\panose 00000000000000000000}New York{\*\falt Times New Roman};}{\f13\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}System;}{\f14\fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;}{\f15\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}{\f16\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Bookman;}{\f17\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}TektoMM_240 RG 564 NO;}{\f18\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}TektoMM;}{\f19\froman\fcharset0\fprq2{\*\panose 00000000000000000000}ACaslon Bold;}{\f20\froman\fcharset0\fprq2{\*\panose 00000000000000000000}ACaslon Regular;}{\f21\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Bodoni BoldCondensed;}{\f22\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}BrushScript;}{\f23\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}GillSans;}{\f24\fmodern\fcharset0\fprq1{\*\panose 00000000000000000000}LetterGothic;}{\f25\fswiss\fcharset0\fprq2{\*\panose 020b0600000000000000}LotusLineDraw;}{\f26\fnil\fcharset2\fprq2{\*\panose 00000000000000000000}LotusWPSet;}{\f27\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}NewsGothic;}{\f28\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Perpetua;}{\f29\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Anna;}{\f30\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Poppl-Laudatio Regular;}{\f31\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Boulevard;}{\f32\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Boton Regular;}{\f33\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Baskerville BE Regular;}{\f34\fdecor\fcharset0\fprq2{\*\panose 00000000000000000000}Giddyup Thangs;}{\f35\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Giddyup;}{\f36\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}TektoMM_100 LT 250 CN;}{\f37\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}TektoMM_100 LT 564 NO;}{\f38\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}TektoMM_100 LT 850 EX;}{\f39\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}TektoMM_240 RG 250 CN;}{\f40\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}TektoMM_240 RG 850 EX;}{\f41\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}TektoMM_503 BD 250 CN;}{\f42\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}TektoMM_503 BD 488 NO;}{\f43\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}TektoMM_503 BD 850 EX;}{\f44\fnil\fcharset2\fprq2{\*\panose 00000000000000000000}Marlett;}{\f45\fswiss\fcharset0\fprq2{\*\panose 020f0704030504030204}Arial Rounded MT Bold;}{\f46\froman\fcharset0\fprq2{\*\panose 02040602050305030304}Book Antiqua;}{\f47\fswiss\fcharset0\fprq2{\*\panose 020b0502020202020204}Century Gothic;}{\f48\froman\fcharset0\fprq2{\*\panose 02040604050505020304}Century Schoolbook;}{\f49\froman\fcharset0\fprq2{\*\panose 00050102010706020507}Map Symbols;}{\f50\fswiss\fcharset0\fprq2{\*\panose 020b0706040902060204}Haettenschweiler;}{\f51\fdecor\fcharset0\fprq2{\*\panose 04020705040a02060702}Algerian;}{\f52\fdecor\fcharset0\fprq2{\*\panose 04030b070d0b02020403}Braggadocio;}{\f53\fswiss\fcharset0\fprq2{\*\panose 020b0903060703020204}Britannic Bold;}{\f54\fscript\fcharset0\fprq2{\*\panose 03060802040406070304}Brush Script MT;}{\f55\fdecor\fcharset0\fprq2{\*\panose 04020805060202030203}Colonna MT;}{\f56\fdecor\fcharset0\fprq2{\*\panose 04020505020e03040504}Desdemona;}{\f57\froman\fcharset0\fprq2{\*\panose 0204060206030a020304}Footlight MT Light;}{\f58\fdecor\fcharset0\fprq2{\*\panose 040307050d0c02020703}Kino MT;}{\f59\froman\fcharset0\fprq2{\*\panose 020a0a07050505020404}Wide Latin;}{\f60\fscript\fcharset0\fprq2{\*\panose 03020802060602070202}Matura MT Script Capitals;}{\f61\fdecor\fcharset0\fprq2{\*\panose 040506030a0602020202}Playbill;}{\f62\froman\fcharset2\fprq2{\*\panose 05050102010205020202}MT Extra;}{\f63\fswiss\fcharset0\fprq2{\*\panose 020e0602030304020304}Albertus Medium;}{\f64\fswiss\fcharset0\fprq2{\*\panose 020e0802040304020204}Albertus Extra Bold;}{\f65\fswiss\fcharset0\fprq2{\*\panose 020b0603020204030204}Antique Olive;}{\f66\fswiss\fcharset0\fprq2{\*\panose 020b0502050508020304}CG Omega;}{\f67\froman\fcharset0\fprq2{\*\panose 02020603050405020304}CG Times;}{\f68\froman\fcharset0\fprq2{\*\panose 02040706040705040204}Clarendon Condensed;}{\f69\fscript\fcharset238\fprq2{\*\panose 03030502040406070605}Coronet;}{\f70\froman\fcharset0\fprq2{\*\panose 02020404030301010803}Garamond;}{\f71\fmodern\fcharset0\fprq1{\*\panose 020b0409020202030204}Letter Gothic;}{\f72\fscript\fcharset0\fprq2{\*\panose 03020702040402020504}Marigold;}{\f73\fswiss\fcharset0\fprq2{\*\panose 020b0603020202030204}Univers;}{\f74\fswiss\fcharset0\fprq2{\*\panose 020b0606020202060204}Univers Condensed;}{\f75\fswiss\fcharset0\fprq2{\*\panose 020e0702040304020204}Albertus;}{\f76\fswiss\fcharset0\fprq2{\*\panose 020b0504020202050204}Metrostyle;}{\f77\fswiss\fcharset0\fprq2{\*\panose 020b0507020202060204}Metrostyle Extended;}{\f78\froman\fcharset0\fprq2{\*\panose 0208090404030b020404}Ozzie Black;}{\f79\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Verdana;}{\f80\froman\fcharset0\fprq2{\*\panose 02020500000000000000}CODABAR1;}{\f81\froman\fcharset0\fprq2{\*\panose 02020500000000000000}CODE3OF9X1;}{\f82\fswiss\fcharset0\fprq2{\*\panose 020b0500000000000000}INT2OF5X1;}{\f83\fnil\fcharset0\fprq2{\*\panose 00000000000000000000}USPS Bar Code;}{\f84\fmodern\fcharset2\fprq1{\*\panose 050b0009000000000000}OCR-A;}{\f85\fswiss\fcharset0\fprq2{\*\panose 020b0000000000000000}QuickType;}{\f86\fswiss\fcharset0\fprq2{\*\panose 020b0506030403020203}QuickType Condensed;}{\f87\fnil\fcharset2\fprq2{\*\panose 05000000000000000000}QuickType Pi;}{\f88\fdecor\fcharset0\fprq2{\*\panose 04040a05050d02020502}Beesknees ITC;}{\f89\fscript\fcharset0\fprq2{\*\panose 03070402050302030203}Bradley Hand ITC;}{\f90\froman\fcharset0\fprq2{\*\panose 02040603050505030304}Calisto MT;}{\f91\fdecor\fcharset0\fprq2{\*\panose 04040404050702020202}Curlz MT;}{\f92\froman\fcharset0\fprq2{\*\panose 02020904090505020303}Elephant;}{\f93\fswiss\fcharset0\fprq2{\*\panose 020b0907030504020204}Eras Bold ITC;}{\f94\fswiss\fcharset0\fprq2{\*\panose 020b0805030504020804}Eras Demi ITC;}{\f95\fswiss\fcharset0\fprq2{\*\panose 020b0402030504020804}Eras Light ITC;}{\f96\fswiss\fcharset0\fprq2{\*\panose 020b0602030504020804}Eras Medium ITC;}{\f97\fswiss\fcharset0\fprq2{\*\panose 020b0a07030504020204}Eras Ultra ITC;}{\f98\fdecor\fcharset0\fprq2{\*\panose 04040403040a02020202}Juice ITC;}{\f99\fdecor\fcharset0\fprq2{\*\panose 04040403030d02020704}Matisse ITC;}{\f100\froman\fcharset0\fprq2{\*\panose 02060603020205020403}Rockwell;}{\f101\froman\fcharset0\fprq2{\*\panose 02060903040505020403}Rockwell Extra Bold;}{\f102\fdecor\fcharset0\fprq2{\*\panose 04040a07060a02020202}Snap ITC;}{\f103\fdecor\fcharset0\fprq2{\*\panose 04020404030d07020202}Tempus Sans ITC;}{\f104\fscript\fcharset0\fprq2{\*\panose 03070502030502020203}Viner Hand ITC;}{\f105\fswiss\fcharset0\fprq2{\*\panose 020b0500000000000000}Anson;}{\f106\fnil\fcharset0\fprq2{\*\panose 00000000000000000000}Andes;}{\f107\fnil\fcharset0\fprq2{\*\panose 00000000000000000000}Fences;}{\f108\fnil\fcharset0\fprq2{\*\panose 00000000000000000000}BlackChancery;}{\f109\fmodern\fcharset0\fprq1{\*\panose 020b0009000000000000}QuickType Mono;}{\f110\fscript\fcharset238\fprq2{\*\panose 03010101010201010101}Monotype Corsiva;}{\f111\fnil\fcharset0\fprq2{\*\panose 00000000000000000000}MICRSSK;}{\f112\fswiss\fcharset0\fprq2{\*\panose 020b0506020202030204}Arial Narrow;}{\f113\fswiss\fcharset0\fprq2{\*\panose 020b0a04020102020204}Arial Black;}{\f114\froman\fcharset0\fprq2{\*\panose 02050604050505020204}Bookman Old Style;}{\f115\fnil\fcharset2\fprq2{\*\panose 01010601010101010101}Monotype Sorts;}{\f116\fswiss\fcharset0\fprq2{\*\panose 020b0806030902050204}Impact;}{\f117\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Bookshelf Symbol 3;}{\f118\fscript\fcharset0\fprq2{\*\panose 030f0702030302020204}Comic Sans MS;}{\f119\fnil\fcharset2\fprq2{\*\panose 05000000000000000000}MS Outlook;}{\f120\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}AvantGarde;}{\f121\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Helvetica-Narrow;}{\f122\froman\fcharset0\fprq2{\*\panose 00000000000000000000}NewCenturySchlbk;}{\f123\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Palatino;}{\f124\froman\fcharset0\fprq2{\*\panose 00000000000000000000}ZapfChancery;}{\f125\fdecor\fcharset2\fprq2{\*\panose 00000000000000000000}ZapfDingbats;}{\f216\fswiss\fcharset238\fprq2 Tahoma CE;}{\f217\fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f219\fswiss\fcharset161\fprq2 Tahoma Greek;}{\f220\fswiss\fcharset162\fprq2 Tahoma Tur;}{\f221\fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f408\fswiss\fcharset238\fprq2 Century Gothic CE;}{\f409\fswiss\fcharset204\fprq2 Century Gothic Cyr;}{\f412\fswiss\fcharset162\fprq2 Century Gothic Tur;}{\f413\fswiss\fcharset186\fprq2 Century Gothic Baltic;}{\f504\fswiss\fcharset238\fprq2 Albertus Medium CE;}{\f505\fswiss\fcharset204\fprq2 Albertus Medium Cyr;}{\f508\fswiss\fcharset162\fprq2 Albertus Medium Tur;}{\f509\fswiss\fcharset186\fprq2 Albertus Medium Baltic;}{\f510\fswiss\fcharset238\fprq2 Albertus Extra Bold CE;}{\f511\fswiss\fcharset204\fprq2 Albertus Extra Bold Cyr;}{\f514\fswiss\fcharset162\fprq2 Albertus Extra Bold Tur;}{\f515\fswiss\fcharset186\fprq2 Albertus Extra Bold Baltic;}{\f516\fswiss\fcharset238\fprq2 Antique Olive CE;}{\f517\fswiss\fcharset204\fprq2 Antique Olive Cyr;}{\f520\fswiss\fcharset162\fprq2 Antique Olive Tur;}{\f521\fswiss\fcharset186\fprq2 Antique Olive Baltic;}{\f522\fswiss\fcharset238\fprq2 CG Omega CE;}{\f523\fswiss\fcharset204\fprq2 CG Omega Cyr;}{\f526\fswiss\fcharset162\fprq2 CG Omega Tur;}{\f527\fswiss\fcharset186\fprq2 CG Omega Baltic;}{\f528\froman\fcharset238\fprq2 CG Times CE;}{\f529\froman\fcharset204\fprq2 CG Times Cyr;}{\f532\froman\fcharset162\fprq2 CG Times Tur;}{\f533\froman\fcharset186\fprq2 CG Times Baltic;}{\f534\froman\fcharset238\fprq2 Clarendon Condensed CE;}{\f535\froman\fcharset204\fprq2 Clarendon Condensed Cyr;}{\f538\froman\fcharset162\fprq2 Clarendon Condensed Tur;}{\f539\froman\fcharset186\fprq2 Clarendon Condensed Baltic;}{\f546\froman\fcharset238\fprq2 Garamond CE;}{\f547\froman\fcharset204\fprq2 Garamond Cyr;}{\f549\froman\fcharset161\fprq2 Garamond Greek;}{\f550\froman\fcharset162\fprq2 Garamond Tur;}{\f551\froman\fcharset186\fprq2 Garamond Baltic;}{\f552\fmodern\fcharset238\fprq1 Letter Gothic CE;}{\f553\fmodern\fcharset204\fprq1 Letter Gothic Cyr;}{\f556\fmodern\fcharset162\fprq1 Letter Gothic Tur;}{\f557\fmodern\fcharset186\fprq1 Letter Gothic Baltic;}{\f558\fscript\fcharset238\fprq2 Marigold CE;}{\f562\fscript\fcharset162\fprq2 Marigold Tur;}{\f564\fswiss\fcharset238\fprq2 Univers CE;}{\f565\fswiss\fcharset204\fprq2 Univers Cyr;}{\f568\fswiss\fcharset162\fprq2 Univers Tur;}{\f569\fswiss\fcharset186\fprq2 Univers Baltic;}{\f570\fswiss\fcharset238\fprq2 Univers Condensed CE;}{\f571\fswiss\fcharset204\fprq2 Univers Condensed Cyr;}{\f574\fswiss\fcharset162\fprq2 Univers Condensed Tur;}{\f575\fswiss\fcharset186\fprq2 Univers Condensed Baltic;}{\f576\fswiss\fcharset238\fprq2 Albertus CE;}{\f577\fswiss\fcharset204\fprq2 Albertus Cyr;}{\f580\fswiss\fcharset162\fprq2 Albertus Tur;}{\f581\fswiss\fcharset186\fprq2 Albertus Baltic;}{\f582\fswiss\fcharset238\fprq2 Metrostyle CE;}{\f583\fswiss\fcharset204\fprq2 Metrostyle Cyr;}{\f586\fswiss\fcharset162\fprq2 Metrostyle Tur;}{\f587\fswiss\fcharset186\fprq2 Metrostyle Baltic;}{\f588\fswiss\fcharset238\fprq2 Metrostyle Extended CE;}{\f589\fswiss\fcharset204\fprq2 Metrostyle Extended Cyr;}{\f592\fswiss\fcharset162\fprq2 Metrostyle Extended Tur;}{\f593\fswiss\fcharset186\fprq2 Metrostyle Extended Baltic;}{\f594\froman\fcharset238\fprq2 Ozzie Black CE;}{\f595\froman\fcharset204\fprq2 Ozzie Black Cyr;}{\f598\froman\fcharset162\fprq2 Ozzie Black Tur;}{\f599\froman\fcharset186\fprq2 Ozzie Black Baltic;}{\f624\fnil\fcharset238\fprq2 USPS Bar Code CE;}{\f628\fnil\fcharset162\fprq2 USPS Bar Code Tur;}{\f762\fnil\fcharset238\fprq2 Andes CE;}{\f766\fnil\fcharset162\fprq2 Andes Tur;}{\f774\fnil\fcharset238\fprq2 BlackChancery CE;}{\f778\fnil\fcharset162\fprq2 BlackChancery Tur;}{\f798\fswiss\fcharset238\fprq2 Arial Narrow CE;}{\f799\fswiss\fcharset204\fprq2 Arial Narrow Cyr;}{\f801\fswiss\fcharset161\fprq2 Arial Narrow Greek;}{\f802\fswiss\fcharset162\fprq2 Arial Narrow Tur;}{\f803\fswiss\fcharset186\fprq2 Arial Narrow Baltic;}{\f804\fswiss\fcharset238\fprq2 Arial Black CE;}{\f805\fswiss\fcharset204\fprq2 Arial Black Cyr;}{\f807\fswiss\fcharset161\fprq2 Arial Black Greek;}{\f808\fswiss\fcharset162\fprq2 Arial Black Tur;}{\f809\fswiss\fcharset186\fprq2 Arial Black Baltic;}{\f810\froman\fcharset238\fprq2 Bookman Old Style CE;}{\f811\froman\fcharset204\fprq2 Bookman Old Style Cyr;}{\f813\froman\fcharset161\fprq2 Bookman Old Style Greek;}{\f814\froman\fcharset162\fprq2 Bookman Old Style Tur;}{\f815\froman\fcharset186\fprq2 Bookman Old Style Baltic;}{\f822\fswiss\fcharset238\fprq2 Impact CE;}{\f823\fswiss\fcharset204\fprq2 Impact Cyr;}{\f825\fswiss\fcharset161\fprq2 Impact Greek;}{\f826\fswiss\fcharset162\fprq2 Impact Tur;}{\f827\fswiss\fcharset186\fprq2 Impact Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\nowidctlpar\widctlpar\adjustright \f12\cgrid \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \b\cgrid \sbasedon0 \snext0 toc 1;}{\s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright \f12\cgrid \sbasedon0 \snext16 footer;}{\s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright \f12\cgrid \sbasedon0 \snext17 header;}{\s18\li720\nowidctlpar\widctlpar\adjustright \f12\cgrid \sbasedon0 \snext18 Indented;}{\s19\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \cgrid \sbasedon0 \snext0 toc 2;}{\s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid \sbasedon0 \snext20 chap head;}{\s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid \sbasedon20 \snext21 subchap;}{\s22\li480\nowidctlpar\widctlpar\tqr\tldot\tx10080\adjustright \i\fs20\cgrid \sbasedon0 \snext0 toc 3;}{\s23\li720\nowidctlpar\widctlpar\tqr\tldot\tx10080\adjustright \fs18\cgrid \sbasedon0 \snext0 toc 4;}{\s24\li960\nowidctlpar\widctlpar\tqr\tldot\tx10080\adjustright \fs18\cgrid \sbasedon0 \snext0 toc 5;}{\s25\li1200\nowidctlpar\widctlpar\tqr\tldot\tx10080\adjustright \fs18\cgrid \sbasedon0 \snext0 toc 6;}{\s26\li1440\nowidctlpar\widctlpar\tqr\tldot\tx10080\adjustright \fs18\cgrid \sbasedon0 \snext0 toc 7;}{\s27\li1680\nowidctlpar\widctlpar\tqr\tldot\tx10080\adjustright \fs18\cgrid \sbasedon0 \snext0 toc 8;}{\s28\li1920\nowidctlpar\widctlpar\tqr\tldot\tx10080\adjustright \fs18\cgrid \sbasedon0 \snext0 toc 9;}{\s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid \sbasedon0 \snext0 index 1;}{\s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \lang1024\cgrid \sbasedon0 \snext30 TOC 1a;}{\s31\fi-240\li480\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid \sbasedon0 \snext0 index 2;}{\s32\fi-240\li720\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid \sbasedon0 \snext0 index 3;}{\s33\fi-240\li960\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid \sbasedon0 \snext0 index 4;}{\s34\fi-240\li1200\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid \sbasedon0 \snext0 index 5;}{\s35\fi-240\li1440\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid \sbasedon0 \snext0 index 6;}{\s36\fi-240\li1680\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid \sbasedon0 \snext0 index 7;}{\s37\fi-240\li1920\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid \sbasedon0 \snext0 index 8;}{\s38\fi-240\li2160\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid \sbasedon0 \snext0 index 9;}{\s39\li140\sb240\sa120\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid \sbasedon0 \snext29 index heading;}}{\*\revtbl {Unknown;}}{\info{\title GNO Kernel Reference Manual}{\author Lisa K Holsberg}{\operator Lisa K Holsberg}{\creatim\yr1997\mo8\dy27\hr16\min8}{\revtim\yr1997\mo8\dy27\hr16\min8}{\printim\yr1996\mo8\dy7\hr23\min22}{\version2}{\edmins0}{\nofpages14}{\nofwords15715}{\nofchars89578}{\*\company Promethean Enterprises}{\nofcharsws110008}{\vern71}}\margl1080\margr1080\margb720 \facingp\widowctrl\ftnbj\aenddoc\hyphhotz0\margmirror\sprstsp\otblrul\brkfrm\sprstsm\truncex\nolead\msmcap\lytprtmet\hyphcaps0\viewkind1\viewscale90\pgbrdrhead\pgbrdrfoot \fet0\sectd \pgnrestart\linex0\endnhere\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \nowidctlpar\widctlpar\adjustright \f12\cgrid {
\par }\pard \nowidctlpar\widctlpar\adjustright {
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par }\pard \ri-1440\nowidctlpar\widctlpar\adjustright {
\par }\pard \nowidctlpar\widctlpar\adjustright {
\par
\par
\par
\par
\par
\par
\par
\par
\par
\par }\pard \qr\nowidctlpar\widctlpar\adjustright {\b\f4\fs76 GNO Kernel Reference Manual
\par }\pard \qr\nowidctlpar\widctlpar\adjustright {\f4\fs36 By Jawaid Bazyar
\par Edited by Andrew Roughan}{\f4\fs36
\par }\pard \nowidctlpar\widctlpar\adjustright {\f4\fs36 \page \page }{\f4\fs48 Table of Contents
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }\pard\plain \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \b\cgrid {
\par }{\field\fldedit{\*\fldinst {\f4 TOC \\f }}{\fldrslt {\lang1024 Chapter 1\tab Introducing the GNO Kernel\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074581 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074581 }}{\fldrslt {\lang1024 5}}}}}{\lang1024
\par }\pard \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright {\lang1024 Chapter 2\tab GNO/ME Compliance\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074582 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074582 }}{\fldrslt {\lang1024 7}}}}}{\lang1024
\par }\pard\plain \s19\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \cgrid {\lang1024 \tab Detecting the GNO Environment\tab }{\field\flddirty{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074583 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074583 }}{\fldrslt {\lang1024 7}}}}}{\lang1024
\par }\pard \s19\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright {\lang1024 \tab Terminal I/O\tab }{\field\flddirty{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074584 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074584 }}{\fldrslt {\lang1024 7}}}}}{\lang1024
\par \tab Stack Usage\tab }{\field\flddirty{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074585 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074585 }}{\fldrslt {\lang1024 8}}}}}{\lang1024
\par \tab Disk I/O\tab }{\field\flddirty{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074586 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074586 }}{\fldrslt {\lang1024 9}}}}}{\lang1024
\par \tab Non-Compliant Applications\tab }{\field\flddirty{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074587 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074587 }}{\fldrslt {\lang1024 9}}}}}{\lang1024
\par }\pard\plain \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \b\cgrid {\lang1024 Chapter 3\tab Modifications to GS/OS\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074588 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074588 }}{\fldrslt {\lang1024 11}}}}}{\lang1024
\par }\pard\plain \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \lang1024\cgrid {\tab Mutual Exclusion in GS/OS and ToolBox calls\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074589 }{\field{\*\fldinst { PAGEREF _Toc364074589 }}{\fldrslt {11}}}}}{
\par }\pard \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright {\tab Pathnames and Prefixes\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074590 }{\field{\*\fldinst { PAGEREF _Toc364074590 }}{\fldrslt {11}}}}}{
\par \tab Named prefixes\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074591 }{\field{\*\fldinst { PAGEREF _Toc364074591 }}{\fldrslt {12}}}}}{
\par \tab Open File Tracking\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074592 }{\field{\*\fldinst { PAGEREF _Toc364074592 }}{\fldrslt {12}}}}}{
\par \tab Refnums and file descriptors\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074593 }{\field{\*\fldinst { PAGEREF _Toc364074593 }}{\fldrslt {13}}}}}{
\par \tab GNO/ME Character Devices\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074594 }{\field{\*\fldinst { PAGEREF _Toc364074594 }}{\fldrslt {13}}}}}{
\par \tab Restartability\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074595 }{\field{\*\fldinst { PAGEREF _Toc364074595 }}{\fldrslt {14}}}}}{
\par \tab Miscellaneous\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074596 }{\field{\*\fldinst { PAGEREF _Toc364074596 }}{\fldrslt {15}}}}}{
\par }\pard\plain \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \b\cgrid {\lang1024 Chapter 4\tab Modifications to the ToolBox\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074597 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074597 }}{\fldrslt {\lang1024 17}}}}}{\lang1024
\par }\pard\plain \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \lang1024\cgrid {\tab TextTools Replacement\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074598 }{\field{\*\fldinst { PAGEREF _Toc364074598 }}{\fldrslt {17}}}}}{
\par }\pard \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright {\tab SysFailMgr ($1503)\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074599 }{\field{\*\fldinst { PAGEREF _Toc364074599 }}{\fldrslt {19}}}}}{
\par \tab The Resource Manager\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074600 }{\field{\*\fldinst { PAGEREF _Toc364074600 }}{\fldrslt {20}}}}}{
\par \tab The Control Panel\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074601 }{\field{\*\fldinst { PAGEREF _Toc364074601 }}{\fldrslt {20}}}}}{
\par \tab QDStartup($0204)\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074602 }{\field{\*\fldinst { PAGEREF _Toc364074602 }}{\fldrslt {21}}}}}{
\par }\pard\plain \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \b\cgrid {\lang1024 Chapter 5\tab Process Management\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074603 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074603 }}{\fldrslt {\lang1024 23}}}}}{\lang1024
\par }\pard\plain \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \lang1024\cgrid {\tab Process Table\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074604 }{\field{\*\fldinst { PAGEREF _Toc364074604 }}{\fldrslt {24}}}}}{
\par }\pard \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright {\tab Task Switching\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074605 }{\field{\*\fldinst { PAGEREF _Toc364074605 }}{\fldrslt {25}}}}}{
\par }\pard\plain \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \b\cgrid {\lang1024 Chapter 6\tab Interprocess Communication\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074606 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074606 }}{\fldrslt {\lang1024 27}}}}}{\lang1024
\par }\pard\plain \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \lang1024\cgrid {\tab Semaphores\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074607 }{\field{\*\fldinst { PAGEREF _Toc364074607 }}{\fldrslt {27}}}}}{
\par }\pard \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright {\tab Signals\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074608 }{\field{\*\fldinst { PAGEREF _Toc364074608 }}{\fldrslt {28}}}}}{
\par \tab Pipes\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074609 }{\field{\*\fldinst { PAGEREF _Toc364074609 }}{\fldrslt {30}}}}}{
\par \tab Messages\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074610 }{\field{\*\fldinst { PAGEREF _Toc364074610 }}{\fldrslt {32}}}}}{
\par \tab Ports\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074611 }{\field{\*\fldinst { PAGEREF _Toc364074611 }}{\fldrslt {32}}}}}{
\par \tab Pseudo-Terminals (PTYs)\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074612 }{\field{\*\fldinst { PAGEREF _Toc364074612 }}{\fldrslt {33}}}}}{
\par \tab Deadlock\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074613 }{\field{\*\fldinst { PAGEREF _Toc364074613 }}{\fldrslt {35}}}}}{
\par }\pard\plain \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \b\cgrid {\lang1024 Appendix A\tab Making System Calls\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074614 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074614 }}{\fldrslt {\lang1024 37}}}}}{\lang1024
\par }\pard\plain \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \lang1024\cgrid {\tab System Call Interface\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074615 }{\field{\*\fldinst { PAGEREF _Toc364074615 }}{\fldrslt {37}}}}}{
\par }\pard \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright {\tab System Call Error Codes\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074616 }{\field{\*\fldinst { PAGEREF _Toc364074616 }}{\fldrslt {38}}}}}{
\par \tab System Panics\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074617 }{\field{\*\fldinst { PAGEREF _Toc364074617 }}{\fldrslt {39}}}}}{
\par }\pard\plain \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \b\cgrid {\lang1024 Appendix B\tab Miscellaneous Programming Issues\tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074618 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074618 }}{\fldrslt {\lang1024 40}}}}}{\lang1024
\par }\pard\plain \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \lang1024\cgrid {\tab Option Arguments\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074619 }{\field{\*\fldinst { PAGEREF _Toc364074619 }}{\fldrslt {40}}}}}{
\par }\pard \s30\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright {\tab Pathname Expansion\tab }{\field\flddirty{\*\fldinst { GOTOBUTTON _Toc364074620 }{\field{\*\fldinst { PAGEREF _Toc364074620 }}{\fldrslt {40}}}}}{
\par }\pard\plain \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \b\cgrid {\lang1024 Glossary\tab \tab }{\field{\*\fldinst {\lang1024 GOTOBUTTON _Toc364074621 }{\field{\*\fldinst {\lang1024 PAGEREF _Toc364074621 }}{\fldrslt {\lang1024 41}}}}}{\lang1024
\par }\pard \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright {Index\tab \tab 43
\par }\pard \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright }}\pard\plain \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \b\cgrid {\f4 \page }{\b0\f4 \sect }\sectd \linex0\endnhere\sectdefaultcl {\headerl \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Introducing the GNO Kernel\tab Chapter 1
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\headerr \pard\plain \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright \f12\cgrid {
\par }}{\footerl \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerr \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }{\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid {Chapter 1
\par Introducing the GNO Kernel}{\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \v\f4\fs48\cgrid {\tc {{\*\bkmkstart _Toc364074581}Introducing the GNO Kernel{\*\bkmkend _Toc364074581}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par
\par The GNO kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO kernel}}}{\f4 is the heart of the GNO Multitasking Environment (GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 ). The GNO kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO kernel}}}{\f4 provides a layer of communication between the shell (and shell-based programs) and the operating system, GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 . The kernel handles such things as multitasking}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 multitasking}}}{\f4 , background}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 background}}}{\f4 processes, foreground}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 foreground}}}{\f4 processes and many other features that were not previously available on the Apple IIGS. It is these features which make GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 very powerful.
\par }\pard \nowidctlpar\widctlpar\adjustright {
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 This reference manual is highly technical in nature and is provided to help programmers develop utilities for the GNO Multitasking Environment. The beginner has no need to read this manual and is certainly not expected to understand its contents. However, Chapter 5 }{\b\f4 Process Management}{\f4 and Chapter 6 }{\b\f4 Interprocess Communication}{\f4 provide a good background discussion for anyone who is interested in the internal workings of the kernel.}{
\par }\pard \nowidctlpar\widctlpar\adjustright {\page
\par
\par
\par }{\fs10 (We're sorry, but you did pay 1 cent extra for this blank page)
\par }\pard\plain \s15\nowidctlpar\widctlpar\tx2160\tqr\tldot\tx10080\adjustright \b\cgrid {\sect }\sectd \linex0\endnhere\titlepg\sectdefaultcl {\headerl \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul GNO/ME Compliance\tab Chapter 2}{\f5\ul
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\headerr \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Chapter }{\f5\ul 2}{\f5\ul \tab }{\f5\ul GNO/ME Compliance}{\f5\ul
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerl \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerr \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerf \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid {Chapter 2
\par }\pard \s20\qj\nowidctlpar\widctlpar\adjustright {GNO/ME Compliance}{\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \v\f4\fs48\cgrid {\tc {{\*\bkmkstart _Toc364074582}GNO/ME Compliance{\*\bkmkend _Toc364074582}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par
\par For a program to work effectively under GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 , certain rules must be followed. Most of these rules boil down to one underlying concept - }{\b\f4 never directly access features of the machine}{\f4 . Always use GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 , the ToolBox}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ToolBox}}}{\f4 , or GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 to accomplish what you need. We have taken great care to provide the sorts of services you might need, such as checking for input without having to wait for it. GNO/ME compliance}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME compliance}}}{\f4 isn't just a matter of trying to make applications work well under the environment; it ensures that those applications stay compatible, no matter what changes the system goes through. Below are summarized the points you must consider when you're writing a GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 compliant application.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Detecting the GNO Environment}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074583}Detecting the GNO Environment{\*\bkmkend _Toc364074583}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 If your application requires the GNO Kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO Kernel}}}{\f4 to be active (if it makes any kernel calls), you can make sure of this by making a }{\b\f4 kernStatus}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 kernStatus}}}{\f4 call at the beginning of your program. The call will return no error if the kernel is active, or it will return an error code of $0001 (Tool locator}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Tool locator}}}{\f4 - tool not found), in which case the value returned will be invalid. The call actually returns a 1 if no error occurs, but the value returned will be indeterminate if the kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 kernel}}}{\f4 is not active, so you should only check for an error (the function }{\b\f4 toolerror}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 toolerror}}}{\f4 () or the variable }{\b\f4 _toolErr}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 _toolErr}}}{\f4 in C, the value in the A register in assembly).
\par
\par You can also determine the current version of the GNO Kernel }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO Kernel }}}{\f4 by making the }{\b\f4 kernVersion}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 kernVersion}}}{\f4 call. The format of the version number returned is the same as the standard ToolBox}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ToolBox}}}{\f4 calls. For example a return value of $0201 indicates a version of 2.1.
\par
\par }{\b\f4 kernStatus}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 kernStatus}}}{\f4 and }{\b\f4 kernVersion}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 kernVersion}}}{\f4 are defined in the }{\f6 <gno/gno.h}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 gno.h}}}{\f6 >}{\f4 header file.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Terminal I/O}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074584}Terminal I/O{\*\bkmkend _Toc364074584}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 The Apple II has always been lacking in standardized methods for reading keyboard input and controlling the text screen. This problem was compounded when Apple stopped supporting the TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 in favor of the GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 console driver}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 console driver}}}{\f4 . The console driver}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 console driver}}}{\f4 has a number of problems that prevent it from being a good solution under GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 . There is high overhead involved in using it. It is generally accessed like a regular file, which means any I/O}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O}}}{\f4 on it must filter through several layers before being handled. Even though in System 6.0.1}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 System 6.0.1}}}{\f4 there is a provision for patching the low-level routines the special high-level user input features of the driver cannot be used over a modem}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 modem}}}{\f4 or in a desktop}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 desktop}}}{\f4 program. And GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 must be called to access it, which means that while a console driver}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 console driver}}}{\f4 access is occurring, no other processes can execute. See Chapter 3 }{\b\f4 Mutual Exclusion in GS/OS and ToolBox calls}{\f4 .
\par
\par GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 ignores the GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 '}{\f6 .CONSOLE}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 .CONSOLE}}}{\f6 '}{\f4 driver and replaces the TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 with a high-performance, very flexible generic terminal control system. GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 directly supports the console}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 console}}}{\f4 (keyboard and screen), as well as the serial ports}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 serial ports}}}{\f4 , as terminal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 terminal}}}{\f4 s. In order for a user program to take advantage of these features and to be GNO/ME compliant}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME compliant}}}{\f4 , you must do terminal I/O}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O}}}{\f4 only through the TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 }}}{\f4 , or through stdin}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stdin}}}{\f4 , stdout}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stdout}}}{\f4 , and stderr}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stderr}}}{\f4 (refNums 1,2, and 3 initially) via GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 . By its very nature TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 is slow, so we recommend using them only for small and simple tasks. Calls to the GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 console driver}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 console driver}}}{\f4 will not crash the system, but they will make other processes stop until the call is completed.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par You must not get input directly from the keyboard latch}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 keyboard latch}}}{\f4 (memory location }{\f6 $E0C000}{\f4 ), nor may you write directly to the screen memory}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 screen memory}}}{\f4 . GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 's terminal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 terminal}}}{\f4 I/O}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O}}}{\f4 system has been designed so you don't have to do either of these things. If you need to check for keyboard input}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 keyboard input}}}{\f4 without stopping your application, you can make the appropriate }{\b\f4 ioctl}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ioctl}}}{\f4 (2) call to do what you need.
\par
\par In the future, GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 may provide a GNO/ME-friendly version of the GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 .CONSOLE}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 .CONSOLE}}}{\f4 driver.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Stack Usage}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074585}Stack Usage{\*\bkmkend _Toc364074585}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 Stack}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Stack}}}{\f4 space is at a premium on the Apple II}{\f4\fs20 GS}{\f4 . Process stacks can only be located in Bank 0}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Bank 0}}}{\f4 - a total of 64K. This theoretical limit doesn't apply, however, as GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 and other bits of system software reserve a large chunk of this without any way to reclaim it. There is approximately 48K of usable stack}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack}}}{\f4 space. This space also has to be shared with direct page}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 direct page}}}{\f4 space for Tools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Tools}}}{\f4 and certain types of device drivers}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 device drivers}}}{\f4 , however. For a program to be GNO compliant}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO compliant}}}{\f4 , stack}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack}}}{\f4 usage analysis must be done and acted upon. Use of the stack}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack}}}{\f4 should be minimized so that many processes can coexist peacefully. From experience we've found that 1K usually suffices for well-written C applications, and at a maximum 4K can be allocated.
\par
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 Assembly}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Assembly}}}{\f4 language programs tend to be very efficient when it comes to use of the stack. The 4K provided by default to applications is usually more than enough for assembly}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 assembly}}}{\f4 language programs. C programs can use up tremendous amounts of stack}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack}}}{\f4 space, especially if recursion}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 recursion}}}{\f4 is employed or string manipulation}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 string manipulation}}}{\f4 is done without concern for stack}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack}}}{\f4 usage; however, even assembly}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 assembly}}}{\f4 programs can be written poorly and use a lot of stack}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack}}}{\f4 space. Below are some hints to keep stack}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack}}}{\f4 usage at a minimum.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }\pard \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright {\f4 \bullet \tab Avoid use of large local arrays}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 local arrays}}}{\f4 and character strings}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 character strings}}}{\f4 . Instead, dynamically allocate large structures such as GS/OS}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 strings with }{\b\f4 malloc}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 malloc}}}{\f4 () or the Memory Manager}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Memory Manager}}}{\f4 . Alternatively, you can designate such items as }{\f6 'static}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 static}}}{\f6 '}{\f4 , which causes the C compiler}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 C compiler}}}{\f4 to allocate the space for the variable}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 variable}}}{\f4 from main memory}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 main memory}}}{\f4 .
\par
\par \bullet \tab Try not to use recursion}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 recursion}}}{\f4 unless absolutely necessary. All recursive functions can be rewritten using standard loops}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 standard loops}}}{\f4 and creative programming}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 creative programming}}}{\f4 . This is a good general programming rule because your program will run faster because setting up stack frames}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack frames}}}{\f4 is expensive in terms of time and memory.
\par
\par \bullet \tab ORCA/C 1.3}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA/C 1.3}}}{\f4 (and older) generates 8K of stack}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack}}}{\f4 by default, in case the desktop is started up. Since GNO/ME compliant}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME compliant}}}{\f4 programs generally will not be desktop}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 desktop}}}{\f4 -based, make sure you judge how much stack your program will require and use the }{\f6 #pragma stacksize}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 }{\txe pragma stacksize}}}{\f4 directive to limit how much stack space ORCA/C}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA/C}}}{\f4 tries to allocate for your program. Also, since ORCA/C}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA/C}}}{\f4 programs don't use the stack given them by GNO/ME}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 and GS/OS}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 , when you link your program include a small (256 bytes) stack segment}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack segment}}}{\f4 . See the utilities sources for examples of this. ORCA/C 2.0}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA/C 2.0}}}{\f4 allocates stack via the GS/OS}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 supported method, so ORCA/C 2.0}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA/C 2.0}}}{\f4 programs use exactly the amount of stack specified by }{\f6 #pragma stacksize}{\pard\plain \qj\fi-720\li900\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 }{\txe pragma stacksize}}}{\f4 .
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {\b\f4 }{\f4 {\*\bkmkstart _Toc364074586}.i.Disk I/O{\*\bkmkend _Toc364074586}\tcl1}}}{\f4 Since the Apple IIgs doesn't have coprocessors to manage disk access}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 disk access}}}{\f4 and the serial ports}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 serial ports}}}{\f4 , either of these requires the complete attention of the main 65816 processor}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 65816 processor}}}{\f4 . This can wreak havoc in an environment with slow disks or high-speed serial links, as accessing disks usually results in turning off interrupts for the duration of the access. This situation is lessened considerably with a DMA}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 DMA}}}{\f4 disk controller, such as the Apple High Speed SCSI or CV Technologies RamFAST. But this isn't as bad as it sounds; the IBM PC and Apple Macintosh also suffer from this problem, and the solution is robust programming. Make sure your communications protocol can handle errors where expected data doesn't arrive quite on time, or in full. The best solution would be an add-on card with serial ports}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 serial ports}}}{\f4 and an on-board processor to make sure all serial data was received whether or not the main processor was busy (this is a hint to some enterprising hardware hacker, by the way).
\par
\par Yet another concern for GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 applications is file sharing. GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 provides support for file sharing}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 file sharing}}}{\f4 , but it is up to the application author to use it via the requestAccess}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 requestAccess}}}{\f4 field in the }{\f6 OpenGS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 OpenGS}}}{\f4 call. GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 only allows file sharing}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 file sharing}}}{\f4 if all current references to a file (other instances of the file being opened) are read-only. GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 authors should use read-only access as much as possible. For example, an editor doesn't need write permission when it's initially reading in a file. Note that the }{\b\f4 fopen}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fopen}}}{\f4 () library routine in ORCA/C 1.2}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA/C 1.2}}}{\f4 does NOT support read-only mode (even if you open the file with a 'r' specificier), but it does in ORCA/C 1.3}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA/C 1.3}}}{\f4 and later.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Non-Compliant Applications}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074587}Non-Compliant Applications{\*\bkmkend _Toc364074587}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 wasn't really designed with the intention of making EVERY program you currently run work under GNO/ME; that task would have been impossible. Our main goal was to provide a UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 -based multitasking environment; that we have done. We made sure as many existing applications as we had time to track and debug worked with GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 . The current list of compatible and non-compatible applications can be found in the file "RELEASE.NOTES}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 RELEASE.NOTES}}}{\f4 " on the GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 disk.
\par
\par However, due to the sheer number of applications and authors, there are some programs that just plain don't work; and some that mostly work, except for annoyances such as two cursors appearing, or keyboard characters getting 'lost'. The problem here is that some programs use their own text drivers (since TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 output was very slow at one time); since GNO/ME doesn't know about these custom drivers, it goes on buffering keyboard characters and displaying the cursor. There is a way, however, to tell GNO/ME about these programs that break GNO/ME's rules.
\par
\par We've defined an auxType}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 auxType}}}{\f4 for S16}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 S16}}}{\f4 and EXE}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EXE}}}{\f4 files, to allow distinction between programs that are GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 compliant and those that are not. Setting the auxType}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 auxType}}}{\f4 of an application to $DC00 disables the interrupt driven keyboard buffering and turns off the GNO/ME cursor. Desktop}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Desktop}}}{\f4 programs use the GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 keyboard I/O}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O}}}{\f4 via the Event Manager}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Event Manager}}}{\f4 , and thus should }{\i\f4 not}{\f4 have their auxType}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 auxType}}}{\f4 changed.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par You can change a program's auxType}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 auxType}}}{\f4 with the following shell command:
\par
\par }{\f6 \tab chtyp}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 chtyp}}}{\f6 -a \\$DC00 filename}{\f4
\par
\par where filename is the name of the application. As more programmers become aware of GNO/ME and work to make their software compatible with it, this will become less of a problem, but for older applications that are unlikely to ever change (like the America OnLine software) $DC00 is a reasonable approach.
\par }{\f4 \sect }\sectd \psz1\linex0\endnhere\titlepg\sectdefaultcl {\headerl \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Modifications to GS/OS\tab Chapter 3}{\f5\ul
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\headerr \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Chapter }{\f5\ul 3}{\f5\ul \tab }{\f5\ul Modifications to GS/OS}{\f5\ul
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid {Chapter 3
\par }\pard \s20\qj\nowidctlpar\widctlpar\adjustright {Modifications to GS/OS}{\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \v\f4\fs48\cgrid {\tc {{\*\bkmkstart _Toc364074588}Modifications to GS/OS{\*\bkmkend _Toc364074588}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par
\par The GNO system modifies the behavior of a number of GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 s in order to allow many programs to execute concurrently, and to effect new features. The changes are done in such a way that old software can take advantage of these new features without modification. Following is a complete description of all the changes made. Each section has details in text, followed by a list of the specific GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 or ToolBox}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ToolBox}}}{\f4 calls affected.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Mutual Exclusion in GS/OS and ToolBox calls}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074589}Mutual Exclusion in GS/OS and ToolBox calls{\*\bkmkend _Toc364074589}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 The Apple IIGS was not designed as a multitasking}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 multitasking}}}{\f4 machine, and GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 and the Toolbox}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Toolbox}}}{\f4 reflect this in their design. The most notable problem with making multitasking}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 multitasking}}}{\f4 work on the Apple IIgs is the use of global (common to all processes) information, such as prefixes}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 prefixes}}}{\f4 and direct page}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 direct page}}}{\f4 space for tool sets which includes information like SANE}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SANE}}}{\f4 results, QuickDraw}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 QuickDraw}}}{\f4 drawing information, etc. In most cases we've corrected these deficiencies by keeping track of such information on a per-process basis, that is, each process has its own copy of the information and changes to it do not affect any other process' information.
\par
\par However, there were many other situations where this could not be done. Therefore, there is a limit of one process at a time inside either GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 or the ToolBox}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ToolBox}}}{\f4 . GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 automatically enforces this restriction whenever a tool or GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 is made.
\par
\par The method and details of making GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 s does not change! The calls listed below have been expanded transparently. There are no new parameters and no new parameter values. In all cases, the corresponding ProDOS-16}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ProDOS-16}}}{\f4 interface calls are also supported, except ExpandPath}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ExpandPath}}}{\f4 and other calls which do not exist in ProDOS-16}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ProDOS-16}}}{\f4 .
\par
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Pathnames and Prefixes}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074590}Pathnames and Prefixes{\*\bkmkend _Toc364074590}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 Normally under GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 there are 32 prefixes}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 prefixes}}}{\f4 , and these are all under control of the current application. GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 extends this concept to provide each process with it's own copies of all prefixes. When a process modifies one of these prefixes via the GS/OS SetPrefix}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SetPrefix}}}{\f4 call, it modifies only it's own copy of that prefix- the same numbered prefixes of any other processes are not modified.
\par
\par Pathname processing has been expanded in GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 . There are now two new special pathname operators that are accepted by any GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 that takes a pathname parameter:
\par }{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\b\f6 .}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\b\f6 .}}}{\tab }{\f4 current working directory
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\b\f6 ..}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\b\f6 ..}}}{\tab }{\f4 parent directory
\par
\par For example, presume that the current working directory (prefix 0) is }{\f6 /foo/bar/moe}{\f4 . "}{\f6 ./ls}{"}{\f4 refers to the file "}{\f6 /foo/bar/moe/ls}{\f4 ", and since a pathname was specified, this overrides the shell's hash table. "}{\f6 ../ls}{\f4 " refers to "}{\f6 /foo/bar/ls}{\f4 ". The operators can be combined, also, as in "}{\f6 ../../ls}{\f4 " ("}{\f6 /foo/ls}{\f4 "), "}{\f6 ./.././ls}{\f4 " ("}{\f6 /foo/bar/ls}{\f4 "). As you can see, the '.' operator is simply removed and has no effect other than to force a full expansion of the pathname.
\par
\par Shorthand device names (.d2}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 .d2}}}{\f4 , .d5}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 .d5}}}{\f4 , etc) as in ORCA}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA}}}{\f4 are available only under System Software 6.0 and later. The common pathname operator '}{\b\f4 ~}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ~}}}{\f4 ' (meaning the home directory) is handled by the shell; if the character appears in a GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 it is not treated specially.}{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {
\par }{\f6 \tab $2004 ChangePath}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 ChangePath}}}{\f6 \tab \tab $2006 GetFileInfo}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 GetFileInfo}}}{\f6
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6 \tab $200B ClearBackupBit}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 ClearBackupBit}}}{\f6 \tab $200A GetPrefix}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 GetPrefix}}}{\f6
\par \tab $2001 Create}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 Create}}}{\f6 \tab \tab \tab $2010 Open}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 Open}}}{\f6
\par \tab $2002 Destroy}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 Destroy}}}{\f6 \tab \tab \tab $2005 SetFileInfo}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 SetFileInfo}}}{\f6
\par \tab $200E ExpandPath}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 ExpandPath}}}{\f6 \tab \tab $2009 SetPrefix}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 SetPrefix}}}{\f6
\par }{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\b\f4
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Named prefixes}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074591}Named prefixes{\*\bkmkend _Toc364074591}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 In order to allow easy installation and configuration of third-party software into all systems, GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 provides a feature called named prefixes. These prefixes are defined in the /etc/namespace}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 /etc/namespace}}}{\f4 file. Basically, since all UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 systems have /bin}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 /bin}}}{\f4 , /usr}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 /usr}}}{\f4 , /etc}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 /etc}}}{\f4 , and other similar standard partitions, but Apple IIgs systems generally do not have these partitions, named prefixes provide a way to simulate the UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 directories without forcing GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 users to rename their partitions (an arduous and problem-filled task).
\par
\par Named prefixes are handled by the GNO kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO kernel}}}{\f4 in the same GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 s described in Chapter 3 }{\b\f4 Pathnames and Prefixes}{\f4 .
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Open File Tracking}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074592}Open File Tracking{\*\bkmkend _Toc364074592}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 Previously, a major problem with the way GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 handled open files was that unrelated programs could affect each other's open files. For example, a Desk Accessory (or a background program of any sort) could open a file and have it closed without it's knowledge by the main application program. This presented all kinds of problems for desk accessory authors. Apple presented a partial solution with System Software 5.0.4}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 System Software 5.0.4}}}{\f4 , but it wasn't enough for a true multitasking}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 multitasking}}}{\f4 environment. GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 keeps track of exactly which process opened which file. It also discontinues the concept of a global File Level}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 File Level}}}{\f4 , opting instead for a per-process File Level}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 File Level}}}{\f4 . Any operations a process performs on a file (opening, closing, etc.) do not affect any other process' files.
\par
\par In addition to this behavior, when a process terminates in any manner all files that it currently has opened will be closed automatically. This prevents problems of the sort where a program under development terminates abnormally, often leaving files open and formerly necessitating a reboot.
\par
\par The Flush}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Flush}}}{\f4 GS/OS call is not modified in this manner as its effects are basically harmless.
\par The Close}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Close}}}{\f4 call accepts a refNum}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 refNum}}}{\f4 parameter of 0 (zero), to close all open files. This works the same way under GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 , except of course that only the files of the process calling Close}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Close}}}{\f4 are in fact closed.
\par }{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6 \tab $2010 Open}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 Open}}}{\f6
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6 \tab $2014 Close}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 Close}}}{\f6
\par \tab $201B GetLevel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 GetLevel}}}{\f6
\par \tab $201A SetLevel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 SetLevel}}}{\f6
\par }{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\tc {\v\f4 }{\f4 \tcl1}}}{\f4
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Quitting applications
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 The QUIT}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 QUIT}}}{\f4 and QuitGS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 QuitGS}}}{\f4 calls have been modified to support the GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 process scheme. Quitting to another application, whether by specifying a pathname or by popping the return stack, is accomplished with }{\b\f4 execve}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 execve}}}{\f4 (2). When there are no entries on the return stack, the process is simply killed. See the }{\i\f4 GS/OS Reference Manual}{\f4 for more details on how the Quit stack works.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Refnums and file descriptors}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074593}Refnums and file descriptors{\*\bkmkend _Toc364074593}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 tells you about open files in the form of refNum}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 refNum}}}{\f4 s (reference numbers). UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 's term for the same concept is 'file descriptor}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 file descriptor}}}{\f4 '. From a user's or programmer's view of GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 , these terms are identical and will be used as such; which one depends on what seems most appropriate in context.
\par
\par For each process, GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 keeps track of which files that particular process has opened. No other process can directly access a file that another process opened (unless programmed explicitly), because it doesn't have access to any file descriptors other than its own. This is different from GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 in that GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 allows access to a file even if a program guessed the refNum}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 refNum}}}{\f4 , either deliberately or accidentally. This is one of the aspects of process protection in GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 .
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par All of the various I/O}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O}}}{\f4 mechanisms that GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 supports (file}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 file}}}{\f4 s, pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipe}}}{\f4 s, and TTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TTY}}}{\f4 s) are handled with the same GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 s you are familiar with. When you create a pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipe}}}{\f4 , for example, you are returned file descriptors which, because of synonymity with refNum}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 refNum}}}{\f4 s, you can use in GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 s. Not all GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 s that deal with files are applicable to a particular file descriptor; these are detailed in the sections on pipes and TTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TTY}}}{\f4 s.
\par
\par GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 sets no limit on the number of files a process may have open at one time. (Most UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 's have a set limit at 32).
\par }{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {GNO/ME Character Devices}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074594}GNO/ME Character Devices{\*\bkmkend _Toc364074594}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 supports a new range of character device}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 character device}}}{\f4 drivers. These drivers are not installed like normal GS/OS drivers}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS drivers}}}{\f4 , but they are accessed the same way. There are the following built-in drivers:
\par }{
\par }\pard \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright {\f6 .TTYCO}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 .TTYCO}}}{\tab }{\f4 This is the GNO/ME}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 console driver}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 console driver}}}{\f4 . The driver supports the TextTools}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 Pascal control codes}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Pascal control codes}}}{\f4 , plus a few GNO/ME}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 -specific ones. These are documented in Chapter 4 }{\b\f4 TextTools Replacement}{\f4 . This driver is highly optimized both through the GS/OS}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 and TextTools}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 interfaces.
\par }\pard \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright {\f6 .TTYA[0-9,A-F]}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 .TTYA[0-9,A-F]}}}{\f4
\par }{\f6 .PTYQ[0-9,A-F]}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 .PTYQ[0-9,A-F]}}}{
\par }\pard \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright {\tab }{\f4 Pseudo-terminal devices; PTY}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 s are used for interprocess communication and in network activities.
\par }\pard \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright {\f6 .NULL}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 .NULL}}}{\tab }{\f4 This driver is a bit bucket. Any data written to it is ignored, and any attempt to read from it results in an end-of-file error ($4C).}{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {
\par }{\f4 Just as with GS/OS device}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS device}}}{\f4 s, these GNO/ME drivers}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME drivers}}}{\f4 are accessed with the same Open}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Open}}}{\f4 , Read}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Read}}}{\f4 , Write}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Write}}}{\f4 , and Close}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Close}}}{\f4 calls that are used on files. Unlike GS/OS character devices}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 character devices}}}{\f4 , the characteristics of GNO/ME drivers}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME drivers}}}{\f4 are controlled through the }{\b\f4 ioctl}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ioctl}}}{\f4 () system call. The GS/OS Device}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS Device}}}{\f4 calls (like DInfo}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 DInfo}}}{\f4 , DStatus}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 DStatus}}}{\f4 ) are not applicable to GNO/ME drivers}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME drivers}}}{\f4 . See the }{\b\f4 ioctl}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ioctl}}}{\f4 (2) and }{\b\f4 tty}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 tty}}}{\f4 (4) manpage for details.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par Some GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 s will return an error when given a refNum}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 refNum}}}{\f4 referring to a GNO/ME character driver or pipe because the concepts simply do not apply. The error returned will be $58 (Not a Block Device), and the calls are as follows:
\par }{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6 \tab $2016 SetMark}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SetMark}}}{\f6 \tab \tab $2017 GetMark}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 GetMark}}}{\f6
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6 \tab $2018 SetEOF}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SetEOF}}}{\f6 \tab \tab $2019 GetEOF}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 GetEOF}}}{\f6
\par \tab $2015 Flush}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 Flush}}}{\f6 \tab \tab $201C GetDirEntry}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\f6 GetDirEntry}}}{\f6
\par }{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 GNO/ME loaded drivers (generally for serial communications, but other uses are possible) are configured in the }{\f6 /etc/tty.config}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f6 /etc/tty.config}}}{\f4 file. Each line in }{\f6 /etc/tty.config}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f6 /etc/tty.config}}}{\f4 describes one driver. The format of each line is:
\par }\pard\plain \s18\qj\li720\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4 filename\tab slot\tab devname
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }{\b\f4 devname}{\f4 is the name of the device as it will be accessed (e.g. .ttya}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 .ttya}}}{\f4 ). }{\b\f4 slot}{\f4 is the slot in the device table where the device will be accessed from; it may refer to one of the physical expansion slots, as TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 will use the specified driver when redirecting output to a slot. The }{\b\f4 modem}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 modem}}}{\f4 and }{\b\f4 printer}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 printer}}}{\f4 port drivers}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 port drivers}}}{\f4 are configured for slots 2 and 1, respectively.
\par
\par Pseudo-terminals}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Pseudo-terminals}}}{\f4 are pre-configured into the kernel. PTYs are discussed further in Chapter 6 }{\b\f4 Psuedo-terminals PTYs}{\f4 .
\par
\par Since .ttyco}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 .ttyco}}}{\f4 and the pseudo-terminals}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pseudo-terminals}}}{\f4 are pre-configured in the GNO kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO kernel}}}{\f4 , entries for these devices do not appear in }{\f6 /etc/tty.config}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f6 /etc/tty.config}}}{\f4 .
\par }{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Restartability}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074595}Restartability{\*\bkmkend _Toc364074595}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 supports the concept of program 'restartability}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 restartability}}}{\f4 '. This allows programs which are written in a certain way to remain in memory in a purgeable state so that if they are invoked again, and their memory has not been purged, they can be restarted without any disk access. This greatly increases the speed with which restartable programs can be executed.
\par
\par The ORCA}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA}}}{\f4 environment specifies whether or not a program is restartable via a flag character in the SYSCMND}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SYSCMND}}}{\f4 file. The GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 standard method, however, is to set the appropriate flags bit in the GS/OS Quit}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Quit}}}{\f4 call. This is the method that GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 supports. Provided with the GNO/ME standard library is a routine }{\b\f4 rexit}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 rexit}}}{\f4 (3). }{\b\f4 rexit}{\f4 (3) only works with ORCA/C 2.0}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA/C 2.0}}}{\f4 .}{\b\f4 rexit}{\f4 (3) works just like the normal C }{\b\f4 exit}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 exit}}}{\f4 () call but it sets the restart flag when calling QuitGS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 QuitGS}}}{\f4 .
\par
\par The standard ORCA/C 1.3}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA/C 1.3}}}{\f4 libraries are not restartable, but the ORCA/C 2.0}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA/C 2.0}}}{\f4 libraries are.
\par
\par
\par }{\b\f4 Miscellaneous}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {\b\f4 {\*\bkmkstart _Toc364074596}Miscellaneous{\*\bkmkend _Toc364074596}\tcl1}}}{\f4
\par
\par The following miscellaneous GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 s have also been modified for GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 .
\par }{
\par }\pard \qj\fi-2880\li2880\nowidctlpar\widctlpar\adjustright {\f6 $2027 GetName}{\pard\plain \qj\fi-2880\li2880\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 GetName}}}{\tab }{\f4 Returns the name on disk of the process. This only returns valid information after an }{\b\f4 execve}{\pard\plain \qj\fi-2880\li2880\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 execve}}}{\f4 (2).
\par }\pard \qj\fi-2880\li2880\nowidctlpar\widctlpar\adjustright {\f6 $2003 OSShutdown}{\pard\plain \qj\fi-2880\li2880\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 OSShutdown}}}{\tab }{\f4 This call has been modified to kill all processes before performing the actual shutdown operation.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }{\page \sect }\sectd \linex0\endnhere\titlepg\sectdefaultcl {\headerl \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Modifications to the ToolBox\tab Chapter 4
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\headerr \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Chapter 4\tab Modifications to the ToolBox
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerl \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerr \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerf \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }{\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid {Chapter 4
\par }\pard \s20\qj\nowidctlpar\widctlpar\adjustright {Modifications to the ToolBox}{\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \v\f4\fs48\cgrid {\tc {{\*\bkmkstart _Toc364074597}Modifications to the ToolBox{\*\bkmkend _Toc364074597}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par
\par Several changes have been made to the ToolBox}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ToolBox}}}{\f4 , the most major of which is the replacement of the entire TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 tool set. The TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 were replaced for a number of reasons- better control over text I/O}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O}}}{\f4 , increased speed, and emulation of ORCA}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA}}}{\f4 's redirection system with as little overhead as possible. Other changes were made to modify the behavior of some tool calls to be more consistent with the idea of a multitasking}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 multitasking}}}{\f4 environment.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {TextTools Replacement}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074598}TextTools Replacement{\*\bkmkend _Toc364074598}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 The changes to the TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 have turned it into a much more powerful general I/O}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O}}}{\f4 manager. The TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 now intrinsically handle pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipe}}}{\f4 s and redirection}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 redirection}}}{\f4 , and you can install custom drivers}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 custom drivers}}}{\f4 for TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 to use. Also, the TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 have had their old slot-dependence}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 slot-dependence}}}{\f4 removed; the parameter that used to refer to 'slot' in the original texttools calls now refers to a driver number}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 driver number}}}{\f4 . A summary of driver numbers (including those that come pre-installed into GNO) are as follows:
\par
\par }\pard \qj\li720\nowidctlpar\widctlpar\adjustright {\f4 0\tab Null device driver}{\pard\plain \qj\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\f4 Null device driver}}}{\f4
\par 1\tab serial driver}{\pard\plain \qj\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 serial driver}}}{\f4 (for printer port compatibility)
\par 2\tab serial driver }{\pard\plain \qj\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 serial driver }}}{\f4 (for modem port compatibility)
\par 3\tab console driver}{\pard\plain \qj\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 console driver}}}{\f4 (Pascal-compatible 80-column text screen)
\par 4-5\tab User installed
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par See Chapter 3 }{\b\f4 GNO/ME Character Devices}{\f4 , for information on configuring these drivers.
\par
\par There are also new device types in the TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 ; the complete list of supported device types and what their slotNum}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 slotNum}}}{\f4 's (from SetInputDevice}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SetInputDevice}}}{\f4 , SetOutputDevice}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SetOutputDevice}}}{\f4 , etc) mean is as follows:
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }\pard \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright {\f4 0\tab Used to be BASIC}{\pard\plain \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 BASIC}}}{\f4 text drivers. These are no longer supported under GNO/ME}{\pard\plain \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 , and setting I/O to a basic driver actually selects a Pascal driver}{\pard\plain \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Pascal driver}}}{\f4 .
\par 1\tab Pascal text driver. This is one of the drivers specified in /etc/ttys}{\pard\plain \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 /etc/ttys}}}{\f4 or built-in to GNO/ME}{\pard\plain \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 .
\par \tab slotNum: driver number as listed above
\par }\pard \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright {\f4 2\tab RAM-based Driver (documented in }{\i\f4 ToolBox Reference Volume 2}{\f4 )
\par }\pard \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright {\f4 \tab slotNum}{\pard\plain \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 slotNum}}}{\f4 : pointer to the RAM-based driver's jump table
\par 3\tab file redirection
\par \tab slotNum}{\pard\plain \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 slotNum}}}{\f4 : refNum}{\pard\plain \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 refNum}}}{\f4 (file descriptor}{\pard\plain \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 file descriptor}}}{\f4 ) of the file to access through TextTools}{\pard\plain \qj\fi-720\li720\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\f4 TextTools}}}{\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par The new console driver}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 console driver}}}{\f4 supports all the features of the old 80-column Pascal firmware}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Pascal firmware}}}{\f4 , and adds a few extensions, with one exception - the codes that switched between 40 and 80 columns modes are not supported. It is not compatible with the GS/OS '}{\f6 .console}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 .console}}}{\f4 ' driver. The control codes supported are as follows:
\par
\par }\pard \qj\li720\nowidctlpar\widctlpar\tx1800\tx3600\adjustright {\f4\ul Hex\tab ASCII\tab Action
\par }{\f4 01\tab CTRL-A\tab set cursor to flashing block
\par 02\tab CTRL-B\tab set cursor to flashing underscore
\par 03\tab CTRL-C\tab Begin "Set Text Window" sequence
\par 05\tab CTRL-E\tab Cursor on
\par 06\tab CTRL-F\tab Cursor off
\par 07\tab CTRL-G\tab Perform FlexBeep
\par 08\tab CTRL-H\tab Move left one character
\par 09\tab CTRL-I\tab Tab
\par 0A\tab CTRL-J\tab Move down a line
\par 0B\tab CTRL-K\tab Clear to EOP (end of screen)
\par 0C\tab CTRL-L\tab Clear screen, home cursor
\par 0D\tab CTRL-M\tab Move cursor to left edge of line
\par 0E\tab CTRL-N\tab Normal text
\par 0F\tab CTRL-O\tab Inverse text
\par 11\tab CTRL-Q\tab Insert a blank line at the current cursor position
\par 12\tab CTRL-R\tab Delete the line at the current cursor position.
\par 15\tab CTRL-U\tab Move cursor right one character
\par 16\tab CTRL-V\tab Scroll display down one line
\par 17\tab CTRL-W\tab Scroll display up one line
\par 18\tab CTRL-X\tab Normal text, mousetext off
\par 19\tab CTRL-Y\tab Home cursor
\par 1A\tab CTRL-Z\tab Clear entire line
\par 1B\tab CTRL-[\tab MouseText on
\par 1C\tab CTRL-\\\tab Move cursor one character to the right
\par 1D\tab CTRL-]\tab Clear to end of line
\par 1E\tab CTRL-^\tab Goto XY
\par 1F\tab CTRL-_\tab Move up one line
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par (Note: the }{\i\f4 Apple IIgs Firmware Reference}{\f4 incorrectly has codes 05 and 06 reversed. The codes listed here are correct for both GNO/ME and the Apple IIgs 80-column firmware)
\par
\par FlexBeep}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 FlexBeep}}}{\f4 is a custom beep routine that doesn't turn off interrupts for the duration of the noise as does the default Apple IIgs beep. This means that the beep could sound funny from time to time, but it allows other processes to keep running. We also added two control codes to control what kind of cursor is used. There are two types available as in most text-based software; they are underscore for 'insert' mode, and block for 'overstrike'. You may, of course, use whichever cursor you like. For example, a communications program won't have need of insert mode, so it can leave the choice up to the user.
\par
\par The Set Text Window sequence (begun by a $03 code) works as follows:
\par
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 \tab CTRL-C '[' LEFT RIGHT TOP BOTTOM
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par CTRL-C is of course hex $03, and '[' is the open bracket character ($5B). TOP, BOTTOM, LEFT, and RIGHT are single-byte ASCII values that represent the margin settings. Values for TOP and BOTTOM range from 0 to 23; LEFT and RIGHT range from 0 to 79. TOP must be numerically less than BOTTOM; LEFT must be less than RIGHT. Any impossible settings are ignored, and defaults are used instead. The extra '[' in the sequence helps prevent the screen from becoming confused in the event that random data is printed to the screen.
\par
\par After a successful Set Text Window sequence, only the portion of the screen inside the 'window' will be accessible, and only the window will scroll; any text outside the window is not affected.
\par
\par The cursor blinks at a rate defined by the }{\b\f4 Control Panel/Options/Cursor Flash}{\f4 setting. Far left is no blinking (solid), and far right is extremely fast blinking.
\par
\par }{\f6 ReadLine}{\f4 }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 ReadLine }}}{\f4 ($240C) now sports a complete line editor unlike the old TextTools version. Following is a list of the editor commands.
\par
\par }\pard \qj\fi-2880\li3600\nowidctlpar\widctlpar\adjustright {\f4 EOL}{\pard\plain \qj\fi-2880\li3600\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EOL}}}{\f4 \tab Terminates input (EOL is a parameter to the _ReadLine call)
\par LEFT-ARROW}{\pard\plain \qj\fi-2880\li3600\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 LEFT-ARROW}}}{\f4 \tab Move cursor to the left
\par RIGHT-ARROW}{\pard\plain \qj\fi-2880\li3600\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 RIGHT-ARROW}}}{\f4 \tab Move cursor to right. Won't go past rightmost character.
\par DELETE}{\pard\plain \qj\fi-2880\li3600\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 DELETE}}}{\f4 \tab Delete the character to the left of the cursor.
\par CTRL-D}{\pard\plain \qj\fi-2880\li3600\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 CTRL-D}}}{\f4 \tab Delete character under the cursor.
\par OA-D}{\pard\plain \qj\fi-2880\li3600\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 OA-D}}}{\f4 \tab Delete character under the cursor.
\par OA-E}{\pard\plain \qj\fi-2880\li3600\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 OA-E}}}{\f4 \tab Toggles between overwrite and insert mode.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }{\f6 ReadChar}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 ReadChar}}}{\f4 ($220C) has also been changed. The character returned may now contain the key modification flags ($C025) in the upper byte and the character typed in the lower byte. This is still compatible with the old TextTools ReadChar. To get the keyMod flags, call }{\f6 SetInGlobals}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SetInGlobals}}}{\f4 ($090C) and set the upper byte of the AND mask to $FF. Typical parameters for }{\f6 SetInGlobals}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f6 SetInGlobals}}}{\f4 to get this information are: ANDmask = $FF7F, ORmask\~=\~$0000.
\par
\par The default I/O masks}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O masks}}}{\f4 have also been changed. They are now ANDmask}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ANDmask}}}{\f4 = $00FF, ORmask}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORmask}}}{\f4 = $0000. They are set this way to extend the range of data that can be sent through TextTools. GNO/ME Character drivers}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Character drivers}}}{\f4 do not, like the previous TextTools driver, require the hi-bit to be set.
\par
\par The new TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 are completely reentrant. This means that any number of processes may be executing TextTools calls at the same time, increasing system performance somewhat. The TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 are also the only toolset which is not mutexed.
\par
\par The GNO/ME console driver}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 console driver}}}{\f4 also supports flow-control in the form of Control-S and Control-Q. Control-S is used to stop screen output, and Control-Q is used to resume screen output.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {SysFailMgr ($1503)}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074599}SysFailMgr ($1503){\*\bkmkend _Toc364074599}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 The MiscTool}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 MiscTool}}}{\f4 call SysFailMgr}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SysFailMgr}}}{\f4 has been modified so that a process calling it is simply killed, instead of causing system operation to stop. This was done because many programs use SysFailMgr}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SysFailMgr}}}{\f4 when a simple error message would have sufficed. There are, however, some tool and GS/OS errors}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS errors}}}{\f4 which are truly system failure messages, and these do cause system operation to stop. These errors are as follows:
\par
\par }\pard \qj\li720\nowidctlpar\widctlpar\adjustright {\f6 $0305}{\f4 \tab \tab Damaged heartbeat queue detected
\par }{\f6 $0308}{\f4 \tab \tab Damaged heartbeat queue detected
\par }{\f6 $0681}{\f4 \tab \tab Event queue damaged
\par }{\f6 $0682}{\f4 \tab \tab Queue handle damaged
\par }{\f6 $08FF}{\f4 \tab \tab Unclaimed sound interrupt
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par What the system does after displaying the message is the same as for a system panic}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 system panic}}}{\f4 .
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {The Resource Manager}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074600}The Resource Manager{\*\bkmkend _Toc364074600}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 The Resource Manager}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Resource Manager}}}{\f4 has been modified in some subtle ways. First, GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 makes sure that the CurResourceApp}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 CurResourceApp}}}{\f4 value is always correct before a process makes a Resource Manager}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Resource Manager}}}{\f4 call. Second, all open resource}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 resource}}}{\f4 files are the property of the Kernel. When a GetOpenFileRefnum}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GetOpenFileRefnum}}}{\f4 call is made, a new refnum is }{\b\f4 dup}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 dup}}}{\f4 ()'d to allow the process to access the file. Having the Kernel control resource}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 resource}}}{\f4 files also allows all processes to share SYS.RESOURCES}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SYS.RESOURCES}}}{\f4 without requiring each process to explicitly open it.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\tc {\v\f4 }{\f4 \tcl1}}}{\f4
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {The Event Manager
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 GNO/ME starts up the Event Manager}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Event Manager}}}{\f4 so it is always available to the kernel and shell utilities. Changes were made so that the Event Manager }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Event Manager }}}{\f4 obtains keystrokes from the GNO/ME console driver}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 console driver}}}{\f4 (.ttyco}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 .ttyco}}}{\f4 ). This allows UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 -style utilities and desktop applications to share the keyboard in a cooperative manner. This also makes it possible to suspend desktop}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 desktop}}}{\f4 applications; see Chapter 7, }{\b\f4 Suspend NDA}{\f4 .
\par
\par EMStartUp sets the GNO console driver to RAW mode via an }{\b\f4 ioctl}{\f4 () call, to allow the Event Manager to get single keystrokes at a time, and to prevent users from being able to kill the desktop application with ^C or other interrupt characters. The four "GetEvent" routines, GetNextEvent, GetOSEvent, EventAvail, and OSEventAvail now poll the console for input characters instead of using an interrupt handler.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {The Control Panel}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074601}The Control Panel{\*\bkmkend _Toc364074601}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 In most cases, the CDA}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 CDA}}}{\f4 menu is executed as an interrupt handler. Since the Apple IIgs interrupt handler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 interrupt handler}}}{\f4 firmware isn't reentrant, task switching is not allowed to occur while the control panel is active. This basically means that all processes grind to a halt. In many ways, however, this is not undesirable. It definitely eases debugging, since a static system is much easier to deal with than a dynamic system. Also, CDA}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 CDA}}}{\f4 s assume they have full control of the text screen; multitasking}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 multitasking}}}{\f4 CDAs would confuse and be confused in terms of output.
\par
\par During the execution of the Control Panel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Control Panel}}}{\f4 , the original non-GNO/ME TextTools}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TextTools}}}{\f4 tool is reinstalled to prevent compatibility problems. Another step, taken to maintain user sanity, makes CDAs run under the kernel's process ID.
\par
\par All the changes were made to two tool calls: }{\f6 SaveAll}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SaveAll}}}{\f4 ($0B05) and }{\f6 RestAll}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 RestAll}}}{\f4 ($0C05).
\par
\par }{\f4
\par
\par }{\f4
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {QDStartup($0204)}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074602}QDStartup($0204){\*\bkmkend _Toc364074602}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 The }{\f6 QDStartup}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 QDStartup}}}{\f4 call has been modified to signal an error and terminate any process that tries to make the call when it's controlling terminal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 controlling terminal}}}{\f4 is not the Apple IIgs console}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 console}}}{\f4 . This prevents a user on a remote terminal from bringing up a desktop application on the console, an operation he could not escape from and one that would greatly annoy the user at the console.
\par
\par Another change ensures that an attempt to execute two graphics-based applications concurrently will fail; the second process that tries to call QDStartUp is killed and a diagnostic message is displayed on the screen.
\par
\par }{\page \sect }\sectd \linex0\endnhere\titlepg\sectdefaultcl {\headerl \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Process Management\tab Chapter 5
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\headerr \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Chapter 5\tab Process Management
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerl \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerr \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerf \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid {Chapter 5
\par }\pard \s20\qj\nowidctlpar\widctlpar\adjustright {Process Management}{\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \v\f4\fs48\cgrid {\tc {{\*\bkmkstart _Toc364074603}Process Management{\*\bkmkend _Toc364074603}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par
\par Before discussing process management using Kernel calls, it would be wise to define just exactly what we refer to when we say }{\i\f4 process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 process}}}{\f4 . A process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 process}}}{\f4 is generally considered to be a program in execution. "A program is a passive entity, while a process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 process}}}{\f4 is an active entity." (Operating Systems Concepts p.73, Silberschatz and Peterson, Addison-Wesley, 1989). The concept of process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 process}}}{\f4 includes the information a computer needs to execute a program (such as the program counter, register values, etc).
\par
\par In order to execute multiple processes, the operating system (GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 and GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 in this case) has to make decisions about which process to run and when. GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 supports what is termed }{\i\f4 preemptive multitasking}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 preemptive multitasking}}}{\f4 , which means that processes are interrupted after a certain amount of time (their time slice}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 time slice}}}{\f4 ), at which point another process is allowed to run. The changing of machine registers to make the processor execute a different process is called a }{\i\f4 context switch}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 context switch}}}{\f4 , and the information the operating system needs to do this is called its }{\i\f4 context}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 context}}}{\f4 . The GNO kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO kernel}}}{\f4 maintains a list of all active processes, and assigns time slices to each process according to their order in the list. When the kernel has run through all the processes, it starts again at the beginning of the list. This is called }{\i\f4 round-robin scheduling}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 round-robin scheduling}}}{\f4 . Under certain circumstances, a process can actually execute longer than its allotted time slice because task switches are not allowed during a GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 or ToolBox call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ToolBox call}}}{\f4 . In these cases, as soon as the system call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 system call}}}{\f4 is finished the process is interrupted.
\par
\par Processes can give up the rest of their time slice voluntarily (but not necessarily explicitly) in a number of ways, terminal input being the most common. In this case, the rest of the time slice}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 time slice}}}{\f4 is allocated to the next process in line (to help smooth out scheduling). A process waiting on some event to happen is termed }{\i\f4 blocked}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 blocked}}}{\f4 . There are many ways this can happen, and each will be mentioned in its place.
\par
\par An important item to remember is the }{\i\f4 process ID}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 process ID}}}{\f4 . This is a number which uniquely identifies a process. The ID is assigned when the process is created, and is made available for reassignment when the process terminates. A great many system call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 system call}}}{\f4 s require process IDs as input. Do not confuse this with a userID}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 userID}}}{\f4 , which is a system for keeping track of memory allocation by various parts of the system, and is handled (pardon the pun) by the Memory Manager}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Memory Manager}}}{\f4 tool set. Also, do not confuse Memory Manager userID's with Unix user ID's - numbers which are assigned to the various human users of a multiuser machine.
\par
\par There are two methods for creating new processes: the system call }{\b\f4 fork}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\f4 () and the library routine }{\b\f4 exec}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 exec}}}{\f4 () (specifics for calling these functions and others is in Appendix A }{\b\f4 Making System Calls}{\f4 ). }{\b\f4 fork}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\f4 starts up a process which begins execution at an address you specify. }{\b\f4 exec}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 exec}}}{\f4 starts up a process by loading an executable file (S16}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 S16}}}{\f4 or EXE}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EXE}}}{\f4 ). }{\b\f4 fork}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\v\f4 ()}{\f4 is used mainly for use inside a specific application, such as running shell built-ins in the background, or setting up independent entities inside a program. Forked processes have some limitations, due to the hardware design of the Apple IIgs. The parent process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 parent process}}}{\f4 (the process which called fork) must still exist when the children die, either via }{\b\f4 kill}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 kill}}}{\f4 () or by simply exiting. This is because the forked children share the same memory space as the parent; the memory the children execute from is tagged with the parent's userID. If the parent terminated before the children, the children's code would be deallocated and likely overwritten. A second caveat with }{\b\f4 fork}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\v\f4 ()}{\f4 is the difference between it's UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 counterpart. UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 }{\b\f4 fork}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\v\f4 ()}{\f4 begins executing the child at a point directly after the call to }{\b\f4 fork}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\v\f4 ()}{\f4 . This cannot be accomplished on the Apple IIgs because virtual memory is required for such an operation; thus the need to specify a }{\b\f4 fork}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\v\f4 ()}{\f4 child as a C function. Note that an appropriately written assembly language program need not necessarily have these restrictions. When a process is forked, the child process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 child process}}}{\f4 is given it's own direct page}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 direct page}}}{\f4 and stack space}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack space}}}{\f4 under a newly allocated userID}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 userID}}}{\f4 , so that when the child terminates this memory is automatically freed.
\par
\par }{\b\f4 exec}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 exec}}}{\v\f4 ()}{\f4 is used when the process you wish to start is a GS/OS load file (file type S16}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 S16}}}{\f4 and EXE}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EXE}}}{\f4 ). }{\b\f4 exec}{\f4 follows the procedure outlined in the }{\i\f4 GS/OS Reference Manual}{\f4 for executing a program, and sets up the new program's environment as it expects. After }{\b\f4 exec}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 exec}}}{\v\f4 ()}{\f4 has loaded the program and set up it's environment, the new process is started and }{\b\f4 exec}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 exec}}}{\v\f4 ()}{\f4 returns immediately.
\par
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 Both }{\b\f4 fork}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\v\f4 ()}{\f4 and }{\b\f4 exec}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 exec}}}{\v\f4 ()}{\f4 return the process ID of the child. The parent may use this process ID to send }{\i\f4 signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 signal}}}{\i\f4 s}{\f4 to the child, or simply wait for the child to exit with the }{\b\f4 wait}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 wait}}}{\v\f4 ()}{\f4 system call; indeed, this is the most common use. Whenever a child process terminates or is stopped (See Chapter 6 }{\b\f4 Signals}{\f4 ), the kernel creates a packet of information which is then made available to the process' parent. If the parent is currently inside a wait call, the call returns with the information. If the parent is off doing something else, the kernel sends the parent process a }{\f6 SIGCHLD}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SIGCHLD}}}{\f4 signal. The default is to ignore }{\f6 SIGCHLD}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SIGCHLD}}}{\f4 , but a common technique is to install a handler for }{\f6 SIGCHLD}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SIGCHLD}}}{\f4 , and to make a }{\b\f4 wait}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 wait}}}{\v\f4 ()}{\f4 call inside the handler to retrieve the relevant information.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }{\b\f4 exec}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 exec}}}{\v\f4 ()}{\f4 is actually implemented as two other system calls: }{\b\f4 fork}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\v\f4 ()}{\f4 , and one called }{\b\f4 execve}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 execve}}}{\v\f4 ()}{\f4 . }{\b\f4 execve}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 execve}}}{\v\f4 ()}{\f4 loads a program from an executable file, and begins executing it. The current process' memory is deallocated. The shell uses a }{\b\f4 fork}{\f4 ()/}{\b\f4 execve}{\f4 () pair explicitly, so it can set up redirection and handle job control.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Process Table}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074604}Process Table{\*\bkmkend _Toc364074604}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 Information about processes is maintained in the process table}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 process table}}}{\f4 , which contains one entry for each possible process (}{\b\f4 NPROC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 NPROC}}}{\f4 , defined in the C header file <}{\f6 gno/conf.h}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 conf.h}}}{\f6 >}{\f4 ). There is other per-process information spread about the kernel, but those are usually used for maintaining compatibility with older software, and thus are not described here. Please note that the data in this section is informational only (e.g. for programs like '}{\b\f4 ps}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ps}}}{\f4 '). Do not attempt to modify kernel data structures or the GNO Kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO Kernel}}}{\f4 will likely respond with a resounding crash. Only 'interesting' fields are documented.
\par
\par Copies of process entries should be obtained by using the Kernel Virtual Memory (KVM}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 KVM}}}{\f4 ) routines (kvm_open}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 kvm_open}}}{\f4 , etc.) These are documented in the electronic manual pages.
\par
\par }{\b\f4 processState}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 processState}}}{\f4 - processes have a state associate with them. The state of the process is a description of what the process is doing. The possible process states (as listed in }{\f6 <gno/proc.h}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 proc.h}}}{\f6 >}{\f4 and described here) are:
\par }\pard \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright {\f6 RUNNING}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 RUNNING}}}{\f4 \tab the process is currently in execution.
\par }{\f6 READY}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 READY}}}{\f4 \tab the process is not currently executing, but is ready to be executed as soon as it is assigned a time slice.
\par }{\f6 BLOCKED}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 BLOCKED}}}{\f4 \tab the process is waiting for a slow I/O}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O}}}{\f4 operation to complete (for instance, a read from a TTY}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TTY}}}{\f4 ).
\par }{\f6 NEW}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 NEW}}}{\f4 \tab the process has been created, but has not executed yet.
\par }{\f6 SUSPENDED}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SUSPENDED}}}{\f4 \tab the process was stopped with SIGSTOP}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGSTOP}}}{\f4 , SIGTSTP}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGTSTP}}}{\f4 , SIGTTIN}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGTTIN}}}{\f4 , or SIGTTOU}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGTTOU}}}{\f4 .
\par }{\f6 WAITING}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 WAITING}}}{\f4 \tab the process is waiting on a semaphore 'signal}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 signal}}}{\f4 ' operation. Programs waiting for data from a pipe}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipe}}}{\f4 have this state.
\par }{\f6 WAITSIGCH}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 WAITSIGCH}}}{\f4 \tab the process is waiting to receive a SIGCHLD}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGCHLD}}}{\f4 signal.
\par }{\f6 PAUSED}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 PAUSED}}}{\f4 \tab the process is waiting for any signal.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }\pard \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright {\b\f4 ttyID}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ttyID}}}{\f4 \tab the device number of the controlling TTY}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TTY}}}{\f4 for this process. This is not a GS/OS refnum}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 refnum}}}{\f4 ; rather, it is an index into the kernel's internal character device}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 character device}}}{\f4 table. See below for a mapping of ttyID}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ttyID}}}{\f4 s to devices.
\par }{\b\f4 ticks}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ticks}}}{\f4 \tab the number of full ticks this process has executed. If a process gives up it's time slice due to an I/O}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O}}}{\f4 operation, this value is not incremented. A tick is 1/60 second.
\par }{\b\f4 alarmCount}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\xe {\b\f4 alarmCount}}}{\f4
\par \tab if an }{\b\f4 alarm}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 alarm}}}{\f4 (2) request was made, this is the number of seconds remaining until the process is sent SIGALRM}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGALRM}}}{\f4 .
\par }{\b\f4 openFiles}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 openFiles}}}{\f4 \tab this is a structure which stores information about the files a process has open. See }{\f6 struct ftable}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 struct ftable}}}{\f4 and }{\f6 struct fdentry}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 struct fdentry}}}{\f4 in }{\f6 <gno/proc.h}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 proc.h}}}{\f6 >}{\f4 .
\par }{\b\f4 irq_A}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 irq_A}}}{\b\f4 , irq_X}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 irq_X}}}{\b\f4 , irq_Y}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 irq_Y}}}{\b\f4 , irq_S}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 irq_S}}}{\b\f4 , irq_D}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 irq_D}}}{\b\f4 , irq_B}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 irq_B}}}{\b\f4 , irq_P}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 irq_P}}}{\b\f4 , irq_state}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 irq_state}}}{\b\f4 , irq_PC}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 irq_PC}}}{\b\f4 , irq_K}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\xe {\b\f4 irq_K}}}{\f4
\par \tab Context information for the process. These fields are the values of the 65816 registers}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 65816 registers}}}{\f4 at the last context switch}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 context switch}}}{\f4 . They only truly represent the machine state of the process if the process is not }{\f6 RUNNING}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 RUNNING}}}{\f4 .
\par }{\b\f4 args}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 args}}}{\f4 \tab a NUL-terminated (C-style) string that contains the command line the process was ivoked with. This string begins with 'BYTEWRKS}{\pard\plain \qj\fi-1080\li1080\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 BYTEWRKS}}}{\f4 ', the shell identifier.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par For more details and an example of how to investigate process information, look at the source code for 'GNO Snooper CDA}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO Snooper CDA}}}{\f4 ' (}{\b\f4 GNOSnooper.c}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 GNOSnooper.c}}}{\f4 ).
\par
\par The value in ttyID can be interpreted as follows:
\par \tab 0 - .null}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\f4 .null}}}{\f4
\par \tab 1 - .ttya}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\f4 .ttya}}}{\f4
\par \tab 2 - .ttyb}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\f4 .ttyb}}}{\f4
\par \tab 3 - .ttyco}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\f4 .ttyco}}}{\f4
\par \tab 6 - .ptyq0}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 .ptyq0}}}{\f4 \tab pty0 master side
\par \tab 7 - .ttyq0}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 .ttyq0}}}{\f4 \tab pty0 slave side
\par Other values may be appropriate depending on the tty.config}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 tty.config}}}{\f4 file. Namely, 1 and 2 (by default the modem}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 modem}}}{\f4 and printer}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 printer}}}{\f4 port drivers}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 port drivers}}}{\f4 ), and 4 and 5 (unassigned by default) may be assigned to different devices.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Task Switching}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074605}Task Switching{\*\bkmkend _Toc364074605}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 As mentioned earlier, user code can often unwittingly initiate a context switch}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 context switch}}}{\f4 by reading from the console (and other miscellaneous things). There are a few situations where this can cause a problem, namely inside interrupt handler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 interrupt handler}}}{\f4 s. While the kernel makes an attempt to prevent this, it cannot predict every conceivable problem. The kernel attempts to detect and prevent context switches inside interrupt handler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 interrupt handler}}}{\f4 s by checking for the following situations.
\par
\par \bullet \tab Is the system busy flag non-zero? (the busy flag is located at address }{\f6 $E100FF}{\f4 ).
\par \bullet \tab Is the "No-Compact" flag set? (Located at }{\f6 $E100CB}{\f4 )
\par \bullet \tab Does the stack pointer point to $0100-$01FF?
\par \bullet \tab Is the interrupt bit in the processor status register set?
\par
\par If any of these conditions are met, a context switch will not take place. This can cause problems in certain circumstances. The basic rule is to avoid making Kernel calls that might cause a context switch}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 context switch}}}{\f4 or change in process state from inside an interrupt handler. This includes the following:
\par
\par reading from the console or acessing a pipe
\par }{\b\f4 wait}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 wait}}}{\f4 (), }{\b\f4 pause}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 pause}}}{\f4 (), }{\b\f4 sigpause}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 sigpause}}}{\f4 (), }{\b\f4 kill}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 kill}}}{\f4 (), }{\b\f4 fork}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\f4 (), }{\b\f4 execve}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 execve}}}{\f4 (), }{\b\f4 receive}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 receive}}}{\f4 ()
\par
\par Calls such as }{\b\f4 send}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 send}}}{\f4 (), however, are okay to use from an interrupt handler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 interrupt handler}}}{\f4 , and in fact are very useful in such situations.
\par
\par
\par }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\tc {\v\f4 }{\f4 \tcl1}}}{\f4
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Job Control
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 Job control}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Job control}}}{\f4 is a feature of the kernel that helps processes orderly share a terminal. It prevents such quandaries as "What happens when two processes try to read from the terminal at the same time?".
\par
\par Job control}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Job control}}}{\f4 works by assigning related process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 process}}}{\f4 es to a }{\i\f4 process group}{\f4 .}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 process group.}}}{\f4 For example, all of the processes in a pipeline}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipeline}}}{\f4 belong to one process group. Terminal device drivers}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 device drivers}}}{\f4 also belong to process groups, and when the process group of a job does not match that of its }{\i\f4 controlling terminal}{\f4 }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 controlling terminal }}}{\f4 the job is said to be in the background}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 background}}}{\f4 . Background}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Background}}}{\f4 jobs have access to their controlling terminal restricted in certain ways.
\par
\par }\pard \qj\fi-720\li1440\nowidctlpar\widctlpar\adjustright {\f4 \bullet \tab If a background job attempts to read from the terminal, the kernel suspends the process by sending the }{\f6 SIGTTIN}{\pard\plain \qj\fi-720\li1440\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SIGTTIN}}}{\f4 signal.
\par \bullet \tab The interrupt signals }{\f6 SIGTSTP}{\pard\plain \qj\fi-720\li1440\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SIGTSTP}}}{\f4 and }{\f6 SIGINT}{\pard\plain \qj\fi-720\li1440\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SIGINT}}}{\f4 , generated by ^Z}{\pard\plain \qj\fi-720\li1440\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ^Z}}}{\f4 and ^C}{\pard\plain \qj\fi-720\li1440\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ^C}}}{\f4 respectively, are sent only to the foregound job. This allows backgrounded jobs to proceed without interruption.
\par \bullet \tab Certain }{\b\f4 ioctl}{\pard\plain \qj\fi-720\li1440\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ioctl}}}{\f4 () calls cannot be made by a background job; the result is a }{\f6 SIGTTIN}{\pard\plain \qj\fi-720\li1440\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SIGTTIN}}}{\f4 signal.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par Job control is accessed by software through the }{\b\f4 tcnewpgrp}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 tcnewpgrp}}}{\f4 , }{\b\f4 tctpgrp}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 tctpgrp}}}{\f4 , and }{\b\f4 settpgrp}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 settpgrp}}}{\f4 system calls. See the }{\b\f4 JOB CONTROL}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 JOB CONTROL}}}{\f4 (2) and }{\b\f4 ioctl}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ioctl}}}{\f4 (2) manpages.
\par
\par }{\sect }\sectd \linex0\endnhere\titlepg\sectdefaultcl {\headerl \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Interprocess Communication\tab Chapter 6
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\headerr \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Chapter 6\tab Interprocess Communication
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerl \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerr \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerf \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid {Chapter 6
\par }\pard \s20\qj\nowidctlpar\widctlpar\adjustright {Interprocess Communication}{\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \v\f4\fs48\cgrid {\tc {{\*\bkmkstart _Toc364074606}Interprocess Communication{\*\bkmkend _Toc364074606}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f4\fs18 \tab "Oh, give me a home where the semaphores roam, and the pipes are not deadlocked all day..."}{\f4\fs14
\par }\pard \qj\nowidctlpar\widctlpar\tqr\tx10080\adjustright {\f4 \tab }{\f4\fs18 Unknown western hero}{\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par The term Interprocess Communication}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Interprocess Communication}}}{\f4 (}{\i\f4 IPC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 IPC}}}{\f4 ) covers a large range of operating system features. Any time a process needs to send information to another process some form of IPC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 IPC}}}{\f4 is used. The GNO Kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO Kernel}}}{\f4 provides several basic types: semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 s, signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 signal}}}{\f4 s, pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipe}}}{\f4 s, messages}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 messages}}}{\f4 , ports}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ports}}}{\f4 , and pseudo-terminals}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pseudo-terminals}}}{\f4 . These IPC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 IPC}}}{\f4 mechanisms cover almost every conceivable communication task a program could possibly need to do.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Semaphores}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074607}Semaphores{\*\bkmkend _Toc364074607}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 In the days before radio, when two ships wished to communicate with each other to decide who was going first to traverse a channel wide enough only for one, they used multicolored flags called semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 s. Computer scientists, being great lovers of anachronistic terms, adopted the term and meaning of the word semaphore to create a way for processes to communicate when accessing shared information.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 , like other multitasking}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 multitasking}}}{\f4 systems, provides applications with semaphore routines. Semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Semaphore}}}{\f4 s sequentialize access to data by concurrently executing process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 process}}}{\f4 es. You should use semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 s whenever two or more processes want to access shared information}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 shared information}}}{\f4 . For example, suppose there were three process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 process}}}{\f4 es, each of which accepted input from user terminals and stored this input into a buffer in memory. Suppose also that there is another process which reads the information out of the buffer and stores it on disk. If one of the processes putting information in the buffer (writer process) was in the middle of storing information in the buffer when a context switch}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 context switch}}}{\f4 occurred, and one of the other processes then accessed the buffer, things would get really confused. Code that accesses the buffer should not be interrupted by another process that manipulates the buffer; this code is called a }{\i\f4 critical section}{\f4 ;}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 critical section\;}}}{\f4 in order to operate properly, this code must not be interrupted by any other attempts to access the buffer.
\par
\par To prevent the buffer from becoming corrupted, a semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 would be employed. As part of it's startup, the application that started up the other processes would also create a semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 using the }{\b\f4 screate}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 screate}}}{\f4 (2) system call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 system call}}}{\f4 with a parameter of 1. This number means (among other things) that only one process at a time can enter the critical section}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 critical section}}}{\f4 , and is called the }{\i\f4 count}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 count}}}{\f4 .
\par When a process wishes to access the buffer, it makes a }{\b\f4 swait}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 swait}}}{\f4 (2), giving as argument the semaphore number returned by }{\b\f4 screate}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 screate}}}{\v\f4 ()}{\f4 . When it's done with the buffer, it makes an }{\b\f4 ssignal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ssignal}}}{\f4 (2) call to indicate this fact.
\par
\par This is what happens when }{\b\f4 swait}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 swait}}}{\v\f4 ()}{\f4 is called: the kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 kernel}}}{\f4 first decrements the count. If the count is then less than zero, the kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 kernel}}}{\f4 suspends the process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 process}}}{\f4 , because a count of less than zero indicates that another process is already inside a critical section}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 critical section}}}{\f4 . This suspended}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 suspended}}}{\f4 state is called 'waiting' (hence the name of }{\b\f4 swait}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 swait}}}{\v\f4 ()}{\f4 ). Every process that tries to call }{\b\f4 swait}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 swait}}}{\v\f4 ()}{\f4 with count < 0 will be suspended; a queue of all the processes currently waiting on the semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 is associated with the semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 .
\par
\par Now, when the process inside the critical section leaves and executes }{\b\f4 ssignal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ssignal}}}{\v\f4 ()}{\f4 , the kernel increments the count. If there are processes waiting for the semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 , the kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 kernel}}}{\f4 chooses one arbitrarily and restarts it. When the process resumes execution at its next time slice, its }{\b\f4 swait}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 swait}}}{\v\f4 ()}{\f4 call will finish executing and it will have exclusive control of the critical section}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 critical section}}}{\f4 . This cycle continues until there are no processes waiting on the semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 , at which point its count will have returned to 1.
\par
\par When the semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 is no longer needed, you should dispose of it with the }{\b\f4 sdelete}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 sdelete}}}{\f4 (2) call. This call frees any processes that might be waiting on the semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 and returns the semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 to the semaphore pool}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore pool}}}{\f4 .
\par
\par One must be careful in use of semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 s or }{\i\f4 deadlock}{\f4 }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 deadlock }}}{\f4 can occur.
\par
\par There are (believe it or not) many situations in everyday programming when you may need semaphores}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphores}}}{\f4 , moreso than real UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 systems due to the Apple IIgs's lack of virtual memory}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 virtual memory}}}{\f4 . The most common of these is your C or Pascal compiler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Pascal compiler}}}{\f4 's stdio library}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stdio library}}}{\f4 ; these are routines like }{\b\f4 printf}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 printf}}}{\v\f4 ()}{\f4 and }{\b\f4 writeln}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 writeln}}}{\v\f4 ()}{\f4 . In many cases, these libraries use global variables and buffers. If you write a program which forks a child process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 child process}}}{\f4 that shares program code with the parent process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 parent process}}}{\f4 (i.e. doesn't }{\b\f4 execve}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 execve}}}{\v\f4 ()}{\f4 to another executable), and that child and the parent both use non-}{\i\f4 reentrant}{\f4 }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 reentrant }}}{\f4 library calls, the library will become confused. In the case of text output routines, this usually results in garbaged output.
\par
\par Other library routines can have more disastrous results. For example, if a parent's }{\b\f4 free}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 free}}}{\f4 () or }{\b\f4 dispose}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 dispose}}}{\f4 () memory management call is interrupted, and the child makes a similar call during this time, the linked lists that the library maintains to keep track of allocated memory could become corrupted, resulting most likely in a program crash.
\par
\par GNO/ME provides }{\i\f4 mutual exclusion}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 mutual exclusion}}}{\f4 (i.e., lets a maximum of one process at a time execute the code) automatically around all Toolbox}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Toolbox}}}{\f4 and GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 s as described in Chapter 3, and also uses semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 s internally in many other places. Any budding GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 programmer is well advised to experiment with semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 s to get a feel for when and where they should be used. Examples of semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 semaphore}}}{\f4 use can be found in the sample source code, notably }{\f6 dp.c}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 dp.c}}}{\f4 (Dining Philosophers demo) and and }{\f6 pipe*.c}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 pipe*.c}}}{\f4 (a sample implementation of pipes written entirely in C).
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Signals}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074608}Signals{\*\bkmkend _Toc364074608}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 Another method of IPC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 IPC}}}{\f4 is software signals. Signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Signal}}}{\f4 s are similar to hardware interrupts in that they are asynchronous; that is, a process receiving a signal does not have to be in a special mode, does not have to wait for it. Also like hardware interrupt}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 hardware interrupt}}}{\f4 s, a process can install signal handler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 signal handler}}}{\f4 s to take special action when a signal arrives. Unlike hardware interrupt}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 hardware interrupt}}}{\f4 s, signals are defined and handled entirely through software.
\par
\par Signals are generally used to tell a process of some event that has occurred. Between the system-defined and user-defined signals, there is a lot of things you can do. GNO/ME currently defines 32 different signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 signal}}}{\f4 s. A list of signals and their codes can be found in }{\b\f4 signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 signal}}}{\f4 (2) and the header file }{\f6 <gno/signal.h}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 signal.h}}}{\f6 >}{\f4 .
\par
\par There are three types of default actions that occur upon receipt of a signal. The process receiving the signal might be terminated, or stopped; or, the signal might be ignored. The default action of any signal can be changed by a process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 process}}}{\f4 , with some exceptions. Not all of the defined signals are currently used by GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 , as some are not applicable to the Apple IIgs, or represent UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 features not yet implemented in GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 . Here is a list of the signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 signal}}}{\f4 s that are used by GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 .
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }\pard \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright {\f4 SIGINT}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGINT}}}{\f4 \tab This signal is sent to the foreground job when a user types ^C}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ^C}}}{\f4 at the terminal keyboard.
\par SIGKILL}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGKILL}}}{\f4 \tab The default action of this signal (termination) cannot be changed. This provides a sure-fire means of stopping an otherwise unstoppable process.
\par SIGPIPE}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGPIPE}}}{\f4 \tab Whenever a process tries to write on a pipe}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipe}}}{\f4 with no readers, it is sent this signal.
\par SIGALRM}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGALRM}}}{\f4 \tab SIGALRM}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGALRM}}}{\f4 is sent when an alarm timer expires (counts down to zero). An application can start an alarm timer with the }{\b\f4 alarm}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 alarm}}}{\f4 (2) system call.
\par SIGTERM}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGTERM}}}{\f4 \tab This is the default signal sent by }{\b\f4 kill}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 kill}}}{\f4 (1). Use of this signal allows applications to clean up (delete temporary files, free system resources like semaphores, etc) before terminating at the user's bequest.
\par SIGSTOP}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGSTOP}}}{\f4 \tab This signal is used to stop a process' execution temporarily. Like SIGKILL}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGKILL}}}{\f4 , processes are not allowed to install a handler for this signal.
\par SIGCONT}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGCONT}}}{\f4 \tab To restart a stopped process, send this signal.
\par SIGTSTP}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGTSTP}}}{\f4 \tab This is similar to SIGSTOP}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGSTOP}}}{\f4 , but is sent when the user types ^Z}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ^Z}}}{\f4 at the keyboard. Unlike SIGSTOP}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGSTOP}}}{\f4 , this signal can be ignored, caught, or blocked.
\par SIGCHLD}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGCHLD}}}{\f4 \tab A process receives this signal whenever a child process is stopped or terminates. }{\b\f4 gsh}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 gsh}}}{\f4 uses this to keep track of jobs, and the wait system call}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 system call}}}{\f4 waits for this signal to arrive before exiting.
\par SIGTTIN}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGTTIN}}}{\f4 \tab This signal also stops a process. It is sent to background}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 background}}}{\f4 jobs that try to get input from the terminal.
\par SIGTTOU}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGTTOU}}}{\f4 \tab Similar to SIGTTIN}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGTTIN}}}{\f4 , but is sent when a background process tries to write to the terminal. This behavior is optional and is by default turned off.
\par SIGUSR1}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGUSR1}}}{\f4 \tab
\par SIGUSR2}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGUSR2}}}{\f4 \tab These two signals are reserved for application authors. Their meaning will change from application to application.
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par As you can see, signals are used by many aspects of the system. For detailed information on what various signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 signal}}}{\f4 s mean, consult the appropriate electronic manual page - see }{\b\f4 tty}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 tty}}}{\f4 (4), }{\b\f4 wait}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 wait}}}{\f4 (2), and }{\b\f4 signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 signal}}}{\f4 (2).
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 For an example of signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 signal}}}{\f4 usage, consider a print spooler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 print spooler}}}{\f4 . A print spooler takes files that are put in the spool directory on a disk and sends the data in the files to a printer}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 printer}}}{\f4 . There are generally two parts to a print spooler: the }{\i\f4 daemon}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 daemon}}}{\f4 , a process that resides in memory and performs the transfer of data to the printer in the background}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 background}}}{\f4 ; and the spooler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 spooler}}}{\f4 . There can be many different types of spoolers, say one for desktop printing, one for printing source code, etc. To communicate to the daemon}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 daemon}}}{\f4 that they have just placed a new file in the spool directory, the spoolers could send the daemon }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 daemon }}}{\f4 SIGUSR}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGUSR}}}{\f4 . The daemon will have a handler for SIGUSR}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGUSR}}}{\f4 , and that handler will locate the file and set things up so the print will begin. Note that the actual implementation of the print spooling system in GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 , }{\b\f4 lpr}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 lpr}}}{\f4 (1) and }{\b\f4 lpd}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 lpd}}}{\f4 (8), is somewhat more complex and uses messages and ports instead of signals. However, an earlier version of the spooler software }{\i\f4 did}{\f4 use signals for communication.
\par
\par Signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Signal}}}{\f4 s should not be sent from inside an interrupt handler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 interrupt handler}}}{\f4 , nor from inside a GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 or Toolbox call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Toolbox call}}}{\f4 . Window Manager}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Window Manager}}}{\f4 update routines are a prime example of code that should not send signals; they are executed as part of a tool call. The GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 aspect of this limitation is a little harder to come up against. GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 does maintain a software signal facility of it's own, used to notify programs when certain low-level events have occurred. Do not confuse these GS/OS signals}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS signals}}}{\f4 with GNO/ME signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME signal}}}{\f4 s, and above all, don't send a GNO/ME signal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME signal}}}{\f4 from a GS/OS signal handler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS signal handler}}}{\f4 .
\par
\par When a process receives a signal for which it has installed a handler, what occurs is similar to a context switch}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 context switch}}}{\f4 . The process' context is saved on the stack, and the context is set so that the signal handler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 signal handler}}}{\f4 routine will be executed. Since the old context is stored on the stack, the signal handler may if it wishes return to some other part of the program. It accomplishes this by setting the stack pointer}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack pointer}}}{\f4 to a value saved earlier in the program and jumping to the appropriate place. Jumps like this can be made with C's }{\b\f4 setjmp}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 setjmp}}}{\f4 and }{\b\f4 longjmp}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 longjmp}}}{\f4 functions. The following bit of code demonstrates this ability.
\par
\par }{\f6\fs20 void sighandler(int sig, int code)
\par \{
\par \tab printf("Got a signal!");
\par \tab longjmp(jmp_buf);
\par \}
\par
\par void routine(void)
\par \{
\par \tab signal(SIGUSR,sighandler);
\par \tab if (setjmp(jmp_buf)) \{
\par \tab \tab printf("Finally done! Sorry for all that....");
\par \tab \}
\par \tab else \{ while (1) \{
\par \tab \tab printf("While I wait I will annoy you!");
\par \tab \tab \}
\par \tab \}
\par \}
\par }{\f4
\par This program basically prints an annoying message over and over until SIGUSR }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGUSR }}}{\f4 is received. At that point, the handler prints "Got a Signal!" and jumps back to the part of the if statement that prints an apology. If the signal handler}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 signal handler}}}{\f4 hadn't made the }{\b\f4 longjmp}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 longjmp}}}{\f4 , when the handler exited control would have returned to the exact place in the }{\b\f4 while}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 while}}}{\f4 (1) loop that was interrupted.
\par
\par Similar techniques can be applied in assembly language.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Pipes}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074609}Pipes{\*\bkmkend _Toc364074609}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 This third form of IPC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 IPC}}}{\f4 implemented in GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 is one of the most powerful features ever put into an operating system. A pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipe}}}{\f4 is a conduit for information from one process to another. Pipes are accessed just like regular files; the same GS/OS}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS}}}{\f4 and ToolBox call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ToolBox call}}}{\f4 s currently used to manipulate files are also used to manipulate pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipe}}}{\f4 s. When combined with GNO/ME standard I/O}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O}}}{\f4 features, pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipe}}}{\f4 s become very powerful indeed. For examples on how to use }{\b\f4 gsh}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 gsh}}}{\f4 to connect applications with pipes, see the }{\i\f4 GNO Shell Reference Manual}{\f4 .
\par
\par Pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Pipe}}}{\f4 s are uni-directional channels between processes. Pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Pipe}}}{\f4 s are created with the }{\b\f4 pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 pipe}}}{\f4 (2) system call, which returns two GS/OS refNum}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS refNum}}}{\f4 s; one for the write end, and one for the read end. An attempt to read from the write end or vice-versa results in an error.
\par
\par Pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Pipe}}}{\f4 s under GNO/ME}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO/ME}}}{\f4 are implemented as a circular buffer of 4096 bytes. Semaphore}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Semaphore}}}{\f4 s are employed to prevent the buffer from overflowing, and to maintain synchronization between the processes accessing the pipe. This is done by creating two semaphores; their counts indicate how many bytes are available to be read and how many bytes may be written to the buffer (0 and 4096 initially). If an I/O operation on the pipe would result in the buffer being emptied or filled, the calling process is blocked until the data (or space) becomes available.
\par
\par The usual method of setting up a pipeline}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipeline}}}{\f4 between processes, used by }{\b\f4 gsh}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 gsh}}}{\f4 and utilities such as script}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 script}}}{\f4 , is to make the }{\b\f4 pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 pipe}}}{\f4 () call and then }{\b\f4 fork}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\v\f4 ()}{\f4 off the processes to be connected by the pipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 pipe}}}{\f4 .
\par
\par }{\f6\fs20 int fd[2];
\par int testPipe(void)
\par \{
\par \tab pipe(fd);\tab \tab /* create the pipe */
\par \tab fork(proc1);\tab /* create the writer process */
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6\fs20 \tab fork(proc2);\tab /* create the reader process */
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6\fs20 \tab close(fd[1]);\tab /* we don't need the pipe anymore, because */
\par \tab close(fd[0]);\tab /* the children inherited them */
\par \tab \{ wait for processes to terminate ... \}
\par \}
\par
\par
\par void proc1(void)
\par \{
\par \tab dup2(STDOUT_FILENO,fd[1]);\tab /* reset standard output to the write pipe */
\par \tab close(fd[0]);\tab \tab \tab /* we don't need the read end */
\par \tab \{ exec writer process ... \}
\par \}
\par void proc2(void)
\par \{
\par \tab dup2(STDIN_FILENO,fd[0]);\tab /* reset standard input to the pipe */
\par \tab close(fd[1]);\tab \tab \tab /* we don't need the write end */
\par \tab \{ exec reader process ... \}
\par \}
\par }{\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 Recall that when a new process is forked, it inherits all of the open files of it's parent; thus, the two children here inherit not only standard I/O}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 I/O}}}{\f4 but also the pipe. After the forks, the parent process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 parent process}}}{\f4 closes the pipe and each of the child process}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 child process}}}{\f4 es closes the end of the pipe it doesn't use. This is actually a necessary step because the kernel must know when the reader has terminated in order to also stop the writer (by sending }{\f6 SIGPIPE}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SIGPIPE}}}{\f4 ). Since each open refNum}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 refNum}}}{\f4 to the read end of the pipe is counted as a reader, any unnecessary copies must be closed.
\par
\par For further examples of implementing and programming pipes, see the sample source code for }{\f6 pipe*.c}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 pipe*.c}}}{\f6 .}{\f4
\par
\par }{\f4
\par }{\f4
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Messages}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074610}Messages{\*\bkmkend _Toc364074610}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 GNO's Message IPC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 IPC}}}{\f4 is borrowed from the XINU Operating System, designed by Douglas Comer. It is a simple way to send a datum (a message) to another process. Messages are 32-bit (4-byte) longwords.
\par
\par The Message IPC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 IPC}}}{\f4 is centered around two calls, }{\b\f4 send}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 send}}}{\f4 () and }{\b\f4 receive}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 receive}}}{\f4 (). }{\b\f4 send}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 send}}}{\f4 () sends a message to a specified process ID}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 process ID}}}{\f4 . To access that message, a process must use }{\b\f4 receive}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 receive}}}{\f4 (). If no message is waiting for a process when it calls }{\b\f4 receive}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 receive}}}{\f4 (), it is put to sleep until a message becomes available.
\par
\par Since a process can only have one pending message, the Message IPC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 IPC}}}{\f4 is useful mostly in applications where two or more cooperating processes only occasionally need to signal each other; for example, the }{\b\f4 init}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 init}}}{\f4 (8) program communicates with the Init daemon by sending messages. Various attributes are encoded in the 32-bit value sent to }{\b\f4 init}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 init}}}{\f4 (8) to instruct it on how to change its state.
\par
\par If a process doesn't want to indefinitely block waiting for a message, it can call }{\b\f4 recvtim}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 recvtim}}}{\f4 (). }{\b\f4 recvtim}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 recvtim}}}{\f4 () accepts a timeout parameter which indicates the maximum amount of time to wait for a message.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Ports}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074611}Ports{\*\bkmkend _Toc364074611}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 GNO/ME Ports}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Ports}}}{\f4 IPC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 IPC}}}{\f4 can be thought of as an extended version of Messages}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Messages}}}{\f4 . Whereas only one message can be pending at once, a port can contain any number of pending messages (up to a limit defined when an application creates a port).
\par
\par Like Messages, Ports transmit 32-bit values between processes. The calls }{\b\f4 psend}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 psend}}}{\f4 () and }{\b\f4 preceive}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 preceive}}}{\f4 () work similarly to their Message counterparts.
\par
\par A Port is created with the }{\b\f4 pcreate}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 pcreate}}}{\f4 () call. The application specifies the size of the port in this call. When the application is done with the port, it should call }{\b\f4 pdelete}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 pdelete}}}{\f4 () to free up the resources used by the port.
\par
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 One of the most important aspects of ports is the ability to bind a }{\i\f4 name}{\f4 to a port. Whereas many of GNO/ME IPC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 IPC}}}{\f4 mechanisms require the communicating processes to be related in some way (common children of the same parent, for instance) being able to give a port a name means that totally unrelated processes can communicate. For example, the GNO/ME print spooling system uses a named port for communicating information about the addition of new jobs to the print queue. The printer daemon, }{\b\f4 lpd}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 lpd}}}{\f4 (8), creates a port with a specific name; the name is defined by the author of the print daemon; any application that wishes to have the daemon print a spool file also knows this name. (The standard print daemon uses the name "LPDPrinter"). The name allows an application to find lpd's port regardless of the actual numeric port ID (which might be different from system to system, or even from session to session on the same machine).
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par Names are bound to ports with the }{\b\f4 pbind}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 pbind}}}{\f4 () call. The numeric port ID}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 port ID}}}{\f4 can be obtained by passing a name to }{\b\f4 pgetport}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 pgetport}}}{\f4 ().
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {\page }{Pseudo-Terminals (PTYs)}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074612}Pseudo-Terminals (PTYs){\*\bkmkend _Toc364074612}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 Pseudo-terminals}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 Pseudo-terminals}}}{\f4 are a bi-directional communication channel that can be used to connect two processes (or more correctly, a process group to another process). You may (correctly) ask why two pipes would not do the same thing; the answer is that a lot of modern UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 software relies on the way the terminal interface works, and thus would malfunction when presented with a pipe as standard input. What PTYs provide is a lot like two pipes, but with a TTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TTY}}}{\f4 interface.
\par
\par PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 s can be used in a number of important and exciting applications, such as windowing systems and 'script-driven' interfaces.
\par
\par Windowing systems like the UNIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 X-Windows use PTYs to give a process group an interface that looks exactly like a real terminal; however, the 'terminal' in this case is actually a window in a graphics-based system. The program that manages the window ('xterm' in X-Windows) is called the }{\i\f4 master}{\f4 .}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 master.}}}{\f4 It is responsible for setting up the PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 , and starting up the process with redirection}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 redirection}}}{\f4 (usually a shell) that is to run in the window. The process running in the window is called the }{\i\f4 slave}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 slave}}}{\f4 .
\par
\par To allocate a PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 , the master opens in turn each PTY device starting with .ptyq0}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 .ptyq0}}}{\f4 . If a PTY is already in use, the open call will return an error (the kernel uses the EXCL }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EXCL }}}{\f4 flag internally). When an open succeeds, the master then has exclusive access to that PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 . At this point, the master}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 master}}}{\f4 opens the corresponding TTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 TTY}}}{\f4 file (.ttyq0}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 .ttyq0}}}{\f4 - .ttyqf}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 .ttyqf}}}{\f4 ), or the slave}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 slave}}}{\f4 device. It then forks off a process, which sets redirection}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 redirection}}}{\f4 up in the normal fashion and then exec}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 exec}}}{\f4 's the program to run on the PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 . The following is taken from the source code for the Graphical Shell Interface (GSI) NDA.
\par }{\f6\fs20 initPipe}{\f4 }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\fs20\cgrid {\xe {\v\f6\fs20 }{\f6\fs20 initPipe }}}{\f4 scans the PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 devices, looking for a free one as discussed above. Note that the master}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 master}}}{\f4 side of a PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 does _not_ have (by default) a terminal}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 terminal}}}{\f4 interface; it is a very raw device, with only a few ioctl's to be able to send signals and handle other such low-level tasks.}{\f6\fs20
\par
\par char buffer[1024];
\par int ptyno, master;
\par
\par int initPipe(void)
\par \{
\par int cl[2];
\par struct sgttyb sb;
\par char *ptyname = ".ptyq0";
\par unsigned i;
\par
\par /* We have to open the master first */
\par
\par for (i = 0; i < 2; i++) \{
\par ptyname[5] = intToHex(i); /* generate a PTY name from the index */
\par master = open(ptyname,O_RDWR);
\par if (master > 0) break; /* successful open */
\par \}
\par if (master < 1) \{ return -1; \}
\par ptyno = i;
\par pid1 = fork(producer);
\par return 0;
\par \}
\par }{\f4
\par }{\f6\fs20 producer}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\fs20\cgrid {\xe {\v\f6\fs20 }{\f6\fs20 producer}}}{\f4 () sets up redirection for the shell, and also opens the slave}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 slave}}}{\f4 side of the PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 . The slave processes must not have any access whatsoever to the master}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 master}}}{\f4 side of the PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 , so }{\b\f4 close}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 close}}}{\f4 (0) is used to close all open files (which includes, at this point, the master PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 file descriptor}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 file descriptor}}}{\f4 from initPipe}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 initPipe}}}{\f4 ). Note that as in many pipe applications, the file descriptor that will be assigned to a newly opened file is assumed, and that can be safely done in this case because it is clear that with no files open the next file descriptor will be 1.
\par
\par }{\f6\fs20 /* the shell is executed here */
\par #pragma databank 1
\par void producer(void)
\par \{
\par char *ptyname = ".ttyq0";
\par
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6\fs20 \tab /* we must not have access to ANY other ttys */
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6\fs20 \tab close(0); /* close ALL open files */
\par \tab ptyname[5] = intToHex(ptyno);
\par \tab /* modify the tty slave name to correspond to the master */
\par \tab slave = open(ptyname,O_RDWR); /* file descriptor 1 */
\par \tab dup(slave); /* fd 2 */
\par \tab dup(slave); /* fd 3 */
\par \tab SetOutputDevice(3,2l); /* Set up the TextTools redirection */
\par \tab SetErrorDevice(3,3l);
\par \tab SetInputDevice(3,1l);
\par \tab WriteCString("Welcome to GNO GSI\\r\\n");
\par \tab execve(":bin:gsh","gsh -f");
\par \tab /* If we get here, we were unable to run the shell */
\par \tab printf("Could not locate :bin:gsh : %d",errno);
\par \}
\par #pragma databank 0
\par
\par consume}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\fs20\cgrid {\xe {\v\f6\fs20 }{\f6\fs20 consume}}}{\f6\fs20 () }{\f4 is called as part of GSI's event loop. It simply checks to see if there is any data for the master by using the FIONREAD}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 FIONREAD}}}{\f4 ioctl}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ioctl}}}{\f4 , one of the few ioctl}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ioctl}}}{\f4 's supported by the master}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 master}}}{\f4 side. See PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 (4) for details. Any data that is available is sent to the window via a routine toOut}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 toOut}}}{\f4 , which inserts the new data into a TextEdit record.}{\f6\fs20
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6\fs20
\par void consume(CtlRecHndl teH)
\par \{
\par char ch;
\par int fio,fio1,i;
\par
\par ioctl(master,FIONREAD,&fio);
\par if (fio) \{
\par \tab if (fio > 256) fio = 256;
\par \tab fio1 = read(master,buffer,fio);
\par \tab buffer[fio] = 0;
\par \tab toOut(buffer,fio,teH);
\par \tab updateWind1(fio,fio1);
\par \}
\par \}
\par
\par }{\f4 \page }{\f4 When the user types a key, the keypress is sent to the slave by simply writing the data with a write call.
\par
\par }{\f6\fs20 void writedata(char k)
\par \{
\par write(master, &k, 1);
\par \}
\par }{\f4
\par When the user is done with the window and closes it, GSI}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GSI}}}{\f4 closes the master end of the PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 .
\par
\par }{\f6\fs20 void closePipe(void)
\par \{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6\fs20 int cl[2];
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f6\fs20
\par close(master);
\par \}
\par }{\f4
\par When this is done, the slave }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 slave }}}{\f4 process }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 process }}}{\f4 receives a SIGHUP }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGHUP }}}{\f4 signal, to indicate that the connection was lost. Since the standard behavior of SIGHUP }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGHUP }}}{\f4 is to terminate the process, the slave }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 slave }}}{\f4 dies and either the slave }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 slave }}}{\f4 or the kernel }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 kernel }}}{\f4 closes the slave }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 slave }}}{\f4 end. At this point, the PTY }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY }}}{\f4 is available for re-use by another application.
\par
\par As you can see, PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 s are very simple to program and use. The simplicity can be misleading, for PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 s are a very powerful method of IPC}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 IPC}}}{\f4 . As another example of the use of PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 s, we point out that PTYs can be used to drive programs with 'script}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 script}}}{\f4 s'. These scripts are a series of 'wait-for' and 'print' operations, much like auto-logon macros in communications programs such as ProTERM. Script-driving a program can be used to automate testing or use of an application.
\par
\par PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 s can be used to test software that would normally work over a regular terminal (such as a modem). Since PTYs are identical (to the slave) to terminals, the application being tested doesn't know the difference. What this means to the programmer is incredible power and flexibility in testing the application. For example, a communications program could be nearly completely tested without ever dialing to another computer with a modem!
\par
\par There are so many applications of PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 s that to attempt to discuss them all here would be impossible; as PTYs are discovered by more GNO/ME programmers we expect that more useful PTY}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 PTY}}}{\f4 applications will become available.
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Deadlock}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074613}Deadlock{\*\bkmkend _Toc364074613}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 With interprocess communication comes the problem of }{\i\f4 deadlock}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 deadlock}}}{\f4 . If a situation arises where two or more processes are all waiting for an signal }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 signal }}}{\f4 from one of the other waiting processes, the processes are said to be deadlocked.
\par
\par The best way to explain deadlock }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 deadlock }}}{\f4 is to give an example. Suppose that two processes are connected with two pipes so that they can communicate bidirectionally. Also suppose that each of the pipes are full, and that when each process writes into one of the pipes they are blocked. Both processes are blocked waiting for the other to unblock them.
\par
\par There is no way for the operating system to detect every conceivable deadlock condition without expending large amounts of CPU time. Thus, the only way to recover from a deadlock }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 deadlock }}}{\f4 is to kill }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 kill }}}{\f4 the processes in question. Responsibility for preventing deadlock }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 deadlock }}}{\f4 situations is placed on the programmer. Fortunately, situations where deadlock can occur are infrequent; however, you should keep an eye out for them and try to work around them when they do occur.
\par }{\sect }\sectd \linex0\endnhere\titlepg\sectdefaultcl {\headerl \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Miscellaneous Programming Issues\tab Appendix B
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\headerr \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Appendix B\tab Miscellaneous Programming Issues
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerl \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerr \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerf \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid {Appendix A
\par }\pard \s20\qj\nowidctlpar\widctlpar\adjustright {Making System Calls}{\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \v\f4\fs48\cgrid {\tc {{\*\bkmkstart _Toc364074614}Making System Calls{\*\bkmkend _Toc364074614}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4
\par
\par The GNO Kernel}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GNO Kernel}}}{\f4 is accessed through system call}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 system call}}}{\f4 s. The actual procedure is very simple from C: simply #include}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 }{\txe include}}}{\f4 the appropriate header file as noted in the synopsis of the call's manual page, and call it as you would any other C function. From assembly language the procedure is no more difficult, using the advanced macros provided for the APW}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 APW}}}{\f4 and ORCA}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA}}}{\f4 assemblers. Make sure, however, that you have defined a word variable }{\b\f4 errno}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 errno}}}{\f4 . Lowercase is important, use the 'case on' and 'case off' directives to ensure that the definition of }{\b\f4 errno}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 errno}}}{\f4 is case-sensitive. The system call interface libraries store any error codes returned by the kernel in this variable.
\par
\par If you are going to be accessing the kernel from a language other than those for which interfaces are provided, then the following information is for you.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {System Call Interface}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074615}System Call Interface{\*\bkmkend _Toc364074615}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 The system calls}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 system calls}}}{\f4 are implemented as a user toolset, tool number 3. These tools are called the same way regular system tools (such as QuickDraw}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 QuickDraw}}}{\f4 ) are called, except that you must JSL }{\f6 $E10008}{\f4 instead of }{\f6 JSL\~$E10000}{\f4 (or }{\f6 $E1000C}{\f4 instead of }{\f6 $E10004}{\f4 for the alternate entry point). The function numbers for the currently defined tools are as follows:
\par
\par }\trowd \trgaph80\trleft-80\trkeep \clvertalt\cltxlrtb \cellx4960\clvertalt\cltxlrtb \cellx10000\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\v\f6 *}{\f6 getpid}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 getpid}}}{\f6 \tab $0903\cell kill}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 kill}}}{\f6 \tab $0A03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\trowd \trgaph80\trleft-80\trkeep \clvertalt\cltxlrtb \cellx4960\clvertalt\cltxlrtb \cellx10000\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 fork}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 fork}}}{\f6 \tab $0B03\cell swait}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 swait}}}{\f6 \tab $0D03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 ssignal}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 ssignal}}}{\f6 \tab $0E03\cell }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 screate}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 screate}}}{\f6 \tab $0F03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 sdelete}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 sdelete}}}{\f6 \tab $1003\cell kvm_open}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 kvm_open}}}{\f6 \tab $1103\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 kvm_close}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 kvm_close}}}{\f6 \tab $1203\cell kvm_getproc}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 kvm_getproc}}}{\f6 \tab $1303\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 kvm_nextproc}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 kvm_nextproc}}}{\f6 \tab $1403\cell kvm_setproc}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 kvm_setproc}}}{\f6 \tab $1503\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 signal}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 signal}}}{\f6 \tab $1603\cell wait}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 wait}}}{\f6 \tab $1703\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 tcnewpgrp}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 tcnewpgrp}}}{\f6 \tab $1803\cell settpgrp}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 settpgrp}}}{\f6 \tab $1903\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 tctpgrp}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 tctpgrp}}}{\f6 \tab $1A03\cell sigsetmask}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 sigsetmask}}}{\f6 \tab $1B03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 sigblock}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 sigblock}}}{\f6 \tab $1C03\cell execve}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 execve}}}{\f6 \tab $1D03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 alarm}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 alarm}}}{\f6 \tab $1E03\cell }{\v\f6 *}{\f6 setdebug}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 setdebug}}}{\f6 \tab $1F03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\v\f6 *}{\f6 setsystemvector}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 setsystemvector}}}{\f6 \tab $2003\cell sigpause}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 sigpause}}}{\f6 \tab $2103\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 dup}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 dup}}}{\f6 \tab $2203\cell dup2}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 dup2}}}{\f6 \tab $2303\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 pipe}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 pipe}}}{\f6 \tab $2403\cell getpgrp}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 getpgrp}}}{\f6 \tab $2503\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 ioctl}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 ioctl}}}{\f6 \tab $2603\cell stat}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 stat}}}{\f6 \tab $2703\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 fstat}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 fstat}}}{\f6 \tab $2803\cell lstat}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 lstat}}}{\f6 \tab $2903\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 getuid}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 getuid}}}{\f6 \tab $2A03\cell }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 getgid}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 getgid}}}{\f6 \tab $2B03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 geteuid}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 geteuid}}}{\f6 \tab $2C03\cell getegid}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 getegid}}}{\f6 \tab $2D03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 setuid}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 setuid}}}{\f6 \tab $2E03\cell setgid}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 setgid}}}{\f6 \tab $2F03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 send}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 send}}}{\f6 \tab $3003\cell receive}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 receive}}}{\f6 \tab $3103\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 recvclr}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 recvclr}}}{\f6 \tab $3203\cell recvtim}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 recvtim}}}{\f6 \tab $3303\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 setpgrp}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 setpgrp}}}{\f6 \tab $3403\cell times}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 times}}}{\f6 \tab $3503\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 pcreate}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 pcreate}}}{\f6 \tab $3603\cell psend}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 psend}}}{\f6 \tab $3703\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 preceive}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 preceive}}}{\f6 \tab $3803\cell pdelete}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 pdelete}}}{\f6 \tab $3903\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 preset}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 preset}}}{\f6 \tab $3A03\cell pbind}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 pbind}}}{\f6 \tab $3B03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 pgetport}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 pgetport}}}{\f6 \tab $3C03\cell pgetcount}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 pgetcount}}}{\f6 \tab $3D03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 scount}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 scount}}}{\f6 \tab $3E03\cell fork2}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 fork2}}}{\f6 \tab $3F03\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 getppid}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 getppid}}}{\f6 \tab $4003\cell SetGNOQuitRec}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 SetGNOQuitRec}}}{\f6 \tab $4103\cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\trowd \trgaph80\trleft-80\trkeep \clvertalt\cltxlrtb \cellx4960\clvertalt\cltxlrtb \cellx10000\pard \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright {\f6 alarm10}{\pard\plain \qj\li720\nowidctlpar\widctlpar\intbl\tx3960\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 alarm10}}}{\f6 \tab $4203\cell \cell }\pard \nowidctlpar\widctlpar\intbl\adjustright {\f6 \row }\pard \qj\li720\nowidctlpar\widctlpar\tx3240\adjustright {\f4
\par }\pard \qj\nowidctlpar\widctlpar\tx3240\adjustright {\f4 Parameters should be pushed onto the stack in the same order as defined by the C prototypes outlines in the synopsis section of the manual pages; that is, left-to-right. In addition to those parameters, all of the functions (except those denoted by a *) take an integer pointer parameter }{\b\f4 ERRNO}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ERRNO}}}{\f4 . This is a pointer to a word value which will contain the }{\b\f4 errno}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 errno}}}{\f4 code returned by the function if an error occurs, and should be pushed onto the stack after all the other parameters. The calls do not clear this code to 0 if no error occurs; thus, you must check the return value of the function to see if an error occurred, and then check errno to get the actual error code.
\par }\pard \qj\nowidctlpar\widctlpar\tx3240\adjustright {\f4
\par Do not forget to also push space on the stack}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 stack}}}{\f4 (before the parameters) for the call to store its return value.
\par
\par These low-level system call interfaces are not to be used in general programming. It is assumed the programmer will use the libraries provided, or use this information to create a new library. The system call interface is subject to change without notice; any changes will, of course, be documented in future versions of GNO/ME.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {System Call Error Codes}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074616}System Call Error Codes{\*\bkmkend _Toc364074616}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\tx3240\adjustright {\f4 The following codes are taken from }{\f6 <errno.h}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f6\cgrid {\xe {\v\f6 }{\f6 errno.h}}}{\f6 >}{\f4 . The codes up to EPERM}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EPERM}}}{\f4 are the same values as those defined by ORCA/C}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA/C}}}{\f4 for compatibility reasons. Error conditions are usually reported by system calls by returning a -1 (word) or NULL (long) value. Which error codes can be expected from a particular call are detailed in the errors section in the appropriate manual page.
\par }\pard \qj\li720\nowidctlpar\widctlpar\tx3240\adjustright {\f4
\par }\pard \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright {\f4 EDOM}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EDOM}}}{\f4 \tab domain error. Basically an undefined error code.
\par ERANGE}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ERANGE}}}{\f4 \tab Range error. A value passed to a system call was too large, too small, or illegal.
\par ENOMEM}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ENOMEM}}}{\f4 \tab Not enough memory. The kernel could not allocate enough memory to complete the requested operation.
\par ENOENT}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ENOENT}}}{\f4 \tab No such file or directory. The file specified could not be found.
\par EIO}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EIO}}}{\f4 \tab I/O error. An error occurred trying to perform an I/O operation (could be bad media). Also refers to a disk error not covered by the other errno codes.
\par EINVAL}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EINVAL}}}{\f4 \tab Invalid argument. An argument to a system call was invalid in some way.
\par EBADF}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EBADF}}}{\f4 \tab bad file descriptor. The file descriptor passed to the kernel does not represent an open file.
\par EMFILE}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EMFILE}}}{\f4 \tab too many files are open. The kernel cannot open any more files for this process; it's open file table is full. Close some other open files to retry the operation.
\par EACCESS}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EACCESS}}}{\f4 \tab access bits prevent the operation. One of the access bit settings (delete, rename, read, write) associated with the file does not allow the requested operation.
\par EEXIST}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EEXIST}}}{\f4 \tab the file exists. An attempt to create a new file with the same name as an existing file results in this error.
\par ENOSPC}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ENOSPC}}}{\f4 \tab No space on device. There is not enough room on the requested device to complete the operation. This is usually indicative of a full disk.
\par EPERM}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EPERM}}}{\f4 \tab Not owner. Not yet used in GNO.
\par ESRCH}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ESRCH}}}{\f4 \tab No such process. The process ID specified does not refer to an active process. Possibly the process terminated earlier.
\par EINTR}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EINTR}}}{\f4 \tab Interrupted system call. Certain system calls can be interrupted by signals. In cases where the user has specified that those calls not be automatically restarted, the call will return this error.
\par E2BIG}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 E2BIG}}}{\f4 \tab Arg list too long. Too many arguments were specified in an execve calls.
\par ENOEXEC}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ENOEXEC}}}{\f4 \tab Exec format error. The file specified is not in an executable format (OMF load file).
\par ECHILD}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ECHILD}}}{\f4 \tab No children. This error is returned by }{\b\f4 wait}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 wait}}}{\f4 (2) when there are no child processes left running.
\par EAGAIN}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EAGAIN}}}{\f4 \tab No more processes. The process table is full, the }{\b\f4 fork}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 fork}}}{\f4 (2) cannot complete.
\par ENOTDIR}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ENOTDIR}}}{\f4 \tab Not a directory. One of the elements in a pathname refers to a file which is not a directory.
\par ENOTTY}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ENOTTY}}}{\f4 \tab Not a terminal. The file descriptor passed to an }{\b\f4 ioctl}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 ioctl}}}{\f4 (2) or job control call does not refer to a terminal file.
\par EPIPE}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 EPIPE}}}{\f4 \tab Broken pipe. If a process attempts to write on a pipe with no readers, and has blocked or ignored SIGPIPE}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 SIGPIPE}}}{\f4 , this error is returned by the write operation.
\par ESPIPE}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ESPIPE}}}{\f4 \tab Illegal seek. Similar to ENOTBLK}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ENOTBLK}}}{\f4 , but specific for pipes.
\par ENOTBLK}{\pard\plain \qj\fi-1440\li2160\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ENOTBLK}}}{\f4 \tab not a block device. An attempt to perform an operation on a character device that only makes sense on a block device, e.g. creating a file.
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {System Panics}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074617}System Panics{\*\bkmkend _Toc364074617}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\tx3240\adjustright {\f4 In most cases, if the kernel detects an error in operation an appropriate error code is returned by the function in question (GS/OS call}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 GS/OS call}}}{\f4 s, ToolBox call}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ToolBox call}}}{\f4 s, or system call}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 system call}}}{\f4 s as described above). However, there are rare circumstances where the kernel detects what should be an impossible condition. This can happen due to bugs in the kernel, because the kernel was overwritten by a buggy program, or for any number of other reasons.
\par
\par When the kernel}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 kernel}}}{\f4 does come across such an error, system operation cannot continue and what ensues is called a }{\i\f4 system panic}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\i\f4 system panic}}}{\f4 . Panics are very easily noticed- the kernel}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 kernel}}}{\f4 will print an error message on the screen and ensure that the text screen is visible, turning off any graphics mode if necessary. The kernel then sets the text and background colors to red on white - a very noticeable condition. At that point, the kernel turns off context switch}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 context switch}}}{\f4 ing to prevent any background process or other interrupt}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 interrupt}}}{\f4 driven code from further confusing the system. This is done mainly to prevent damage to disk directory structures by a bad system.
\par }\pard \qj\nowidctlpar\widctlpar\tx3240\adjustright {\f4
\par }\pard \qj\nowidctlpar\widctlpar\tx3240\adjustright {\f4 When a system panic}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 system panic}}}{\f4 does occur, the only thing you can do is reboot your system. If you can reliably reproduce a system panic}{\pard\plain \qj\nowidctlpar\widctlpar\tx3240\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 system panic}}}{\f4 , please record the panic message and the sequence of events necessary to evoke the panic and report the information to Procyon, Inc.
\par
\par }\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid {\page }{Appendix B
\par }\pard \s20\qj\nowidctlpar\widctlpar\adjustright {Miscellaneous Programming Issues}{\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \v\f4\fs48\cgrid {\tc {{\*\bkmkstart _Toc364074618}Miscellaneous Programming Issues{\*\bkmkend _Toc364074618}\tcl1}}}{\b
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par
\par
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Option Arguments}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074619}Option Arguments{\*\bkmkend _Toc364074619}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\f4 The Free Software Foundation (known as the FSF), invented user friendly long format option arguments}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 option arguments}}}{\f4 , and defined the "}{\b\f4 +}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 +}}}{\f4 " character for interpretation that a long format follows. This interpretation is generally followed in the U}{\f4\fs20 NIX}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 UNIX}}}{\f4 community. There are two files which will assist you in programming GNO/ME utilities with both short and long format options, "getopt.h}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 getopt.h}}}{\f4 " for short options}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 short options}}}{\f4 , and "getopt1.h}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 getopt1.h}}}{\f4 " for long options}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 long options}}}{\f4 .
\par }{
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {
\par }\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\f4\cgrid {Pathname Expansion}{\pard\plain \s21\qj\nowidctlpar\widctlpar\adjustright \b\v\f4\cgrid {\tc {{\*\bkmkstart _Toc364074620}Pathname Expansion{\*\bkmkend _Toc364074620}\tcl1}}}{
\par }\pard\plain \qj\nowidctlpar\widctlpar\adjustright \f12\cgrid {
\par }{\f4 Those of you familiar with programming in the ORCA}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\f4 ORCA}}}{\f4 environment should be familiar with the shell calls }{\f6\fs20 InitWildcard}{\f4 }{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\fs20\cgrid {\xe {\v\f6\fs20 }{\f6\fs20 InitWildcard }}}{\f4 and }{\f6\fs20 NextWildcard}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f6\fs20\cgrid {\xe {\v\f6\fs20 }{\f6\fs20 NextWildcard}}}{\f4 . These shell calls, while supported by }{\b\f4 gsh}{\pard\plain \qj\nowidctlpar\widctlpar\adjustright \v\f4\cgrid {\xe {\v\f4 }{\b\f4 gsh}}}{\f4 , are no longer necessary. All shell utilities that work with multiple filenames do not need to provide support for file globbing, as this is taken care of transparently to the command.}{
\par
\par }{\sect }\sectd \linex0\endnhere\titlepg\sectdefaultcl {\headerl \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul \tab Glossary
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\headerr \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Glossary\tab
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerl \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerr \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\footerf \pard\plain \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright \f12\cgrid {\ul \tab \tab
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx10080\adjustright {\tab \tab \chpgn
\par }\pard \s16\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid {Glossary}{\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \v\f4\fs48\cgrid {\tc {{\*\bkmkstart _Toc364074621}Glossary{\*\bkmkend _Toc364074621}\tcl1}}}{
\par }\pard\plain \fi-2340\li2340\nowidctlpar\widctlpar\adjustright \f12\cgrid {\f4
\par }\pard \fi-2340\li2340\nowidctlpar\widctlpar\adjustright {\f4
\par
\par The following terms usually have references in the main text, indicated by italics.
\par }{\b\f4
\par }{\b\i\f4 Asynchronous}{\f4 \tab An event that may take place at any time. See synchronous.
\par }\pard \qj\fi-2340\li2340\nowidctlpar\widctlpar\adjustright {\b\i\f4 BASIC}{\f4 \tab Beginners All-purpose Symbolic Instruction Code. A simple computer language.}{\b\i\f4\fs28
\par }\pard \fi-2340\li2340\nowidctlpar\widctlpar\adjustright {\b\i\f4 Blocked}{\b\f4 \tab }{\f4 Refers to a process waiting for some event to occur. Processes can block on terminal I/O, signals, and other IPC and I/O functions.}{\b\f4
\par }{\b\i\f4 Console}{\b\f4 \tab }{\f4 The terminal which represents the IIGS's keyboard and monitor.}{\b\f4
\par }{\b\i\f4 Context}{\b\f4 \tab }{\f4 The attributes which define the state of a process. This includes the program counter, stack pointer, and other machine registers (both CPU and other computer hardware).}{\b\f4
\par }{\b\i\f4 Controlling terminal}{\b\f4 \tab }{\f4 The terminal which 'controls' a process or process group; processes can receive keyboard signals (such as SIGTSTP, or ^Z) only from their controlling terminal.}{\b\f4
\par }{\b\i\f4 Critical section}{\f4 \tab A piece of code inside which only one process at a time may be allowed to execute. Critical sections are usually protected by semaphores.
\par }{\b\i\f4 Daemon}{\f4 \tab A process that runs in the background and waits to act on an asynchronous event. These can be anything: waiting for a caller on a modem, waiting for spooled files to print, etc. Daemons are usually started at boot time by the }{\b\f4 init}{\f4 (8) process.
\par }{\b\i\f4 Deadlock}{\f4 \tab A situation where two or more communicating processes are blocked, waiting on each other. See Chapter 5, "Deadlock".
\par }{\b\i\f4 Errno}{\b\f4 \tab }{\f4 A variable which holds a descriptive numeric error code, returned from C libraries and system calls.}{\b\f4
\par }{\b\i\f4 Foobar \{foo, bar\}}{\f4 \tab foobar derives from an old military acronym FUBAR. In it's politest interpretation it stands for Fouled Up Beyond All Recognition. Computer scientists borrowed the term and created foobar. When a name for an object is needed but the name itself is not important, foo and bar are first choice among computing science types.
\par }{\b\i\f4 Executable}{\f4 \tab A program as it resides on disk. Executables can be compiled or assembled programs, or shell scripts. Executables are run by typing their name on the shell's command line and frequently take paramters to determine what data they operate on and particulars of how they do it.
\par }\pard \qj\fi-2340\li2340\nowidctlpar\widctlpar\adjustright {\b\i\f4 GNO/ME}{\f4 .\tab GNO Multitasking Environment. The complete package including the GNO kernel and the GNO Shell.
\par }{\b\i\f4 GNO Kernel}{\f4 .\tab Heart of GNO/ME. Executes processes when asked by the GNO Shell
\par }{\b\i\f4 GNO Shell}{\f4 .\tab Provides an interface between the user and the GNO kernel.
\par }{\b\i\f4 gsh}{\f4 .\tab GNO Implementation of a UNIX-like shell.
\par }{\b\i\f4 GS/OS}{\f4 .\tab 16 bit Operating System for the Apple IIgs.}{\b\i\f4
\par }\pard \fi-2340\li2340\nowidctlpar\widctlpar\adjustright {\b\i\f4 IPC}{\b\f4 \tab }{\f4 "Inter-Process Communication". Any method by which processes can pass information to other processes.}{\b\f4
\par }\pard \fi-2340\li2340\nowidctlpar\widctlpar\adjustright {\b\i\f4 Job}{\b\f4 \tab }{\f4 A set of related processes. Jobs are generally composed of processes with a common parent and the same controlling terminal.}{\b\f4
\par }{\b\i\f4 Manpage}{\f4 \tab Refers to the system call and utility documentation provided with GNO. Manpages exist on disk in pre-formatted source form (AppleWorks GS currently), and can be viewed by various utilites on a variety of output devices.
\par }{\b\i\f4 Master}{\b\f4 \tab }{\f4 Refers to the .PTYxx side of a pseudo-terminal, and also the process controlling that device. The master is usually responsible for setting up the PTY and running a process on it.}{\b\f4
\par }{\b\i\f4 Message}{\b\f4 \tab }{\f4 A 32-bit value that is passed via the Messages IPC mechanism to another process.}{\b\f4
\par }{\b\i\f4 Mutex}{\f4 \tab Short for mutual exclusion, a term that refers to protecting a critical section.
\par }{\b\i\f4 Panic}{\b\f4 \tab }{\f4 An unrecoverable kernel error, usually indicating that an internal data structure has become corrupted.}{\b\f4
\par }{\b\i\f4 Parent}{\b\f4 \tab }{\f4 When talking about a process, the parent of a process is the one that spawned it; i.e., made the }{\b\f4 fork}{\f4 () call.}{\b\f4
\par }{\b\i\f4 Pipe}{\f4 \tab A unidirectional IPC mechanism. Pipes transmit binary 8-bit data.
\par }{\b\i\f4 Pipeline}{\f4 \tab Two or more processes connected by pipes.
\par }{\b\i\f4 Port}{\b\f4 \tab }{\f4 A flow-controlled IPC mechanism that can pass longwords of data.}{\b\f4
\par }{\b\i\f4 Process}{\f4 \tab A program in execution.
\par }{\b\i\f4 Process group}{\f4 \tab An identifying code for a job. Process groups are also assigned to TTY's, which allows the TTY to differentiate background jobs from foreground jobs when sending interrupt signals.
\par }{\b\i\f4 Pseudo-terminal}{\b\f4 \tab }{\f4 A bidirectional communications channel, normally used in windowing systems or for advanced control and testing applications.}{\b\f4
\par }{\b\i\f4 PTY}{\b\f4 \tab }{\f4 See 'pseudo-terminal'.}{\b\f4
\par }{\b\i\f4 Semaphore}{\f4 \tab A data object used to synchronize concurrent processes.
\par }{\b\i\f4 Sequentialization}{\f4 \tab The task of ensuring that critical sections are only executed by one concurrent process at a time.
\par }{\b\i\f4 Signal}{\f4 \tab A software interrupt and IPC mechanism.
\par }{\b\i\f4 Slave}{\b\f4 \tab }{\f4 1. A good term to describe the relationship of Joe Citizen to the IRS.
\par \tab 2. The .TTYxx side of a pseudo-terminal; the slave is usually an application program of some kind, like a shell.}{\b\f4
\par }{\b\i\f4 Suspended}{\b\f4 \tab }{\f4 Refers to a process whose execution has been stopped.}{\b\f4
\par }{\b\i\f4 Synchronous}{\f4 \tab An event that takes place at a predetermined time or sequence of times. Also used to indicate the act of waiting for an event to happen. See asynchronous.
\par }{\b\i\f4 Terminal}{\b\f4 \tab }{\f4 Any device that looks like a terminal; this includes pseudo-ttys. By definition, a terminal supports all of the }{\b\f4 tty}{\f4 (4) ioctl calls.}{\b\f4
\par }{\b\i\f4 Tty}{\f4 \tab Short for Teletype. TTY is an anachronistic term; in modern usage it is taken to mean 'terminal'.
\par }\pard \qj\fi-2340\li2340\nowidctlpar\widctlpar\adjustright {\b\i\f4 UNIX}{\f4 .\tab Popular operating system which has growing use in education and business. One of the first operating systems to support multitasking.}{\b\i\f4
\par }\pard \fi-2340\li2340\nowidctlpar\widctlpar\adjustright {\f4
\par }\pard \qj\nowidctlpar\widctlpar\adjustright {\sect }\sectd \sbknone\linex0\endnhere\titlepg\sectdefaultcl {\headerl \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul \tab }{\f5\ul Index}{\f5\ul
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}{\headerr \pard\plain \s17\nowidctlpar\widctlpar\tqr\tx10080\adjustright \f12\cgrid {\f5\ul Index\tab }{\f5\ul
\par }\pard \s17\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright {
\par }}\pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid {\sect }\sectd \linex0\endnhere\titlepg\sectdefaultcl \pard\plain \s20\qj\nowidctlpar\widctlpar\adjustright \f4\fs48\cgrid {Index
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \f12\cgrid {
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\field\fldedit{\*\fldinst {\fs24 INDEX \\h "A" \\c "2" }}{\fldrslt {\fs24\lang1024 \sect }\sectd \sbknone\linex0\cols2\endnhere\titlepg\sectdefaultcl \pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 .
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\b\lang1024 .}{\lang1024 , 11
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\b\lang1024 ..}{\lang1024 , 11
\par .CONSOLE, 7, 8, 17
\par .d2, 12
\par .d5, 12
\par .NULL, 14, 25
\par .PTYQ[0-9,A-F], 14
\par .ptyq0, 25, 33
\par .ttya, 14, 25
\par .TTYA[0-9,A-F], 14
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 .ttyb, 25
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 .TTYCO, 13, 14, 20, 25
\par .ttyq0, 25, 33
\par .ttyqf, 33
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 /
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 /bin, 12
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 /etc, 12
\par /etc/namespace, 12
\par /etc/tty.config, 14
\par /etc/ttys, 17
\par /usr, 12
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 ^
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 ^C, 26, 29
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 ^Z, 26, 29
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 _
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\b\lang1024 _toolErr}{\lang1024 , 7
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 ~
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\b\lang1024 ~}{\lang1024 , 12
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 +
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\b\lang1024 +}{\lang1024 , 40
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 6
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 65816 processor, 9
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 65816 registers, 25
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 A
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\b\lang1024 alarm}{\lang1024 , 25, 29, 37
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 alarm10, 38
\par }{\b\lang1024 alarmCount}{\lang1024 , 25
\par ANDmask, 19
\par APW, 37
\par }{\b\lang1024 args}{\lang1024 , 25
\par Assembly, 8
\par auxType, 9
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 B
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 background, 5, 26, 29
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 Bank 0, 8
\par BASIC, 17
\par }{\i\lang1024 blocked}{\lang1024 , 23, 24
\par BYTEWRKS, 25
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 C
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 C compiler, 8
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 CDA, 20
\par ChangePath, 12
\par character device, 13, 25
\par character devices, 14
\par Character drivers, 19
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 character strings, 8
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 child process, 24, 28, 31
\par chtyp, 9
\par ClearBackupBit, 12
\par Close, 13, 14, 34
\par conf.h, 24
\par console, 7, 21
\par console driver, 7, 8, 13, 17, 19, 20
\par consume, 34
\par }{\i\lang1024 context}{\lang1024 , 23
\par }{\i\lang1024 context switch}{\lang1024 , 23, 25, 26, 27, 30, 39
\par Control Panel, 20
\par controlling terminal, 21
\par }{\i\lang1024 controlling terminal}{\lang1024 , 26
\par }{\i\lang1024 count}{\lang1024 , 27
\par Create, 12
\par creative programming, 8
\par critical section, 27, 28
\par }{\i\lang1024 critical section;}{\lang1024 , 27
\par CTRL-D, 19
\par CurResourceApp, 20
\par custom drivers, 17
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 D
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\i\lang1024 daemon}{\lang1024 , 29
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\i\lang1024 deadlock}{\lang1024 , 28, 35, 36
\par DELETE, 19
\par desktop, 7, 8, 9, 20
\par Destroy, 12
\par device drivers, 8, 26
\par DInfo, 14
\par direct page, 8, 11, 24
\par disk access, 9
\par }{\b\lang1024 dispose}{\lang1024 , 28
\par DMA, 9
\par dp.c, 28
\par driver number, 17
\par DStatus, 14
\par }{\b\lang1024 dup}{\lang1024 , 20, 37
\par dup2, 37
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 E
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 E2BIG, 39
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 EACCESS, 38
\par EAGAIN, 39
\par EBADF, 38
\par ECHILD, 39
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 EDOM, 38
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 EEXIST, 39
\par EINTR, 39
\par EINVAL, 38
\par EIO, 38
\par EMFILE, 38
\par ENOENT, 38
\par ENOEXEC, 39
\par ENOMEM, 38
\par ENOSPC, 39
\par ENOTBLK, 39
\par ENOTDIR, 39
\par ENOTTY, 39
\par EOL, 19
\par EPERM, 38, 39
\par EPIPE, 39
\par ERANGE, 38
\par }{\b\lang1024 errno}{\lang1024 , 37, 38
\par errno.h, 38
\par ESPIPE, 39
\par ESRCH, 39
\par Event Manager, 9, 20
\par Event Manager, 20
\par EXCL, 33
\par EXE, 9, 23, 24
\par }{\b\lang1024 exec}{\lang1024 , 23, 24, 33
\par }{\b\lang1024 execve}{\lang1024 , 13, 15, 24, 26, 28, 37
\par }{\b\lang1024 exit}{\lang1024 , 15
\par ExpandPath, 11, 12
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 F
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 file, 13
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 file descriptor, 13, 17, 34
\par File Level, 12
\par file sharing, 9
\par FIONREAD, 34
\par FlexBeep, 18
\par Flush, 12, 14
\par }{\b\lang1024 fopen}{\lang1024 , 9
\par foreground, 5
\par }{\b\lang1024 fork}{\lang1024 , 23, 24, 26, 31, 37, 39
\par fork2, 38
\par }{\b\lang1024 free}{\lang1024 , 28
\par fstat, 37
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 G
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 GetDirEntry, 14
\par getegid, 37
\par GetEOF, 14
\par geteuid, 37
\par GetFileInfo, 12
\par getgid, 37
\par GetLevel, 13
\par GetMark, 14
\par GetName, 15
\par GetOpenFileRefnum, 20
\par getopt.h, 40
\par getopt1.h, 40
\par getpgrp, 37
\par getpid, 37
\par getppid, 38
\par GetPrefix, 12
\par getuid, 37
\par GNO compliant, 8
\par GNO kernel, 5, 7, 12, 14, 23, 24, 27, 37
\par GNO Snooper CDA, 25
\par gno.h, 7
\par GNO/ME, 5, 7, 8, 9, 11, 12, 13, 15, 17, 20, 23, 27, 28, 29, 30, 31
\par GNO/ME compliance, 7
\par GNO/ME compliant, 8
\par GNO/ME drivers, 14
\par GNO/ME signal, 30
\par }{\b\lang1024 GNOSnooper.c}{\lang1024 , 25
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 GS/OS, 5, 7, 8, 9, 11, 12, 13, 14, 15, 23, 30
\par GS/OS call, 11, 12, 13, 14, 15, 28, 39
\par GS/OS device, 14
\par GS/OS drivers, 13
\par GS/OS errors, 19
\par GS/OS refNum, 31
\par GS/OS signal handler, 30
\par GS/OS signals, 30
\par }{\b\lang1024 gsh}{\lang1024 , 29, 30, 31, 40
\par GSI, 35
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 H
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 hardware interrupt, 28
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 I
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 I/O, 7, 8, 9, 13, 17, 24, 25, 30, 31
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 I/O masks, 19
\par }{\b\lang1024 init}{\lang1024 , 32
\par initPipe, 33, 34
\par InitWildcard, 40
\par Interprocess Communication, 27
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 interrupt, 39
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 interrupt handler, 20, 25, 26, 30
\par }{\b\lang1024 ioctl}{\lang1024 , 8, 14, 26, 34, 37, 39
\par }{\i\lang1024 IPC}{\lang1024 , 27, 28, 30, 32, 35
\par }{\b\lang1024 irq_A}{\lang1024 , 25
\par }{\b\lang1024 irq_B}{\lang1024 , 25
\par }{\b\lang1024 irq_D}{\lang1024 , 25
\par }{\b\lang1024 irq_K}{\lang1024 , 25
\par }{\b\lang1024 irq_P}{\lang1024 , 25
\par }{\b\lang1024 irq_PC}{\lang1024 , 25
\par }{\b\lang1024 irq_S}{\lang1024 , 25
\par }{\b\lang1024 irq_state}{\lang1024 , 25
\par }{\b\lang1024 irq_X}{\lang1024 , 25
\par }{\b\lang1024 irq_Y}{\lang1024 , 25
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 J
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 Job control, 26
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 K
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 kernel, 7, 27, 28, 39
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 kernel, 35
\par }{\b\lang1024 kernStatus}{\lang1024 , 7
\par }{\b\lang1024 kernVersion}{\lang1024 , 7
\par keyboard input, 8
\par keyboard latch, 8
\par }{\b\lang1024 kill}{\lang1024 , 23, 26, 29, 37
\par kill, 35
\par KVM, 24
\par kvm_close, 37
\par kvm_getproc, 37
\par kvm_nextproc, 37
\par kvm_open, 24, 37
\par kvm_setproc, 37
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 L
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 LEFT-ARROW, 19
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 local arrays, 8
\par long options, 40
\par }{\b\lang1024 longjmp}{\lang1024 , 30
\par }{\b\lang1024 lpd}{\lang1024 , 29, 32
\par }{\b\lang1024 lpr}{\lang1024 , 29
\par lstat, 37
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 M
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 main memory, 8
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\b\lang1024 malloc}{\lang1024 , 8
\par master, 33, 34
\par }{\i\lang1024 master.}{\lang1024 , 33
\par Memory Manager, 8, 23
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 messages, 27, 32
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 MiscTool, 19
\par modem, 7, 14, 25
\par multitasking, 5, 11, 12, 17, 20, 27
\par }{\i\lang1024 mutual exclusion}{\lang1024 , 28
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 N
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 NEW, 25
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 NextWildcard, 40
\par }{\b\lang1024 NPROC}{\lang1024 , 24
\par Null device driver, 17
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 O
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 OA-D, 19
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 OA-E, 19
\par Open, 12, 13, 14
\par }{\b\lang1024 openFiles}{\lang1024 , 25
\par OpenGS, 9
\par option arguments, 40
\par ORCA, 12, 15, 17, 37, 40
\par ORCA/C, 8, 38
\par ORCA/C 1.2, 9
\par ORCA/C 1.3, 8, 9, 15
\par ORCA/C 2.0, 9, 15
\par ORmask, 19
\par OSShutdown, 15
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 P
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 parent process, 23, 28, 31
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 Pascal compiler, 28
\par Pascal control codes, 13
\par Pascal driver, 17
\par Pascal firmware, 17
\par }{\b\lang1024 pause}{\lang1024 , 26
\par PAUSED, 25
\par }{\b\lang1024 pbind}{\lang1024 , 32, 38
\par }{\b\lang1024 pcreate}{\lang1024 , 32, 38
\par }{\b\lang1024 pdelete}{\lang1024 , 32, 38
\par pgetcount, 38
\par }{\b\lang1024 pgetport}{\lang1024 , 32, 38
\par pipe, 13, 17, 25, 27, 29, 30, 31, 37
\par pipe*.c, 28, 31
\par pipeline, 26, 31
\par port drivers, 14, 25
\par port ID, 32
\par ports, 27, 32
\par }{\b\lang1024 preceive}{\lang1024 , 32, 38
\par }{\i\lang1024 preemptive multitasking}{\lang1024 , 23
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 prefixes, 11
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 preset, 38
\par print spooler, 29
\par }{\b\lang1024 printer}{\lang1024 , 14, 25, 29
\par }{\b\lang1024 printf}{\lang1024 , 28
\par proc.h, 24, 25
\par }{\i\lang1024 process}{\lang1024 , 23, 26, 27, 29
\par process, 35
\par }{\i\lang1024 process group.}{\lang1024 , 26
\par }{\i\lang1024 process ID}{\lang1024 , 23, 32
\par process table, 24
\par }{\b\lang1024 processState}{\lang1024 , 24
\par ProDOS-16, 11
\par producer, 34
\par }{\b\lang1024 ps}{\lang1024 , 24
\par }{\b\lang1024 psend}{\lang1024 , 32, 38
\par Pseudo-terminals, 14, 27, 33
\par PTY, 14, 33, 34, 35
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 Q
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 QDStartup, 21
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 QuickDraw, 11, 37
\par QUIT, 13, 15
\par QuitGS, 13, 15
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 R
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 Read, 14
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 ReadChar, 19
\par ReadLine, 19
\par READY, 24
\par }{\b\lang1024 receive}{\lang1024 , 26, 32, 37
\par recursion, 8
\par recvclr, 37
\par }{\b\lang1024 recvtim}{\lang1024 , 32, 37
\par redirection, 17, 33
\par }{\i\lang1024 reentrant}{\lang1024 , 28
\par refNum, 13, 14, 17, 25, 31
\par RELEASE.NOTES, 9
\par requestAccess, 9
\par resource, 20
\par Resource Manager, 20
\par RestAll, 20
\par restartability, 14
\par }{\b\lang1024 rexit}{\lang1024 , 15
\par RIGHT-ARROW, 19
\par }{\i\lang1024 round-robin scheduling}{\lang1024 , 23
\par RUNNING, 24, 25
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 S
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 S16, 9, 23, 24
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 SANE, 11
\par SaveAll, 20
\par scount, 38
\par }{\b\lang1024 screate}{\lang1024 , 27, 37
\par screen memory, 8
\par script, 31, 35
\par }{\b\lang1024 sdelete}{\lang1024 , 28, 37
\par semaphore, 27, 28, 31
\par semaphore pool, 28
\par semaphores, 28
\par }{\b\lang1024 send}{\lang1024 , 26, 32, 37
\par serial driver, 17
\par serial driver, 17
\par serial ports, 8, 9
\par setdebug, 37
\par SetEOF, 14
\par SetFileInfo, 12
\par setgid, 37
\par SetGNOQuitRec, 38
\par SetInGlobals, 19
\par SetInputDevice, 17
\par }{\b\lang1024 setjmp}{\lang1024 , 30
\par SetLevel, 13
\par SetMark, 14
\par SetOutputDevice, 17
\par setpgrp, 38
\par SetPrefix, 11, 12
\par setsystemvector, 37
\par }{\b\lang1024 settpgrp}{\lang1024 , 26, 37
\par setuid, 37
\par shared information, 27
\par short options, 40
\par SIGALRM, 25, 29
\par sigblock, 37
\par SIGCHLD, 24, 25, 29
\par SIGCONT, 29
\par SIGHUP, 35
\par SIGINT, 26, 29
\par SIGKILL, 29
\par }{\i\lang1024 signal}{\lang1024 , 24, 25, 27, 28, 29, 30, 37
\par signal, 35
\par signal handler, 28, 30
\par signal.h, 28
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\b\lang1024 sigpause}{\lang1024 , 26, 37
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 SIGPIPE, 29, 31, 39
\par sigsetmask, 37
\par SIGSTOP, 25, 29
\par SIGTERM, 29
\par SIGTSTP, 25, 26, 29
\par SIGTTIN, 25, 26, 29
\par SIGTTOU, 25, 29
\par SIGUSR, 29
\par SIGUSR, 30
\par SIGUSR1, 29
\par SIGUSR2, 29
\par }{\i\lang1024 slave}{\lang1024 , 33, 34
\par slave, 35
\par slot-dependence, 17
\par slotNum, 17
\par spooler, 29
\par }{\b\lang1024 ssignal}{\lang1024 , 27, 28, 37
\par Stack, 8, 38
\par stack frames, 8
\par stack pointer, 30
\par stack segment, 8
\par stack space, 24
\par standard loops, 8
\par stat, 37
\par static, 8
\par stderr, 8
\par stdin, 8
\par stdio library, 28
\par stdout, 8
\par string manipulation, 8
\par struct fdentry, 25
\par struct ftable, 25
\par SUSPENDED, 25, 27
\par }{\b\lang1024 swait}{\lang1024 , 27, 28, 37
\par SYS.RESOURCES, 20
\par SYSCMND, 15
\par SysFailMgr, 19
\par System 6.0.1, 7
\par system call, 23, 27, 29, 37, 39
\par system calls, 37
\par system panic, 20, 39
\par System Software 5.0.4, 12
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 T
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\b\lang1024 tcnewpgrp}{\lang1024 , 26, 37
\par }{\b\lang1024 tctpgrp}{\lang1024 , 26, 37
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 terminal, 8, 33
\par TextTools, 7, 8, 9, 13, 14, 17, 19, 20
\par }{\b\lang1024 ticks}{\lang1024 , 25
\par time slice, 23
\par times, 38
\par Tool locator, 7
\par ToolBox, 7, 11, 17, 28
\par ToolBox call, 23, 30, 39
\par }{\b\lang1024 toolerror}{\lang1024 , 7
\par Tools, 8
\par toOut, 34
\par TTY, 13, 14, 24, 25, 29, 33
\par tty.config, 25
\par }{\b\lang1024 ttyID}{\lang1024 , 25
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 U
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 UNIX, 9, 12, 13, 20, 24, 28, 29, 33, 40
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 userID, 23, 24
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 V
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\lang1024 variable, 8
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 virtual memory, 28
\par }\pard\plain \s39\li140\sb240\sa120\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\cgrid {\b0\f0\lang1024 W
\par }\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {\b\lang1024 wait}{\lang1024 , 24, 26, 29, 37, 39
\par }\pard \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright {\lang1024 WAITING, 25
\par WAITSIGCH, 25
\par }{\b\lang1024 while}{\lang1024 , 30
\par Window Manager, 30
\par Write, 14
\par }{\b\lang1024 writeln}{\lang1024 , 28
\par }{\fs24\lang1024 \sect }\sectd \sbknone\linex0\endnhere\titlepg\sectdefaultcl \pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid }}\pard\plain \s29\fi-240\li240\nowidctlpar\widctlpar\tqr\tx4680\adjustright \fs18\cgrid {
\par }}