__pid_t __waitpid (__pid_t pid, int *stat_loc, int options) { #ifdef __NR_waitpid return SYSCALL_CANCEL (waitpid, pid, stat_loc, options); #else return SYSCALL_CANCEL (wait4, pid, stat_loc, options, NULL); #endif }
int __libc_accept (int fd, __SOCKADDR_ARG addr, socklen_t *len) { #ifdef __ASSUME_ACCEPT_SYSCALL return SYSCALL_CANCEL (accept, fd, addr.__sockaddr__, len); #elif defined __ASSUME_ACCEPT4_FOR_ACCEPT_SYSCALL return SYSCALL_CANCEL (accept4, fd, addr.__sockaddr__, len, 0); #else return SOCKETCALL_CANCEL (accept, fd, addr.__sockaddr__, len); #endif }
ssize_t __libc_recv (int fd, void *buf, size_t len, int flags) { #ifdef __ASSUME_RECV_SYSCALL return SYSCALL_CANCEL (recv, fd, buf, len, flags); #elif defined __ASSUME_RECVFROM_FOR_RECV_SYSCALL return SYSCALL_CANCEL (recvfrom, fd, buf, len, flags, NULL, NULL); #else return SOCKETCALL_CANCEL (recv, fd, buf, len, flags); #endif }
int __libc_pause (void) { sigset_t set; int rc = SYSCALL_CANCEL (rt_sigprocmask, SIG_BLOCK, NULL, &set, _NSIG / 8); if (rc == 0) rc = SYSCALL_CANCEL (rt_sigsuspend, &set, _NSIG / 8); return rc; }
int sync_file_range (int fd, __off64_t offset, __off64_t len, unsigned int flags) { #if defined (__NR_sync_file_range2) return SYSCALL_CANCEL (sync_file_range2, fd, flags, SYSCALL_LL64 (offset), SYSCALL_LL64 (len)); #elif defined (__NR_sync_file_range) return SYSCALL_CANCEL (sync_file_range, fd, __ALIGNMENT_ARG SYSCALL_LL64 (offset), SYSCALL_LL64 (len), flags); #endif }
int __select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { int result; struct timespec ts, *tsp = NULL; if (timeout) { TIMEVAL_TO_TIMESPEC (timeout, &ts); tsp = &ts; } result = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, tsp, NULL); if (timeout) { /* Linux by default will update the timeout after a pselect6 syscall (though the pselect() glibc call suppresses this behavior). Since select() on Linux has the same behavior as the pselect6 syscall, we update the timeout here. */ TIMESPEC_TO_TIMEVAL (timeout, &ts); } return result; }
int epoll_pwait (int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *set) { return SYSCALL_CANCEL (epoll_pwait, epfd, events, maxevents, timeout, set, _NSIG / 8); }
int __waitid (idtype_t idtype, id_t id, siginfo_t *infop, int options) { /* The unused fifth argument is a `struct rusage *' that we could pass if we were using waitid to simulate wait3/wait4. */ return SYSCALL_CANCEL (waitid, idtype, id, infop, options, NULL); }
/* Wait for a child to die. When one does, put its status in *STAT_LOC and return its process ID. For errors, return (pid_t) -1. */ pid_t __libc_wait (__WAIT_STATUS_DEFN stat_loc) { pid_t result = SYSCALL_CANCEL (wait4, WAIT_ANY, stat_loc, 0, (struct rusage *) NULL); return result; }
ssize_t __libc_recvmsg (int fd, struct msghdr *msg, int flags) { #ifdef __ASSUME_RECVMSG_SYSCALL return SYSCALL_CANCEL (recvmsg, fd, msg, flags); #else return SOCKETCALL_CANCEL (recvmsg, fd, msg, flags); #endif }
int __libc_connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len) { #ifdef __ASSUME_CONNECT_SYSCALL return SYSCALL_CANCEL (connect, fd, addr.__sockaddr__, len); #else return SOCKETCALL_CANCEL (connect, fd, addr.__sockaddr__, len); #endif }
int accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags) { #ifdef __ASSUME_ACCEPT4_SYSCALL return SYSCALL_CANCEL (accept4, fd, addr.__sockaddr__, addr_len, flags); #else return SOCKETCALL_CANCEL (accept4, fd, addr.__sockaddr__, addr_len, flags); #endif }
ssize_t __libc_sendmsg (int fd, const struct msghdr *msg, int flags) { # ifdef __ASSUME_SENDMSG_SYSCALL return SYSCALL_CANCEL (sendmsg, fd, msg, flags); # else return SOCKETCALL_CANCEL (sendmsg, fd, msg, flags); # endif }
ssize_t __libc_send (int fd, const void *buf, size_t len, int flags) { #ifdef __ASSUME_SEND_SYSCALL return SYSCALL_CANCEL (send, fd, buf, len, flags); #else return SOCKETCALL_CANCEL (send, fd, buf, len, flags); #endif }
/* Reserve storage for the data of the file associated with FD. */ int fallocate (int fd, int mode, __off_t offset, __off_t len) { #ifdef __NR_fallocate return SYSCALL_CANCEL (fallocate, fd, mode, offset, len); #else __set_errno (ENOSYS); return -1; #endif }
int open_by_handle_at (int mount_fd, struct file_handle *handle, int flags) { #ifdef __NR_open_by_handle_at return SYSCALL_CANCEL (open_by_handle_at, mount_fd, handle, flags); #else __set_errno (ENOSYS); return -1; #endif }
ssize_t pwritev (int fd, const struct iovec *vector, int count, off_t offset) { # ifdef __NR_pwritev ssize_t result = SYSCALL_CANCEL (pwritev, fd, vector, count, LO_HI_LONG (offset)); if (result >= 0 || errno != ENOSYS) return result; # endif return __atomic_pwritev_replacement (fd, vector, count, offset); }
ssize_t __libc_sendto (int fd, const void *buf, size_t len, int flags, __CONST_SOCKADDR_ARG addr, socklen_t addrlen) { #ifdef __ASSUME_SENDTO_SYSCALL return SYSCALL_CANCEL (sendto, fd, buf, len, flags, addr.__sockaddr__, addrlen); #else return SOCKETCALL_CANCEL (sendto, fd, buf, len, flags, addr.__sockaddr__, addrlen); #endif }
/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG, a third argument is the file protection. */ int __libc_open64 (const char *file, int oflag, ...) { int mode = 0; if (__OPEN_NEEDS_MODE (oflag)) { va_list arg; va_start (arg, oflag); mode = va_arg (arg, int); va_end (arg); } return SYSCALL_CANCEL (openat, AT_FDCWD, file, oflag | O_LARGEFILE, mode); }
int ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, const sigset_t *sigmask) { /* The Linux kernel can in some situations update the timeout value. We do not want that so use a local variable. */ struct timespec tval; if (timeout != NULL) { tval = *timeout; timeout = &tval; } return SYSCALL_CANCEL (ppoll, fds, nfds, timeout, sigmask, _NSIG / 8); }
/* Open FILE with access OFLAG. Interpret relative paths relative to the directory associated with FD. If OFLAG includes O_CREAT or O_TMPFILE, a fourth argument is the file protection. */ int __OPENAT (int fd, const char *file, int oflag, ...) { mode_t mode = 0; if (__OPEN_NEEDS_MODE (oflag)) { va_list arg; va_start (arg, oflag); mode = va_arg (arg, mode_t); va_end (arg); } /* We have to add the O_LARGEFILE flag for openat64. */ #ifdef MORE_OFLAGS oflag |= MORE_OFLAGS; #endif return SYSCALL_CANCEL (openat, fd, file, oflag, mode); }
ssize_t PWRITEV (int fd, const struct iovec *vector, int count, OFF_T offset) { #ifdef __NR_pwritev ssize_t result; result = SYSCALL_CANCEL (pwritev, fd, vector, count, LO_HI_LONG (offset)); # ifdef __ASSUME_PWRITEV return result; # endif #endif #ifndef __ASSUME_PWRITEV # ifdef __NR_pwritev if (result >= 0 || errno != ENOSYS) return result; # endif return PWRITEV_REPLACEMENT (fd, vector, count, offset); #endif }
/* Return any pending signal or wait for one for the given time. */ int __sigwaitinfo (const sigset_t *set, siginfo_t *info) { #ifdef SIGCANCEL sigset_t tmpset; if (set != NULL && (__builtin_expect (__sigismember (set, SIGCANCEL), 0) # ifdef SIGSETXID || __builtin_expect (__sigismember (set, SIGSETXID), 0) # endif )) { /* Create a temporary mask without the bit for SIGCANCEL set. */ // We are not copying more than we have to. memcpy (&tmpset, set, _NSIG / 8); __sigdelset (&tmpset, SIGCANCEL); # ifdef SIGSETXID __sigdelset (&tmpset, SIGSETXID); # endif set = &tmpset; } #endif /* XXX The size argument hopefully will have to be changed to the real size of the user-level sigset_t. */ int result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, NULL, _NSIG / 8); /* The kernel generates a SI_TKILL code in si_code in case tkill is used. tkill is transparently used in raise(). Since having SI_TKILL as a code is useful in general we fold the results here. */ if (result != -1 && info != NULL && info->si_code == SI_TKILL) info->si_code = SI_USER; return result; }
/* Send N bytes of BUF to socket FD. Returns the number sent or -1. */ ssize_t __libc_send (int fd, const void *buf, size_t n, int flags) { return SYSCALL_CANCEL (sendto, fd, buf, n, flags, NULL, (size_t) 0); }
/* Write NBYTES of BUF to FD. Return the number written, or -1. */ ssize_t __libc_write (int fd, const void *buf, size_t nbytes) { return SYSCALL_CANCEL (write, fd, buf, nbytes); }
/* Helper function to support starting threads for SIGEV_THREAD. */ static void * timer_helper_thread (void *arg) { /* Wait for the SIGTIMER signal, allowing the setXid signal, and none else. */ sigset_t ss; sigemptyset (&ss); __sigaddset (&ss, SIGTIMER); /* Endless loop of waiting for signals. The loop is only ended when the thread is canceled. */ while (1) { siginfo_t si; /* sigwaitinfo cannot be used here, since it deletes SIGCANCEL == SIGTIMER from the set. */ /* XXX The size argument hopefully will have to be changed to the real size of the user-level sigset_t. */ int result = SYSCALL_CANCEL (rt_sigtimedwait, &ss, &si, NULL, _NSIG / 8); if (result > 0) { if (si.si_code == SI_TIMER) { struct timer *tk = (struct timer *) si.si_ptr; /* Check the timer is still used and will not go away while we are reading the values here. */ pthread_mutex_lock (&__active_timer_sigev_thread_lock); struct timer *runp = __active_timer_sigev_thread; while (runp != NULL) if (runp == tk) break; else runp = runp->next; if (runp != NULL) { struct thread_start_data *td = malloc (sizeof (*td)); /* There is not much we can do if the allocation fails. */ if (td != NULL) { /* This is the signal we are waiting for. */ td->thrfunc = tk->thrfunc; td->sival = tk->sival; pthread_t th; (void) pthread_create (&th, &tk->attr, timer_sigev_thread, td); } } pthread_mutex_unlock (&__active_timer_sigev_thread_lock); } else if (si.si_code == SI_TKILL) /* The thread is canceled. */ pthread_exit (NULL); } } }
/* Reserve storage for the data of the file associated with FD. */ int fallocate64 (int fd, int mode, __off64_t offset, __off64_t len) { return SYSCALL_CANCEL (fallocate, fd, mode, SYSCALL_LL64 (offset), SYSCALL_LL64 (len)); }
/* Change the set of blocked signals to SET, wait until a signal arrives, and restore the set of blocked signals. */ int __sigsuspend (const sigset_t *set) { return SYSCALL_CANCEL (rt_sigsuspend, set, _NSIG / 8); }
ssize_t __libc_send (int sockfd, const void *buffer, size_t len, int flags) { return SYSCALL_CANCEL (sendto, sockfd, buffer, len, flags, NULL, 0); }
ssize_t __libc_recv (int fd, void *buf, size_t n, int flags) { return SYSCALL_CANCEL (recvfrom, fd, buf, n, flags, NULL, NULL); }