Example #1
0
int open(const char *file, int oflag, ...)
{
    mode_t mode = 0;

    if (oflag & O_CREAT) {
        va_list arg;
        va_start(arg, oflag);
        mode = va_arg(arg, mode_t);
        va_end(arg);
    }

    if (SINGLE_THREAD_P)
#if defined(__NR_open)
        return __NC(open)(file, oflag, mode);
#elif defined(__NR_openat)
        return openat(AT_FDCWD, file, oflag, mode);
#endif

#ifdef __NEW_THREADS
    int oldtype = LIBC_CANCEL_ASYNC ();
# if defined(__NR_open)
    int result = __NC(open)(file, oflag, mode);
# else
    int result = openat(AT_FDCWD, file, oflag, mode);
# endif
    LIBC_CANCEL_RESET (oldtype);
    return result;
#endif
}
Example #2
0
int fcntl64(int fd, int cmd, ...)
{
	long arg;
	va_list list;

	va_start(list, cmd);
	arg = va_arg(list, long);
	va_end(list);

	if (SINGLE_THREAD_P || (cmd != F_SETLKW64))
		return __NC(fcntl64)(fd, cmd, arg);
# ifdef __NEW_THREADS
	int oldtype = LIBC_CANCEL_ASYNC();
	int result = __NC(fcntl64)(fd, cmd, arg);
	LIBC_CANCEL_RESET(oldtype);
	return result;
# endif
}
Example #3
0
static int __NC(sigwait)(const sigset_t *set, int *sig)
{
  sigset_t tmp_mask;
  struct sigaction saved[NSIG];
  struct sigaction action;
  int save_errno;
  int this;

  /* Prepare set.  */
  __sigfillset (&tmp_mask);

  /* Unblock all signals in the SET and register our nice handler.  */
  action.sa_handler = ignore_signal;
  action.sa_flags = 0;
  __sigfillset (&action.sa_mask);       /* Block all signals for handler.  */

  /* Make sure we recognize error conditions by setting WAS_SIG to a
     value which does not describe a legal signal number.  */
  was_sig = -1;

  for (this = 1; this < NSIG; ++this)
    if (__sigismember (set, this))
      {
        /* Unblock this signal.  */
        __sigdelset (&tmp_mask, this);

        /* Register temporary action handler.  */
        /* In Linux (as of 2.6.25), fails only if sig is SIGKILL or SIGSTOP */
        /* (so, will it work correctly if set has, say, SIGSTOP?) */
        if (sigaction (this, &action, &saved[this]) != 0)
          goto restore_handler;
      }

  /* Now we can wait for signals.  */
  __NC(sigsuspend)(&tmp_mask);

 restore_handler:
  save_errno = errno;

  while (--this >= 1)
    if (__sigismember (set, this))
      /* We ignore errors here since we must restore all handlers.  */
      sigaction (this, &saved[this], NULL);

  __set_errno (save_errno);

  /* Store the result and return.  */
  *sig = was_sig;
  return was_sig == -1 ? -1 : 0;
}
Example #4
0
/* Return any pending signal or wait for one for the given time.  */
static int __NC(sigwait)(const sigset_t *set, int *sig)
{
	int ret;

	do
		/* we might as well use sigtimedwait and do not care about cancellation */
		ret = __NC(sigtimedwait)(set, NULL, NULL);
	while (ret == -1 && errno == EINTR);
	if (ret != -1) {
		*sig = ret;
		ret = 0;
	} else
		ret = errno;

	return ret;
}
Example #5
0
static ssize_t __NC(send)(int sockfd, const void *buffer, size_t len, int flags)
{
# ifdef __NR_send
	return (ssize_t)INLINE_SYSCALL(send, 4, sockfd, buffer, len, flags);
# elif defined __NR_sendto && defined _syscall6
	return __NC(sendto)(sockfd, buffer, len, flags, NULL, 0);
# else
	unsigned long args[4];

	args[0] = sockfd;
	args[1] = (unsigned long) buffer;
	args[2] = len;
	args[3] = flags;
	return (ssize_t)__socketcall(SYS_SEND, args);
# endif
}
Example #6
0
static ssize_t __NC(recv)(int sockfd, void *buffer, size_t len, int flags)
{
# ifdef __NR_recv
	return (ssize_t)INLINE_SYSCALL(recv, 4, sockfd, buffer, len, flags);
# elif defined __NR_recvfrom && defined _syscall6
	return __NC(recvfrom)(sockfd, buffer, len, flags, NULL, NULL);
# else
	unsigned long args[4];

	args[0] = sockfd;
	args[1] = (unsigned long) buffer;
	args[2] = len;
	args[3] = flags;
	return (ssize_t)__socketcall(SYS_RECV, args);
# endif
}
Example #7
0
int
accept (int fd, __SOCKADDR_ARG addr, socklen_t *len)
{
  return _syscall3(int, __NC(accept), int, fd, __SOCKADDR_ARG,
			addr.__sockaddr__, socklen_t*, len);
}
Example #8
0
int __NC(poll)(struct pollfd *fds, nfds_t nfds, int timeout)
{
    static int max_fd_size;
    struct timeval tv;
    fd_set *rset, *wset, *xset;
    struct pollfd *f;
    int ready;
    int maxfd = 0;
    int bytes;

    if (!max_fd_size)
	max_fd_size = getdtablesize ();

    bytes = howmany (max_fd_size, __NFDBITS);
    rset = alloca (bytes);
    wset = alloca (bytes);
    xset = alloca (bytes);

    /* We can't call FD_ZERO, since FD_ZERO only works with sets
       of exactly __FD_SETSIZE size.  */
    memset (rset, 0, bytes);
    memset (wset, 0, bytes);
    memset (xset, 0, bytes);

    for (f = fds; f < &fds[nfds]; ++f)
    {
	f->revents = 0;
	if (f->fd >= 0)
	{
	    if (f->fd >= max_fd_size)
	    {
		/* The user provides a file descriptor number which is higher
		   than the maximum we got from the `getdtablesize' call.
		   Maybe this is ok so enlarge the arrays.  */
		fd_set *nrset, *nwset, *nxset;
		int nbytes;

		max_fd_size = roundup (f->fd, __NFDBITS);
		nbytes = howmany (max_fd_size, __NFDBITS);

		nrset = alloca (nbytes);
		nwset = alloca (nbytes);
		nxset = alloca (nbytes);

		memset ((char *) nrset + bytes, 0, nbytes - bytes);
		memset ((char *) nwset + bytes, 0, nbytes - bytes);
		memset ((char *) nxset + bytes, 0, nbytes - bytes);

		rset = memcpy (nrset, rset, bytes);
		wset = memcpy (nwset, wset, bytes);
		xset = memcpy (nxset, xset, bytes);

		bytes = nbytes;
	    }

	    if (f->events & POLLIN)
		FD_SET (f->fd, rset);
	    if (f->events & POLLOUT)
		FD_SET (f->fd, wset);
	    if (f->events & POLLPRI)
		FD_SET (f->fd, xset);
	    if (f->fd > maxfd && (f->events & (POLLIN|POLLOUT|POLLPRI)))
		maxfd = f->fd;
	}
    }

    tv.tv_sec = timeout / 1000;
    tv.tv_usec = (timeout % 1000) * 1000;

    while (1)
    {
	ready = __NC(select) (maxfd + 1, rset, wset, xset,
		timeout == -1 ? NULL : &tv);

	/* It might be that one or more of the file descriptors is invalid.
	   We now try to find and mark them and then try again.  */
	if (ready == -1 && errno == EBADF)
	{
	    fd_set *sngl_rset = alloca (bytes);
	    fd_set *sngl_wset = alloca (bytes);
	    fd_set *sngl_xset = alloca (bytes);
	    struct timeval sngl_tv;

	    /* Clear the original set.  */
	    memset (rset, 0, bytes);
	    memset (wset, 0, bytes);
	    memset (xset, 0, bytes);

	    /* This means we don't wait for input.  */
	    sngl_tv.tv_sec = 0;
	    sngl_tv.tv_usec = 0;

	    maxfd = -1;

	    /* Reset the return value.  */
	    ready = 0;

	    for (f = fds; f < &fds[nfds]; ++f)
		if (f->fd != -1 && (f->events & (POLLIN|POLLOUT|POLLPRI))
			&& (f->revents & POLLNVAL) == 0)
		{
		    int n;

		    memset (sngl_rset, 0, bytes);
		    memset (sngl_wset, 0, bytes);
		    memset (sngl_xset, 0, bytes);

		    if (f->events & POLLIN)
			FD_SET (f->fd, sngl_rset);
		    if (f->events & POLLOUT)
			FD_SET (f->fd, sngl_wset);
		    if (f->events & POLLPRI)
			FD_SET (f->fd, sngl_xset);

		    n = __NC(select) (f->fd + 1, sngl_rset, sngl_wset, sngl_xset,
			    &sngl_tv);
		    if (n != -1)
		    {
			/* This descriptor is ok.  */
			if (f->events & POLLIN)
			    FD_SET (f->fd, rset);
			if (f->events & POLLOUT)
			    FD_SET (f->fd, wset);
			if (f->events & POLLPRI)
			    FD_SET (f->fd, xset);
			if (f->fd > maxfd)
			    maxfd = f->fd;
			if (n > 0)
			    /* Count it as being available.  */
			    ++ready;
		    }
		    else if (errno == EBADF)
			f->revents |= POLLNVAL;
		}
	    /* Try again.  */
	    continue;
	}

	break;
    }

    if (ready > 0)
	for (f = fds; f < &fds[nfds]; ++f)
	{
	    if (f->fd >= 0)
	    {
		if (FD_ISSET (f->fd, rset))
		    f->revents |= POLLIN;
		if (FD_ISSET (f->fd, wset))
		    f->revents |= POLLOUT;
		if (FD_ISSET (f->fd, xset))
		    f->revents |= POLLPRI;
	    }
	}

    return ready;
}