Start the SIGCHLD signal watcher before calling fork(). There was a very subtle
race where a child process could quit (and generate a SIGCHILD) before the
signal handler was installed.
To reproduce, call uv_spawn() repeatedly with the below x86_64 program:
// compile with `gcc -O2 -nostdlib`
void _start(void)
{
// syscall(SYS_exit, 0)
__asm__ __volatile__ (
"xorq %rdi, %rdi;"
"xorq %rax, %rax;"
"mov $0x3c, %al;"
"syscall;"
);
for (;;);
}
poll() on newer versions of OS X sets POLLHUP|POLLIN whereas older versions
(and other Unices) only set POLLHUP. It was tripping up a check that expected
to read data when POLLIN was set.
While easy to work around, I switched it to a blocking read instead:
it's less code and avoids surprises like the one above altogether.
Fixes#522.
OS X has no public API for fdatasync. And as pointed out in `man fsync(2)`:
For applications that require tighter guarantees about the integrity of
their data, Mac OS X provides the F_FULLFSYNC fcntl. The F_FULLFSYNC
fcntl asks the drive to flush all buffered data to permanent storage.
Applications, such as databases, that require a strict ordering of writes
should use F_FULLFSYNC to ensure that their data is written in the order
they expect. Please see fcntl(2) for more detail.
The Sun Studio compiler did not define any of the symbols used to determine if
the system was a unix-like system or not causing it to include the windows
header.
uv_spawn() saves and restores the environ in case the child clobbers it -
which is impossible because the child process runs in a separate address space.
Problem: registering two uv_fs_event_t watchers for the same path, then closing
them, caused a segmentation fault. While active, the watchers didn't work right
either, only one would receive events.
Cause: each watcher has a wd (watch descriptor) that's used as its key in a
binary tree. When you call inotify_watch_add() twice with the same path, the
second call doesn't return a new wd - it returns the existing one. That in turn
resulted in the first handle getting ousted from the binary tree, leaving
dangling pointers.
This commit addresses that by storing the watchers in a queue and storing the
queue in the binary tree instead of storing the watchers directly in the tree.
Fixesjoyent/node#3789.