@@ -1029,8 +1029,7 @@ pub enum SigevNotify {
10291029 /// structure of the queued signal.
10301030 si_value: libc:: intptr_t
10311031 } ,
1032- // Note: SIGEV_THREAD is not implemented because libc::sigevent does not
1033- // expose a way to set the union members needed by SIGEV_THREAD.
1032+ // Note: SIGEV_THREAD is not implemented, but could be if desired.
10341033 /// Notify by delivering an event to a kqueue.
10351034 #[ cfg( any( target_os = "dragonfly" , target_os = "freebsd" ) ) ]
10361035 #[ cfg_attr( docsrs, doc( cfg( all( ) ) ) ) ]
@@ -1040,8 +1039,24 @@ pub enum SigevNotify {
10401039 /// Will be contained in the kevent's `udata` field.
10411040 udata: libc:: intptr_t
10421041 } ,
1042+ /// Notify by delivering an event to a kqueue, with optional event flags set
1043+ #[ cfg( target_os = "freebsd" ) ]
1044+ #[ cfg_attr( docsrs, doc( cfg( all( ) ) ) ) ]
1045+ #[ cfg( feature = "event" ) ]
1046+ SigevKeventFlags {
1047+ /// File descriptor of the kqueue to notify.
1048+ kq: RawFd ,
1049+ /// Will be contained in the kevent's `udata` field.
1050+ udata: libc:: intptr_t,
1051+ /// Flags that will be set on the delivered event. See `kevent(2)`.
1052+ flags: crate :: sys:: event:: EventFlag
1053+ } ,
10431054 /// Notify by delivering a signal to a thread.
1044- #[ cfg( any( target_os = "freebsd" , target_os = "linux" ) ) ]
1055+ #[ cfg( any(
1056+ target_os = "freebsd" ,
1057+ target_env = "gnu" ,
1058+ target_env = "uclibc" ,
1059+ ) ) ]
10451060 #[ cfg_attr( docsrs, doc( cfg( all( ) ) ) ) ]
10461061 SigevThreadId {
10471062 /// Signal to send
@@ -1062,10 +1077,7 @@ mod sigevent {
10621077 #![ any( feature = "aio" , feature = "signal" ) ]
10631078
10641079 use std:: mem;
1065- use std:: ptr;
10661080 use super :: SigevNotify ;
1067- #[ cfg( any( target_os = "freebsd" , target_os = "linux" ) ) ]
1068- use super :: type_of_thread_id;
10691081
10701082 /// Used to request asynchronous notification of the completion of certain
10711083 /// events, such as POSIX AIO and timers.
@@ -1093,53 +1105,51 @@ mod sigevent {
10931105 // See https://github.com/nix-rust/nix/issues/1441
10941106 #[ cfg_attr( target_os = "fuchsia" , allow( invalid_value) ) ]
10951107 pub fn new( sigev_notify: SigevNotify ) -> SigEvent {
1096- let mut sev = unsafe { mem:: MaybeUninit :: <libc:: sigevent>:: zeroed( ) . assume_init( ) } ;
1097- sev. sigev_notify = match sigev_notify {
1098- SigevNotify :: SigevNone => libc:: SIGEV_NONE ,
1099- SigevNotify :: SigevSignal { ..} => libc:: SIGEV_SIGNAL ,
1108+ let mut sev: libc:: sigevent = unsafe { mem:: zeroed( ) } ;
1109+ match sigev_notify {
1110+ SigevNotify :: SigevNone => {
1111+ sev. sigev_notify = libc:: SIGEV_NONE ;
1112+ } ,
1113+ SigevNotify :: SigevSignal { signal, si_value} => {
1114+ sev. sigev_notify = libc:: SIGEV_SIGNAL ;
1115+ sev. sigev_signo = signal as libc:: c_int;
1116+ sev. sigev_value. sival_ptr = si_value as * mut libc:: c_void
1117+ } ,
11001118 #[ cfg( any( target_os = "dragonfly" , target_os = "freebsd" ) ) ]
1101- SigevNotify :: SigevKevent { ..} => libc:: SIGEV_KEVENT ,
1119+ SigevNotify :: SigevKevent { kq, udata} => {
1120+ sev. sigev_notify = libc:: SIGEV_KEVENT ;
1121+ sev. sigev_signo = kq;
1122+ sev. sigev_value. sival_ptr = udata as * mut libc:: c_void;
1123+ } ,
11021124 #[ cfg( target_os = "freebsd" ) ]
1103- SigevNotify :: SigevThreadId { .. } => libc :: SIGEV_THREAD_ID ,
1104- # [ cfg ( all ( target_os = "linux" , target_env = "gnu" , not ( target_arch = "mips" ) ) ) ]
1105- SigevNotify :: SigevThreadId { .. } => libc:: SIGEV_THREAD_ID ,
1106- # [ cfg ( all ( target_os = "linux" , target_env = "uclibc" ) ) ]
1107- SigevNotify :: SigevThreadId { .. } => libc:: SIGEV_THREAD_ID ,
1108- # [ cfg ( any ( all ( target_os = "linux" , target_env = "musl" ) , target_arch = "mips" ) ) ]
1109- SigevNotify :: SigevThreadId { .. } => 4 // No SIGEV_THREAD_ID defined
1110- } ;
1111- sev . sigev_signo = match sigev_notify {
1112- SigevNotify :: SigevSignal { signal , .. } => signal as libc:: c_int ,
1113- # [ cfg ( any ( target_os = "dragonfly" , target_os = "freebsd" ) ) ]
1114- SigevNotify :: SigevKevent { kq , .. } => kq ,
1115- # [ cfg ( any ( target_os = "linux" , target_os = "freebsd" ) ) ]
1116- SigevNotify :: SigevThreadId { signal , .. } => signal as libc :: c_int ,
1117- _ => 0
1118- } ;
1119- sev . sigev_value . sival_ptr = match sigev_notify {
1120- SigevNotify :: SigevNone => ptr :: null_mut :: <libc :: c_void> ( ) ,
1121- SigevNotify :: SigevSignal { si_value , .. } => si_value as * mut libc :: c_void ,
1122- # [ cfg ( any ( target_os = "dragonfly" , target_os = "freebsd" ) ) ]
1123- SigevNotify :: SigevKevent { udata , .. } => udata as * mut libc:: c_void ,
1124- # [ cfg ( any ( target_os = "freebsd" , target_os = "linux" ) ) ]
1125- SigevNotify :: SigevThreadId { si_value , .. } => si_value as * mut libc :: c_void ,
1126- } ;
1127- SigEvent :: set_tid ( & mut sev , & sigev_notify ) ;
1125+ # [ cfg ( feature = "event" ) ]
1126+ SigevNotify :: SigevKeventFlags { kq , udata , flags } => {
1127+ sev . sigev_notify = libc:: SIGEV_KEVENT ;
1128+ sev . sigev_signo = kq ;
1129+ sev . sigev_value . sival_ptr = udata as * mut libc:: c_void ;
1130+ sev . _sigev_un . _kevent_flags = flags . bits ( ) ;
1131+ } ,
1132+ # [ cfg ( target_os = "freebsd" ) ]
1133+ SigevNotify :: SigevThreadId { signal , thread_id , si_value } => {
1134+ sev . sigev_notify = libc:: SIGEV_THREAD_ID ;
1135+ sev . sigev_signo = signal as libc :: c_int ;
1136+ sev . sigev_value . sival_ptr = si_value as * mut libc :: c_void ;
1137+ sev . _sigev_un . _threadid = thread_id ;
1138+ }
1139+ # [ cfg ( any (
1140+ target_env = "gnu" ,
1141+ target_env = "uclibc" ,
1142+ ) ) ]
1143+ SigevNotify :: SigevThreadId { signal , thread_id , si_value } => {
1144+ sev . sigev_notify = libc :: SIGEV_THREAD_ID ;
1145+ sev . sigev_signo = signal as libc:: c_int ;
1146+ sev . sigev_value . sival_ptr = si_value as * mut libc :: c_void ;
1147+ sev . _sigev_un . _tid = thread_id ;
1148+ }
1149+ }
11281150 SigEvent { sigevent: sev}
11291151 }
11301152
1131- #[ cfg( any( target_os = "freebsd" , target_os = "linux" ) ) ]
1132- fn set_tid( sev: & mut libc:: sigevent, sigev_notify: & SigevNotify ) {
1133- sev. sigev_notify_thread_id = match * sigev_notify {
1134- SigevNotify :: SigevThreadId { thread_id, .. } => thread_id,
1135- _ => 0 as type_of_thread_id
1136- } ;
1137- }
1138-
1139- #[ cfg( not( any( target_os = "freebsd" , target_os = "linux" ) ) ) ]
1140- fn set_tid( _sev: & mut libc:: sigevent, _sigev_notify: & SigevNotify ) {
1141- }
1142-
11431153 /// Return a copy of the inner structure
11441154 pub fn sigevent( & self ) -> libc:: sigevent {
11451155 self . sigevent
0 commit comments