Studio:How do I work around variable arguments for stubs?

From STRIDE Wiki
Revision as of 22:47, 12 June 2007 by Root (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

STRIDE does not directly support variable argument lists; however, it is possible to call interfaces with variable arguments as stubs. Currently there is no workaround for proxies or dynamic delegates.
Interfaces with variable arguments can be wrapped using helper functions in the SCL file. The wrapper function depends on the number of variable arguments and the interface.
For example, the UNIX system call "open" is defined as:

extern int open (const char *__file, int __oflag, ...);

In most cases, the variable argument is NULL; however, when creating a file, the file permission can be specified as an optional argument. In this case, it is simplest to call a wrapper function to the SCL file which has 3 arguments (the 3rd one being the mode). The wrapper function would be defined as follows:

static __inline int scl_file_open (const char *file, int oflag, mode_t mode)
{
return open(file, oflag, mode);
}

The wrapper function calls the open interface with the three arguments. The SCL pragmas would be applied to scl_file_open:

#pragma scl_function(scl_file_open)
#pragma scl_string(scl_file_open.file, MAX_FILE_NAME_LENGTH)

Having a wrapper function for each possible variable argument could require a number of different wrapper functions if the variable argument can be of different types (e.g., a pointer to different structures), depending on the mandatory arguments. In this case, it would be easier to define the variable arguments as a union of all possible types. The UNIX system call "ioctl" could be an example of such an interface:

extern int ioctl (int __fd, unsigned long int __request, ...) ;

In most cases the variable argument (if there is one) is a pointer to a structure. The structure depends on the request value. An ioctl request has encoded in it whether the argument is an "in" parameter or "out" parameter, and the size of the variable argument in bytes.

Click here for a list of possible ioctl requests and the variable argument types. In this case, the variable argument could be wrapped by a union. The following example demonstrates a possible union definition in the SCL file:

typedef union
{
struct termios* p_termios; /* TCGETS, TCSETS, TCSETSW, TCSETSF, TIOCGLCKTRMIOS, TIOCSLCKTRMIOS */
struct termio* p_termio; /* TCGETA, TCSETA, TCSETAW, TCSETAF */
int data; /* TCSBRK, TCXONC, TCFLSH, TIOCSCTTY, TCSBRKP, TIOCSBRK, TIOCCBRK, TIOCMIWAIT, TIOCGICOUNT, IOCGHAYESESP, TIOCSHAYESESP */
int* p_int; /* TIOCOUTQ, TIOCMGET, TIOCMBIS,TIOCMBIC, TIOCMSET, TIOCGSOFTCAR, TIOCSSOFTCAR, FIONREAD, TIOCINQ, IOCPKT, FIONBIO, TIOCSETD, TIOCGETD, FIOASYNC, TIOCSERGWILD, TIOCSERSWILD, TIOCSERGETLSR, FIOQSIZE */
pid_t* p_pid; /* TIOCGPGRP, TIOCSPGRP, TIOCGSID */
char* p_char; /* TIOCSTI, TIOCLINUX */
struct winsize* p_winsize; /* TIOCGWINSZ, TIOCSWINSZ */
struct serial_struct* p_serial_struct; /* TIOCGSERIAL, TIOCSSERIAL */
struct async_struct* p_async_struct; /* TIOCSERGSTRUCT */
struct serial_multiport_struct* p_serial_mp; /* TIOCSERGETMULTI, TIOCSERSETMULTI */
/* void: TIOCNXCL, TIOCCONS, TIOCNOTTY, FIONCLEX, FIOCLEX, TIOCSERCONFIG, TIOCEXCL, */ } scl_ioctl_u;