The server script creates a mailslot by FUNCDEF'ing, and then calling, the operating system function CreateMailslot. An example of a server script (called serverslot.rex) is included with this tutorial. You should persue this to see how to create and read records from a mailslot.

Note: To make error-checking very simple, serverslot.rex FUNCDEFs the MailSlot functions so that they raise a USER condition upon returning an error value. Then it traps the USER condition instead of checking for error returns. In the examples below, we FUNCDEF the MailSlot functions so that they do not raise any condition, so we must check for error returns manually. This is just to show you how to do both styles of error checking so you can see which you prefer. In general, using raised conditions means you'll have to write a lot less error checking and your script will be easier to read.

The first argument to CreateMailslot is the name of the mailslot.

The second argument is the maximum size (in bytes) of a single record that you allow to be written to the mailslot. If you wish to allow any size record, then you can omit this arg (or pass 0).

The third arg is the number of milliseconds you wish to wait for a record to arrive before your script can resume doing other things. As you'll see later, you call a particular operating system function to read the next record in your mailslot. But if there is no record already waiting there, then that operating system function will suspend your script (inside of that call), and wait for a record to arrive before it returns. So, this arg tells how long you're willing to wait inside of that call to the operating system function for a record to arrive before the operating system function gives up and returns without reading a record (if no record arrives during that time). If you're not willing to wait at all, you can omit this arg or pass 0. If you're willing to wait forever (ie, the operating system function never returns until some record arrives), then you pass a -1. If you're willing to wait any other amount of time, pass the number of milliseconds. For example, 60000 will wait one minute.

The last arg you pass is the name of a REXX variable that is a SECURITY_ATTRIBUTES struct you fill in. This arg needs to be passed only if your server script plans to pass off the mailslot handle to another script to allow it to read messages from the mailslot. If you don't need this ability, then omit this arg.

If CreateMailslot is successful at creating the mailslot, it will return a handle that you'll need to pass to other mailslot functions. If CreateMailslot fails, we'll FUNCDEF it to return an empty string, and also tell Reginald to save the error number from the operating system so that we can fetch it with RXFUNCERRMSG(). We can also get an error message by passing that number to UNIXERROR().

For example, the following FUNCDEFs a few Mailslot functions we need to call, and then calls CreateMailslot to create a mailslot named "blort". Note that error-checking on the FUNCDEF statements is omitted for brevity. See serverslot.rex for real error-checking.

/* Register some Mailslot functions */
DO

   FUNCDEF("CreateMailslot", "void, str, 32u, 32, void", "kernel32",,"O -1")
   FUNCDEF("GetMailslotInfo", "32, void, 32u *, 32 * stor, 32u * stor, 32u * dual", "kernel32",,"O 0")
   FUNCDEF("ReadFile", "32, void, void, 32u, 32u * stor, void", "kernel32",,"O 0")
   FUNCDEF("CloseHandle", "32, void", "kernel32", "O 0")

   CATCH FAILURE
      CONDITION('M')
      RETURN
END

/* Create a mail slot named blort, allowing any size records
 * to be received (up to 64K). Specify that we'll wait forever
 * when reading a record.
 */
handle = CreateMailslot("\\.\mailslot\blort", , -1)
IF handle == "" THEN DO
   SAY "ERROR:" UNIXERROR(RXFUNCERRMSG())
   RETURN
END