@@ -42,6 +42,7 @@ void OSSpinLockLock(volatile OSSpinLock *__lock);
4242#endif
4343
4444#include < fcntl.h>
45+ #include < poll.h>
4546#include < pthread.h>
4647#include < stdarg.h>
4748#include < stdio.h>
@@ -612,6 +613,104 @@ INTERCEPTOR(int, shutdown, int socket, int how) {
612613 return REAL (shutdown)(socket, how);
613614}
614615
616+ // I/O Multiplexing
617+
618+ INTERCEPTOR (int , poll, struct pollfd *fds, nfds_t nfds, int timeout) {
619+ __rtsan_notify_intercepted_call (" poll" );
620+ return REAL (poll)(fds, nfds, timeout);
621+ }
622+
623+ #if !SANITIZER_APPLE
624+ // FIXME: This should work on all unix systems, even Mac, but currently
625+ // it is showing some weird error while linking
626+ // error: declaration of 'select' has a different language linkage
627+ INTERCEPTOR (int , select, int nfds, fd_set *readfds, fd_set *writefds,
628+ fd_set *exceptfds, struct timeval *timeout) {
629+ __rtsan_notify_intercepted_call (" select" );
630+ return REAL (select)(nfds, readfds, writefds, exceptfds, timeout);
631+ }
632+ #define RTSAN_MAYBE_INTERCEPT_SELECT INTERCEPT_FUNCTION (select)
633+ #else
634+ #define RTSAN_MAYBE_INTERCEPT_SELECT
635+ #endif // !SANITIZER_APPLE
636+
637+ INTERCEPTOR (int , pselect, int nfds, fd_set *readfds, fd_set *writefds,
638+ fd_set *exceptfds, const struct timespec *timeout,
639+ const sigset_t *sigmask) {
640+ __rtsan_notify_intercepted_call (" pselect" );
641+ return REAL (pselect)(nfds, readfds, writefds, exceptfds, timeout, sigmask);
642+ }
643+
644+ #if SANITIZER_INTERCEPT_EPOLL
645+ INTERCEPTOR (int , epoll_create, int size) {
646+ __rtsan_notify_intercepted_call (" epoll_create" );
647+ return REAL (epoll_create)(size);
648+ }
649+
650+ INTERCEPTOR (int , epoll_create1, int flags) {
651+ __rtsan_notify_intercepted_call (" epoll_create1" );
652+ return REAL (epoll_create1)(flags);
653+ }
654+
655+ INTERCEPTOR (int , epoll_ctl, int epfd, int op, int fd,
656+ struct epoll_event *event) {
657+ __rtsan_notify_intercepted_call (" epoll_ctl" );
658+ return REAL (epoll_ctl)(epfd, op, fd, event);
659+ }
660+
661+ INTERCEPTOR (int , epoll_wait, int epfd, struct epoll_event *events,
662+ int maxevents, int timeout) {
663+ __rtsan_notify_intercepted_call (" epoll_wait" );
664+ return REAL (epoll_wait)(epfd, events, maxevents, timeout);
665+ }
666+
667+ INTERCEPTOR (int , epoll_pwait, int epfd, struct epoll_event *events,
668+ int maxevents, int timeout, const sigset_t *sigmask) {
669+ __rtsan_notify_intercepted_call (" epoll_pwait" );
670+ return REAL (epoll_pwait)(epfd, events, maxevents, timeout, sigmask);
671+ }
672+ #define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE INTERCEPT_FUNCTION (epoll_create)
673+ #define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE1 INTERCEPT_FUNCTION (epoll_create1)
674+ #define RTSAN_MAYBE_INTERCEPT_EPOLL_CTL INTERCEPT_FUNCTION (epoll_ctl)
675+ #define RTSAN_MAYBE_INTERCEPT_EPOLL_WAIT INTERCEPT_FUNCTION (epoll_wait)
676+ #define RTSAN_MAYBE_INTERCEPT_EPOLL_PWAIT INTERCEPT_FUNCTION (epoll_pwait)
677+ #else
678+ #define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE
679+ #define RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE1
680+ #define RTSAN_MAYBE_INTERCEPT_EPOLL_CTL
681+ #define RTSAN_MAYBE_INTERCEPT_EPOLL_WAIT
682+ #define RTSAN_MAYBE_INTERCEPT_EPOLL_PWAIT
683+ #endif // SANITIZER_INTERCEPT_EPOLL
684+
685+ #if SANITIZER_INTERCEPT_KQUEUE
686+ INTERCEPTOR (int , kqueue, void ) {
687+ __rtsan_notify_intercepted_call (" kqueue" );
688+ return REAL (kqueue)();
689+ }
690+
691+ INTERCEPTOR (int , kevent, int kq, const struct kevent *changelist, int nchanges,
692+ struct kevent *eventlist, int nevents,
693+ const struct timespec *timeout) {
694+ __rtsan_notify_intercepted_call (" kevent" );
695+ return REAL (kevent)(kq, changelist, nchanges, eventlist, nevents, timeout);
696+ }
697+
698+ INTERCEPTOR (int , kevent64, int kq, const struct kevent64_s *changelist,
699+ int nchanges, struct kevent64_s *eventlist, int nevents,
700+ unsigned int flags, const struct timespec *timeout) {
701+ __rtsan_notify_intercepted_call (" kevent64" );
702+ return REAL (kevent64)(kq, changelist, nchanges, eventlist, nevents, flags,
703+ timeout);
704+ }
705+ #define RTSAN_MAYBE_INTERCEPT_KQUEUE INTERCEPT_FUNCTION (kqueue)
706+ #define RTSAN_MAYBE_INTERCEPT_KEVENT INTERCEPT_FUNCTION (kevent)
707+ #define RTSAN_MAYBE_INTERCEPT_KEVENT64 INTERCEPT_FUNCTION (kevent64)
708+ #else
709+ #define RTSAN_MAYBE_INTERCEPT_KQUEUE
710+ #define RTSAN_MAYBE_INTERCEPT_KEVENT
711+ #define RTSAN_MAYBE_INTERCEPT_KEVENT64
712+ #endif // SANITIZER_INTERCEPT_KQUEUE
713+
615714// Preinit
616715void __rtsan::InitializeInterceptors () {
617716 INTERCEPT_FUNCTION (calloc);
@@ -696,6 +795,18 @@ void __rtsan::InitializeInterceptors() {
696795 INTERCEPT_FUNCTION (sendto);
697796 INTERCEPT_FUNCTION (shutdown);
698797 INTERCEPT_FUNCTION (socket);
798+
799+ RTSAN_MAYBE_INTERCEPT_SELECT;
800+ INTERCEPT_FUNCTION (pselect);
801+ INTERCEPT_FUNCTION (poll);
802+ RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE;
803+ RTSAN_MAYBE_INTERCEPT_EPOLL_CREATE1;
804+ RTSAN_MAYBE_INTERCEPT_EPOLL_CTL;
805+ RTSAN_MAYBE_INTERCEPT_EPOLL_WAIT;
806+ RTSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;
807+ RTSAN_MAYBE_INTERCEPT_KQUEUE;
808+ RTSAN_MAYBE_INTERCEPT_KEVENT;
809+ RTSAN_MAYBE_INTERCEPT_KEVENT64;
699810}
700811
701812#endif // SANITIZER_POSIX
0 commit comments