DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
Network services

Receiving output from the remote application

Since REXEC uses bi-directional asynchronous connections, incoming data (remote process output) has to be polled for. However, when the data does arrive, it is packaged in packets that only REXEC client routines can understand. Therefore, the user program has to poll the file descriptor used by the REXEC connection (which can be obtained using the rx_fd routine). Once an indication of new data has been received, the data is actually read in by rx_proc_msg. This routine will read in an REXEC packet and handle it appropriately.

int	cnum;			/* connection number */

main() { struct pollfd pollfd[5]; /* structure for poll() */ long talen, /* returned type-ahead length */ msg_type, /* rexec message type */ ret_code; /* terminating process' return code */ . . . pollfd[0].fd = rx_fd(cnum); pollfd[0].events = POLLRDNORM; nfds = 1;

if (poll(pollfd, nfds, INFTIM) < 0) { if (errno != EINTR) { fprintf(stderr, "poll error\n"); exit(1); }

if ((talen = rx_proc_msg(cnum, &msg_type, &ret_code)) < 0) { rxperror(Rx_errno); exit(1); }

/* handle special conditions */

switch(msg_type) {

case RX_INCOMPLETE: case RX_PROTOCOL: case RX_DATA: case RX_IOCTL:

/* no additional action required */ break;

case RX_SERVICE_DEAD:

/* * remote process died: * can still receive output, but * should not send any more input * */ break;

case RX_TYPEAHEAD:

/* * process returned type-ahead * and close connection * */ break; } } }

If the REXEC message contains data, it will be written using a pre-defined write routine. By default, this is simply the write system call, but it can be changed (for example, for debugging purposes) by using the set_write_hand routine as follows:
static int
my_write(fd, buf, len)
int	fd;		/* file descriptor */
char	*buf;		/* data buffer */
int	len;		/* data length */
{
	printf("my_write: writing %d bytes to fd %d\n", len, fd);
	return(write(fd, buf, len));
}

main() { . . . (void) set_write_hand(cnum, my_write); . . . }

The destination file descriptor (1 -- standard output, 2 -- standard error) will be preserved if the RX_SEPERR flag was turned on in the flags parameter to rexecve. Otherwise, the destination file descriptor will always be 1 -- standard output.

If the REXEC message contains an ioctl message, it will be executed using a pre-defined ioctl routine. By default, this is simply the ioctl system call, but it can be changed by using the set_ioctl_hand routine as follows:

static int
my_ioctl(fd, cmd, buf)
int	fd;		/* file descriptor */
int	cmd;		/* ioctl command */
char	*buf;		/* ioctl data buffer */
{
	printf("my_ioctl: sending ioctl cmd #%d to fd #%d\n", cmd, fd);
	return(ioctl(fd, cmd, buf));
}

main() { . . . (void) set_ioctl_hand(cnum, my_ioctl); . . . }

REXEC supports only the termio, termios, and certain windowing ioctl calls. Unsupported ioctl calls received by the REXEC server from the application are ignored by the server and will not appear at the client side.
© 2005 The SCO Group, Inc. All rights reserved.
SCO OpenServer Release 6.0.0 -- 02 June 2005