═══ 1. About YDBAUTIL ═══ YDBAUTIL is a package of diverse OS/2 Rexx External Functions. Some functions in this package work with features of Extended Services (ES), although you do not need to have ES installed to use the non-ES functions. Almost all the functions in this package are in use in many of my own programs and are fairly well de-bugged. Please let me know of any problems you encounter in using the functions, or of any suggestions for enhancements to existing functions, or ideas for new ones. With the functions in the YDBAUTIL function package, you can make use of some of OS/2's most powerful facilities, such as multi-threading, processes, sessions, semaphores, shared memory, OS/2 queues, etc. Some of these features are not only useful in pure Rexx applications, but they allow you to write Rexx programs which can talk to compiled programs on their level (i.e. reference memory by address, use semaphores, etc.). Another benefit is the ability to quickly prototype real OS/2 programs using real OS/2 APIs so that you can cheaply 'prove' techniques before committing them to 'C' code. The capabilities provided to Rexx programs by this package, in conjunction with those provided by other Rexx function packages (database access, APPC, etc.) and the base language itself allow you to prototype or build Rexx applications with much of the functional sophistication (and complexity, unfortunately) of "real" OS/2 applications. In addition to the many OS/2 API "passthrough" functions, there are some Rexx-specific enhancements and additions. Author: Dave Boll (CompuServe = 74170,2016) IBMMAIL(USFMCFKF) Release Date: 21 June, 1993 Version: 1.1 ═══ 2. Release Notes ═══ This release contains fixes for some minor problems and includes help information for OS/2 queue functions (which were there for v.10 but I forgot to document). I have tried this on OS/2 v2.1 GA code and it seems to work just fine. This function package will only work on OS/2 2.x as it is 32-bit code. ═══ 3. How to Use It ═══ How to register the functions: In order to use the functions, you have to register them with Rexx like this: call rxfuncadd 'rxydbautilinit','ydbautil','rxydbautilinit' call rxydbautilinit The .DLL "ydbautil.dll" must be in your libpath. The program "RXSRS.EXE" must be in your path in order to use the functions "RxStartRexxSession" and "RxDetachRexxPgm". ═══ 4. Available External Functions ═══ The available functions are: Function Package utility functions ---------------------------------- RxYdbaUtilInit - Register all YDBAUTIL Rexx functions RxYdbaUtilTerm - De-Register all YDBAUTIL Rexx functions RxYdbaUtilQuery - Query available external function entry point names UPM Related ----------- RxUpm - Rexx interface to UPM RxNet - Rexx interface to certain NET calls (also some UPM-related calls) System-Info related ------------------- RxProcId - Get process' own PID and TID information RxQuerySysInfo - Invoke DosQuerySysInfo RxPStat - Obtain Process Status Information (like PSTAT) RxSetError - Set DosError settings (enable/disable HardError and Exception popups) Rexx programming and debugging functions ---------------------------------------- RxVlist - List, manipulate Rexx variable pool RxScount - Count strings (needle) in another string (haystack) RxPmPrintf - Write lines to a PMPrintf Monitor RxCallInStore - Execute a string as a program RxTokenize - Tokenize ("Compile") a program string RxPullQueue - Pull items from any Rexx data queue RxAddQueue - Add items to any Rexx data queue RxQueued - Query number of items on any Rexx data queue RxQExists - Query existence of a Rexx Queue I/O related ----------- RxRsoe2f - Redirect StdOut/StdErr to a file (by file name) RxSoSe2H - Redirect StdOut/StdErr to a file (by file handle) RxSi2H - Redirect StdIn from a file (by file handle) RxRSi2F - Redirect StdIn from a file (by file name) RxRead - Read data from a file handle RxWrite - Write data to a file handle RxCloseH - Close a file handle RxExecI - Read data into a Rexx queue or stem from a file RxExecO - Write data from a Rexx queue or stem to a file OS/2 Pipes ---------- RxCreateNPipe - Create a named pipe RxConnectNPipe - Connect to a named pipe RxDisConnectNPipe - Disconnect from a named pipe RxCreatePipe - Create an un-named pipe RxDestroyPipe - Destroy a pipe OS/2 Queues ---------- RxCreateQueue - DosCreateQueue RxOpenQueue - DosOpenQueue RxPeekQueue - DosPeekQueue RxReadQueue - DosReadQueue RxWriteQueue - DosWriteQueue RxPurgeQueue - DosPurgeQueue RxQueryQueue - DosQueryQueue RxCloseQueue - DosCloseQueue RxReadQueueStr - Returns data from de-referenced queue pointer NetBios information ------------------- RxNbSessionStatus - Obtain NETBIOS session status information Tasking, threads, etc. ---------------------- RxSetPriority - Set the priority of processes or threads Process - Related RxKillProcess - Kill an OS/2 process by process-id RxExecPgm - Execute a program using DosExecPgm RxStartSession - Start a program in another session (DosStartSession) RxStartRexxSession - Start a Rexx program in another session RxDetachRexxPgm - Detach a Rexx program Thread - Related RxCreateRexxThread - Execute a Rexx program on another thread RxCreateThread - Call a procedure address on another thread RxKillThread - Kill a thread by thread-id RxResumeThread - Resume thread execution by thread-id RxSuspendThread - Suspend thread execution by thread-id RxCallEntryPoint - Call a (non-Rexx) routine by entry point address OS/2 Memory managment --------------------- RxStorage - Query/Alter storage by address RxAdd2Ptr - Pointer Arithmetic (Add/Subtract) RxAllocMem - Allocate Memory RxFreeMem - Free Memory RxAllocSharedMem - Allocated Shared memory (named or un-named) RxGetSharedMem - Get (gettable) shared memory RxGiveSharedMem - Give (giveable) shared memory RxGetNamedSharedMem - Get named shared memory RxSetMem - Set memory attributes RxQueryMem - Query memory attributes RxSubAllocMem - Suballocate memory RxSubFreeMem - Free suballocated memory RxSubSetMem - Set memory for suballocation RxSubUnsetMem - Unset previously "SubSet" memory OS/2 Semaphores --------------- Event Semaphore RxCreateEventSem - Create an event semaphore RxCloseEventSem - Close an event semaphore RxOpenEventSem - Open an event semaphore RxPostEventSem - Post an event semaphore RxQueryEventSem - Query an event semaphore RxResetEventSem - Reset an event semaphore RxWaitEventSem - Wait on an event semaphore Mutex Semaphore RxCreateMutexSem - Create a Mutex semaphore RxOpenMutexSem - Invoke DosOpenMutexSem RxCloseMutexSem - Invoke DosCloseMutexSem RxQueryMutexSem - Invoke DosQueryMutexSem RxReleaseMutexSem - Invoke DosReleaseMutexSem RxRequestMutexSem - Invoke DosRequestMutexSem MuxWait Semaphore RxCreateMuxWaitSem - Invoke DosCreateMuxWaitSem RxCloseMuxWaitSem - Invoke DosCloseMuxWaitSem RxOpenMuxWaitSem - Invoke DosOpenMuxWaitSem RxWaitMuxWaitSem - Invoke DosWaitMuxWaitSem RxAddMuxWaitSem - Invoke DosAddMuxWaitSem RxDeleteMuxWaitSem - Invoke DosDeleteMuxWaitSem RxQueryMuxWaitSem - Invoke DosQueryMuxWaitSem DLL Handling ------------ RxLoadModule - Load a DLL RxFreeModule - Free a DLL RxQueryModuleName - Query the fully qualified name of a DLL (by handle) RxQueryModuleHandle - Query the module handle of a DLL (by name) RxQueryProcType - Query the addressing mode of an entry point in a DLL RxQueryProcAddr - Query the procedure address of an entry point in a DLL Rexx Macro Space Handling ------------------------- RxAddMacro - Add a particular Macro Space function RxDropMacro - Drop a particular Macro Space function RxClearMacroSpace - Clear the Rexx Macro Space RxSaveMacroSpace - Save a particular Macro Space function to a file RxLoadMacroSpace - Load a particular Macro Space function from a file RxQueryMacro - Query the position of a particular Macro Space function RxReorderMacro - Reorder a function's position in a Macro Space PM / Wp related functions ------------------------- RxWinQueryObject - Query object handle of a WP object RxWinDestroyObject - Destroy a WP object ═══ 5. UPM Related Functions ═══ Functions which allow certain UPM activities to be performed. ═══ 5.1. RxUpm - Rexx/UPM Interface ═══ This function allows you to make most UPM calls from a Rexx program. Syntax: func = 'Logon' For Process level logon, only usable by that process */ 'Logonp' = 'Logonu' For "User" logon, usable by all processes = 'Logoff' For Process level logoff, undoes a "LOGONP" 'Logoffp' = 'Logoffu' For "User" logoff, undoes a "LOGONU" = 'LogonList' Gets list of current active logons uid = 'Userid' Userid to be logged on/off = 'stemname' Name of Rexx stem variable under which results of "LogonList" are mapped as such: stem.0 - Number of logons reported on stem.n.1 - Userid stem.n.2 - Node/Domain name stem.n.3 - Session-Id stem.n.4 - Logon type (Local/Node/Domain) pw = 'Password' Password to be used with 'Userid' (for logon) type = 'Local' Logs you on/off UPM locally (default is LOCAL if no value supplied) = 'Node' Logs you on/off a node = 'Domain' Logs you on/off a LAN domain = 'dataBase' Logs you on/off the correct node for a database name = 'Name' The name of the node/domain/database, depending on what "TYPE" was chosen check = 'Admin' Checks to see if userid has Admin authority = 'User' Checks to see if userid has User authority = 'Config' Checks to see if logon was done from Config.Sys upmrc = RxUpm(func, uid, pw, type, name, check) ═══ 5.2. RxNet - Rexx/NET Interface ═══ This function allows you to make certain NetApi calls from Rexx. This enables you to do such things as changing passwords, adding and deleting userids, validating a userid/pw, listing users and logons. Syntax: /* General syntax */ netrc = RxNet(func, server, arg3, arg4, arg5, arg6) where: func = 'UserPwSet' /* Change a user's password */ = 'UserAdd' /* Add a user to UPM */ = 'UserDel' /* Delete a user from UPM */ = 'UserVal' /* Validate a userid/password without logging on */ = 'UserEnum' /* List users in UPM */ = 'LogonEnum' /* List active logons */ = 'FileEnum' /* File usage on the LAN */ server = name of server, or '00'x for local netrc = return code from NetApi call. If netrc < 2100, then it's probably a base OS/2 return code, otherwise, it's defined in NETCONS.H /* Specific calls */ netrc = RxNet('UserPwSet', server, userid, oldpw, newpw) netrc = RxNet('UserAdd', server, userid, password, type, comment) type = 'User', 'Guest', or 'Admin' netrc = RxNet('UserDel', server, userid) netrc = RxNet('UserVal', server, userid, password) netrc = RxNet('UserEnum',server, rexxstem) rexxstem = Rexx stem name, under which results are mapped as: stem.0 = number of users stem.n.1 = userid stem.n.2 = privilege level (Guest, User, Admin, ?) stem.n.3 = password age (in seconds) stem.n.4 = comment netrc = RxNet('LogonEnum',server, rexxstem) rexxstem = Rexx stem name, under which results are mapped as: stem.0 = number of users stem.n.1 = userid netrc = RxNet('FileEnum',server, basepath, username, rexxstem) basepath = file path/name qualifier username = username qualifier rexxstem = Rexx stem name, under which results are mapped as: stem.0 = number of entries stem.n.1 = file-id stem.n.2 = permissions stem.n.3 = numlocks stem.n.4 = pathname stem.n.5 = username ═══ 6. Rexx Programming/Debugging ═══ Tools for developing Rexx programs. ═══ 6.1. RxSCount - Count instances of a string ═══ This function returns a count of the number of instances of a string "needle" in a string "haystack", optionally ignoring case. Syntax: numitem = rxscount(needle,haystack[,case]) where: needle = string you want to count instances of haystack = string in which you want to count instances of "needle" case = any character to indicate that case (upper/lower) is to be ignored numitem = number of times "needle" is found in "haystack" ═══ 6.2. RxPmPrintf - Write lines to a PMPrintf Monitor ═══ This function writes data lines to a PMPrintf "Monitor" program. Syntax: bytes = RxPmPrintf(qname, [data1 [,data2 [,data3 [...]]]] ) where: qname = name of PMPrintf queue If blank, uses default PMPrintf Queue (PRINTF32). data1 = data to be written to PMPrintf ... Each argument is written as a separate line datan bytes = number of bytes written in this operation Notes: The PMPrintf tool can be downloaded from the OS/2 Bulletin Board. This Rexx function does work with PMPrintf v2.5, but may not work with earlier versions. You can start the PMPrintf program with a command line argument specifying an alternate queue name for it to use. This queue name can be supplied as the first argument of RxPmPrintf to direct the data to a specific running instance of PMPrintf. If only the queue name is supplied (i.e. args 2-n are not supplied), nothing at all is written to queue. If an argument has zero length, no data will be written to the queue for that argument (i.e. you must supply at least one byte to be written to queue). ═══ 6.3. RxCallInStore - Execute a string as a program ═══ This function allows the Rexx program developer to execute a string as though it were a Rexx program. This allows you to build the equivalent of a Rexx program's text in a variable, and then execute it from the string. Actually, the Rexx program text can come from anywhere -- a file, over a communications link, from a database. For repeated execution of a program, use "RxTokenize" to "compile" the program, then call "RxCallInStore" with "&" to re-use the tokenized program. Syntax: result = RxCallInStore strtext, arg1, arg2, ..., arg19 where: strtext = text of a Rexx program, complete with crlf and eof markers or a '$' immediately preceding a source program string or a '&' immediately preceding a tokenized program string arg1 = arguments to the called program ... arg19 Note: Example of executing a program string: crlf = '0d0a'x str = '/* Rexx */'crlf str = str 'Do i=1 To Arg()'crlf str = str ' Say "Arg#"i "= {"arg(i)"}"'crlf str = str 'End'crlf str = str||'1a'x /* EOF marker */ call rxcallinstore str, date(), time() ( or ) call rxcallinstore '$'str, date(), time() ( or ) tstr = rxtokenize(str) call rxcallinstore '&'tstr, date(), time() ═══ 6.4. RxTokenize - Tokenize a program source string ═══ This function in effect "compiles" a program source string for re-use with subsequent "RxCallInstore" or "RxCreateRexxThread" calls. This provides better performance when a program string is repeatedly called. Syntax: tokenstr = RxTokenize(progstr) where: progstr = actual Rexx program source string tokenstr = tokenized ("compiled") result of "progstr" Note: This function, in conjunction with the "RxCallInstore" and/or "RxCreateRexxThread" functions, can be used to achieve the same effect as the Rexx Macrospace, except that this technique is local to the program using it (whereas the Macrospace is system global). ═══ 6.5. RxVlist - Display/Process Rexx Variables ═══ This function allows the Rexx program developer to view portions of the Rexx variable pool. It also allows you to effectively "pass" variable pools (or subsets thereof) between execs across Rexx queues. Syntax: numvar = RxVlist( [vnamepat] [,func] [,qname] ) where: func = 'V' /* Puts variable name/value pairs on a queue */ = 'N' /* Puts variable names on a queue */ = 'G' /* Gets variable name/value pairs off a queue */ /* and incorporates them into the current variable pool */ = 'D' /* display variables and their values (default) */ vnamepat = variable name prefix (every variable whose name begins with this value is processed according to the specified function) (default is all variables) qname = name of a Rexx queue to use (default is the current queue) ═══ 6.6. RxPullQueue - Pull items off any Rexx queue ═══ This function does what the Rexx "Pull" instruction and "LineIn" functions do, except this function allows you to specify the queue name as part of the call, regardless of what the current queue may be. Syntax: data = RxPullQueue( [qname] [,type] [,rexxvar] ) where: qname = name of Rexx queue to pull from (default is current queue) type = 'Wait' or 'Nowait' (default is 'Wait') rexxvar = name of a Rexx variable into which is put the queue-insertion- timestamp for the retreived element data = data obtained from queue ═══ 6.7. RxAddQueue - Add items to any Rexx queue ═══ This function does what the Rexx "Queue" and "Push" instructions, and the "LineOut" function do, except this function allows you to specify the queue name as part of the call, regardless of what the current queue may be. Syntax: qrc = RxAddQueue( data [,qname] [,type] ) where: data = data to be placed on queue qname = name of Rexx queue to add to (default is current queue) type = 'Queue' or 'Push' (default is 'Queue') ═══ 6.8. RxQueued - Query number of items on any Rexx queue ═══ This function does what the Rexx "Queued" function does, except this function allows you to specify the queue name as part of the call, regardless of what the current queue may be. Syntax: numq = RxQueued( [qname] ) where: qname = name of Rexx queue to report on (default is current queue) ═══ 6.9. RxQExists - Query existence of a Rexx Queue ═══ This function returns "1" or "0", indicating the existence of the Rexx Queue whose name you supply as an argument. Syntax: bool = RxQExists( [qname] ) where: qname = name of Rexx queue to check for existence of bool = truth value of queue's existence ═══ 7. Memory Management/Access ═══ These functions allow Rexx programs to create, access, and manage OS/2 memory objects by address. This includes objects such as shared memory (named and un-named). ═══ 7.1. RxStorage - Access/Alter memory by address ═══ This function allows a Rexx program to access and/or alter storage by address. This could be used to process data passed to it by a program. This could also be used to "Pass By Reference" among Rexx programs when using the RxAllocMem and RxFreeMem functions. Syntax: outdata = RxStorage( pointer [, length] [, indata] ) where pointer = 32-bit pointer (address) length = Length of storage to be queried (defaults to 1) indata = Data to place at address "pointer" for the length of the data (regardless of "length" value) outdata = Data at address "pointer" for length "length" (truncated if "length" takes you beyond allowed storage) Note: A request to query memory out-of-bounds returns a string up to the bound- ary. A request to set memory out-of-bounds, sets memory up to the bound- ary. All memory is allocated in 4k chunks. Therefore, some query or set operations will access memory up to the next 4k boundary. ═══ 7.2. RxAdd2Ptr - Pointer Arithmetic (Add/Subtract) ═══ This function allows a Rexx program to add or subtract from an OS/2 32-bit linear address. Syntax: newptr = RxAdd2Ptr( pointer , [number] ) where: pointer = 32-bit pointer (address) number = amount by which "pointer" is to be incremented/decremented in bytes. Default is zero. newptr = result of addition/subtraction ═══ 7.3. RxAllocMem - Allocate memory (using DosAllocMem) ═══ This function allows a Rexx program to allocate memory. This memory can then be accessed using RxStorage. Syntax: allocrc = RxAllocMem(rexxvar, length, flags) where rexxvar = name of a rexx variable in which pointer is returned length = a decimal integer indicating amount of storage (in bytes) to allocate flags = any combination of: C - Pag_Commit T - Obj_Tile X - Pag_Execute R - Pag_Read W - Pag_Write G - Pag_Guard allocrc = return code from DosAllocMem() for example: /* Following would get 4k committed read/write */ allocrc = RxAllocMem('pointer', 4096, 'crw') Note: All memory is allocated in 4k chunks. Therefore, even if you allocate 200 bytes, you will get access to 4096 bytes. ═══ 7.4. RxFreeMem - Free memory allocated by RxAllocMem ═══ This function allows a Rexx program to free memory allocated by RxAllocMem. Syntax: freerc = RxFreeMem(pointer) where pointer - A valid 32 bit pointer. Note: Returned value is return code from DosFreeMem ═══ 7.5. RxAllocSharedMem - Allocate shared memory ═══ This function allocates shared (named or un-named) memory. Other processes can access this memory with either RxGetSharedMem (un-named), or RxGetNamedSharedMem (named), or if it is "Given", followed by calls to RxStorage. Syntax: allocrc = RxAllocSharedMem(rexxvar, length, flags [,memname] ) where rexxvar = name of a rexx variable in which pointer is returned length = a decimal integer indicating amount of storage (in bytes) to allocate flags = any combination of: C - Pag_Commit T - Obj_Tile I - Obj_Giveable E - Obj_Gettable (sic) X - Pag_Execute R - Pag_Read W - Pag_Write G - Pag_Guard memname = name of shared memory object, if this is to be named shared memory allocrc = return code from DosAllocSharedMem() for example: /* To allocate an un-named, gettable object */ allocrc = RxAllocSharedMem('pointer', 4096, 'cerw') /* To allocate a named object */ allocrc = RxAllocSharedMem('pointer', 4096, 'crw','\SHAREMEM\TEST.MEM') Note: All memory is allocated in 4k chunks. Therefore, even if you allocate 200 bytes, you will get access to 4096 bytes. ═══ 7.6. RxGiveSharedMem - Give access to shared memory ═══ This function gives access to shared, un-named memory to a process-id Syntax: giverc = RxGiveSharedMem(pointer, pid [,flags]) where pointer = valid 32-bit pointer pid = valid process-id (as a decimal integer) flags = any combination of: X - Pag_Execute R - Pag_Read W - Pag_Write G - Pag_Guard for example: /* To give shared memory */ giverc = RxGiveSharedMem(pointer, 23, 'rw') Note: A valid pointer must be supplied. This is obtained from the process which allocated the shared un-named memory via RxAllocSharedMem. The process-id supplied must be valid (i.e. must currently exist). ═══ 7.7. RxGetSharedMem - Get access to shared memory ═══ This function gets access to shared, un-named, gettable memory. Syntax: getrc = RxGetSharedMem(pointer, flags) where pointer = valid 32-bit pointer flags = any combination of: X - Pag_Execute R - Pag_Read W - Pag_Write G - Pag_Guard for example: /* To get shared memory */ getrc = RxGetSharedMem(pointer, 'rw') Note: A valid pointer must be supplied. This is obtained from the process which allocated the shared un-named memory via RxAllocSharedMem. ═══ 7.8. RxGetNamedSharedMem - Get access to named shared memory ═══ This function gets access to shared, named memory. Syntax: getrc = RxGetNamedSharedMem(rexxvar, memname, flags) where rexxvar = name of a rexx variable in which pointer is returned memname = valid name of a shared memory object flags = any combination of: X - Pag_Execute R - Pag_Read W - Pag_Write G - Pag_Guard getrc = return code from DosGetNamedSharedMem() for example: /* To get named shared memory */ getrc = RxGetNamedSharedMem('pointer', '\SHAREMEM\TEST.MEM', 'rw') ═══ 7.9. RxSetMem - Set memory attributes ═══ This function sets memory attributes using DosSetMem Syntax: setrc = RxSetMem(pointer [,memsize [,flags]]) where pointer = valid 32-bit pointer memsize = size of memory block to set flags = any combination of: C - Pag_Commit D - Pag_Decommit F - Pag_Default X - Pag_Execute R - Pag_Read W - Pag_Write G - Pag_Guard for example: /* To set memory attributes */ setrc = RxSetMem(pointer, 4096, 'crw') Note: Returned value is return code from DosSetMem. ═══ 7.10. RxQueryMem - Query memory attributes ═══ This function queries memory attributes using DosQueryMem Syntax: qinfo = RxQueryMem(pointer [,memsize]) where pointer = valid 32-bit pointer memsize = size of memory block to query qinfo = either one or three blank-delimited tokens: 1) return code from DosQueryMem If #1 is zero: 2) actual memory size 3) memory attribute flags, which can be any combination of: C - Pag_Commit F - Pag_Free S - Pag_Shared B - Pag_Base X - Pag_Execute R - Pag_Read W - Pag_Write G - Pag_Guard for example: /* To query memory attributes */ qinfo = RxQueryMem(pointer, 4096) /* "Say qinfo" might say -> "0 4096 CSRW" for instance */ Note: If first token is not zero, no other information was returned. ═══ 7.11. RxSubSetMem - Set memory for suballocation ═══ This function sets memory for suballocation using DosSubSetMem Syntax: subsetrc = RxSubSetMem(pointer [,memsize [,flags]]) where pointer = valid 32-bit pointer to pool memsize = size of memory block to subset flags = any combination of: I - DosSub_Init G - DosSub_Grow S - DosSub_Sparse R - DosSub_Serialize for example: /* To subset some memory */ subsetrc = RxSubSetMem(pointer, 4096, 'i') Note: Returned value is return code from DosSubSetMem. ═══ 7.12. RxSubUnSetMem - UnSet memory from suballocation ═══ This function unsets memory from suballocation using DosSubUnSetMem Syntax: subunsetrc = RxSubUnSetMem(pointer) where pointer = valid 32-bit pointer to pool for example: /* To subunset some memory */ subunsetrc = RxSubUnSetMem(pointer) Note: Returned value is return code from DosSubUnSetMem. ═══ 7.13. RxSubAllocMem - Suballocate memory ═══ This function suballocates memory. Syntax: subarc = RxSubAllocMem(rexxvar, pointer [,memsize]) where rexxvar = name of a rexx variable in which block offset is returned pointer = valid 32-bit pointer to pool memsize = size of block to suballocate subarc = return code from DosSubAllocMem() for example: /* To suballocate some memory */ subarc = RxSubAllocMem('block_offset', pointer, 4096) ═══ 7.14. RxSubFreeMem - Free suballocated memory ═══ This function frees suballocated memory. Syntax: freerc = RxSubFreeMem(pointer, boffset [,memsize]) where pointer = valid 32-bit pointer to pool boffset = block offset pointer memsize = size of block to free for example: /* To free suballocated memory */ freerc = RxSubFreeMem(pointer, boffset, 4096) Note: Returned value is return code from DosSubFreeMem. ═══ 8. Sempahore handling ═══ These functions allow Rexx programs to make use of OS/2 semaphores for synchronization/serialization purposes. ═══ 8.1. RxCreateEventSem - Create an event semaphore ═══ This function creates a (named or un-named) event semaphore. Syntax: semrc = RxCreateEventSem(rexxvar [,type] [,name] [,state] ) where rexxvar = name of a rexx variable in which sem handle is returned type = 'Shared' or 'Private' (default is Private) name = semaphore name (default is un-named) state = 'Reset' or 'Posted' (default is Reset) semrc = return code from DosCreateEventSem() ═══ 8.2. RxOpenEventSem - Open an event semaphore ═══ This function opens an event semaphore for use by a process that did not create the semaphore. Syntax: semrc = RxOpenEventSem(rexxvar, semid) where rexxvar = name of a rexx variable in which sem handle is returned semid = either a semaphore handle, or a semaphore name semrc = return code from DosOpenEventSem() Note: A zero length string is returned if DosOpenEventSem fails. ═══ 8.3. RxPostEventSem - Post an event semaphore ═══ This function posts an event semaphore. Syntax: postrc = RxPostEventSem(hev) where hev = semaphore handle postrc = return code from DosPostEventSem ═══ 8.4. RxQueryEventSem - Query an event semaphore ═══ This function returns the post count for an event semaphore. Syntax: info = RxQueryEventSem(hev) where hev = semaphore handle info = return code from DosQueryEventSem, followed by number of posts Note: Word 1 of info is the return code from DosQueryEventSem Word 2 of info is the actual number of posts to the semaphore ═══ 8.5. RxResetEventSem - Reset an event semaphore ═══ This function resets an event semaphore, returning the number of postings for that semaphore. Syntax: info = RxResetEventSem(hev) where hev = semaphore handle info = return code from DosResetEventSem, followed by number of posts Note: Word 1 of info is the return code from DosResetEventSem Word 2 of info is the actual number of posts to the semaphore before the Reset. ═══ 8.6. RxWaitEventSem - Wait on an event semaphore ═══ This function waits on the posting of an event semaphore. Syntax: semhandle /* A valid semaphore handle */ time = 1000 /* in milliseconds */ waitrc = RxWaitEventSem(hev [,time]) where hev = semaphore handle time = number of miliseconds to wait before returning, or the word 'Indefinite'. Default is 'Indefinite'. waitrc = return code from DosWaitEventSem ═══ 8.7. RxCloseEventSem - Close an event semaphore ═══ This function closes an event semaphore Syntax: closerc = RxCloseEventSem(hev) where hev = semaphore handle closerc = return code from DosCloseEventSem ═══ 8.8. RxCreateMutexSem - Create a Mutex Semaphore ═══ This function creates a mutex semaphore Syntax: semrc = RxCreateMutexSem(rexxvar [,type] [,name] [,state] ) where rexxvar = name of a rexx variable in which sem handle is returned type = 'Shared' or 'Private' (default is 'Private') name = semaphore name (default is un-named) state = 'Owned' or 'Unowned' (default is un-owned) semrc = return code from DosCreateMutexSem() ═══ 8.9. RxOpenMutexSem - Open a Mutex Semaphore ═══ This function opens a mutex semaphore Syntax: semrc = RxOpenMutexSem(rexxvar, semid ) where rexxvar = name of a rexx variable in which sem handle is returned semid = either a semaphore name, or an existing mutex semaphore handle semrc = return code from DosOpenMutexSem() ═══ 8.10. RxCloseMutexSem - Close a Mutex Semaphore ═══ This function closes a mutex semaphore Syntax: mtxrc = RxCloseMutexSem( hmtx ) where hmtx = existing mutex semaphore handle mtxrc = return code from DosCloseMutexSem ═══ 8.11. RxQueryMutexSem - Query Mutex Semaphore ═══ This function queries a mutex semaphore's attributes Syntax: mtxinfo = RxQueryMutexSem( hmtx ) where hmtx = existing mutex semaphore handle mtxinfo = four blank delimited tokens: 1) return code from DosQueryMutexSem 2) Process-Id of semaphore's current owner 3) Thread-Id of semaphore's current owner 4) A count of the number of calls to DosRequestMutexSem, minus the number of calls to DosReleaseMutexSem, that have been made for the semaphore by the owning thread. If the semaphore is unowned, this value will be zero. If the owning thread has ended, the value will be the request count for the ended owner. ═══ 8.12. RxReleaseMutexSem - Release Mutex Semaphore ═══ This function releases a mutex semaphore Syntax: mtxrc = RxReleaseMutexSem( hmtx ) where hmtx = existing mutex semaphore handle mtxrc = return code from DosReleaseMutexSem ═══ 8.13. RxRequestMutexSem - Request Mutex Semaphore ═══ This function requests a mutex semaphore Syntax: mtxrc = RxRequestMutexSem( hmtx [, timeout] ) where hmtx = existing mutex semaphore handle timeout = either a decimal integer (miliseconds to block), or the word 'Indefinite' mtxrc = return code from DosRequestMutexSem ═══ 8.14. RxCreateMuxWaitSem - Create a MuxWait Semaphore ═══ This function creates a muxwait semaphore Syntax: semrc = RxCreateMuxWaitSem(rexxvar, stemname [,type] [,anyall] [,name] ) where rexxvar = name of a rexx variable in which sem handle is returned stemname = a Rexx stem name (ending in a period '.'), under which are supplied the semaphore handles which constitute this muxwait semaphore. The expected structure of the stem is: 1) stem.0 = a decimal integer indicating how many semaphores are supplied 2) stem.n.1 = handle of Nth semaphore 3) stem.n.2 = decimal integer used as an Id for Nth semaphore type = 'Shared' or 'Private' (default is 'Private') anyall = 'Any' or 'All' (default is 'All') name = semaphore name (default is un-named) semrc = return code from DosCreateMuxWaitSem() ═══ 8.15. RxOpenMuxWaitSem - Open a MuxWait Semaphore ═══ This function opens a muxwait semaphore Syntax: semrc = RxOpenMuxWaitSem(rexxvar, semid ) where rexxvar = name of a rexx variable in which sem handle is returned semid = either a semaphore name, or an existing muxwait semaphore handle semrc = return code from DosOpenMuxWaitSem() ═══ 8.16. RxCloseMuxWaitSem - Close a MuxWait Semaphore ═══ This function closes a muxwait semaphore Syntax: muxrc = RxCloseMuxWaitSem( hmux ) where hmux = existing muxwait semaphore handle muxrc = return code from DosCloseMuxWaitSem ═══ 8.17. RxDeleteMuxWaitSem - Delete from a MuxWait Semaphore ═══ This function deletes a semaphore from a muxwait semaphore list Syntax: muxrc = RxDeleteMuxWaitSem( hmux, hsem ) where hmux = existing muxwait semaphore handle hsem = handle of a semaphore in the muxwait semaphore list muxrc = return code from DosDeleteMuxWaitSem ═══ 8.18. RxAddMuxWaitSem - Add to a MuxWait Semaphore ═══ This function adds a semaphore to a muxwait semaphore list Syntax: muxrc = RxAddMuxWaitSem( hmux, hsem, semid ) where hmux = existing muxwait semaphore handle hsem = handle of a semaphore to add to the muxwait semaphore list semid = decimal integer used as an Id for this semaphore muxrc = return code from DosAddMuxWaitSem ═══ 8.19. RxQueryMuxWaitSem - Query a MuxWait Semaphore ═══ This function queries information about a muxwait semaphore Syntax: muxinfo = RxQueryMuxWaitSem( hmux, stemname ) where hmux = existing muxwait semaphore handle stemname = a Rexx stem name (ending in a period '.'), under which is returned information about the muxwait semaphore. The structure of the returned information is: 1) stem.0 = a decimal integer indicating how many semaphores are listed in this muxwait semaphore 2) stem.n.1 = handle of Nth semaphore 3) stem.n.2 = decimal integer Id of Nth semaphore muxinfo = Two blank delimited tokens: 1) return code from DosQueryMuxWaitSem 2) a string of letters indicating this muxwait semaphore's properties: 'S' if it's shared 'Y' if it's a wait ANY 'L' if it's a wait ALL ═══ 8.20. RxWaitMuxWaitSem - Wait on a MuxWait Semaphore ═══ This function waits on a muxwait semaphore Syntax: muxinfo = RxWaitMuxWaitSem( hmux [,timeout] ) where hmux = existing muxwait semaphore handle timeout = either a decimal integer (miliseconds to block), or the word 'Indefinite' muxinfo = Two blank delimited tokens: 1) return code from DosQueryMuxWaitSem 2) semaphore-id of releaser of muxwait sem (for more info, see details of DosWaitMuxWaitSem) ═══ 9. Rexx Macro Space Functions ═══ These functions allow Rexx programs to query and alter the Rexx MacroSpace. ═══ 9.1. RxAddMacro - Add Entry to MacroSpace ═══ This function adds a Rexx program to the macrospace. Syntax: addrc = RxAddMacro(funcname, sourcefile [,order]) where funcname = name for function in macrospace sourcefile = name of source file where Rexx source code exists order = order in macrospace (Before or After) Note: Returned value is return code from RexxAddMacro. ═══ 9.2. RxDropMacro - Drop Entry from MacroSpace ═══ This function drops a function from the macrospace. Syntax: droprc = RxDropMacro(funcname) where funcname = name of function in macrospace Note: Returned value is return code from RexxDropMacro. ═══ 9.3. RxClearMacroSpace - Clear Entire MacroSpace ═══ This function clears all functions from the macro space. Be careful when using this as it will affect all processes in the system. Syntax: clear_rc = RxClearMacroSpace() Note: Returned value is return code from RexxClearMacroSpace. ═══ 9.4. RxSaveMacroSpace - Save Macro to File ═══ This function saves a macrospace function to a file. Syntax: saverc = RxSaveMacroSpace(funcname, macfile) where funcname = name of function in macrospace macfile = name of file in which to save macro Note: Returned value is return code from RexxSaveMacroSpace. ═══ 9.5. RxLoadMacroSpace - Load a Macro from File ═══ This function loads a macrospace function from a file. Syntax: loadrc = RxLoadMacroSpace(funcname, macfile) where funcname = name of function in macrospace macfile = name of file in which to save macro Note: Returned value is return code from RexxLoadMacroSpace. ═══ 9.6. RxQueryMacro - Query MacroSpace ═══ This function queries the existence/position of a macro in the macrospace. Syntax: qinfo = RxQueryMacro(funcname) where funcname = name of function in macrospace qinfo = blank-delimited tokens: 1) return code from RexxQueryMacro If #1 is zero, then: 2) Before/After/? Note: If first token is not zero, no other information was returned. ═══ 9.7. RxReorderMacro - Reorder Macro Position ═══ This function reorders the position of a macro within the macrospace. Syntax: reorderrc = RxReorderMacro(funcname, position) where funcname = name of function in macrospace position = relative position in macrospace (Before/After) Note: Returned value is return code from RexxReorderMacro ═══ 10. Threads, Tasking, etc. ═══ These functions allow a Rexx program to start and control new threads and processes. ═══ 10.1. RxExecPgm - Execute a program ═══ This function starts another program in the same session. Syntax: exrc = RxExecPgm(pgmname [, mode [,argstring]]) where pgmname = name of .EXE file to execute mode = 'S'ync, 'A'sync, async'R'esult, 'T'race, 'B'ackground, 'L'oad, asyncresult'D'b. Default is 'S'ync. argstring = arg string to pass to program exrc = three blank-delimited tokens: 1) return code from DosExecPgm 2) termination code / process-id (for asynchronous) 3) new program's return code ═══ 10.2. RxStartSession - Start Another Session ═══ This function starts a program in another OS/2 session. Syntax: strc = RxStartSession(pgmname [,args [,related [,fgbg [,title [,type [,ctrl] ] ] ] ] ]) where pgmname = name of .EXE file to execute args = arg string to pass to program related = Relation of started session to this session, can be: 'I'ndependent or 'C'hild fgbg = Foreground/Background option, can be: 'F'oreground or 'B'ackground title = Session title (defaults to program name) type = Program type, can be: 'D'efault, 'F'ullscreen, 'P'M, 'V'irtual-Dos, 'W'indowed-Virtual-Dos, vi'O'-windowable ctrl = Program control, can be: 'V'isible, 'I'nvisible, ma'X'imized, mi'N'imized, no'A'utoclose strc = if DosStartSession failed: - return code from DosStartSession followed by error info if DosStartSession got zero rc: - return code from DosStartSession Session-ID Process-ID ═══ 10.3. RxStartRexxSession - Start a Rexx program on another session ═══ This function starts a Rexx program in another OS/2 session. (The program "RXSRS.EXE" must be in your path in order to use this function) Syntax: strc = RxStartRexxSession(execname [,arg1] [,arg2] ... [,argn]) where execname = name of Rexx program to execute or a '$' immediately preceding a source program string or a '&' immediately preceding a tokenized program string (for more info about these, see "RxCallInStore" and "RxTokenize") arg1 = arguments 1-n for target Rexx program ... argn strc = if DosStartSession failed: - return code from DosStartSession followed by error info if DosStartSession worked: - return code from DosStartSession Session-ID Process-ID ═══ 10.4. RxDetachRexxPgm - Detach a Rexx program ═══ This function starts a Rexx program in the detached OS/2 session. (The program "RXSRS.EXE" must be in your path in order to use this function) Syntax: dtrc = RxDetachRexxPgm(execname [,arg1] [,arg2] ... [,argn]) where execname = name of Rexx program to execute or a '$' immediately preceding a source program string or a '&' immediately preceding a tokenized program string (for more info about these, see "RxCallInStore" and "RxTokenize") arg1 = arguments 1-n for target Rexx program ... argn dtrc = if DosExecPgm failed: - return code from DosExecPgm, followed by error info if DosExecPgm worked: - return code from DosExecPgm "codeTerminate" and "codeResult" ═══ 10.5. RxKillProcess - Kill an OS/2 Process ═══ This function kills an OS/2 process by process-id. Syntax: killrc = RxKillProcess(pid [, action]) where pid = process-id (decimal integer) action = 'Process' or 'Tree' (default is 'Process') killrc = return code from DosKillProcess ═══ 10.6. RxCreateThread - Start new thread ═══ This function starts execution at a supplied entry point on a new thread. The entry point is any valid procedure address (e.g. obtained by a call to RxQueryProcAddr, etc.). Syntax: tid = RxCreateThread(procaddr [, dataptr [, linktype [, stacksize [, threadflag]]]]) where procaddr = Procedure Address dataptr = pointer to arguments linktype = 'System' or 'Optlink' If linktype is 'System', then args 4 and 5 are: stacksize = stacksize for thread (default is 8192) threadflag = 'Immediate' or 'Suspend' tid = thread-id of new thread Note: Pointer to arguments is optional, but if supplied must be a valid pointer. ═══ 10.7. RxKillThread - Kill a thread ═══ This function kills a thread by thread-id. Syntax: killrc = RxKillThread(tid) where tid = thread-id killrc = return code from DosKillThread ═══ 10.8. RxSetPriority - Set the priority of processes or threads ═══ This function sets the priority of one or more process and/or threads. Syntax: setrc = RxSetPriority(scope,class,delta,id) where scope = 'P'rocess (default) t'R'ee 'T'hread class = 'N'ochange (default) 'I'dletime 'R'egular 'T'imecritical foreground'S'erver delta = any integer from -31 to +31, or ma'X'imum, or mi'N'imum id = a Process-Id, Thread-Id, or nothing, depending on value of "scope" setrc = return code from DosSetPriority ═══ 10.9. RxResumeThread - Resume thread execution ═══ This function causes a thread to resume execution Syntax: resrc = RxResumeThread(tid) where tid = thread-id resrc = return code from DosResumeThread ═══ 10.10. RxSuspendThread - Suspend thread execution ═══ This function causes a thread to suspend execution Syntax: susrc = RxSuspendThread(tid) where tid = thread-id susrc = return code from DosSuspendThread ═══ 10.11. RxCreateRexxThread - Rexx on another thread ═══ This function executes a Rexx program on another thread of the same process. The started Rexx program has a separate variable pool, and maintains its own "current Rexx queue", indpendently of the starting Rexx program. But all other features of multi-threaded applications apply (i.e. shared file handles, etc.) Syntax: tid = RxCreateRexxThread(execname [,arg1 [,arg2 [, ...]]]) where execname = name of Rexx program to execute or a '$' immediately preceding a source program string or a '&' immediately preceding a tokenized program string (for more info about these, see "RxCallInStore" and "RxTokenize") arg1 = arguments to Rexx program (up to 19 possible) arg2 ... tid = Thread-Id of new thread Note: Example of executing a program string: crlf = '0d0a'x str = '/* Rexx */'crlf str = str 'Do i=1 To Arg()'crlf str = str ' Say "Arg#"i "= {"arg(i)"}"'crlf str = str 'End'crlf str = str||'1a'x /* EOF marker */ call rxcreaterexxthread '$'str, date(), time() ═══ 11. NETBIOS information ═══ These functions allow a Rexx program to access certain NETBIOS information. ═══ 11.1. RxNbSessionStatus - NetBios Session Status ═══ This function gets NetBios session status information. Syntax: nbname = 'S$SQLDBSERVR1#DB' nbrc = RxNbSessionStatus(nbname,'s.','r') Note: Return code is from NETBIOS api. Second argument is name of a Rexx stem variable under which results are returned as such: stem.0 = number of sessions reported on stem.n.1 = Local session number stem.n.2 = Session state stem.n.3 = Local name stem.n.4 = Remote name stem.n.5 = Number of receive commands pending stem.n.6 = Number of send commands pending Third argument may be supplied to have a NETBIOS "Reset" done before and after obtaining session status. ═══ 12. DLL Handling ═══ These functions allow a Rexx program to load and execute procedures with- in DLL's. Also, certain information about DLL's can be obtained. ═══ 12.1. RxLoadModule - Load a DLL ═══ This function loads a DLL, returning a module handle (or an error code). Syntax: dosrc = RxLoadModule(rexxvar, dllname) where: rexxvar = name of rexx variable in which module handle is returned dllname = name of DLL to load dosrc = return code from DosLoadModule ═══ 12.2. RxFreeModule - Free a DLL ═══ This function frees the DLL whose module handle is supplied. Syntax: dosrc = RxFreeModule(hmod) where: hmod = module handle dosrc = return code from DosFreeModule ═══ 12.3. RxQueryModuleName - Get Module Name ═══ This function returns the name of a module, given the module handle. Syntax: dosrc = RxQueryModuleName(rexxvar,hmod) where: rexxvar = name of rexx variable in which module name is returned hmod = module handle of DLL dosrc = return code from DosQueryModuleName ═══ 12.4. RxQueryModuleHandle - Get Module Handle ═══ This function returns the handle of a module, given the module's name. Syntax: dosrc = RxQueryModuleHandle(rexxvar,modname) where: rexxvar = name of rexx variable in which module handle is returned modname = name of DLL dosrc = return code from DosQueryModuleHandle ═══ 12.5. RxQueryProcType - Query Procedure Type ═══ This function returns the addressing mode (16/32 bit) of a procedure of a DLL. The procedure can be identified either by name, or ordinal number. Syntax: entryname = 'SQLEXEC' ordinal = 3 procinfo = RxQueryProcType(hmod,procid) amode = RxQueryProcType(hmod,entryname) where: hmod = module handle procid = procedure-id (either an ordinal, or a procedure name) procinfo = Two blank-delimited tokens: 1) return code from DosQueryProcType 2) either "16" or "32", indicating 16 or 32 bit ═══ 12.6. RxQueryProcAddr - Query Procedure Address ═══ This function returns the address of an entry point in a DLL. This entry point can then be used in RxCallEntryPoint to call an entry point in a Loaded DLL. Syntax: entryname = 'SQLEXEC' /* Entry name */ 3 /* Entry ordinal */ dosrc = RxQueryProcAddr(rexxvar,hmod,procid) where: rexxvar = name of rexx variable in which procedure address is returned hmod = module handle of DLL procid = procedure-id (either an ordinal, or a procedure name) ═══ 12.7. RxCallEntryPoint - Call an entry point ═══ This function "calls" the code which begins at the ProcAddress supplied. This ProcAddress could be the address obtained by RxQueryProcAddr for the entry point of a DLL. But, it can be any "legal" entry point address of any routine. Syntax: procrc = RxCallEntryPoint(procaddr [,arg1 [, arg2 [,...]]] ) where procaddr = proc-address (could be obtained from RxQueryProcAddr, etc.) parg1 ... parg19 = up to 19 arguments. If an argument is a valid pointer, the pointer will be passed. If not, a copy of the argument's value will be passed by reference. Either way, the procedure must be expecting a pointer for each argument. procrc = return code from the procedure Note: Linkage to the proc-address is type _System. ═══ 13. OS/2 Pipes ═══ An assortment of OS/2 pipe-related functions (not complete). ═══ 13.1. RxCreateNPipe - Create a named pipe ═══ This function creates an OS/2 named pipe. Syntax: dosrc = RxCreateNPipe( rexxvar, pipename, openmode, pipemode, instance_count, outbufsize, inbufsize, timeout) where rexxvar = name of Rexx variable into which read/write handle is placed pipename = name of pipe OpenMode Values W = WriteBehind w = NoWriteBehind I = Inherit i = NoInherit N(n) = Access Inbound O(o) = Access Outbound D(d) = Access Duplex PipeMode Values W = Wait w = NoWait T = Pipe Type "Byte" t = Pipe Type "Message" R = Readmode "Byte" r = Readmode "Message" Instance_Count Integer Outbuf Size Integer Inbuf Size Integer Timeout Integer dosrc = return code from DosCreateNPipe() ═══ 13.2. RxConnectNPipe - Connect to a named pipe ═══ This function connects to a named pipe Syntax: dosrc = RxConnectNPipe(hpipe) where hpipe = pipe handle dosrc = return code from DosConnectNPipe() ═══ 13.3. RxDisConnectNPipe - Disconnect from a named pipe ═══ This function disconnects from a named pipe Syntax: dosrc = RxDisConnectNPipe(hpipe) where hpipe = pipe handle dosrc = return code from DosDisConnectNPipe() ═══ 13.4. RxCreatePipe - Create an un-named pipe ═══ This function creates an OS/2 un-named pipe Syntax: dosrc = RxCreatePipe(rexxstem [,pipesize]) where rexxstem = name of Rexx stem variable under which read handle, write handle, and pipe size are returned as such: stem.1 = read handle stem.2 = write handle stem.3 = pipe size dosrc = return code from DosCreatePipe() ═══ 13.5. RxDestroyPipe - Destroy an un-named pipe ═══ This function destroys an OS/2 un-named pipe Syntax: dosrc = RxDestroyPipe(hread,hwrite) where hread = read handle hwrite = write handle dosrc = return codes from DosClose() ═══ 14. OS/2 Queues ═══ Most of the OS/2 queue APIs are implemented here. ═══ 14.1. RxCreateQueue - Create an OS/2 queue. ═══ This function creates an OS/2 queue. Syntax: dosrc = RxCreateQueue(rexxvar, qname, qflags) where rexxvar = name of Rexx variable into which queue handle is placed qname = name of OS/2 queue qflags = flags for queue creation: F - Fifo L - Lifo P - Priority C - Convert Address N - No-convert Address dosrc = return code from DosCreateQueue() ═══ 14.2. RxOpenQueue - Open an OS/2 queue ═══ This function opens an OS/2 queue Syntax: dosrc = RxOpenQueue(rexxstem,qname) where rexxstem = name of Rexx stem, under which info is returned: stem.1 = queue-owner-pid (integer) stem.2 = queue handle qname = name of queue to open dosrc = return code from DosOpenQueue() ═══ 14.3. RxPeekQueue - Peek at an OS/2 queue ═══ This function peeks at an OS/2 queue without reading it Syntax: dosrc = RxPeekQueue(rexxstem,qhandle,elemcode,waitcode,semhandle) where rexxstem = name of Rexx stem, under which info is returned: stem.1 = data pointer (e.g. for use with RxStorage) stem.2 = data length (of that pointed to by stem.1) stem.3 = PID of process which enqueued element stem.4 = event code (RequestData.ulData) stem.5 = element code stem.6 = element priority qhandle = handle to queue elemcode = element code (integer) waitcode = whether to wait for data in queue W = Wait N = Nowait semhandle = handle of semaphore dosrc = return code from DosPeekQueue() ═══ 14.4. RxReadQueue - Read an OS/2 queue ═══ This function reads an element off an OS/2 Syntax: dosrc = RxReadQueue(rexxstem,qhandle,elemcode,waitcode,semhandle) where rexxstem = name of Rexx stem, under which info is returned: stem.1 = data pointer (e.g. for use with RxStorage) stem.2 = data length (of that pointed to by stem.1) stem.3 = PID of process which enqueued element stem.4 = event code (RequestData.ulData) stem.5 = element priority qhandle = handle to queue elemcode = element code (integer) waitcode = whether to wait for data in queue W = Wait N = Nowait semhandle = handle of semaphore dosrc = return code from DosReadQueue() ═══ 14.5. RxWriteQueue - Write to an OS/2 queue ═══ This function writes an element to an OS/2 Syntax: dosrc = RxWriteQueue(qhandle,pointer,length,reqdata,elemprty) where qhandle = handle to queue pointer = whatever 32 bits you want to put on queue length = integer length associated with "pointer" reqdata = integer request data elemprtry = element priority, if this is a priority queue dosrc = return code from DosWriteQueue() ═══ 14.6. RxPurgeQueue - Purge elements from OS/2 queue ═══ This function purges elements from an OS/2 queue Syntax: dosrc = RxPurgeQueue(qhandle) where qhandle = handle to queue dosrc = return code from DosPurgeQueue() ═══ 14.7. RxQueryQueue - Query info about OS/2 queue ═══ This function returns information about an OS/2 queue Syntax: info = RxQueryQueue(qhandle) where qhandle = handle to queue info = two blank delimited tokens: 1) return code from DosQueryQueue() 2) number of elements on queue (if (1) is zero) ═══ 14.8. RxCloseQueue - Close an OS/2 queue ═══ This function closes an OS/2 queue Syntax: dosrc = RxCloseQueue(qhandle) where qhandle = handle to queue dosrc = return code from DosCloseQueue() ═══ 14.9. RxReadQueueStr - Read data from OS/2 queue ═══ This function returns the de-referenced contents of an OS/2 queue element. That is, it dequeues an element and returns the data pointed to by the dequeued element as the function result. It first does a DosOpenQueue, then a DosReadQueue(wait), but does NOT do a DosCloseQueue. Syntax: datastr = RxReadQueueStr(qname) where qname = name of queue to read datastr = data pointed to by dequeued pointer ═══ 15. I/O Related ═══ Miscellaneous functions related to I/O operations. ═══ 15.1. RxRead - Read from File Handle ═══ This function reads a character stream in from a file handle, rather than from a file name. Syntax: dosrc = RxRead( rexxvar, hfile [,length] ) where rexxvar = name of Rexx variable into which read data is placed hfile = handle of file to be read from length = number of bytes to read (defaults to zero) dosrc = two blank-delimited words: 1) return code from DosRead 2) if (1) is zero, an integer indicating number of bytes read (should be same as length of rexx variable's value) ═══ 15.2. RxWrite - Write to File Handle ═══ This function writes a character stream out to a file handle, rather than from a file name. Syntax: dosrc = RxWrite( hfile , data ) where hfile = handle of file to be written to data = data to be written to file dosrc = two blank-delimited words: 1) return code from DosWrite 2) if (1) is zero, an integer indicating number of bytes written (may not be same as length of data supplied) ═══ 15.3. RxCloseH - Close a File Handle ═══ This function closes a file handle. Syntax: closerc = RxCloseH(hfile) where hfile = handle of file to be closed closerc = return code from DosClose ═══ 15.4. RxExecI - Read data into a Rexx queue or stem from a file ═══ This function reads (text) data into a Rexx queue or stem variable from a file. It is meant to be like EXECIO in TSO and VM, and can be used in a similar fashion for file input. Syntax: info = RxExecI([fname], [qtype], [name], [type]) where: fname = name of file to be read from (default reads from stdin) qtype = 'Lifo' or 'Fifo' (default is 'Fifo') determines how lines are read onto queue (ignored for stems) name = name of Rexx queue from into which data is read (default uses current queue) or name of a Rexx stem variable under which data is to be mapped as stem.0 = number of lines (stem.1 - stem.n) stem.1 stem.2 ... stem.n type = 'Queue' or 'Stem' (default is 'Queue') this tells whether arg 3 is a Rexx Queue name or a stem variable name info = two blank delimited numbers: 1) number of lines read 2) total number of bytes read Example: /* Read a text file into the Rexx stem 's.' */ info = rxexeci('c:\config.sys',,'s.','s') parse var info lines bytes Say lines 'lines were read' Say bytes 'bytes were read' ═══ 15.5. RxExecO - Write data from a Rexx queue or stem to a file ═══ This function writes data from a Rexx queue or stem variable to a file. It is meant to be like EXECIO in TSO and VM, and can be used in a similar fashion for file output. Syntax: info = RxExecO([fname], [action], [name], [type]) where: fname = name of file to be written to (default sends to stdout) action = Replace or Append (default is 'Replace') replaces or appends to 'fname' name = name of Rexx queue from which to get data (default uses current queue) or name of a Rexx stem variable under which data is mapped as stem.1 stem.2 ... stem.n Once an uninitialized value for 'stem.n' is encountered, i/o stops. type = 'Queue' or 'Stem' (default is 'Queue') this tells whether arg 3 is a Rexx Queue name or a stem variable name info = two blank delimited numbers: 1) number of lines written 2) total number of bytes written Example: /* Write 100 lines from current queue to c:\junk.dat (replace file) */ Do 100 Queue i time('l') End info = rxexeco('c:\junk.dat','r') parse var info lines bytes Say lines 'lines were written' Say bytes 'bytes were written' ═══ 15.6. Rxrsoe2f - Redirect Std-Out/Err to File ═══ This function redirects Standard Out and Standard Error to a named file (or device name, such as "CON"). Syntax: Call Rxrsoe2f stream,opt where: stream = name of file or device (e.g. 'con', 'nul', 'kbd', etc.) to which standard-out and standard-error are re-directed. opt = either 'Append' or 'Replace' file/device ═══ 16. System-Info related ═══ Functions returning OS/2 system information. ═══ 16.1. RxPstat - Get Process Status Information ═══ This function returns process status information (like PSTAT). Syntax: procrc = RxPStat(stemname) where: stemname = a Rexx stem variable name under which results are mapped as such: stem.P.0 = number of processes stem.P.n.1 = process-id stem.P.n.2 = parent process-id stem.P.n.3 = process type stem.P.n.4 = process status stem.P.n.5 = process session-id stem.P.n.6 = process module name stem.P.n.T = process thread count stem.P.n.T.m.1 = thread-id within process stem.P.n.T.m.2 = unique thread slot number stem.P.n.T.m.3 = sleep-id thread is sleeping on stem.P.n.T.m.4 = thread priority stem.P.n.T.m.5 = thread state stem.P.n.T.m.6 = thread system time stem.P.n.T.m.7 = thread user time procrc = return code from DosQProcStatus Example: prc = rxpstat('s.') Say 'There are' s.p.0 'processes running right now' ═══ 16.2. RxSetError - Set DosError settings ═══ This function allows you to turn HardError and Exception popup on or off. This change takes effect for the process in which it is issued, no matter what the previous setting was, by whom, or on what thread. Presently, there is no way (that I know of) to query or "reset" these error settings. Syntax: dosrc = RxSetError(flag) where: flag = any combination of: 'h' to disable HardError popup 'H' to enable HardError popup 'e' to disable Exception popup 'E' to enable Exception popup dosrc = return code from DosError() Example: Call rxseterror 'eh' /* would suppress popups from both harderror */ /* and exception conditions */ ═══ 16.3. RxProcId - Get process' own PID and TID information ═══ This function returns the process-id, parent process-id, and thread-id of the current thread of the current process. Syntax: procinfo = rxprocid() where: procinfo = three blank delimited integers: 1) process-id 2) parent process-id 3) thread-id ═══ 16.4. RxQuerySysInfo - Query OS/2 SysInfo ═══ This function returns live system information about OS/2 via the DosQuerySysInfo API. Syntax: rc = RxQuerySysInfo( stemname [,startidx [,endidx]]) where stemname = Rexx stem name, under which results are returned. Each DosQuerySysInfo item is returned under the appropriate stem.n For instance, the call "call rxquerysysinfo('s.',3,5)" would set the rexx variables "s.3", "s.4", and "s.5". startidx = (see programming info for DosQuerySysInfo) Default is 1 endidx = (see programming info for DosQuerySysInfo) Default is 23 rc = return code from DosQuerySysInfo ═══ 17. PM / Wp related functions ═══ Functions related to PM or Workplace Shell Objects ═══ 17.1. RxWinQueryObject - Query WP-Shell Object Handle ═══ This function returns the object handle of a WorkPlace Shell object. Syntax: hobj = RxWinQueryObject(objname) where objname = name of WorkPlace Shell object hobj = handle to object (or null string if not successful) ═══ 17.2. RxWinDestroyObject - Destroy a WP-Shell Object ═══ This function destroys a WorkPlace Shell object by object handle. Syntax: yorn = RxWinDestroyObject(hobj) where hobj = handle to object yorn = "1" if it worked, "0" if it didn't