Cygwin: signal: implement signalfd
First cut of a signalfd implementation. Still TODO: Non-polling select. This should mostly work as on Linux except for missing support for some members of struct signalfd_siginfo, namely ssi_fd, ssi_band (both SIGIO/SIGPOLL, not fully implemented) and ssi_trapno (HW exception, required HW support). Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
8ae26f96ae
commit
9d13a2995c
|
@ -298,6 +298,7 @@ DLL_OFILES:= \
|
||||||
fhandler_raw.o \
|
fhandler_raw.o \
|
||||||
fhandler_registry.o \
|
fhandler_registry.o \
|
||||||
fhandler_serial.o \
|
fhandler_serial.o \
|
||||||
|
fhandler_signalfd.o \
|
||||||
fhandler_socket.o \
|
fhandler_socket.o \
|
||||||
fhandler_socket_inet.o \
|
fhandler_socket_inet.o \
|
||||||
fhandler_socket_local.o \
|
fhandler_socket_local.o \
|
||||||
|
|
|
@ -1333,6 +1333,7 @@ siginterrupt SIGFE
|
||||||
sigismember SIGFE
|
sigismember SIGFE
|
||||||
siglongjmp NOSIGFE
|
siglongjmp NOSIGFE
|
||||||
signal SIGFE
|
signal SIGFE
|
||||||
|
signalfd SIGFE
|
||||||
significand NOSIGFE
|
significand NOSIGFE
|
||||||
significandf NOSIGFE
|
significandf NOSIGFE
|
||||||
sigpause SIGFE
|
sigpause SIGFE
|
||||||
|
|
|
@ -120,6 +120,9 @@ const _device dev_piper_storage =
|
||||||
const _device dev_pipew_storage =
|
const _device dev_pipew_storage =
|
||||||
{"", {FH_PIPEW}, "", exists_internal};
|
{"", {FH_PIPEW}, "", exists_internal};
|
||||||
|
|
||||||
|
const _device dev_signalfd_storage =
|
||||||
|
{"", {FH_SIGNALFD}, "", exists_internal};
|
||||||
|
|
||||||
const _device dev_socket_storage =
|
const _device dev_socket_storage =
|
||||||
{"", {FH_SOCKET}, "", exists_internal};
|
{"", {FH_SOCKET}, "", exists_internal};
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,8 @@ enum fh_devices
|
||||||
FH_DEV = FHDEV (DEV_VIRTFS_MAJOR, 193),
|
FH_DEV = FHDEV (DEV_VIRTFS_MAJOR, 193),
|
||||||
FH_CYGDRIVE= FHDEV (DEV_VIRTFS_MAJOR, 192),
|
FH_CYGDRIVE= FHDEV (DEV_VIRTFS_MAJOR, 192),
|
||||||
|
|
||||||
|
FH_SIGNALFD= FHDEV (DEV_VIRTFS_MAJOR, 13),
|
||||||
|
|
||||||
DEV_FLOPPY_MAJOR = 2,
|
DEV_FLOPPY_MAJOR = 2,
|
||||||
FH_FLOPPY = FHDEV (DEV_FLOPPY_MAJOR, 0),
|
FH_FLOPPY = FHDEV (DEV_FLOPPY_MAJOR, 0),
|
||||||
|
|
||||||
|
@ -400,6 +402,8 @@ extern const _device dev_af_local_storage;
|
||||||
extern const _device dev_af_unix_storage;
|
extern const _device dev_af_unix_storage;
|
||||||
#define af_unix_dev ((device *) &dev_af_unix_storage)
|
#define af_unix_dev ((device *) &dev_af_unix_storage)
|
||||||
|
|
||||||
|
extern const _device dev_signalfd_storage;
|
||||||
|
#define signalfd_dev ((device *) &dev_signalfd_storage)
|
||||||
extern const _device dev_piper_storage;
|
extern const _device dev_piper_storage;
|
||||||
#define piper_dev ((device *) &dev_piper_storage)
|
#define piper_dev ((device *) &dev_piper_storage)
|
||||||
extern const _device dev_pipew_storage;
|
extern const _device dev_pipew_storage;
|
||||||
|
|
|
@ -116,6 +116,9 @@ const _device dev_piper_storage =
|
||||||
const _device dev_pipew_storage =
|
const _device dev_pipew_storage =
|
||||||
{"", {FH_PIPEW}, "", exists_internal};
|
{"", {FH_PIPEW}, "", exists_internal};
|
||||||
|
|
||||||
|
const _device dev_signalfd_storage =
|
||||||
|
{"", {FH_SIGNALFD}, "", exists_internal};
|
||||||
|
|
||||||
const _device dev_socket_storage =
|
const _device dev_socket_storage =
|
||||||
{"", {FH_SOCKET}, "", exists_internal};
|
{"", {FH_SOCKET}, "", exists_internal};
|
||||||
|
|
||||||
|
|
|
@ -575,6 +575,9 @@ fh_alloc (path_conv& pc)
|
||||||
case FH_CYGDRIVE:
|
case FH_CYGDRIVE:
|
||||||
fh = cnew (fhandler_cygdrive);
|
fh = cnew (fhandler_cygdrive);
|
||||||
break;
|
break;
|
||||||
|
case FH_SIGNALFD:
|
||||||
|
fh = cnew (fhandler_signalfd);
|
||||||
|
break;
|
||||||
case FH_TTY:
|
case FH_TTY:
|
||||||
if (!pc.isopen ())
|
if (!pc.isopen ())
|
||||||
{
|
{
|
||||||
|
|
|
@ -1345,6 +1345,9 @@ fhandler_base::fstat (struct stat *buf)
|
||||||
case FH_PIPER:
|
case FH_PIPER:
|
||||||
buf->st_mode = S_IFIFO | S_IRUSR;
|
buf->st_mode = S_IFIFO | S_IRUSR;
|
||||||
break;
|
break;
|
||||||
|
case FH_SIGNALFD:
|
||||||
|
buf->st_mode = S_IRUSR | S_IWUSR;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;
|
buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -420,6 +420,7 @@ public:
|
||||||
virtual class fhandler_socket *is_socket () { return NULL; }
|
virtual class fhandler_socket *is_socket () { return NULL; }
|
||||||
virtual class fhandler_socket_wsock *is_wsock_socket () { return NULL; }
|
virtual class fhandler_socket_wsock *is_wsock_socket () { return NULL; }
|
||||||
virtual class fhandler_console *is_console () { return 0; }
|
virtual class fhandler_console *is_console () { return 0; }
|
||||||
|
virtual class fhandler_signalfd *is_signalfd () { return NULL; }
|
||||||
virtual int is_windows () {return 0; }
|
virtual int is_windows () {return 0; }
|
||||||
|
|
||||||
virtual void __reg3 raw_read (void *ptr, size_t& ulen);
|
virtual void __reg3 raw_read (void *ptr, size_t& ulen);
|
||||||
|
@ -2633,6 +2634,44 @@ class fhandler_procnet: public fhandler_proc
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class fhandler_signalfd : public fhandler_base
|
||||||
|
{
|
||||||
|
sigset_t sigset;
|
||||||
|
|
||||||
|
public:
|
||||||
|
fhandler_signalfd ();
|
||||||
|
fhandler_signalfd (void *) {}
|
||||||
|
|
||||||
|
fhandler_signalfd *is_signalfd () { return this; }
|
||||||
|
|
||||||
|
char *get_proc_fd_name (char *buf);
|
||||||
|
|
||||||
|
int signalfd (const sigset_t *mask, int flags);
|
||||||
|
int __reg2 fstat (struct stat *buf);
|
||||||
|
void __reg3 read (void *ptr, size_t& len);
|
||||||
|
|
||||||
|
int poll ();
|
||||||
|
|
||||||
|
select_record *select_read (select_stuff *);
|
||||||
|
select_record *select_write (select_stuff *);
|
||||||
|
select_record *select_except (select_stuff *);
|
||||||
|
|
||||||
|
void copyto (fhandler_base *x)
|
||||||
|
{
|
||||||
|
x->pc.free_strings ();
|
||||||
|
*reinterpret_cast<fhandler_signalfd *> (x) = *this;
|
||||||
|
x->reset (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
fhandler_signalfd *clone (cygheap_types malloc_type = HEAP_FHANDLER)
|
||||||
|
{
|
||||||
|
void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_signalfd));
|
||||||
|
fhandler_signalfd *fh = new (ptr) fhandler_signalfd (ptr);
|
||||||
|
copyto (fh);
|
||||||
|
return fh;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct fhandler_nodevice: public fhandler_base
|
struct fhandler_nodevice: public fhandler_base
|
||||||
{
|
{
|
||||||
fhandler_nodevice ();
|
fhandler_nodevice ();
|
||||||
|
@ -2672,6 +2711,7 @@ typedef union
|
||||||
char __pty_master[sizeof (fhandler_pty_master)];
|
char __pty_master[sizeof (fhandler_pty_master)];
|
||||||
char __registry[sizeof (fhandler_registry)];
|
char __registry[sizeof (fhandler_registry)];
|
||||||
char __serial[sizeof (fhandler_serial)];
|
char __serial[sizeof (fhandler_serial)];
|
||||||
|
char __signalfd[sizeof (fhandler_signalfd)];
|
||||||
char __socket_inet[sizeof (fhandler_socket_inet)];
|
char __socket_inet[sizeof (fhandler_socket_inet)];
|
||||||
char __socket_local[sizeof (fhandler_socket_local)];
|
char __socket_local[sizeof (fhandler_socket_local)];
|
||||||
#ifdef __WITH_AF_UNIX
|
#ifdef __WITH_AF_UNIX
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
/* fhandler_signalfd.cc: fhandler for /proc/<pid>/fd/<desc> operations
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "winsup.h"
|
||||||
|
#include "path.h"
|
||||||
|
#include "fhandler.h"
|
||||||
|
#include "pinfo.h"
|
||||||
|
#include "dtable.h"
|
||||||
|
#include "cygheap.h"
|
||||||
|
#include "sigproc.h"
|
||||||
|
#include <cygwin/signal.h>
|
||||||
|
#include <sys/signalfd.h>
|
||||||
|
|
||||||
|
fhandler_signalfd::fhandler_signalfd () :
|
||||||
|
fhandler_base (),
|
||||||
|
sigset (0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
fhandler_signalfd::get_proc_fd_name (char *buf)
|
||||||
|
{
|
||||||
|
return strcpy (buf, "anon_inode:[signalfd]");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_signalfd::signalfd (const sigset_t *mask, int flags)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
sigset = *mask & ~(SIGKILL | SIGSTOP);
|
||||||
|
}
|
||||||
|
__except (EINVAL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
|
if (flags & SFD_NONBLOCK)
|
||||||
|
set_nonblocking (true);
|
||||||
|
if (flags & SFD_CLOEXEC)
|
||||||
|
set_close_on_exec (true);
|
||||||
|
if (get_unique_id () == 0)
|
||||||
|
{
|
||||||
|
nohandle (true);
|
||||||
|
set_unique_id ();
|
||||||
|
set_ino (get_unique_id ());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __reg2
|
||||||
|
fhandler_signalfd::fstat (struct stat *buf)
|
||||||
|
{
|
||||||
|
int ret = fhandler_base::fstat (buf);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
buf->st_dev = FH_SIGNALFD;
|
||||||
|
buf->st_ino = get_unique_id ();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
copy_siginfo_to_signalfd (struct signalfd_siginfo *sfd,
|
||||||
|
const siginfo_t * const si)
|
||||||
|
{
|
||||||
|
sfd->ssi_signo = si->si_signo;
|
||||||
|
sfd->ssi_errno = si->si_errno;
|
||||||
|
sfd->ssi_code = si->si_code;
|
||||||
|
sfd->ssi_pid = si->si_pid;
|
||||||
|
sfd->ssi_uid = si->si_uid;
|
||||||
|
sfd->ssi_fd = -1;
|
||||||
|
sfd->ssi_tid = si->si_tid;
|
||||||
|
sfd->ssi_band = 0;
|
||||||
|
sfd->ssi_overrun = si->si_overrun;
|
||||||
|
sfd->ssi_trapno = 0;
|
||||||
|
sfd->ssi_status = si->si_status;
|
||||||
|
sfd->ssi_int = si->si_value.sival_int;
|
||||||
|
sfd->ssi_ptr = (uint64_t) si->si_value.sival_ptr;
|
||||||
|
sfd->ssi_utime = si->si_utime;
|
||||||
|
sfd->ssi_stime = si->si_stime;
|
||||||
|
sfd->ssi_addr = (uint64_t) si->si_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __reg3
|
||||||
|
fhandler_signalfd::read (void *ptr, size_t& len)
|
||||||
|
{
|
||||||
|
const LARGE_INTEGER poll = { QuadPart : 0 };
|
||||||
|
siginfo_t si;
|
||||||
|
int ret, old_errno;
|
||||||
|
size_t curlen = 0;
|
||||||
|
signalfd_siginfo *sfd_ptr = (signalfd_siginfo *) ptr;
|
||||||
|
|
||||||
|
if (len < sizeof (struct signalfd_siginfo))
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
len = (size_t) -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
old_errno = get_errno ();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Even when read is blocking, only one pending signal is actually
|
||||||
|
required to return. Subsequently use sigtimedwait to just poll
|
||||||
|
if some more signal is available. */
|
||||||
|
ret = sigwait_common (&sigset, &si, (is_nonblocking () || curlen)
|
||||||
|
? (PLARGE_INTEGER) &poll : NULL);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
if (curlen == 0)
|
||||||
|
{
|
||||||
|
if (get_errno () == EINTR && curlen == 0)
|
||||||
|
continue;
|
||||||
|
set_errno (old_errno);
|
||||||
|
}
|
||||||
|
len = curlen ?: (size_t) -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
copy_siginfo_to_signalfd (sfd_ptr, &si);
|
||||||
|
}
|
||||||
|
__except (EFAULT)
|
||||||
|
{
|
||||||
|
len = (size_t) -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__endtry
|
||||||
|
sfd_ptr++;
|
||||||
|
curlen += sizeof (*sfd_ptr);
|
||||||
|
}
|
||||||
|
while ((len - curlen >= sizeof (struct signalfd_siginfo)));
|
||||||
|
set_errno (old_errno);
|
||||||
|
len = curlen;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_signalfd::poll ()
|
||||||
|
{
|
||||||
|
Sleep (1L); /* BAD HACK, FIXME, need a non-polling technique. */
|
||||||
|
sigset_t outset = (sigset_t) sig_send (myself, __SIGPENDING, &_my_tls);
|
||||||
|
if (outset == SIG_BAD_MASK)
|
||||||
|
return -1;
|
||||||
|
if ((outset & sigset) != 0)
|
||||||
|
return 0;
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -502,12 +502,13 @@ details. */
|
||||||
330: Add CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_COARSE,
|
330: Add CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_COARSE,
|
||||||
CLOCK_BOOTTIME.
|
CLOCK_BOOTTIME.
|
||||||
331: Add timer_getoverrun, DELAYTIMER_MAX.
|
331: Add timer_getoverrun, DELAYTIMER_MAX.
|
||||||
|
332: Add signalfd.
|
||||||
|
|
||||||
Note that we forgot to bump the api for ualarm, strtoll, strtoull,
|
Note that we forgot to bump the api for ualarm, strtoll, strtoull,
|
||||||
sigaltstack, sethostname. */
|
sigaltstack, sethostname. */
|
||||||
|
|
||||||
#define CYGWIN_VERSION_API_MAJOR 0
|
#define CYGWIN_VERSION_API_MAJOR 0
|
||||||
#define CYGWIN_VERSION_API_MINOR 331
|
#define CYGWIN_VERSION_API_MINOR 332
|
||||||
|
|
||||||
/* There is also a compatibity version number associated with the shared memory
|
/* There is also a compatibity version number associated with the shared memory
|
||||||
regions. It is incremented when incompatible changes are made to the shared
|
regions. It is incremented when incompatible changes are made to the shared
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* sys/signalfd.h: define signalfd(2) and struct signalfd_siginfo
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef _SYS_SIGNALFD_H
|
||||||
|
#define _SYS_SIGNALFD_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/_default_fcntl.h>
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SFD_CLOEXEC = O_CLOEXEC,
|
||||||
|
SFD_NONBLOCK = O_NONBLOCK
|
||||||
|
};
|
||||||
|
#define SFD_CLOEXEC SFD_CLOEXEC
|
||||||
|
#define SFD_NONBLOCK SFD_NONBLOCK
|
||||||
|
|
||||||
|
struct signalfd_siginfo
|
||||||
|
{
|
||||||
|
uint32_t ssi_signo;
|
||||||
|
int32_t ssi_errno;
|
||||||
|
int32_t ssi_code;
|
||||||
|
uint32_t ssi_pid;
|
||||||
|
uint32_t ssi_uid;
|
||||||
|
int32_t ssi_fd;
|
||||||
|
uint32_t ssi_tid;
|
||||||
|
uint32_t ssi_band;
|
||||||
|
uint32_t ssi_overrun;
|
||||||
|
uint32_t ssi_trapno;
|
||||||
|
int32_t ssi_status;
|
||||||
|
int32_t ssi_int;
|
||||||
|
uint64_t ssi_ptr;
|
||||||
|
uint64_t ssi_utime;
|
||||||
|
uint64_t ssi_stime;
|
||||||
|
uint64_t ssi_addr;
|
||||||
|
uint8_t pad[48];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int signalfd (int, const sigset_t *, int);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _SYS_SIGNALFD_H */
|
|
@ -27,7 +27,7 @@ What's new:
|
||||||
- Support overrun counter for posix timers (via timer_getoverrun() or
|
- Support overrun counter for posix timers (via timer_getoverrun() or
|
||||||
siginfo_t::si_overrun).
|
siginfo_t::si_overrun).
|
||||||
|
|
||||||
- New API: timer_getoverrun.
|
- New API: signalfd, timer_getoverrun.
|
||||||
|
|
||||||
|
|
||||||
What changed:
|
What changed:
|
||||||
|
|
|
@ -1731,3 +1731,68 @@ fhandler_windows::select_except (select_stuff *ss)
|
||||||
s->windows_handle = true;
|
s->windows_handle = true;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
peek_signalfd (select_record *me, bool)
|
||||||
|
{
|
||||||
|
if (((fhandler_signalfd *) me->fh)->poll () == 0)
|
||||||
|
{
|
||||||
|
select_printf ("signalfd %d ready", me->fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
select_printf ("signalfd %d not ready", me->fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
verify_signalfd (select_record *me, fd_set *rfds, fd_set *wfds,
|
||||||
|
fd_set *efds)
|
||||||
|
{
|
||||||
|
return peek_signalfd (me, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
select_record *
|
||||||
|
fhandler_signalfd::select_read (select_stuff *ss)
|
||||||
|
{
|
||||||
|
select_record *s = ss->start.next;
|
||||||
|
if (!s->startup)
|
||||||
|
{
|
||||||
|
s->startup = no_startup;
|
||||||
|
}
|
||||||
|
s->verify = verify_signalfd;
|
||||||
|
s->peek = peek_signalfd;
|
||||||
|
s->read_selected = true;
|
||||||
|
s->read_ready = true;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
select_record *
|
||||||
|
fhandler_signalfd::select_write (select_stuff *ss)
|
||||||
|
{
|
||||||
|
select_record *s = ss->start.next;
|
||||||
|
if (!s->startup)
|
||||||
|
{
|
||||||
|
s->startup = no_startup;
|
||||||
|
s->verify = no_verify;
|
||||||
|
}
|
||||||
|
s->peek = NULL;
|
||||||
|
s->write_selected = false;
|
||||||
|
s->write_ready = false;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
select_record *
|
||||||
|
fhandler_signalfd::select_except (select_stuff *ss)
|
||||||
|
{
|
||||||
|
select_record *s = ss->start.next;
|
||||||
|
if (!s->startup)
|
||||||
|
{
|
||||||
|
s->startup = no_startup;
|
||||||
|
s->verify = no_verify;
|
||||||
|
}
|
||||||
|
s->peek = NULL;
|
||||||
|
s->except_selected = false;
|
||||||
|
s->except_ready = false;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ details. */
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/cygwin.h>
|
#include <sys/cygwin.h>
|
||||||
|
#include <sys/signalfd.h>
|
||||||
#include "pinfo.h"
|
#include "pinfo.h"
|
||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
|
@ -592,7 +593,7 @@ siginterrupt (int sig, int flag)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
int
|
||||||
sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime)
|
sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
@ -781,3 +782,62 @@ sigaltstack (const stack_t *ss, stack_t *oss)
|
||||||
__endtry
|
__endtry
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" int
|
||||||
|
signalfd (int fd_in, const sigset_t *mask, int flags)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
fhandler_signalfd *fh;
|
||||||
|
|
||||||
|
debug_printf ("signalfd (%d, %p, %y)", fd_in, mask, flags);
|
||||||
|
|
||||||
|
if ((flags & ~(SFD_NONBLOCK | SFD_CLOEXEC)) != 0)
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd_in != -1)
|
||||||
|
{
|
||||||
|
/* Change signal mask. */
|
||||||
|
cygheap_fdget fd (fd_in);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
goto done;
|
||||||
|
fh = fd->is_signalfd ();
|
||||||
|
if (!fh)
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
if (fh->signalfd (mask, flags) == 0)
|
||||||
|
ret = fd_in;
|
||||||
|
}
|
||||||
|
__except (EINVAL) {}
|
||||||
|
__endtry
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Create new signalfd descriptor. */
|
||||||
|
cygheap_fdnew fd;
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
goto done;
|
||||||
|
fh = (fhandler_signalfd *) build_fh_dev (*signalfd_dev);
|
||||||
|
if (fh && fh->signalfd (mask, flags) == 0)
|
||||||
|
{
|
||||||
|
fd = fh;
|
||||||
|
if (fd <= 2)
|
||||||
|
set_std_handle (fd);
|
||||||
|
ret = fd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
delete fh;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
syscall_printf ("%R = signalfd (%d, %p, %y)", ret, fd_in, mask, flags);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -79,6 +79,7 @@ void __stdcall sigalloc ();
|
||||||
int kill_pgrp (pid_t, siginfo_t&);
|
int kill_pgrp (pid_t, siginfo_t&);
|
||||||
void __reg1 exit_thread (DWORD) __attribute__ ((noreturn));
|
void __reg1 exit_thread (DWORD) __attribute__ ((noreturn));
|
||||||
void __reg1 setup_signal_exit (int);
|
void __reg1 setup_signal_exit (int);
|
||||||
|
int sigwait_common (const sigset_t *, siginfo_t *, PLARGE_INTEGER);
|
||||||
|
|
||||||
class no_thread_exit_protect
|
class no_thread_exit_protect
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,7 @@ siginfo_t::si_overrun).
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
New API: timer_getoverrun.
|
New API: signalfd, timer_getoverrun.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
|
|
|
@ -1378,6 +1378,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
||||||
scandirat
|
scandirat
|
||||||
sched_getcpu
|
sched_getcpu
|
||||||
setxattr
|
setxattr
|
||||||
|
signalfd
|
||||||
sincos
|
sincos
|
||||||
sincosf
|
sincosf
|
||||||
sincosl
|
sincosl
|
||||||
|
|
Loading…
Reference in New Issue