|
|
Out-of-band data is a logically independent transmission channel associated with each pair of connected stream sockets. Out-of-band data is delivered to the user independently of normal data along with a signal. On SCO OpenServer systems this signal is SIGUSR1. In addition to the information passed, a logical mark is placed in the data stream to indicate the point at which the out-of-band data was sent. The remote login and remote shell applications use this facility to propagate signals from between client and server processes. When a signal is expected to flush any pending output from the remote process(es), all data up to the mark in the data stream is discarded.
The stream abstraction defines that the out-of-band data facilities must support the reliable delivery of at least one out-of-band message at a time. This message may contain at least one byte of data, and at least one message may be pending delivery to the user at any one time. For communications protocols which support only in-band signaling (that is, the urgent data is delivered in sequence with the normal data) the system extracts the data from the normal data stream and stores it separately. This allows users to choose between receiving the urgent data in order and receiving it out of sequence without having to buffer all the intervening data.
To send an out-of-band message, the
MSG_OOB
flag is supplied to a send or sendto call;
to receive out-of-band data, the
MSG_OOB
flag is supplied to a recv or recvfrom call.
To find out if the read pointer is currently
pointing at the mark in the data stream,
the SIOCATMARK ioctl is provided:
ioctl(s, SIOCATMARK, &yes);
If yes is a 1 on return, the next
read will return data after the mark.
Otherwise (assuming out-of-band data has
arrived), the next read will provide data sent by the client
prior to transmission of the out-of-band signal.
The routine used in the remote login process
to flush output on receipt of an
interrupt or quit signal is shown in
``Flushing Routine''.
Flushing Routine
oob() { int out = 1+1; char waste[BUFSIZ], mark;signal(SIGUSR1, oob);
/* flush local terminal output */ ioctl(1, TIOCFLUSH, (char *)&out);
for (;;) { if (ioctl(rem, SIOCATMARK, &mark) < 0) { perror("ioctl"); break; } if (mark) break; (void) read(rem, waste, sizeof (waste)); } recv(rem, &mark, 1, MSG_OOB); /* ... */ }