-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathsignalfd.c
110 lines (99 loc) · 3.93 KB
/
signalfd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/******************************************************************************/
/* signalfd stubs */
/* */
/* NO COPYRIGHT -- RELEASED INTO THE PUBLIC DOMAIN */
/* */
/* Author: Kaustuv Chaudhuri <[email protected]> */
/******************************************************************************/
#define EXTUNIX_WANT_SIGNALFD
#include "config.h"
#if defined(EXTUNIX_HAVE_SIGNALFD)
extern int caml_convert_signal_number(int signo);
extern int caml_rev_convert_signal_number(int signo);
CAMLprim
value caml_extunix_signalfd(value vfd, value vsigs, value vflags, value v_unit)
{
CAMLparam4(vfd, vsigs, vflags, v_unit);
int fd = ((Val_none == vfd) ? -1 : Int_val(Some_val(vfd)));
int flags = 0;
int ret = 0;
sigset_t ss;
sigemptyset (&ss);
while (!Is_long (vsigs)) {
int sig = caml_convert_signal_number (Int_val (Field (vsigs, 0)));
if (sigaddset (&ss, sig) < 0) uerror ("sigaddset", Nothing);
vsigs = Field (vsigs, 1);
}
while (!Is_long (vflags)) {
int f = Int_val (Field (vflags, 0));
if (SFD_NONBLOCK == f) flags |= SFD_NONBLOCK;
if (SFD_CLOEXEC == f) flags |= SFD_CLOEXEC;
vflags = Field (vflags, 1);
}
ret = signalfd (fd, &ss, flags);
if (ret < 0) uerror ("signalfd", Nothing);
CAMLreturn (Val_int (ret));
}
/* [HACK] improve these -- bytestream representation is OK */
static struct custom_operations ssi_ops = {
"signalfd.signalfd_siginfo",
custom_finalize_default,
custom_compare_default, custom_hash_default,
custom_serialize_default, custom_deserialize_default,
#if defined(custom_compare_ext_default)
custom_compare_ext_default,
#endif
#if defined(custom_fixed_length_default)
custom_fixed_length_default,
#endif
};
#define SSI_SIZE sizeof(struct signalfd_siginfo)
CAMLprim
value caml_extunix_signalfd_read(value v_fd)
{
CAMLparam1(v_fd);
CAMLlocal1(vret);
int fd = Int_val(v_fd);
struct signalfd_siginfo ssi;
ssize_t nread = 0;
caml_enter_blocking_section();
nread = read(fd, &ssi, SSI_SIZE);
caml_leave_blocking_section();
if (nread != SSI_SIZE)
unix_error(EINVAL,"signalfd_read",Nothing);
vret = caml_alloc_custom(&ssi_ops, SSI_SIZE, 0, 1);
memcpy(Data_custom_val(vret),&ssi,SSI_SIZE);
CAMLreturn(vret);
}
CAMLprim
value caml_extunix_ssi_signo_sys(value vssi)
{
CAMLparam1(vssi);
struct signalfd_siginfo *ssi = (void *)(Data_custom_val(vssi));
CAMLreturn(Val_int(caml_rev_convert_signal_number(ssi->ssi_signo)));
}
#define SSI_GET_FIELD(field,coerce) \
CAMLprim \
value caml_extunix_ssi_##field(value vssi) \
{ \
CAMLparam1(vssi); \
struct signalfd_siginfo *ssi = (void *)Data_custom_val(vssi); \
CAMLreturn(coerce(ssi->ssi_##field)); \
} \
SSI_GET_FIELD( signo , caml_copy_int32 )
SSI_GET_FIELD( errno , caml_copy_int32 )
SSI_GET_FIELD( code , caml_copy_int32 )
SSI_GET_FIELD( pid , caml_copy_int32 )
SSI_GET_FIELD( uid , caml_copy_int32 )
SSI_GET_FIELD( fd , Val_int )
SSI_GET_FIELD( tid , caml_copy_int32 )
SSI_GET_FIELD( band , caml_copy_int32 )
SSI_GET_FIELD( overrun , caml_copy_int32 )
SSI_GET_FIELD( trapno , caml_copy_int32 )
SSI_GET_FIELD( status , caml_copy_int32 )
SSI_GET_FIELD( int , caml_copy_int32 )
SSI_GET_FIELD( ptr , caml_copy_int64 )
SSI_GET_FIELD( utime , caml_copy_int64 )
SSI_GET_FIELD( stime , caml_copy_int64 )
SSI_GET_FIELD( addr , caml_copy_int64 )
#endif /* EXTUNIX_HAVE_SIGNALFD */