Yes, it will break stuff, in exciting and interesting ways.
The problem is that Unix-like systems typically allocate file descriptors sequentially. When a program wants a new file descriptor (ie they call
socket(), and any other function that allocates an fd) the kernel will find the lowest-numbered "free" descriptor, and hand that out.
Imagine now, if you will, that you have closed fd 2 (stderr). Something in the process then wants a file descriptor (the next open file). The kernel goes looking for a free fd, sees that fd 2 is unused, and gives that back to the program.
Now, imagine something else in the program wants to write to stderr. It blindly writes to fd 2, because that where stderr lives. Except now it doesn't. If you're lucky, fd 2 was opened read-only, and the write gets an error. Everyone assumes that writes to stderr will always succeed, so that'll be fun. At least as likely, though, is that the fd is read-write (five of the six
fopen(2) modes are write-enabled --
w+) and the message that was supposed to go to stderr has just ended up splattered into whoknowswhere.
Even more exciting, *file descriptors are inherited on
fork(). That means that every child process will also have the ability to scribble somewhere unexpected. Worse, even "safe" forking strategies, for example where all fds get closed before
exec, typically don't touch fds 0, 1, or 2. So your little breakage will almost certainly survive ordinary strategies meant to prevent disaster across process boundaries.
You may say, "well, I'll never use a library that writes to stderr, then, and I'll be careful never to write to stderr myself". To that, I just have two things to say:
- Future-you won't be that careful. You'll forget that you closed stderr.
- Everyone else who may ever have the misfortune to deal with your crazy code won't be that careful, either.
Friends don't let friends close stderr. Womble out. drops mic