mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-07 03:38:31 +00:00
Improve cancellations, randomness, and time
- Exhaustively document cancellation points - Rename SIGCANCEL to SIGTHR just like BSDs - Further improve POSIX thread cancellations - Ensure asynchronous cancellations work correctly - Elevate the quality of getrandom() and getentropy() - Make futexes cancel correctly on OpenBSD 6.x and 7.x - Add reboot.com and shutdown.com to examples directory - Remove underscore prefix from awesome timespec_*() APIs - Create assertions that help verify our cancellation points - Remove bad timespec APIs (cmp generalizes eq/ne/gt/gte/lt/lte)
This commit is contained in:
parent
0d7c265392
commit
3f0bcdc3ef
173 changed files with 1599 additions and 782 deletions
|
@ -25,19 +25,45 @@
|
|||
|
||||
/**
|
||||
* Closes stream created by popen().
|
||||
*
|
||||
* This function may be interrupted or cancelled, however it won't
|
||||
* actually return until the child process has terminated. Thus we
|
||||
* always release the resource, and errors are purely advisory.
|
||||
*
|
||||
* @return termination status of subprocess, or -1 w/ ECHILD
|
||||
* @raise ECANCELED if thread was cancelled in masked mode
|
||||
* @raise ECHILD if child pid didn't exist
|
||||
* @raise EINTR if signal was delivered
|
||||
* @cancellationpoint
|
||||
*/
|
||||
int pclose(FILE *f) {
|
||||
int ws, pid;
|
||||
int e, rc, ws, pid;
|
||||
bool iscancelled, wasinterrupted;
|
||||
pid = f->pid;
|
||||
fclose(f);
|
||||
if (!pid) return 0;
|
||||
TryAgain:
|
||||
if (wait4(pid, &ws, 0, 0) != -1) {
|
||||
return ws;
|
||||
} else if (errno == EINTR) {
|
||||
goto TryAgain;
|
||||
iscancelled = false;
|
||||
wasinterrupted = false;
|
||||
for (e = errno;;) {
|
||||
if (wait4(pid, &ws, 0, 0) != -1) {
|
||||
rc = ws;
|
||||
break;
|
||||
} else if (errno == ECANCELED) {
|
||||
iscancelled = true;
|
||||
errno = e;
|
||||
} else if (errno == EINTR) {
|
||||
wasinterrupted = true;
|
||||
errno = e;
|
||||
} else {
|
||||
rc = echild();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (iscancelled) {
|
||||
return ecanceled();
|
||||
} else if (wasinterrupted) {
|
||||
return eintr();
|
||||
} else {
|
||||
return echild();
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue