I recently looked again at PPerl, because I wanted to fix some other behaviour, and found that it doesn't build on Windows. After a quick converstation with the author, Matt Sergeant, I found that PPerl doesn't cater for Windows because the functionality it needs, sendfd() and SOCK_PERM, only exists on Linux and some other unixish OSes and not on Windows.

Almost by chance, I happened over the DuplicateHandle() API of Windows, which allows to duplicate a file handle for use in another process. My test file implementing this is below.

I use a child process, to which I print the handle number on STDIN. The child process then reads from that filehandle which it knows no name of. With a child process, the same could well have been done using input/output redirection, but the use of a child process is only to alleviate
permission issues and general coordination issues, like how the two processes find each other.

This is interesting. In linux, all filehandles in a threaded app can be shared thru the fileno, which can be very useful. I guess in the MSWindows kernel, everything is a thread, and all filno's can be accesed?

Just how does the Microsoft kernel differ from the modern linux kernel in protecting filehandles?

No. There would be no need for this API if file handles were shared as you describe in Win32. The API has the kernel create in one process a new file handle that points to the same kernel data structure as an existing file handle of another process. This is the same thing that happens in Unix when you pass an open file descriptor over a socket. It is just that the interface for getting it done is different.

File handles in Windows are actually very similar to file handles in Unix in many ways (including that they can't be used by another process but can be used by other threads of the same process). For example, the seek position is shared between the two file handles/descriptors in the two processes after this type of operation in both Windows and Unix.

One difference between the two scenarios regarding protections is that the Windows API requires that one process be able to get a handle to another process (or to the other two processes) with sufficient access to be allowed to copy or create the other process's handle. With the Unix API, the processes need to cooperate (of course) but neither process needs any special access permissions to the other.

Interestingly, giving out access to your process such that DuplicateHandle() can be used on that process actually means that one can also fairly easily get unrestricted access to the process. So security concerns could easily make the use of this API unacceptable in some scenarios.

In contrast, one of the example scenarios for the use of the Unix API is to allow processes to share privileges while keeping more control.

For example, you could have a server process that has special access to manage the directory where log files are kept. A client could be given a file handle that only allows them to append to a log file, a log file that they have no permissions to access in a directory that they have no permissions to access. Yet they can write directly to the log file, not having to pass data through some server process to have it append it for them. (But if the server process is compromised, it only has access to log files, it can't read/write pages of memory of every potential client process.)

As far as I'm aware, each handle (not a fileno, necessarily, as Windows handles exist for UI-Windows, process/thread handles, mutexes and various other things) is only valid per-thread. To pass a handle to another thread (or another process), you need to DuplicateHandle() it for the recipient.