Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

Signal-safe system call wrappers

These are alternate system call wrappers which are guaranteed to return an EINTR immediately if a "safe" signal is delivered on or before the transition back to userspace. More...

Functions

int sigsafe_read (int fd, void *buf, size_t count)
 Signal-safe read(2).

int sigsafe_readv (int d, const struct iovec *iov, int iovcnt)
 Signal-safe readv(2).

int sigsafe_write (int fd, const void *buf, size_t count)
 Signal-safe write(2).

int sigsafe_writev (int d, const struct iovec *iov, int iovcnt)
 Signal-safe writev(2).

int sigsafe_wait4 (pid_t wpid, int *status, int options, struct rusage *rusage)
 Signal-safe wait4(2).

int sigsafe_accept (int fd, struct sockaddr *addr, socklen_t *addrlen)
 Signal-safe accept(2).

int sigsafe_connect (int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
 Signal-safe connect(2).

int sigsafe_nanosleep (const struct timespec *rqtp, struct timespec *rmtp)
 Signal-safe nanosleep(2).

int sigsafe_sigsuspend (const sigset_t *)
int sigsafe_pause (void)

Detailed Description

These are alternate system call wrappers which are guaranteed to return an EINTR immediately if a "safe" signal is delivered on or before the transition back to userspace.

In particular, they will return EINTR if a signal has been delivered before the function call or immediately before the transition to kernel space within the function. They will also return EINTR on receipt of a "safe" system call in kernel space even when using SA_RESTART. And they return error values as negative numbers rather than through errno. These are their sole visible differences from the standardized system calls of the same names. Like the standardized system call wrappers, it will not return with EINTR if the system call has already completed.

Usage example:
 ssize_t retval;
 while ((retval = sigsafe_read(fd, buf, count)) == -EINTR) {
     handle_signal();
 }
 if (retval < 0) {
     printf("read error %zd (%s)\n", -retval, strerror(-retval));
 } else if (retval == 0) {
     printf("stream end\n");
 } else {
     printf("read %zd bytes\n", retval);
 }
Implementation:
Internally, these check a thread-specific value noting if a signal has arrived. They then proceed with no regard to signals. The addresses of key points of the code are known to the signal handler, which allows it to make a long jump to the appropriate branch. Thus, they have virtually no overhead over the standard system call wrappers.
Note:
If you do not see the system call you want here, don't panic. It's very easy to add new system calls in most cases.

Function Documentation

int sigsafe_accept int  fd,
struct sockaddr *  addr,
socklen_t *  addrlen
 

Signal-safe accept(2).

Definition at line 17 of file i386-linux/emulated_syscalls.c.

int sigsafe_connect int  sockfd,
const struct sockaddr *  serv_addr,
socklen_t  addrlen
 

Signal-safe connect(2).

Definition at line 22 of file i386-linux/emulated_syscalls.c.

int sigsafe_nanosleep const struct timespec *  rqtp,
struct timespec *  rmtp
 

Signal-safe nanosleep(2).

Availability:
Currently not implemented on Tru64/alpha or Darwin/ppc. I expect it will be in a future release.

Definition at line 32 of file ppc-darwin/emulated_syscalls.c.

int sigsafe_read int  fd,
void *  buf,
size_t  count
 

Signal-safe read(2).

int sigsafe_readv int  d,
const struct iovec *  iov,
int  iovcnt
 

Signal-safe readv(2).

int sigsafe_wait4 pid_t  wpid,
int *  status,
int  options,
struct rusage *  rusage
 

Signal-safe wait4(2).

int sigsafe_write int  fd,
const void *  buf,
size_t  count
 

Signal-safe write(2).

int sigsafe_writev int  d,
const struct iovec *  iov,
int  iovcnt
 

Signal-safe writev(2).


Generated on Fri Feb 4 11:13:32 2005 for sigsafe by doxygen 1.3.5