summaryrefslogtreecommitdiffstats
path: root/sysif.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-04-23 06:54:45 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-04-23 06:54:45 -0700
commit7fbf6b853893f65193ea9c81cf467be08c651244 (patch)
tree23f312ec0794edc5d653f67a652317f1b05e5502 /sysif.c
parent269044136fa1d73a6bc1a764211cc18119bc1207 (diff)
downloadtxr-7fbf6b853893f65193ea9c81cf467be08c651244.tar.gz
txr-7fbf6b853893f65193ea9c81cf467be08c651244.tar.bz2
txr-7fbf6b853893f65193ea9c81cf467be08c651244.zip
poll: allow execution of async signal handlers.
* sysif.c (poll_wrap): Allocate poll array using alloca so it will be disposed of naturally if an exception occurs. Place sig_save_enable and sig_restore_disable around poll call to allow non-deferred handler execution.
Diffstat (limited to 'sysif.c')
-rw-r--r--sysif.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/sysif.c b/sysif.c
index 4bf76a38..dcea7964 100644
--- a/sysif.c
+++ b/sysif.c
@@ -1311,7 +1311,7 @@ static val poll_wrap(val poll_list, val timeout_in)
{
nfds_t i, len = c_num(length(poll_list));
val iter;
- struct pollfd *pfd = coerce(struct pollfd *, chk_calloc(len, sizeof *pfd));
+ struct pollfd *pfd = coerce(struct pollfd *, alloca(len * sizeof *pfd));
val timeout = default_arg(timeout_in, negone);
int res;
@@ -1346,18 +1346,18 @@ static val poll_wrap(val poll_list, val timeout_in)
}
}
+ sig_save_enable;
+
res = poll(pfd, len, c_num(timeout));
- if (res < 0) {
- free(pfd);
+ sig_restore_enable;
+
+ if (res < 0)
uw_throwf(file_error_s, lit("poll failed: ~d/~s"),
num(errno), string_utf8(strerror(errno)), nao);
- }
- if (res == 0) {
- free(pfd);
+ if (res == 0)
return nil;
- }
{
list_collect_decl (out, ptail);
@@ -1368,7 +1368,6 @@ static val poll_wrap(val poll_list, val timeout_in)
ptail = list_collect(ptail, cons(car(pair), num(pfd[i].revents)));
}
- free(pfd);
return out;
}
}