home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / pascal / 4947 < prev    next >
Encoding:
Internet Message Format  |  1992-08-20  |  27.1 KB

  1. Path: sparky!uunet!munnari.oz.au!metro!grivel!metz.une.edu.au!ddavidso
  2. From: ddavidso@metz.une.edu.au (Dean Davidson)
  3. Newsgroups: comp.lang.pascal
  4. Subject: Re: Network Programming....
  5. Keywords: Netbios Netware TCP/IP
  6. Message-ID: <1682@grivel.une.edu.au>
  7. Date: 20 Aug 92 23:15:07 GMT
  8. References: <12AUG199221531849@gergo.tamu.edu>
  9. Sender: usenet@grivel.une.edu.au
  10. Organization: University of New England, Armidale, Australia
  11. Lines: 622
  12.  
  13. In article <12AUG199221531849@gergo.tamu.edu> chris@gergo.tamu.edu (Chris King) writes:
  14. >Does anyone out there know how to program networks with Turbo Pascal,
  15. >and If so are you willing to share the information.
  16. >
  17.  
  18. I have been waiting for someone more knowledgeable than me to reply to
  19. this, but no one did.  For some reason network programming is kept as a
  20. deep dark secret by those in the know.  The rest of us just have to muddle
  21. through.
  22.  
  23. For what it is worth, here is my experiences etc.
  24.  
  25. As another poster mentioned, first run your programs, and use the data from,
  26. one common directory on the server disk, eg F:\COMMON
  27.  
  28. Make sure that the server loads SHARE - I do it in CONFIG.SYS with:
  29. INSTALL=C:\DOS\SHARE.EXE/L:200/F:2048
  30.  
  31. The next thing is a magic line in you program somewhere that says:
  32. filemod := 66;
  33.  
  34. This allows shared acces to your files. (see article by John Wulff, appended
  35. to this post)
  36.  
  37. Having done this, you are up and running!  That is, one workstation can read
  38. a data file while another writes to it.
  39.  
  40. You may however want to try record locking.  In one application I have,
  41. a log file is maintained of certain status functions.  Naturally I don't
  42. want two workstations writing to this at the same time.  Have a look at
  43. Karl Brendel's article (appended) about a DOS method, but I do it using
  44. TP.
  45.  
  46. Following is three inclusions.  First, my method of locking
  47. Second John Wullf's article, third Karl Brendel's posting.
  48.  
  49. I hope this is useful and takes some of the mystery out of network programming
  50.  
  51. Cheers,
  52. Dean
  53.  
  54. -----------------------------------------------------------------------------
  55.  
  56. { Record locking program fragment}
  57.  
  58. type
  59. masty = record
  60.           log : boolean;
  61.           {locks for other files}
  62.         end;
  63.  
  64. function log_is_locked : boolean;
  65. {check if log file is locked}
  66.  
  67. var
  68. fmast : file of masty;
  69. mastrec : masty;
  70.  
  71. begin
  72.   assign(fmast,mastnam);
  73.   reset(fmast);
  74.   read(fmast,mastrec);
  75.   log_is_locked := mastrec.log;
  76.   close(fmast);
  77. end;
  78.  
  79. procedure lock_log;
  80. {lock log file}
  81. var
  82. fmast : file of masty;
  83. mastrec : masty;
  84.  
  85. begin
  86.   assign(fmast,mastnam);
  87.   reset(fmast);
  88.   read(fmast,mastrec);
  89.   mastrec.log := True;
  90.   reset(fmast);
  91.   write(fmast,mastrec);
  92.   close(fmast);
  93. end;
  94.  
  95. procedure unlock_log;
  96. {unlock log file}
  97. var
  98. fmast : file of masty;
  99. mastrec : masty;
  100.  
  101. begin
  102.   assign(fmast,mastnam);
  103.   reset(fmast);
  104.   read(fmast,mastrec);
  105.   mastrec.log := False;
  106.   reset(fmast);
  107.   write(fmast,mastrec);
  108.   close(fmast);
  109. end;
  110.  
  111. procedure open_logfile(lock : boolean);
  112. {open log file, optionally lock it if lock is true}
  113.  
  114. begin
  115.   while log_is_locked do  {dont let anyone else on the network at it}
  116.     delay(random(2000));  {retry randomly at an average of 1 second intervals}
  117.  
  118.   if lock then {going to be writing to it}
  119.     lock_log;
  120.   assign(flog,flognam);
  121.   reset(flog);
  122. end;
  123.  
  124. procedure close_logfile;
  125. {close the log file, removing any locks}
  126. begin
  127.   close(flog);
  128.   unlock_log;
  129. end;
  130.  
  131. {initialisation}
  132. var
  133. fmast : file of masty;
  134. mastrec : masty;
  135.  
  136. begin
  137.   {set the master file holding the locks, so that none are on}
  138.   assign(fmast,mastnam);
  139.   rewrite(fmast);
  140.   mastrec.log := False;
  141.   {other locks here}
  142.   write(fmast,mastrec);
  143.   close(fmast);
  144. end.
  145.  
  146. ------------------------------------------------------------------------------
  147.  
  148.  
  149.                         Methods for Dealing with Shared Files
  150.                              in TURBO Pascal Version 5.0
  151.                                           by
  152.                                     John W. Wulff
  153.                                Wulff Enterprises, Inc.
  154.                                  260 Terranova Drive
  155.                               Warrenton, VA  22186-9227
  156.                                     (703) 349-8805
  157.  
  158.                                  Revised May 15, 1989
  159.            
  160.           This paper was first written January 19, 1987 as a means of
  161.           demonstrating how to modify Turbo Pascal 3.x to handle the
  162.           opening of READ-ONLY files and to make it able to deal with files
  163.           in a Shared, network environment.  It provided a means of finding
  164.           an undocumented byte known as the "Open Mode Byte".  Since then,
  165.           Turbo Pascal 5.0 has been released and this byte has been
  166.           globally declared as the FILEMODE variable.  Even so, Turbo
  167.           Pascal 5.0 ignores the variable when opening TEXT files.  While
  168.           there is a small explanation in the Turbo Pascal Reference Guide
  169.           as to its use, the information in this paper is still valid today
  170.           and has been updated to reflect its relevance to Turbo Pascal
  171.           5.0.  For those wishing to continue to work in Turbo Pascal 3.0,
  172.           I have included the locations for this byte in appendix A.
  173.  
  174.           There have been many innovations in the development of PCBoard
  175.           software for BBS's.  One of which is the network environment that
  176.           the authors have included in the code.  While this is wonderful
  177.           for the multi-node system, it does pose certain problems and
  178.           restrictions on application programs and utilities that are being
  179.           written for it, especially those written in Borland's Turbo
  180.           Pascal.
  181.  
  182.           One problem that plagues most authors writing application
  183.           programs that eventually become used in network environments is
  184.           coping with the Share utility that DOS uses to protect files. 
  185.           Any file opened for reading under Turbo Pascal will cause a
  186.           Sharing violation if running under a DOS 3.x and 4.x networking
  187.           mode.  This is because Turbo Pascal opens all files in what is
  188.           known as "Inherited by Child Processes, Compatibility Mode,
  189.           Read/Write access". 
  190.  
  191.           I have written a utility for PCBoard systems, PCBFile, and since
  192.           it is extremely file intensive, I've had to do some research on
  193.           the technical aspects of DOS in the network mode.  Because of
  194.           this research, I've been able to get Turbo Pascal to cooperate
  195.           and have written this paper to help other authors who are
  196.           struggling with the same problems.
  197.  
  198.           As documented in the Turbo Pascal instructions, the FILEMODE
  199.           variable has a value of 2 when opening files for RESET or REWRITE
  200.           which allows both reading and writing.  The instructions suggest
  201.           that you should assign a value of 0 to the variable to RESET or
  202.           REWRITE read-only files.  While this works for READ-ONLY files,
  203.           it is not the only value to consider when running an application
  204.           in a network environment, especially one with PCBoard software
  205.           upon which I will focus my attention for the remainder of the
  206.           document.
  207.            
  208.           One thing to consider, if using other languages, especially
  209.           assembly language, is that this FILEMODE variable, corresponds to
  210.           the AL register.  All references to that byte and its decimal
  211.           number can be applied to assembly in this way: 
  212.  
  213.                  AH contains 3DH - the function call 
  214.                  DS:DX points to an ASCIIZ path name 
  215.                  AL will be loaded with the 8 bit number that the          
  216.                  FILEMODE variable contains. 
  217.  
  218.           When the function returns, AX will contain error codes or a 16
  219.           bit file handle if successful.  (See DOS manual for details.)  I
  220.           don't profess to be anywhere close to fluent in assembly so I
  221.           will leave this information with those who are best suited to
  222.           take advantage of it. 
  223.  
  224.           This variable is GLOBALLY pre-declared in Turbo Pascal, so all
  225.           you have to do is refer to it as FILEMODE.  Then a simple check
  226.           is necessary to see if the variable contains a 2 and if so, load
  227.           it with a 0: 
  228.            
  229.                          begin 
  230.                            if FILEMODE = 2 then 
  231.                              FILEMODE := 0; 
  232.                          end;
  233.  
  234.           The completed routine would look like this:  
  235.  
  236.           Procedure OpenMode(Var OpenFile : text; 
  237.                                InFileName : string
  238.                              Var GoAhead  : boolean); 
  239.  
  240.           {Remember, FILEMODE is a GLOBALLY declared variable of type
  241.            byte.  No other declaration is necessary on your part}
  242.  
  243.           begin 
  244.             if FILEMODE = 2 then 
  245.               FILEMODE := 0; (* allows reading of READ-ONLY files *) 
  246.             assign(OpenFile,InFileName); 
  247.             {$I-} reset(Openfile) {$I+}; 
  248.             GoAhead := (ioresult = 0);   
  249.             if GoAhead then 
  250.               writeln(InFileName,' opened!') 
  251.             else 
  252.               writeln(InFileName,' failed to open!'); 
  253.           end; { of Procedure OpenMode } 
  254.  
  255.           Now we need to determine just what is going on with PCBoard and
  256.           how it opens files using DOS's SHARE.   The DIR files, or the
  257.           files that contain the filenames of the available files for the
  258.           user to download, are opened in READ SHARED mode which in
  259.           QuickBASIC would be: 
  260.  
  261.               OPEN "<filename>" FOR INPUT ACCESS READ SHARED AS #1.   
  262.  
  263.           Upload DIR files are opened for APPEND in a LOCKED WRITE mode.
  264.           This keeps other nodes from writing at that particular moment but
  265.           allows other nodes to read this file.
  266.  
  267.           In order to accomplish these same modes in Turbo Pascal we must
  268.           look into the DOS Technical Reference Manual (groan!).  The
  269.           following is reprinted from that manual with some additions by
  270.           me.
  271.  
  272.           The OPEN mode consists of 4 bit-oriented fields:     
  273.                * INHERITANCE FLAG
  274.                * SHARING MODE FIELD 
  275.                * RESERVED FIELD 
  276.                * ACCESS FIELD   
  277.           The INHERITANCE FLAG determines if the file will ever be
  278.           inherited by another process, which in the case of a network is
  279.           usually the desired effect.  The SHARING FIELD defines what
  280.           operations may be performed on the file by other nodes.  The
  281.           ACCESS FIELD defines what operations THIS node may perform on the
  282.           file.  
  283.  
  284.           The bit fields are mapped as follows: 
  285.                               <I> < S > <R> < A > 
  286.              Open Mode bits    7  6 5 4  3  2 1 0 
  287.           I  INHERITANCE FLAG 
  288.              If I = 0; File is inherited by child processes 
  289.              If I = 1; File is private to the current process 
  290.  
  291.           S  SHARING MODE 
  292.              The file is opened like this:
  293.              if S = 000;  Compatibility mode - The default open mode - it
  294.                           denies ALL OTHER processes access to the file. 
  295.                           Since this is the mode that Turbo Pascal uses to
  296.                           open a file, what do you think will happen on the
  297.                           BBS side if you have a file open on your end and
  298.                           the BBS tries to open it? 
  299.              if S = 001;  Deny Read/Write mode (Exclusive).  This would
  300.                           actually be the same as setting the I flag to 1. 
  301.              if S = 010;  Deny Write mode - you should open a file in this
  302.                           mode if you wish to protect it.  It will allow
  303.                           other processes to read it but not write.
  304.              if S = 011;  Deny Read mode 
  305.              if S = 100;  Deny None mode - Who cares what happens!
  306.  
  307.           It is important to specify what operations you want to perform
  308.           (access mode).  The default access mode is Read/Write and causes
  309.           the open request to fail if another process has the file opened
  310.           with any sharing mode other than Deny None.  File sharing
  311.           requires cooperation of both sharing processes.  This is
  312.           communicated through the sharing and access modes.
  313.  
  314.           R  RESERVED (set third bit field to 0)
  315.  
  316.           A  ACCESS - The file access is assigned as follows:
  317.  
  318.              If A = 000; Read Access 
  319.              if A = 001; Write Access 
  320.              if A = 010; Read/Write access
  321.  
  322.           If all this seems a bit involved, I'm sorry.  I don't know of any
  323.           way to give you the background for all this hocus-pocus except
  324.           with the above info.  I also recommend picking up a Tech Ref
  325.           manual for more detailed study of the 3DH function call.
  326.  
  327.           OK!  With all these numbers in hand, let's see how to get Turbo
  328.           Pascal to duplicate these modes.  Earlier I said that other gurus
  329.           had stated that Turbo Pascal opens files in COMPATIBILITY MODE
  330.           with READ/WRITE ACCESS and INHERITANCE BY CHILD PROCESSES and the
  331.           magic value for the FILEMODE variable is 2.  Let's look at how
  332.           that was done:
  333.  
  334.                Compatibility mode:   000 {S} 
  335.                Read/Write ACCESS :   010 {A} 
  336.                Inherited by child:     0 {I} 
  337.                Reserved as ALWAYS:     0 {R} 
  338.            
  339.           Remember the bit fields are: 
  340.                               <I> < S > <R> < A > 
  341.              Open Mode bits    7  6 5 4  3  2 1 0  Let's plug in 
  342.                                0  0 0 0  0  0 1 0  the numbers. 
  343.           Using binary arithmetic: 
  344.                               <I> <  S   > <R> < A >
  345.                               128 64 32 16  8  4 2 1
  346.                                0   0  0  0  0  0 1 0 = 00000010 = 2 
  347.             
  348.           By using a FILEMODE value of 0 we change the ACCESS field to 000,
  349.           READ ACCESS, which allows us to read a READ-ONLY file.
  350.            
  351.           PCBoard is opening its DIR files as READ ACCESS SHARED and
  352.           actually opening the file with a SHARING MODE of Deny/Write which
  353.           would be a SHARE <S> field of 010.  The value for the FILEMODE
  354.           variable then becomes: 
  355.                               <I> <  S   > <R> < A > 
  356.                               128 64 32 16  8  4 2 1 
  357.                                0   0  1  0  0  0 0 0 = 00100000 = 32
  358.  
  359.           This is how I open ALL my files for reading or for general
  360.           ASSIGNING for RESET in Turbo Pascal for my program PCBFile.  I
  361.           have some procedures written for TEXT files, and files of type
  362.           BYTE.  I have reproduced the code below:  
  363.           (* This procedure, KeepOn, is used to determine if the file has 
  364.           been locked out.  I try a file for 10 times as determined by 
  365.           OpenAtt variable before I give up  *) 
  366.            
  367.           Procedure KeepOn(OpenAtt : byte; var GA : boolean); 
  368.           begin 
  369.             if OpenAtt <= 10 then 
  370.               GA := TRUE      (* GoAhead Flag - if within 10 go for it *) 
  371.             else GA := FALSE;    (* forget it! *) 
  372.           end; {of Procedure KeepOn}
  373.            
  374.           Procedure SetResetMode(Var OpenFile : text;  (* OPEN MODE FOR
  375.                                  InFileName   : string;    TEXT FILES *) 
  376.                                   Var GoAhead : boolean); 
  377.           var
  378.             OpenAttempts  : byte; 
  379.  
  380.           begin 
  381.             OpenAttempts := 1; 
  382.             FILEMODE := 32;         (* this is Deny Write                  
  383.                                        Mode/Read Access *) 
  384.             assign(OpenFile,InFileName); 
  385.             repeat 
  386.               {$I-} reset(Openfile) {$I+}; 
  387.               GoAhead := (ioresult = 0); 
  388.               if not GoAhead then 
  389.                 OpenAttempts := OpenAttempts + 1; 
  390.             until (GoAhead) OR (OpenAttempts > 10); (* keep trying *) 
  391.             KeepOn(OpenAttempts,GoAhead); 
  392.           end; {of Procedure SetResetMode} 
  393.            
  394.           Procedure SetResetModeFile(Var OpenFile : file of byte 
  395.                                      InFileName   : string;                
  396.                                       var GoAhead : boolean);             
  397.           var 
  398.             OpenAttempts  : byte; 
  399.           begin 
  400.             OpenAttempts := 1; 
  401.             if FILEMODE := 32;   (* this is Deny Write                     
  402.                                   Mode/Read Access *)    
  403.           assign(OpenFile,InFileName); 
  404.             repeat 
  405.               {$I-} reset(Openfile) {$I+}; 
  406.               GoAhead := (ioresult = 0); 
  407.               if not GoAhead then OpenAttempts := OpenAttempts + 1; 
  408.             until GoAhead OR (OpenAttempts > 10); 
  409.             KeepOn(OpenAttempts,GoAhead); 
  410.           end; {of Procedure SetResetModeFile}
  411.  
  412.           Now here comes a little zinger to change things up.  I want to
  413.           create a file that I don't want the other nodes to damage.  I
  414.           elect to open the file for READ/WRITE ACCESS for myself and give
  415.           the other nodes READ capability and deny them the ability to
  416.           write to my file.  This would be Deny/Write Mode under the <S> or
  417.           SHARING FIELD and would be coded 010.  For READ/WRITE ACCESS the
  418.           <A> or ACCESS FIELD is coded 010 also.  This is the same mode
  419.           that PCBoard uses for writing to the Upload directory.  Using our
  420.           binary formulae, the FILEMODE value then becomes: 
  421.                               <I> <  S   > <R> < A > 
  422.                               128 64 32 16  8  4 2 1 
  423.                                0   0  1  0  0  0 1 0 = 00100010 = 34 
  424.  
  425.           With the magic number of 34 the SetFileLock procedure was born.
  426.            
  427.           Procedure SetFileLock(Var   OpenFile : text;
  428.                                     InFileName : string; 
  429.                                    var GoAhead : boolean); 
  430.           var 
  431.             OpenAttempts  : byte;  
  432.  
  433.           begin 
  434.             OpenAttempts := 1; 
  435.             FILEMODE := 34;      (* Deny Write Mode/Read-Write Access *) 
  436.             assign(OpenFile,InFileName); 
  437.             repeat 
  438.               {$I-} rewrite(Openfile) {$I+}; 
  439.               GoAhead := (ioresult = 0); 
  440.               if not GoAhead then 
  441.                 OpenAttempts := OpenAttempts + 1; 
  442.             until GoAhead or (OpenAttempts > 10); 
  443.             KeepOn(OpenAttempts,GoAhead); 
  444.           end; {of Procedure SetFileLock}
  445.            
  446.           Finally, a little walk around the park to insure that the
  447.           FILEMODE variable is returned to Borland's normal mode.
  448.  
  449.           Procedure ReleaseOpenMode; 
  450.  
  451.           begin 
  452.             FILEMODE := 2; 
  453.           end; 
  454.  
  455.           So it's really simple to change the Turbo Pascal Open mode to
  456.           exactly what you want, you just have to know what results you
  457.           desire from the program.  Just remember these definitions of the
  458.           fields that make up the magic number for DOS Function call 3DH. 
  459.            
  460.           * INHERITANCE FLAG       I = 0;   Inherited (usually the case) 
  461.                                    I = 1;   Private
  462.  
  463.           * SHARING MODE FIELD     (Other node or process)
  464.                                    S = 000; Compatibility mode 
  465.                                    S = 001; Deny Read/Write mode           
  466.                                    (Exclusive) 
  467.                                    S = 010; Deny Write mode 
  468.                                    S = 011; Deny Read mode 
  469.                                    S = 100; Deny None mode 
  470.  
  471.           * RESERVED FIELD         R = 0; Always 
  472.  
  473.           * ACCESS FIELD           (Your node or process) 
  474.                                    A = 000; Read Access 
  475.                                    A = 001; Write Access 
  476.                                    A = 010; Read/Write Access
  477.           The bit fields: 
  478.                                    <I> < S > <R> < A >
  479.                   Open Mode bits    7  6 5 4  3  2 1 0 
  480.            
  481.           Even though a DOS Technical Reference Manual gives a more
  482.           thorough discussion of Function Call 3DH, I will attempt to
  483.           create a matrix with the number for the FILEMODE variable based
  484.           on the SHARE and ACCESS fields. 
  485.            
  486.             ACCESS   |SHARE-> Compat  Deny/RW  Deny/W  Deny/R  Deny/N 
  487.              |                 000      001     010     011     100 
  488.              v              ------------------------------------------- 
  489.             Read  000       |   0    |   16  |   32  |   48  |   64   | 
  490.                             |--------|-------|-------|-------|--------| 
  491.             Write 001       |   1    |   17  |   33  |   49  |   65   | 
  492.                             |--------|-------|-------|-------|--------| 
  493.             Read/ 010       |   2    |   18  |   34  |   50  |   66   | 
  494.             Write           ------------------------------------------- 
  495.            
  496.           I know that this is probably more than a human can bear to
  497.           assimilate at any one time but I hope that you will be able to
  498.           see the logic behind my system and be able to use Turbo Pascal to
  499.           its full potential.  
  500.            
  501.           PCBoard (c) Clark Development Company, Inc., Murray, UT 
  502.           Turbo Pascal (c) Borland International, Scotts Valley, CA 
  503.           PCBFile (c) John W. Wulff 
  504.           Compuserve (c) Compuserve, Inc., Columbus, OH 
  505.  
  506.                                        Appendix
  507.  
  508.           For Turbo Pascal 3.x Die-Hards:
  509.  
  510.           Bela Lubkin published a text article, ACMODE.DOC, which is on
  511.           Compuserve in the Borland Sig that gives the locations of a
  512.           little gem known as the "Open Mode Byte".  This byte is at an
  513.           absolute address for the various editions of Turbo Pascal and
  514.           communicates to DOS, via Function call 3DH, how the file is to be
  515.           accessed and what access to give other processes.  It also
  516.           becomes very handy for us in trying to use Turbo Pascal in a
  517.           network environment. These locations are:
  518.                Open mode byte for Reset & Rewrite for Turbo 3.00x (PC-DOS) 
  519.                     TURBO.COM      CSEG:$248D 
  520.                     TURBO-87.COM   CSEG:$1F3C 
  521.                     TURBOBCD.COM   CSEG:$2393 
  522.               Open mode byte for Reset & Rewrite for Turbo 3.00x (MS-DOS) 
  523.                     TURBO.COM      CSEG:$2182 
  524.                     TURBO-87.COM   CSEG:$1C31 
  525.                     TURBOBCD.COM   CSEG:$2088 
  526.               Open mode byte for Reset & Rewrite for Turbo 3.01x (PC-DOS) 
  527.                     TURBO.COM      CSEG:$24FC 
  528.                     TURBO-87.COM   CSEG:$1FAB 
  529.                     TURBOBCD.COM   CSEG:$2402 
  530.               Open mode byte for Reset & Rewrite for Turbo 3.01x (MS-DOS) 
  531.                     TURBO.COM      CSEG:$21D4 
  532.                     TURBO-87.COM   CSEG:$1C83 
  533.                     TURBOBCD.COM   CSEG:$20DA 
  534.               Open mode byte for Reset & Rewrite for Turbo 3.02x (PC-DOS) 
  535.                     TURBO.COM      CSEG:$24C6 
  536.                     TURBO-87.COM   CSEG:$1F75 
  537.                     TURBOBCD.COM   CSEG:$23CE 
  538.            
  539.           Another valuable document is Robert K. Blaine's RES_MODE.INC,
  540.           also available on CSERV.  It details the procedure for finding
  541.           out the location of this byte, using DEBUG.
  542.  
  543. ------------------------------------------------------------------------------
  544.  
  545.  
  546. From: CDCKAB%EMUVM1.BITNET@cunyvm.cuny.edu ( Karl Brendel)
  547. Subject: Re: Share
  548.  
  549. In article <sLD243w164w@dat1hb.north.de>, lion@dat1hb.north.de
  550.   (Daniel Tietze) wrote:
  551.  
  552. >  I have a question about using SHARE (as supplied with MS-DOS) with
  553. >Turbo Pascal programs. How can I check SHARE violations in my
  554. >program? What exactly does SHARE do when it encounters a sharing
  555. >violation? I believe the IOResult is set to an appropriate value,
  556. >but I don't know exactly which result is to be expected.
  557.  
  558. Sharing and locking are separate but related matters.
  559.  
  560. Sharing concerns opening the file with the necessary access rights.
  561. In Turbo Pascal, this involves setting the FileMode variable before
  562. opening the file. I believe the details have already been posted to
  563. you. If not, refer to a DOS technical reference on INT $21 function
  564. $3D (you should have such a reference even if you get the essential
  565. information from the net) and set FileMode := the required value of
  566. the AL register in this call.
  567.  
  568. In addition to the normally expected values, Reset and Rewrite will
  569. cause an IOResult of 1 if sharing is not available (i.e., SHARE has
  570. not been loaded); 5 if you can't open the file with the mode you
  571. requested (e.g., another process has opened it with Deny Write and
  572. you are trying to open it with ReadWrite access); or $C if you have
  573. messed up the FileMode value. (What happened to Append? Append is
  574. for text files. Your life with networked Turbo Pascal will be very
  575. much easier if you don't use text files.)
  576.  
  577. MS-DOS locking concerns denying other processes the right to write
  578. _or_ read a specified byte sequence in the file. A lock is placed by
  579. calling INT $21 function $5C with AH := $5C; $AL := 0;$BX := the
  580. file handle; CX,DX := (high,low) word of the byte sequence offset
  581. into the file; SD,DI := (high,low) word of the length of the
  582. sequence. (I.e, the offset and length are double length words, so
  583. they are passed in two registers each.) To remove a lock, you make
  584. the same call you made to place it, with (important!) exactly the
  585. same parameters except that $AL := 1. (So you have to make one
  586. unlock call for every lock you place.) If the lock fails, the carry
  587. flag will be set, and AX will be 1 for "invalid function code"
  588. (probably SHARE not loaded); or $21 if all or part of that region is
  589. already locked.
  590.  
  591. Note that it is a _serious_ mistake to end your program without
  592. removing all locks, so you want to create an exit proc that will
  593. remove all locks. You should also document that if your users crash
  594. one node, they should immediately reboot that node (if required) and
  595. log back onto their network, in the hopes that the network will
  596. recognize any remaining locks as obsolete and clear them. Otherwise,
  597. other nodes may be continue to be denied access to the locked
  598. regions.
  599.  
  600. >  How can I get the program to retry after a sharing violation. Do I
  601. >have to code it explicitly (i.e. repeat .... until (share_ok OR
  602. >computer_switched_off; :-) ) or does SHARE take care of that?
  603.  
  604. You have to do it yourself.
  605.  
  606. >  By the way, when exactly does a sharing violation occur? In
  607. >Read/Read, Read/Write or Write/Write situations?
  608.  
  609. As described above, plus whenever a Read or Write is attempted which
  610. is not allowed by the acquired access and/or locks. E.g., if you try
  611. to access a record which is locked by another process, you will get
  612. a violation on every read or write.
  613.  
  614. My personal recommendations for reference material are _Advanced MS-
  615. DOS_, Ray Duncan, MicroSoft Press, and _MS-DOS Encyclopedia_, Ray
  616. Duncan ed., MicroSoft Press. Of course, my employer makes no such
  617. recommendations. ;)
  618.  
  619. Cheers--                        --Karl
  620.  
  621. +====================================================================+
  622. | Karl Brendel                           Centers for Disease Control |
  623. | Internet: CDCKAB@EMUVM1.BITNET         Epidemiology Program Office |
  624. | Bitnet: CDCKAB@EMUVM1                  Atlanta GA  30333       USA |
  625. |                        Home of Epi Info 5.0                        |
  626. +====================================================================+
  627.  
  628.  
  629.  
  630. -- 
  631. Dean Davidson                                 ddavidso@metz.une.oz.au
  632. Dept Psychology                               Phone 61 67 73 2585
  633. University of New England                     Fax   61 67 72 9816
  634. Armidale NSW 2351 Australia                   VK2 ZID
  635.