2

When we want to pass a descriptor from child to process, UNP V1(Unix network programming V1) specifies a complex procedure of doing this, first to create msghdr struct and then something, etc.

Why cant we pass a descriptor as normal data means as we do send , recv for other data through unix domain sockets? I am able to understand the process. Please explain the method given in that book.

Also, in that book, in read_fd() function, he declares the union to properly align the msghdr struct. How union makes it aligned? and why alignment is required?

avd
  • 13,993
  • 32
  • 78
  • 99

1 Answers1

3

Why cant we pass a descriptor as normal data means as we do send , recv for other data through unix domain sockets?

Because an open file descriptor is not usefully serializable as a stream of bytes.

While file descriptors are actually just integers, they are mapped by the kernel (in a per-process manner) to kernel-internal data structures that describe the details of the opened ‘file’ (is it ‘normal’ file? is is a block/character special device? is it a network socket of some sort? is it anonymous pipe? etc.). The goal of file descriptor passing is to create a new file descriptor (probably with some other integer value) in some other (possibly unrelated) process that is mapped to the same kernel-internal data structure as the original descriptor in the sending process.

The machinations you have to go through to do this are just the “API” to access this functionality (note that System V based Unix systems have an alternate method of file descriptor passing based on STREAMS, which uses a different “API”). I do not know the history, but I would guess that the “complexity” of the BSD file descriptor passing “API” is due to shoehorning the functionality into the preexisting sendmsg(2)/recvmsg(2) API.

How union makes it aligned? and why alignment is required?

I do not have the UNP implementation in front of me, but using a union is not the only way to go. Kragen Sitaker's portlisten example uses the CMSG_* macros instead of a union. The idea is to make sure that <struct msghdr>.msg_control points to the <struct cmsghdr>.

Chris Johnsen
  • 214,407
  • 26
  • 209
  • 186