1 /* fhandler_signalfd.cc: fhandler for signalfd
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
16 #include <cygwin/signal.h>
17 #include <sys/signalfd.h>
19 fhandler_signalfd::fhandler_signalfd () :
26 fhandler_signalfd::get_proc_fd_name (char *buf
)
28 return strcpy (buf
, "anon_inode:[signalfd]");
32 fhandler_signalfd::signalfd (const sigset_t
*mask
, int flags
)
36 sigset
= *mask
& ~(SIGKILL
| SIGSTOP
);
43 if (flags
& SFD_NONBLOCK
)
44 set_nonblocking (true);
45 if (flags
& SFD_CLOEXEC
)
46 set_close_on_exec (true);
47 if (get_unique_id () == 0)
51 set_ino (get_unique_id ());
52 set_flags (O_RDWR
| O_BINARY
);
58 fhandler_signalfd::fstat (struct stat
*buf
)
60 int ret
= fhandler_base::fstat (buf
);
63 buf
->st_mode
= S_IRUSR
| S_IWUSR
;
64 buf
->st_dev
= FH_SIGNALFD
;
65 buf
->st_ino
= get_unique_id ();
71 copy_siginfo_to_signalfd (struct signalfd_siginfo
*sfd
,
72 const siginfo_t
* const si
)
74 sfd
->ssi_signo
= si
->si_signo
;
75 sfd
->ssi_errno
= si
->si_errno
;
76 sfd
->ssi_code
= si
->si_code
;
77 sfd
->ssi_pid
= si
->si_pid
;
78 sfd
->ssi_uid
= si
->si_uid
;
80 sfd
->ssi_tid
= si
->si_tid
;
82 sfd
->ssi_overrun
= si
->si_overrun
;
84 sfd
->ssi_status
= si
->si_status
;
85 sfd
->ssi_int
= si
->si_value
.sival_int
;
86 sfd
->ssi_ptr
= (uint64_t) si
->si_value
.sival_ptr
;
87 sfd
->ssi_utime
= si
->si_utime
;
88 sfd
->ssi_stime
= si
->si_stime
;
89 sfd
->ssi_addr
= (uint64_t) si
->si_addr
;
93 fhandler_signalfd::read (void *ptr
, size_t& len
)
95 const LARGE_INTEGER poll
= { QuadPart
: 0 };
99 signalfd_siginfo
*sfd_ptr
= (signalfd_siginfo
*) ptr
;
101 if (len
< sizeof (struct signalfd_siginfo
))
107 old_errno
= get_errno ();
110 /* Even when read is blocking, only one pending signal is actually
111 required to return. Subsequently use sigtimedwait to just poll
112 if some more signal is available. */
113 ret
= sigwait_common (&sigset
, &si
, (is_nonblocking () || curlen
)
114 ? (PLARGE_INTEGER
) &poll
: NULL
);
117 /* If we already read a signal so the buffer isn't empty, just
126 copy_siginfo_to_signalfd (sfd_ptr
, &si
);
135 curlen
+= sizeof (*sfd_ptr
);
137 while ((len
- curlen
>= sizeof (struct signalfd_siginfo
)));
138 set_errno (old_errno
);
144 fhandler_signalfd::write (const void *, size_t)
150 /* Called from select */
152 fhandler_signalfd::poll ()
154 sigset_t outset
= sig_send (myself
, __SIGPENDING
, &_my_tls
);
155 if (outset
== SIG_BAD_MASK
)
157 if ((outset
& sigset
) != 0)