Initializing help system before first use

File managers

XPRD acts as a master model, and therefore has to process file operations requested from its remote instances (i.e. when a model opens a file using the "rmt:" driver). By default, the library handles file requests using the standard operating system routines looking for files from the process' current working directory. For example, if a remote instance asks for the file "rmt:myfile.txt", the library will look for "myfile.txt" in the current directory. In addition to accessing physical files, the I/O driver "sysfd:" is also supported by the library: typically a remote instance uses "rmt:sysfd:1" for its default output and "rmt:sysfd:2" for its default error stream. These streams are automatically routed to the corresponding local file descriptors such that output from remote instances is sent to the usual streams on the calling process.

At the time of creating a Mosel instance using function XPRDconnect it is possible to specify a file manager in order to complement or replace the default file handling mechanism. The entry point for this user-provided manager is a function of the following type:

void *fmgr(void *fctx, char *fname, int mode,
   XPRDfct_data* sync, XPRDfct_close *close, XPRDfct_skip *skip,
   char *errmsg, int msgsize);

This function is called instead of the default file manager whenever a request for opening a file is received from the corresponding instance. The first argument is the data pointer provided when creating the instance; fname is the file to open and mode its opening mode (e.g. XPRD_F_INPUT for reading). If this routine returns NULL, the file request is processed using the default procedure as described above. If the value XPRD_FMGR_ERR is returned, the request is rejected and an error message (NUL terminated) may be copied into buffer errmsg of size msgsize. Any other value is interpreted as a file descriptor pointer to be used with the provided I/O routines sync, skip and close.

The user functions sync, skip and close are used to transfer data from/to the local file and release the resources used by the file descriptor when the file is closed. Only the first function is mandatory (i.e. the others can be set to NULL). The signature of these routines is as follows:

int sync(void *fd, int buf, int bufsize);
int skip(void *fd,int nbtoskip);
int close(void *fd);

When the file is open for reading, the function sync is expected to copy into buffer buf up to bufsize bytes of data. The return value should be the number of bytes copied (0 indicating an end of file) or a negative value to report an error condition.
In the case of writing to the file, this function has to get bufsize bytes from buffer buf. The return value should be bufsize if writing is successful, any other value is interpreted as an I/O error.
The optional routine skip may be used to skip a number of bytes from a file open for reading (the function is not used on an output stream). Its return value must be positive or 0 in case of success; the special value -2 indicates the operation is not supported (in which case bytes to skip are read using the sync routine) and any other value is interpreted as an I/O error.

In the following example, the file manager my_open redirects the pseudo file "outremote" to the function outremote (that simply displays the text it receives) and keeps the default behaviour for files open for reading and through "sysfd:" (redirection to standard streams). Any other queries are rejected.

void* XPRD_RTC my_open(void *ctx, char *filename,
    int mode, XPRDfct_data* fct_data, XPRDfct_close* fct_close,
    char *msg, int msglen)
{
 if(strcmp(filename,"outremote")==0)
 {
  if((mode&(XPRD_F_READ|XPRD_F_WRITE))!=XPRD_F_WRITE)
  {
   strncpy(msg, "'outremote' is write only!", msglen);
   return XPRD_FMGR_ERR;
  }
  else
  {
   *fct_data=outremote;
   *fct_close=NULL;
   return (void*)1;
  }
 }
 else
  if((strncmp(filename,"sysfd:",6)==0)||
     ((mode&(XPRD_F_READ|XPRD_F_WRITE))==XPRD_F_READ))
   return NULL;
  else
  {
   strncpy(msg, "access denied", msglen);
   return XPRD_FMGR_ERR;
  }
}

int XPRD_RTC outremote(void *data, char *buf, int size)
{
 printf("REMOTE: %.*s", size, buf);
 return size;
}

The above manager has to be passed to XPRD at the time of creating a new instance. In the example below, the error stream of the instance is redirected to the pseudo file "outremote":

mosel=XPRDconnect(xprd, "", my_open, NULL, msg, sizeof(msg));
XPRDsetdefstream(mosel, NULL, XPRD_F_ERROR, "rmt:outremote");

© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.