home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rxnpip20.zip / rxnpipes.inf (.txt) < prev   
OS/2 Help File  |  1995-12-22  |  28KB  |  1,217 lines

  1.  
  2. ΓòÉΓòÉΓòÉ 1. Rexx Named Pipes ΓòÉΓòÉΓòÉ
  3.  
  4. The following sections describe RxNPipes, a function package for use by IBM 
  5. employees that provides access to OS/2 Named Pipes from Rexx. 
  6.  
  7.  
  8. ΓòÉΓòÉΓòÉ 1.1. Introduction ΓòÉΓòÉΓòÉ
  9.  
  10. RxNPipes is a Dynamic Link Library (DLL) which provides the REXX programmer 
  11. with many functions dealing with the operation of OS/2 Named Pipes.  These 
  12. functions allow Rexx procedures running in different sessions to communicate 
  13. among themselves. 
  14.  
  15. This package is for use by IBM employees only. 
  16.  
  17. RxNPipes requires that you are already running under OS/2 2.x or higher with 
  18. OS/2 Procedures Language 2/REXX installed. 
  19.  
  20. Installation of RxNPipes is described in Installation. 
  21.  
  22. To be able to use an RxNPipes function in a REXX program, you must first add 
  23. the functions using the built-in REXX function RxFuncAdd. 
  24.  
  25. Example: 
  26.  
  27.  call RxFuncAdd "RxNPCreate","RxNPipes","RxNPCreate"
  28.  
  29. The above example would add the RxNPCreate function so that it can be used. 
  30.  
  31. The RxNPipes function RxNPLoadFuncs will automatically load all other RxNPipes 
  32. functions.  To do this from within a programme, add the following instructions: 
  33.  
  34.   call RxFuncAdd "RxNPLoadFuncs","RxNPipes","RxNPLoadFuncs"
  35.   call RxNPLoadFuncs
  36.  
  37. Once the RxNPipes functions are loaded by RxNPLoadFuncs they are usable by all 
  38. OS/2 sessions. 
  39.  
  40. The main RxNPipes functions are listed in the Contents. Additional functions 
  41. that return values used in return code are displayed when you select the "+" 
  42. sign beside "Errors and Error Codes". 
  43.  
  44. The functions provided are: 
  45.  
  46.      RxNPLoadFuncs 
  47.      RxNPDropFuncs 
  48.      RxNPCreate 
  49.      RxNPOpen 
  50.      RxNPRead 
  51.      RxNPWrite 
  52.      RxNPReconnect 
  53.      RxNPClose 
  54.      RxNPCreateSem 
  55.      RxNPWaitFree 
  56.      RxNPWaitRead 
  57.      RxNPQuery 
  58.      RxNPDebug 
  59.      RxNPVersion 
  60.      Functions which explain errors and error codes. 
  61.         -  RxNPErrNotFound 
  62.         -  RxNPErrAccessDenied 
  63.         -  RxNPErrInvalidHandle 
  64.         -  RxNPErrNoMemory 
  65.         -  RxNPErrNoStructures 
  66.         -  RxNPErrInvalidParm 
  67.         -  RxNPErrInterrupt 
  68.         -  RxNPErrBroken 
  69.         -  RxNPErrBad 
  70.         -  RxNPErrBusy 
  71.         -  RxNPErrNoData 
  72.         -  RxNPErrNotConnected 
  73.         -  RxNPErrMoreData 
  74.         -  RxNPErrTimeout 
  75.         -  RxNPExplainErr 
  76.  
  77.  These functions should normally be used in a REXX parse statement, as: 
  78.  
  79.   parse value RxNPOpen(PipeName) with retcode handle .
  80.  
  81.  In some cases the RxNPipes functions return debugging tokens beyond those 
  82.  documented here.  These additional tokens are subject to change and should be 
  83.  ignored.  They are not part of the programming interface to RxNPipes. 
  84.  
  85.  
  86. ΓòÉΓòÉΓòÉ 1.2. Debugging ΓòÉΓòÉΓòÉ
  87.  
  88. The underlying Dos... function calls, their return codes, and other pertinent 
  89. information are available to the user of these functions. 
  90.  
  91. This is triggered by the REXX Variable RxNPipes.0, as described below. 
  92.  
  93. The information displayed depends on the particular function call and is 
  94. subject to change from release to release. A single RxNPipes function call may 
  95. result in more than one Dos... function call, and therefore more than one line 
  96. of diagnostic output. 
  97.  
  98. The format and content of this information is not a programming interface. 
  99.  
  100. There are 4 possible destinations for trace information: 
  101.  
  102.      The screen (stdout), 
  103.      A Rexx stem variable, 
  104.      A queue, such as that provided by PMPrintf, or 
  105.      A named file. 
  106.  
  107.  selected according to the value, which may be specified in upper, lower, or 
  108.  mixed case, in RxNPipes.0: 
  109.  
  110.      If this variable has the value "TRACE", then diagnostic information about 
  111.       every Dos... function call will be displayed on Standard Output (stdout). 
  112.      If this has a non-negative numeric value RxNPipes.0 will be incremented 
  113.       and its new value, i, will be used to store the debugging information in 
  114.       RxNPipes.i instead of displaying it. 
  115.      If the variable RxNPipes.0 begins with "\QUEUES\", diagnostic information 
  116.       about every Dos... function call is sent to the queue named by 
  117.       RxNPipes.0.  If RxNPipes.0 contains "\QUEUES\" alone the queue name 
  118.       "\QUEUES\PRINTF32" (the default for PMPrintf) is assumed. 
  119.      If the variable RxNPipes.0 contains a file name, which is recognised by: 
  120.         -  having a period (.) or a backslash (\) in the first position, or 
  121.         -  having a colon (:) in the second position, and 
  122.         -  not being a queue name. 
  123.       the trace information is appended to the named file which is opened, 
  124.       written to, and closed for each trace event. 
  125.  
  126.  Trace information sent to queues or files is preceded by a timestamp taking 
  127.  the form "YYYYMMDD HHMMSShh [pid]: ", where pid is the process id. If the 
  128.  queue or file cannot be opened the trace request is silently ignored. 
  129.  
  130.  In addition, the function RxNPDebug can be used to place arbitrary information 
  131.  in the debug stream. 
  132.  
  133.  
  134. ΓòÉΓòÉΓòÉ 1.3. Return Codes ΓòÉΓòÉΓòÉ
  135.  
  136. These functions return the last-seen return code from the underlying Dos... 
  137. functions executed on behalf of the user. 
  138.  
  139. Arbitrarily, the return codes ERROR_FILE_NOT_FOUND and ERROR_PATH_NOT_FOUND are 
  140. consolidated into a single NotFound value (RxNPErrNotFound(), which happens to 
  141. be the ERROR_PATH_NOT_FOUND value) in places where this type of return is 
  142. expected. 
  143.  
  144. Equally arbitrarily, the return codes ERROR_SEM_TIMEOUT and ERROR_TIMEOUT are 
  145. consolidated into a single Timeout value (RxNPErrTimeout(), which happens to be 
  146. the ERROR_TIMEOUT value) in places where this type of return is expected. 
  147.  
  148. These consolidations happen after the debugging information that is described 
  149. in Debugging Information is produced. 
  150.  
  151.  
  152. ΓòÉΓòÉΓòÉ 1.4. RxNPLoadFuncs ΓòÉΓòÉΓòÉ
  153.  
  154.  Function:        RxNPLoadFuncs 
  155.  
  156.  Purpose:         Use this functions to load all the remaining functions in the 
  157.                   RxNPipes Package. 
  158.  
  159.  Syntax:          parse value RxNPLoadFuncs() with version 
  160.  
  161.                   version                Version identification. This always 
  162.                                          takes the form 
  163.                                          "RxNPipes Version X.X ..." 
  164.  
  165.  Example: 
  166.  
  167.                                     call RxNPLoadFuncs
  168.  
  169.  
  170. ΓòÉΓòÉΓòÉ 1.5. RxNPDropFuncs ΓòÉΓòÉΓòÉ
  171.  
  172.  Function:        RxNPDropFuncs 
  173.  
  174.  Purpose:         Use this functions to drop all the loaded RxNPipes functions. 
  175.                   Once this function is processed by any REXX programme, the 
  176.                   RxNPipes functions are no longer accessible in any OS/2 
  177.                   session. 
  178.  
  179.  Syntax:          call RxNPDropFuncs 
  180.  
  181.  Example: 
  182.  
  183.                                     call RxNPDropFuncs
  184.  
  185.  
  186. ΓòÉΓòÉΓòÉ 1.6. RxNPCreate ΓòÉΓòÉΓòÉ
  187.  
  188.  Function:        RxNPCreate 
  189.  
  190.  Purpose:         Use this function to Create a named pipe, specify its 
  191.                   characteristics, and make it ready for communication. 
  192.  
  193.  Syntax:          parse value 
  194.                   RxNPCreate(name,direction,blocking,instances,buffer1,buffer2) 
  195.                   with retcode handle . 
  196.  
  197.                   name                   The name of the Pipe. This must take 
  198.                                          the form "\pipe\...". This parameter 
  199.                                          is required. 
  200.                   direction              The direction of flow through the 
  201.                                          pipe. This must be one of: "Duplex" 
  202.                                          (the default), "Inbound, or 
  203.                                          "Outbound". Only the first character 
  204.                                          of this parameter is significant. Case 
  205.                                          is Ignored. 
  206.                   blocking               The blocking mode of the pipe. This 
  207.                                          must be "Wait" (the default) or 
  208.                                          "Nowait". Only the first character of 
  209.                                          this parameter is significant. Case is 
  210.                                          Ignored. 
  211.                   instances              The number of instances permitted for 
  212.                                          this pipe. This must be "Unlimited" 
  213.                                          (the default, only the first character 
  214.                                          of this parameter being significant 
  215.                                          with case ignored), or a number 
  216.                                          between 1 and 254. 
  217.                   buffer1                The buffer size for the pipe. For 
  218.                                          Duplex pipes, this is the size of the 
  219.                                          inbound buffer. The default is 4096 
  220.                                          bytes. 
  221.                   buffer2                The outbound buffer size for a duplex 
  222.                                          pipe. This is valid for Duplex pipes 
  223.                                          only. The default is 4096 bytes. 
  224.  
  225.  
  226.                   retcode                The return code from the underlying 
  227.                                          Dos... function. 
  228.                   handle                 The pipe handle 
  229.  
  230.  Example: 
  231.  
  232.                                     parse value RxNPCreate(pipe,"Duplex","Wait",1) with retcode handle .
  233.  
  234.  
  235. ΓòÉΓòÉΓòÉ 1.7. RxNPOpen ΓòÉΓòÉΓòÉ
  236.  
  237.  Function:        RxNPOpen 
  238.  
  239.  Purpose:         Use this function to open an existing Named Pipe. 
  240.  
  241.  Syntax:          parse value RxNPOpen(name) with retcode handle . 
  242.  
  243.                   name                   The name of the Pipe. This must take 
  244.                                          the form "\pipe\...". This parameter 
  245.                                          is required. 
  246.  
  247.  
  248.                   retcode                The return code from the underlying 
  249.                                          Dos... function. 
  250.                   handle                 The handle of the pipe, to be used in 
  251.                                          subsequent calls to RxNPipes 
  252.                                          functions. 
  253.  
  254.  Example: 
  255.  
  256.                                     parse value RxNPOpen("\pipe\exmppipe") with retcode handle .
  257.                                     if retcode=RxNPErrNotFound() then do
  258.                                        say "Pipe does not exist"
  259.                                        return
  260.                                     end
  261.                                     if retcode=RxNPErrBusy() then
  262.                                        retcode=RxNPWaitFree("\pipe\exmppipe")
  263.  
  264.  
  265. ΓòÉΓòÉΓòÉ 1.8. RxNPRead ΓòÉΓòÉΓòÉ
  266.  
  267.  Function:        RxNPRead 
  268.  
  269.  Purpose:         Use this function to read messages from an opened Named Pipe. 
  270.  
  271.  Syntax:          parse value RxNPRead(handle,<symbol>,<buffer size>) with 
  272.                   retcode len message 
  273.  
  274.                   handle                 The pipe handle (as returned by 
  275.                                          RxNPCreate or RxNPOpen) from which a 
  276.                                          message is to be read.  This parameter 
  277.                                          is required. 
  278.                   symbol                 The name of a REXX variable in which 
  279.                                          the returned message is placed.  This 
  280.                                          parameter is optional; if not 
  281.                                          specified the received data are 
  282.                                          returned as part of the function 
  283.                                          return value. 
  284.                                          If an invalid Rexx symbol name is 
  285.                                          given, up to buffer size bytes will be 
  286.                                          read from the pipe (and discarded) 
  287.                                          before the syntax error is detected. 
  288.                   buffer size            The size of buffer to be used to 
  289.                                          receive the message. This parameter is 
  290.                                          optional; if not specified, a 
  291.                                          4096-byte buffer will be used. 
  292.  
  293.  
  294.                   retcode                The return code from the underlying 
  295.                                          Dos... function. 
  296.                   len                    The number of bytes in the returned 
  297.                                          message. 
  298.                   message                The text of the message read.  This is 
  299.                                          supplied only if there is no symbol 
  300.                                          parameter. 
  301.  
  302.  Example: 
  303.  
  304.                                     parse value RxNPRead(handle,"retval") with retcode len
  305.                                     if retcode <> 0 then do
  306.                                        say "Read Error: retcode="retcode"," RxNPExplainErr(retcode)
  307.                                        return
  308.                                     end
  309.                                     say "Received message:" retval
  310.  
  311.  
  312. ΓòÉΓòÉΓòÉ 1.9. RxNPWrite ΓòÉΓòÉΓòÉ
  313.  
  314.  Function:        RxNPWrite 
  315.  
  316.  Purpose:         Use this function to write a message to an opened Named Pipe. 
  317.  
  318.  Syntax:          parse value RxNPWrite(handle,message) with retcode . 
  319.  
  320.                   handle                 The pipe handle (as returned by 
  321.                                          RxNPCreate or RxNPOpen) from which a 
  322.                                          message is to be read. This parameter 
  323.                                          is required. 
  324.                   message                The message to be written to the Named 
  325.                                          Pipe. This parameter is required. 
  326.  
  327.  
  328.                   retcode                The return code from the underlying 
  329.                                          Dos... function. 
  330.  
  331.  Example: 
  332.  
  333.                                     parse value RxNPWrite(handle,"return message") with retcode .
  334.                                     if retcode<>0 then do
  335.                                        say "Write Error: retcode="retcode"," RxNPExplainErr(retcode)
  336.                                        return
  337.                                     end
  338.  
  339.  
  340. ΓòÉΓòÉΓòÉ 1.10. RxNPReconnect ΓòÉΓòÉΓòÉ
  341.  
  342.  Function:        RxNPReconnect 
  343.  
  344.  Purpose:         Use this function to re-enable a Named Pipe for communication 
  345.                   with another client. 
  346.  
  347.  Syntax:          parse value RxNPReconnect(handle) with retcode . 
  348.  
  349.                   handle                 The pipe handle (as returned by 
  350.                                          RxNPCreate or RxNPOpen) from which a 
  351.                                          message is to be read. This parameter 
  352.                                          is required. 
  353.  
  354.  
  355.                   retcode                The return code from the underlying 
  356.                                          Dos... function. 
  357.  
  358.  Example: 
  359.  
  360.                                     parse value RxNPQuery(handle) with retcode state .
  361.                                     select
  362.                                        when retcode<>0 then do
  363.                                           say "Return code="retcode "querying pipe" pipe RxNPExplainErr(retcode)
  364.                                           return
  365.                                        end
  366.                                        when state="CLOSING" then do
  367.                                           parse value RxNPReconnect(handle) with retcode .
  368.                                           if retcode<>0 then do
  369.                                              say "Reconnect: retcode="retcode RxNPExplainErr(retcode)
  370.                                              return
  371.                                           end
  372.                                         end
  373.                                         otherwise nop
  374.                                     end
  375.  
  376.  
  377. ΓòÉΓòÉΓòÉ 1.11. RxNPClose ΓòÉΓòÉΓòÉ
  378.  
  379.  Function:        RxNPClose 
  380.  
  381.  Purpose:         Use this function to close an Named Pipe. 
  382.  
  383.  Syntax:          parse value RxNPClose(handle) with retcode . 
  384.  
  385.                   handle                 The pipe handle (as returned by 
  386.                                          RxNPCreate or RxNPOpen) which is to be 
  387.                                          closed. This parameter is required. 
  388.  
  389.  
  390.                   retcode                The return code from the underlying 
  391.                                          Dos... function. 
  392.  
  393.  Example: 
  394.  
  395.                                     call RxNPClose handle
  396.  
  397.  
  398. ΓòÉΓòÉΓòÉ 1.12. RxNPCreateSem ΓòÉΓòÉΓòÉ
  399.  
  400.  Function:        RxNPCreateSem 
  401.  
  402.  Purpose:         Use this function to create a semaphore that can be used to 
  403.                   wait for Pipes that do not block. 
  404.  
  405.  Syntax:          parse value RxNPCreateSem(handle) with retcode semaphore . 
  406.  
  407.                   handle                 The pipe handle (as returned by 
  408.                                          RxNPCreate or RxNPOpen) with which 
  409.                                          this semaphore is to be associated. 
  410.                                          This parameter is required. 
  411.  
  412.  
  413.                   retcode                The return code from the underlying 
  414.                                          Dos... function. 
  415.                   semaphore              A semaphore that can be used by 
  416.                                          RxNPWaitRead to wait for activity at 
  417.                                          the other end of the named pipe 
  418.                                          identified by handle. 
  419.  
  420.  Example:         See RxNPWaitRead. 
  421.  
  422.  
  423. ΓòÉΓòÉΓòÉ 1.13. RxNPWaitFree ΓòÉΓòÉΓòÉ
  424.  
  425.  Function:        RxNPWaitFree 
  426.  
  427.  Purpose:         Use this function to wait until a Named Pipe is available for 
  428.                   opening and subsequent use. 
  429.  
  430.  Syntax:          parse value RxNPWaitFree(name,<timeout>) with retcode . 
  431.  
  432.                   name                   The name of the Pipe. This must take 
  433.                                          the form "\pipe\...". This parameter 
  434.                                          is required. 
  435.                   timeout                This parameter is optional. If 
  436.                                          specified, it it the time (in 
  437.                                          milliseconds) to wait for the 
  438.                                          specified Named Pipe to be available 
  439.                                          for opening. 
  440.  
  441.  
  442.                   retcode                The return code from the underlying 
  443.                                          Dos... function. 
  444.  
  445.  Example: 
  446.  
  447.                                     do until retcode<>RxNPErrBusy()          /* repeat; someone else may have been waiting too! */
  448.                                        parse value RxNPWaitFree("\pipe\exampipe",10000) with retcode .  /* wait 10 sec for the pipe */
  449.                                        if retcode=RxNPErrTimeout() then do
  450.                                           say "Timout waiting for pipe"
  451.                                           return 0
  452.                                        end
  453.                                        parse value RxNPOpen("\pipe\exampipe") with retcode handle .
  454.                                     end
  455.                                     if retcode <> 0 then do
  456.                                        say "Open Error: retcode="retcode"," RxNPExplainErr(retcode)
  457.                                        return
  458.                                     end
  459.  
  460.  
  461. ΓòÉΓòÉΓòÉ 1.14. RxNPWaitRead ΓòÉΓòÉΓòÉ
  462.  
  463.  Function:        RxNPWaitRead 
  464.  
  465.  Purpose:         Use this function to wait for data to be available. 
  466.  
  467.  Syntax:          parse value RxNPWaitRead(handle,semaphore,timeout) with 
  468.                   retcode . 
  469.  
  470.                   handle                 The pipe handle (as returned by 
  471.                                          RxNPCreate or RxNPOpen) from which a 
  472.                                          message will be read by a subsequent 
  473.                                          call to RxNPRead. This parameter is 
  474.                                          required. 
  475.                   semaphore              The semaphore handle (as returned by 
  476.                                          RxNPCreateSem) 
  477.                   timeout                This parameter is optional. If 
  478.                                          specified, it it the time (in 
  479.                                          milliseconds) to wait for data to 
  480.                                          become available in the specified 
  481.                                          pipe. 
  482.  
  483.  
  484.                   retcode                The return code from the underlying 
  485.                                          Dos... function. 
  486.  
  487.  Example: 
  488.  
  489.                                     parse value RxNPRead(handle) with retcode len message
  490.                                     do while retcode=RxNPErrNodata() | len=0
  491.                                        do forever
  492.                                           parse value RxNPWaitRead(handle,semaphore,4000) with retcode .
  493.                                           if retcode<>RxNPTimeout() then leave
  494.                                           say "timeout tick every 4 seconds at" time()
  495.                                           /* do here whatever needs doing every 4 seconds */
  496.                                        end
  497.                                        parse value RxNPRead(handle) with retcode len message
  498.                                     end
  499.  
  500.  
  501. ΓòÉΓòÉΓòÉ 1.15. RxNPQuery ΓòÉΓòÉΓòÉ
  502.  
  503.  Function:        RxNPQuery 
  504.  
  505.  Purpose:         Use this function to retrieve information about the current 
  506.                   state of the Named Pipe. 
  507.  
  508.  Syntax:          parse value RxNPQuery(handle) with retcode state instance 
  509.                   pipebytes msgbytes cs nw . 
  510.  
  511.                   handle                 The pipe handle (as returned by 
  512.                                          RxNPCreate or RxNPOpen) for which 
  513.                                          information is required. This 
  514.                                          parameter is required. 
  515.  
  516.  
  517.                   retcode                The return code from the underlying 
  518.                                          Dos... function. 
  519.                   state                  The current state of the Pipe.  This 
  520.                                          will be one of "LISTENING", 
  521.                                          "CONNECTED", "CLOSING", or 
  522.                                          "DISCONNECTED". 
  523.  
  524.                                          The pipe is in a listening state after 
  525.                                          the server issues DosConnectNPipe by 
  526.                                          calling RxNPCreate or RxNPReconnect. A 
  527.                                          listening pipe is ready to accept an 
  528.                                          RxNPOpen() request. If the pipe is not 
  529.                                          in a listening state, DosOpen returns 
  530.                                          RxNPErrBusy(). 
  531.  
  532.                                          The pipe is in a connected state after 
  533.                                          a client has successfully issued 
  534.                                          DosOpen by calling RxNPOpen(). The 
  535.                                          connected pipe allows the server and 
  536.                                          the client to read and write to the 
  537.                                          pipe provided both have valid handles. 
  538.  
  539.                                          The pipe is in a closing state after 
  540.                                          the last DosClose request has been 
  541.                                          made by calling RxNPClose to the pipe 
  542.                                          by either the client or the server. 
  543.                                          When DosClose has been issued for the 
  544.                                          client handle and all of its 
  545.                                          duplicates, the client end of the pipe 
  546.                                          is closed. The serving end must 
  547.                                          acknowledge the closing of the client 
  548.                                          end by issuing either 
  549.                                          DosDisConnectNPipe by calling 
  550.                                          RxNPReconnect or DosClose by calling 
  551.                                          RxNPClose. Issuing DosClose 
  552.                                          deallocates the pipe. 
  553.  
  554.                                          The pipe is in a disconnected state 
  555.                                          immediately after a call to 
  556.                                          DosCreateNPipe, or DosDisConnectNPipe. 
  557.                                          A disconnected pipe cannot accept a 
  558.                                          call to DosOpen. The server must issue 
  559.                                          DosDisConnectNPipe before the pipe can 
  560.                                          be opened by a client. This state 
  561.                                          should not occur when using RxNPipes. 
  562.                   instance               The current instance of a named pipe 
  563.                                          that can have more than one instance 
  564.                                          (as specified in the RxNPCreate call). 
  565.                   pipebytes              The number of bytes buffered in the 
  566.                                          pipe (including message header bytes) 
  567.                   msgbytes               The number of bytes in the current 
  568.                                          message. 
  569.                   cs                     "C" if called from the client end of 
  570.                                          the pipe, "S" if called from the 
  571.                                          server end. 
  572.                   nw                     "N" of the Pipe does not block (opened 
  573.                                          with "Nowait"), "W" if it does (opened 
  574.                                          with "Wait"). 
  575.  
  576.  Example: 
  577.  
  578.                                     parse value RxNPQuery(handle) with retcode state .
  579.                                     if retcode<>0 then do
  580.                                        say "Query Error: retcode="retcode"," RxNPExplainErr(retcode)
  581.                                        return
  582.                                     end
  583.                                     if state="CLOSING" then do
  584.                                        parse value RxNPReconnect(handle) with retcode .
  585.                                        if retcode<>0 then do
  586.                                           say "Reconnect: retcode="retcode
  587.                                           return
  588.                                        end
  589.                                     end
  590.  
  591.  
  592. ΓòÉΓòÉΓòÉ 1.16. RxNPDebug ΓòÉΓòÉΓòÉ
  593.  
  594.  Function:        RxNPDebug 
  595.  
  596.  Purpose:         Use this functions to put arbitrary strings on the debug 
  597.                   stream (see Debugging). 
  598.  
  599.  Syntax:          call RxNPDebug string1<,string2>... 
  600.  
  601.  Example: 
  602.  
  603.                                     parse source . . self
  604.                                     parse args argstring
  605.                                     call RxNPDebug self "starting",argstring
  606.  
  607.  
  608. ΓòÉΓòÉΓòÉ 1.17. RxNPVersion ΓòÉΓòÉΓòÉ
  609.  
  610.  Function:        RxNPVersion 
  611.  
  612.  Purpose:         From version 2.0, this function returns the numeric version 
  613.                   of the RxNPipes DLL. 
  614.  
  615.  Syntax:          parse value RxNPVersion() with ver . 
  616.  
  617.  
  618. ΓòÉΓòÉΓòÉ 1.18. Errors and Error codes ΓòÉΓòÉΓòÉ
  619.  
  620. These functions return the error codes associated with various Named Pipe 
  621. conditions. 
  622.  
  623.  
  624. ΓòÉΓòÉΓòÉ 1.18.1. RxNPErrNotFound (3) ΓòÉΓòÉΓòÉ
  625.  
  626. This function returns the error code associated with the File Not Found 
  627. Condition. 
  628.  
  629.  
  630. ΓòÉΓòÉΓòÉ 1.18.2. RxNPErrAccessDenied (5) ΓòÉΓòÉΓòÉ
  631.  
  632. This function returns the error code associated with the Access Denied 
  633. Condition. 
  634.  
  635.  
  636. ΓòÉΓòÉΓòÉ 1.18.3. RxNPErrInvalidHandle (6) ΓòÉΓòÉΓòÉ
  637.  
  638. This function returns the error code associated with the Invalid Handle 
  639. Condition. 
  640.  
  641.  
  642. ΓòÉΓòÉΓòÉ 1.18.4. RxNPErrNoMemory (8) ΓòÉΓòÉΓòÉ
  643.  
  644. This function returns the error code associated with the No Memory Condition. 
  645.  
  646.  
  647. ΓòÉΓòÉΓòÉ 1.18.5. RxNPErrNoStructures (84) ΓòÉΓòÉΓòÉ
  648.  
  649. This function returns the error code associated with the Out of Structures 
  650. Condition. 
  651.  
  652.  
  653. ΓòÉΓòÉΓòÉ 1.18.6. RxNPErrInvalidParm (87) ΓòÉΓòÉΓòÉ
  654.  
  655. This function returns the error code associated with the Invalid Parameter 
  656. Condition. 
  657.  
  658.  
  659. ΓòÉΓòÉΓòÉ 1.18.7. RxNPErrInterrupt (95) ΓòÉΓòÉΓòÉ
  660.  
  661. This function returns the error code associated with the Interrupt Condition. 
  662.  
  663.  
  664. ΓòÉΓòÉΓòÉ 1.18.8. RxNPErrBroken (109) ΓòÉΓòÉΓòÉ
  665.  
  666. This function returns the error code associated with the Broken Pipe Condition. 
  667.  
  668.  
  669. ΓòÉΓòÉΓòÉ 1.18.9. RxNPErrBad (230) ΓòÉΓòÉΓòÉ
  670.  
  671. This function returns the error code associated with the Bad Pipe Condition. 
  672.  
  673.  
  674. ΓòÉΓòÉΓòÉ 1.18.10. RxNPErrBusy (231) ΓòÉΓòÉΓòÉ
  675.  
  676. This function returns the error code associated with the Pipe Busy Condition. 
  677.  
  678.  
  679. ΓòÉΓòÉΓòÉ 1.18.11. RxNPErrNoData (232) ΓòÉΓòÉΓòÉ
  680.  
  681. This function returns the error code associated with the No Data Condition. 
  682.  
  683.  
  684. ΓòÉΓòÉΓòÉ 1.18.12. RxNPErrNotConnected (233) ΓòÉΓòÉΓòÉ
  685.  
  686. This function returns the error code associated with the Pipe Not Connected 
  687. Condition. 
  688.  
  689.  
  690. ΓòÉΓòÉΓòÉ 1.18.13. RxNPErrMoreData (234) ΓòÉΓòÉΓòÉ
  691.  
  692. This function returns the error code associated with the More Data Condition. 
  693.  
  694.  
  695. ΓòÉΓòÉΓòÉ 1.18.14. RxNPErrTimeout (640) ΓòÉΓòÉΓòÉ
  696.  
  697. This function returns the error code associated with the Timeout Condition. 
  698.  
  699.  
  700. ΓòÉΓòÉΓòÉ 1.18.15. RxNPExplainErr ΓòÉΓòÉΓòÉ
  701.  
  702.  Function:        RxNPExplainErr 
  703.  
  704.  Purpose:         Use this function to return a string explaining the meaning 
  705.                   of a return code. 
  706.  
  707.  Syntax:          errstring = RxNPExplainErr(retcode) 
  708.  
  709.                   retcode                A return code returned by a Named Pipe 
  710.                                          function.  This parameter is required. 
  711.  
  712.  
  713.                   errstring              A text string explaining the error. 
  714.  
  715.  Example: 
  716.  
  717.                                     if retcode <> 0 then do
  718.                                        say "Retcode="retcode"," RxNPExplainErr(retcode)
  719.                                        return
  720.                                     end
  721.  
  722.  
  723. ΓòÉΓòÉΓòÉ 1.19. Examples ΓòÉΓòÉΓòÉ
  724.  
  725. The following examples illustrate many of these functions 
  726.  
  727.  
  728. ΓòÉΓòÉΓòÉ 1.19.1. CalcSamp - A full duplex Named Pipe with no Asychronous processing ΓòÉΓòÉΓòÉ
  729.  
  730. /* sample for RxNPipes, duplex, wait calculator */
  731. trace 'o'
  732. signal on syntax
  733. pipe="\pipe\calculator"
  734. mark = "/SERVER"
  735.  
  736. RxNPipes.0="TRACE"
  737.  
  738. if RxFuncQuery("SysSleep") then
  739.    call RxFuncAdd 'SysSleep', 'RexxUtil', 'SysSleep'
  740.  
  741. if RxFuncQuery("RxNpLoadFuncs") then do
  742.    call RxFuncAdd 'RxNPLoadFuncs', 'RxNPipes', 'RxNPLoadFuncs'
  743.    say RxNPLoadFuncs()
  744. end
  745.  
  746. parse source . . self .
  747. parse arg expression
  748. if left(strip(expression),length(mark)) = mark then signal server
  749.  
  750. RxNPipes.0=0
  751.  
  752. busy=RxNPErrBusy()
  753. timeout=RxNPErrTimeout()
  754. notfound=RxNPErrNotFound()
  755.  
  756. parse value RxNPOpen(pipe) with retcode handle .
  757. if retcode=notfound then do
  758.    "start ""Piped Calculator Server""/f" self mark
  759.    do 60
  760.       parse value RxNPOpen(pipe) with retcode handle .
  761.       if retcode <> notfound then leave
  762.       say "Waiting for Server to start"
  763.       call syssleep 1
  764.    end
  765. end
  766.  
  767. do 10 while retcode=busy
  768.    x=time()
  769.    retcode=RxNPWaitFree(pipe,10000)  /* wait 10 sec for it to free up */
  770.    if retcode=timeout then do  /* this happens only if one process ties it up for 10 seconds */
  771.       say "Timout waiting for server"
  772.       return 0
  773.    end
  774.    if retcode<>0 then do
  775.       say "Wait Error: retcode="retcode"," RxNPExplainErr(retcode) "in line"  whatline()
  776.       return
  777.    end
  778.    parse value RxNPOpen(pipe) with retcode handle .
  779. end
  780.  
  781. if retcode <> 0 then do
  782.    say "Open Error: retcode="retcode"," RxNPExplainErr(retcode) "in line"  whatline()
  783.    return
  784. end
  785.  
  786. say 'Expression: "'expression'"'
  787. retcode=RxNPWrite(handle,expression)
  788. if retcode <> 0 then do
  789.    say "Write Error: retcode="retcode"," RxNPExplainErr(retcode) "in line"  whatline()
  790.    return
  791. end
  792.  
  793. parse value RxNPRead(handle,"retval") with retcode len
  794. if retcode <> 0 then do
  795.    say "Read Error: retcode="retcode"," RxNPExplainErr(retcode) "in line"  whatline()
  796.    return
  797. end
  798.  
  799. say 'Result: "'retval'"'
  800. say
  801. call RxNPClose handle
  802.  
  803. do i=1 to RxNPipes.0
  804.   parse var RxNPipes.i f1 f2 d
  805.   say "["i"]" f1 f2
  806.   say "["i"]"  strip(d)
  807.   say
  808. end
  809.  
  810.  
  811. return
  812.  
  813. server:
  814.  
  815. "mode co80,45"
  816.  
  817. parse value RxNPCreate(pipe,"Duplex","Wait",1) with retcode handle .
  818. if retcode<>0 then do
  819.    say "Create Error: retcode="retcode"," RxNPExplainErr(retcode) "creating pipe" pipe "in line"  whatline()
  820.    return
  821. end
  822. signal on halt
  823.  
  824. do forever
  825.    parse value RxNPRead(handle) with retcode len expression
  826.    if retcode<>0 then do
  827.       say "Read Error: retcode="retcode"," RxNPExplainErr(retcode) "in line"  whatline()
  828.       call syssleep 30
  829.       return
  830.    end
  831.    if right(expression,2)="0d0a"x then expression=left(expression,length(expression)-2) /* in case message comes from ECHO */
  832.  
  833.    parse value RxNPQuery(handle) with retcode state .
  834.    select
  835.       when retcode<>0 then do
  836.          say "Query Error: retcode="retcode"," RxNPExplainErr(retcode) "in line"  whatline()
  837.          call syssleep 30
  838.          return
  839.       end
  840.       when translate(expression)="STOP" then do
  841.          call RxNPClose handle
  842.          "exit"
  843.       end
  844.       when translate(expression)="DISP" then do
  845.          if datatype(RxNPipes.0,"N") then do i=1 to RxNPipes.0
  846.             parse var RxNPipes.i f1 f2 d
  847.             say "["i"]" f1 f2
  848.             say "["i"]"  strip(d)
  849.             say
  850.          end
  851.          drop RxNPipes.
  852.          RxNPipes.0=0
  853.          parse value RxNPWrite(handle,"Done") with retcode .
  854.       end
  855.       when translate(expression)="NOTRACE" then do
  856.          drop RxNPipes.
  857.       end
  858.       when translate(expression)="DROP" then do
  859.          call RxNPClose handle
  860.          call RxNPDropFuncs
  861.          "exit"
  862.       end
  863.       when state="CLOSING" then do
  864.          parse value RxNPReconnect(handle) with retcode .
  865.          if retcode<>0 then do
  866.             say "Reconnect Error: retcode="retcode"," RxNPExplainErr(retcode) "in line"  whatline()
  867.             call syssleep 30
  868.             return
  869.          end
  870.       end
  871.       otherwise do
  872.          if len=0 then retval="Empty expression received"
  873.                   else retval=evaluate(expression)
  874.          say 'Received: "'expression'" Returning: "'retval'"'
  875.          parse value RxNPWrite(handle,retval) with retcode .
  876.          if retcode<>0 then do
  877.             say "Write Error: retcode="retcode"," RxNPExplainErr(retcode) "in line"  whatline()
  878.             return
  879.          end
  880.       end
  881.    end
  882. end
  883.  
  884.  
  885. evaluate: procedure
  886.    parse arg expression
  887.    signal on syntax name BADVAL
  888.    signal on novalue name BADVAL
  889.       interpret "Push" expression
  890.       parse pull retval
  891.       call syssleep 3    /* simulate processing time */
  892.       return retval
  893.    BADVAL:
  894.    return expression
  895.  
  896. syntax:
  897.    errcode=rc
  898.    errline=sigl
  899.    say "Error" errcode "("errortext(errcode)") in line" errline":"
  900.    say sourceline(errline)
  901.    return
  902.  
  903. halt:
  904.    errline=sigl
  905.    say "Halt in line" errline":"
  906.    say sourceline(errline)
  907.    call SysSleep 10
  908.    "exit"
  909.  
  910. whatline:
  911.    return "line="sigl
  912.  
  913.  
  914. ΓòÉΓòÉΓòÉ 1.19.2. MsgSamp - An Inbound Named Pipe with Asychronous processing ΓòÉΓòÉΓòÉ
  915.  
  916. /* sample for RxNPipes, inbound, nowait message receiver */
  917. trace 'o'
  918. signal on syntax
  919. pipe="\pipe\message"
  920. mark = "/SERVER"
  921.  
  922. if RxFuncQuery("SysSleep") then
  923.    call RxFuncAdd 'SysSleep', 'RexxUtil', 'SysSleep'
  924.  
  925. if RxFuncQuery("RxNpLoadFuncs") then do
  926.    call RxFuncAdd 'RxNPLoadFuncs', 'RxNPipes', 'RxNPLoadFuncs'
  927.    say RxNPLoadFuncs()
  928. end
  929.  
  930. parse source . . self .
  931. parse arg message
  932. if left(strip(message),length(mark)) = mark then signal server
  933.  
  934. RxNPipes.0=".\rxnpipes.log"
  935.  
  936. busy=RxNPErrBusy()
  937. timeout=RxNPErrTimeout()
  938. notfound=RxNPErrNotFound()
  939.  
  940. parse value RxNPOpen(pipe) with retcode handle .
  941. if retcode=notfound then do
  942.    "start ""Piped Message Server"" /f" self mark
  943.    do 60
  944.       parse value RxNPOpen(pipe) with retcode handle .
  945.       if retcode <> notfound then leave
  946.       say "Waiting for Server to start"
  947.       call syssleep 1
  948.    end
  949. end
  950.  
  951. do 20 while retcode=busy
  952.    x=time()
  953.    retcode=RxNPWaitFree(pipe,10000)  /* wait 10 sec for it to free up */
  954.    if retcode=timeout then do  /* this happens only if one process ties it up for 10 seconds */
  955.       say "Timout waiting for server"
  956.       return 0
  957.    end
  958.    if retcode<>0 then do
  959.       say "Wait Error: retcode="retcode"," RxNPExplainErr(retcode)"in line"  whatline()
  960.       return
  961.    end
  962.    parse value RxNPOpen(pipe) with retcode handle .
  963. end
  964.  
  965. if retcode <> 0 then do
  966.    say "Open Error: retcode="retcode"," RxNPExplainErr(retcode) "in line"  whatline()
  967.    if retcode <> 0 then return
  968. end
  969.  
  970. say "message:" message
  971. retcode=RxNPWrite(handle,message)
  972. if retcode <> 0 then do
  973.    say "Write Error: retcode="retcode"," RxNPExplainErr(retcode) "in line"  whatline()
  974.    return
  975. end
  976.  
  977. call RxNPClose handle
  978. return
  979.  
  980.  
  981. server:
  982. trace 'o'
  983. "mode co80,45"
  984.  
  985. busy=RxNPErrBusy()
  986. timeout=RxNPErrTimeout()
  987. notfound=RxNPErrNotFound()
  988. nodata=RxNPErrNoData()
  989.  
  990. parse value RxNPCreate(pipe,"Inbound","NoWait") with retcode handle .
  991. if retcode<>0 then do
  992.    say "Return code="retcode "creating pipe" pipe
  993.    return
  994. end
  995. signal on halt
  996.  
  997. parse value RxNPCreateSem(handle) with retcode semaphore .
  998. if retcode<>0 then do
  999.    say "Return code="retcode "creating semaphore" RxNPExplainErr(retcode) "in line"  whatline()
  1000.    return
  1001. end
  1002.  
  1003. do forever
  1004.    parse value RxNPRead(handle) with retcode len message
  1005.    do while retcode=nodata | len=0
  1006.       parse value RxNPQuery(handle) with retcode state .
  1007.       select
  1008.          when retcode<>0 then do
  1009.             say "Return code="retcode "querying pipe" pipe RxNPExplainErr(retcode) "in line"  whatline()
  1010.             call syssleep 30
  1011.             return
  1012.          end
  1013.          when state="CLOSING" then do
  1014.             parse value RxNPReconnect(handle) with retcode .
  1015.             if retcode<>0 then do
  1016.                say "Reconnect: retcode="retcode RxNPExplainErr(retcode) "in line"  whatline()
  1017.                call syssleep 30
  1018.                return
  1019.             end
  1020.           end
  1021.           otherwise nop
  1022.       end
  1023.  
  1024.       SaveRxNpipe=""
  1025.       TimeCount=-1
  1026.       do forever
  1027.          parse value RxNPWaitRead(handle,semaphore,4000) with retcode .
  1028.          if retcode<>timeout then do
  1029.             leave
  1030.          end
  1031.          TimeCount=TimeCount+1
  1032.          say "timeout tick every 4 seconds at" time()
  1033.          if datatype(RxNPipes.0,"N") then do
  1034.             SaveRxNpipe=1+RxNPipes.0
  1035.             drop RxNPipes.0
  1036.          end
  1037.       end
  1038.       if SaveRxNPipe<>"" then do
  1039.          RxNPipes.SaveRxNPipe="= =" TimeCount "timeouts skipped"
  1040.          RxNPipes.0=SaveRxNPipe
  1041.       end
  1042.       parse value RxNPRead(handle) with retcode len message
  1043.    end
  1044.    if retcode<>0 then do
  1045.       say "Return code="retcode "reading pipe" pipe RxNPExplainErr(retcode) "in line"  whatline()
  1046.       call syssleep 30
  1047.       return
  1048.    end
  1049.  
  1050.    if right(message,2)="0d0a"x then message=left(message,length(message)-2) /* in case message comes from ECHO */
  1051.    select
  1052.       when translate(message)="STOP" then do
  1053.          call RxNPClose handle
  1054.          "exit"
  1055.       end
  1056.       when translate(message)="DROP" then do
  1057.          call RxNPClose handle
  1058.          call RxNPDropFuncs
  1059.          "exit"
  1060.       end
  1061.       when translate(message)="DISP" then do
  1062.          if datatype(RxNPipes.0,"N") then do i=1 to RxNPipes.0
  1063.             parse var RxNPipes.i f1 f2 d
  1064.             say "["i"]" f1 f2
  1065.             say "["i"]"  strip(d)
  1066.             say
  1067.          end
  1068.          drop RxNPipes.
  1069.          RxNPipes.0=0
  1070.       end
  1071.       when translate(message)="NOTRACE" then do
  1072.          drop RxNPipes.
  1073.       end
  1074.       otherwise do
  1075.          say 'Received: "'message'"'
  1076.       end
  1077.    end
  1078.  
  1079.    parse value RxNPQuery(handle) with retcode state .
  1080.    select
  1081.       when retcode<>0 then do
  1082.          say "Return code="retcode "querying pipe" pipe RxNPExplainErr(retcode) "in line"  whatline()
  1083.          call syssleep 30
  1084.          return
  1085.       end
  1086.       when state="CLOSING" then do
  1087.          parse value RxNPReconnect(handle) with retcode .
  1088.          if retcode<>0 then do
  1089.             say "Reconnect: retcode="retcode RxNPExplainErr(retcode) "in line"  whatline()
  1090.             call syssleep 30
  1091.             return
  1092.          end
  1093.        end
  1094.        otherwise nop
  1095.    end
  1096. end
  1097.  
  1098. return
  1099.  
  1100. syntax:
  1101.    errcode=rc
  1102.    errline=sigl
  1103.    say "Error" errcode "("errortext(errcode)") in line" errline":"
  1104.    say sourceline(errline)
  1105.    return
  1106.  
  1107. halt:
  1108.    errline=sigl
  1109.    say "Halt in line" errline":"
  1110.    say sourceline(errline)
  1111.    call SysSleep 10
  1112.    "exit"
  1113.  
  1114. whatline:
  1115.    return sigl
  1116.  
  1117.  
  1118. ΓòÉΓòÉΓòÉ 1.20. Installation ΓòÉΓòÉΓòÉ
  1119.  
  1120. There are 4 files in this package: 
  1121.  
  1122.      RxNPipes.dll 
  1123.      RxNPipes.inf 
  1124.      magsamp.cmd 
  1125.      calcsamp.cmd 
  1126.  
  1127.  the latter 2 being examples only, and not essential to the operation of 
  1128.  RxNPipes. 
  1129.  
  1130.  RxNPipes.dll must be copied to a directory in the LIBPATH (in CONFIG.SYS) to 
  1131.  enable the facilities described here. 
  1132.  
  1133.  RxNPipes.inf may be copied to a directory in the BOOKSHELF path (in 
  1134.  CONFIG.SYS) to enable the commands 
  1135.  
  1136.        view RxNpipes
  1137.  and 
  1138.  
  1139.        help RxNPipes topic
  1140.  
  1141.   or included as part of the REXX environment variable, as in 
  1142.  
  1143.        set rexx=c:\os2\book\rexx.inf+d:\packages\rxpipe\rxnpipes.inf
  1144.  
  1145.  to enable these functions to appear as a natural part of the REXX environment. 
  1146.  In the latter case the help text in this file will appear as part of the 
  1147.  overall REXX help. 
  1148.  
  1149.  
  1150. ΓòÉΓòÉΓòÉ 1.21. Notes ΓòÉΓòÉΓòÉ
  1151.  
  1152.  
  1153. ΓòÉΓòÉΓòÉ 1.21.1. Version 2.00: 22nd December 1995 ΓòÉΓòÉΓòÉ
  1154.  
  1155. Fixed a bug in the trace output for the openmode parameter in RxNPOpen. Allowed 
  1156. tracing to a PMPRINTF (or any other Queue-supporting) session. Added 
  1157. RxNPDebug() and RxNPVersion(). 
  1158.  
  1159.  
  1160. ΓòÉΓòÉΓòÉ 1.21.2. Version 1.40: 27th July 1994 ΓòÉΓòÉΓòÉ
  1161.  
  1162. Added an optional parameter to RxNPRead to specify the size of receive buffer 
  1163. to use.  The default size is still 4096 bytes. 
  1164.  
  1165.  
  1166. ΓòÉΓòÉΓòÉ 1.21.3. Version 1.30: 23rd May 1994 ΓòÉΓòÉΓòÉ
  1167.  
  1168. Fixed a bug in returning the received message (from RxNPRead) as part of the 
  1169. function return value when the number of bytes received was greater than about 
  1170. 250. 
  1171.  
  1172.  
  1173. ΓòÉΓòÉΓòÉ 1.21.4. Version 1.20: 20th February 1994 ΓòÉΓòÉΓòÉ
  1174.  
  1175. Trace to file contains process id. 
  1176.  
  1177. Formatting improvements made to .inf file 
  1178.  
  1179. Incorrect references to RXNPipe changed to RXNPipes in the .inf file. 
  1180.  
  1181. This version was never put on OS2TOOLS 
  1182.  
  1183.  
  1184. ΓòÉΓòÉΓòÉ 1.21.5. Version 1.10: 17th October 1993 ΓòÉΓòÉΓòÉ
  1185.  
  1186. Trace output can be directed to a file. See Debugging. 
  1187.  
  1188. Samples fixed to load the SysSleep() function from REXXUTIL if required. 
  1189.  
  1190.  
  1191. ΓòÉΓòÉΓòÉ 1.21.6. Version 1.00: 15th September 1993 ΓòÉΓòÉΓòÉ
  1192.  
  1193. Minor editorial changes 
  1194.  
  1195. Compiled with GA-level of IBM C Set++. 
  1196.  
  1197.  
  1198. ΓòÉΓòÉΓòÉ 1.21.7. Version 0.71:  7th September 1993 ΓòÉΓòÉΓòÉ
  1199.  
  1200. Code and INF file marked "IBM Internal Use Only" 
  1201.  
  1202.  
  1203. ΓòÉΓòÉΓòÉ 1.21.8. Version 0.07:  6th September 1993 ΓòÉΓòÉΓòÉ
  1204.  
  1205. This is the first external release. 
  1206.  
  1207. This package was compiled with a Beta Version of the IBM C/C++ Tools Product. 
  1208. My GA version has been ordered but has not arrived; this package will remain at 
  1209. version 0.x until I can rebuild it with the GA product. 
  1210.  
  1211. RxNPipes was built as a static-linked subsystem, so there should be no 
  1212. requirement for other DLLs on your system. 
  1213.  
  1214. When I first started working on this, but before I released it to anyone else, 
  1215. I called it RxNPipe in some places and RxNPipes in others.  It should be called 
  1216. RxNPipes consistently; any reference to the name RxNPipe, either in this .inf 
  1217. file or in the code, is an error.