/* slotserver.rex -- An example of using Reginald * REXX to FUNCDEF and use Windows Mail Slots. * * This is the script that runs on the server * computer. It creates a mailslot and waits for * records sent from the respective script that * runs on the client (ie, clientslot.rex). */ /* So that we don't need the CALL keyword */ OPTIONS "C_CALL WINFUNC NOSOURCE" /* Some OS functions deal with 32-bit addresses so we need * 10 digits to prevent dealing with exponential form */ NUMERIC DIGITS 10 /* ============== FUNCDEF some needed OS functions ============ */ DO /* Register the Windows OS function CreateMailslot(). We tell it to check * for a return of -1, and if so, raise USER 1 condition. */ FUNCDEF("CreateMailslot", "void, str, 32u, 32, void", "kernel32",,"U1 -1") /* Register the Windows OS function GetMailslotInfo(). We tell it to check * for a return of 0, and if so, raise USER 1 condition. */ FUNCDEF("GetMailslotInfo", "32, void, 32u *, 32 * stor, 32u * stor, 32u * dual", "kernel32",,"U1 0") /* Register the Windows OS function ReadFile(). We tell it to check * for a return of 0, and if so, raise USER 1 condition. */ FUNCDEF("ReadFile", "32, void, void, 32u, 32u * stor, void", "kernel32",,"U1 0") /* Register the Windows OS function CloseHandle() */ FUNCDEF("CloseHandle", "32, void", "kernel32") CATCH FAILURE CONDITION("M") RETURN END /* ================ Read incoming records ================ */ DO /* Create a mail slot named testslot in the current directory, * allowing any size records to be received (up to 64K). * Specify that we want ReadFile() to wait forever when reading * a record. */ handle = CreateMailslot("\\.\mailslot\testslot", , -1) again: /* Wait for the next record to be received at the mailslot. Wait up * up to 10000 milliseconds before returning. */ err = 10000 GetMailslotInfo(handle, , msgSize, , err) /* Here you may want to check for user aborting if using some sort * of graphical user interface, and RAISE HALT. You may also want * to clear out messages at the window. For example, with REXX GUI, * you'd do a GuiGetMsg 'CLEAR' operation. */ /* Check if there was a record. If so, the size is not -1 */ DO WHILE msgSize \= -1 /* Allocate memory to read in the record. If an error, * REXX will raise SYNTAX */ buffer = CONVERTDATA(0, msgSize, , "A") /* Read the record */ ReadFile(handle, buffer, msgSize, numRead) /* Make sure all the chars were read */ IF msgSize \= numRead THEN SAY "ERROR: The correct number of characters weren't received!" ELSE DO /* Assign the record chars to the REXX variable named "buffer" */ CONVERTDATA(buffer, "buffer", , "=") /* Display the received record. Here you'd normally do something useful with it */ SAY buffer END /* Read the next message's size */ GetMailslotInfo(handle, , msgSize) END /* msgSize \= -1 */ /* Delay for 5 seconds so we don't eat up too much CPU time */ SLEEP(5) /* Wait for next record */ SIGNAL again /* Let's CATCH USER 1 so we don't have to error check * any of these calls to the above FUNCDEF'ed functions. Yay! */ CATCH USER 1 SAY CONDITION('D') "failed:" UNIXERROR(RXFUNCERRMSG()) SIGNAL again CATCH SYNTAX SAY CONDITION('D') SIGNAL again FINALLY IF EXISTS(handle) THEN CloseHandle(handle) END
/* clientslot.rex -- An example of using Reginald * REXX to FUNCDEF and use Windows Mail Slots. * * This is the script that runs on the client * computer. It sends a record to the respective * script that runs on the server (ie, serverslot.rex). */ /* NOTE!!! You should change the asterisk to the name of the server * computer that is running serverslot.rex unless you want to send * records to every mailslot named "testslot" on the root domain */ mailslotname = "\\*\mailslot\testslot" /* So that we don't need the CALL keyword */ OPTIONS "C_CALL NOSOURCE" DO /* Open the mailslot that the server has already created on the network. * Note: The serverslot.rex example must already be running. We must * use STREAM's 'OPEN WRITE SHARED' mode. */ STREAM(mailslotname, 'C', 'OPEN WRITE SHARED') /* Here are the contents of what I intend to send. It can be anything * you want, text or binary or whatever. */ myMessage = "This is a test." /* Send the record. It is broadcast to every computer in the primary * domain of the system (because of our use of the asterisk on the * mailslot name). To select a particular computer, you'd have * to be more specific in the mailslot name passed to STREAM(). * * A single call to CHAROUT or LINEOUT writes one record. */ CHAROUT(mailslotname, myMessage) /* CATCH NOTREADY so that we don't have to check for errors on STREAM and CHAROUT */ CATCH NOTREADY CONDITION('M') FINALLY /* Close the mailslot. NOTE: REXX does this automatically for you when * your script ends if you forget */ STREAM(mailslotname, 'C', 'CLOSE') RETURN