fdpass.c revision d0f2a0acfe7b88cce6d5ec94452002cd01e99595
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
80c1d98d3638b71e57a39cafa88b9122bf8169c6Timo Sirainen fdpass.c - File descriptor passing between processes via UNIX sockets
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen This isn't fully portable, but pretty much all UNIXes nowadays should
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen support this. If you're having runtime problems, check the end of fd_read()
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen and play with the if condition.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen If this file doesn't compile at all, you should check if this is supported
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen in your system at all. It may require some extra #define to enable it.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen If not, you're pretty much out of luck. Cygwin didn't last I checked.
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen#if defined(irix) || defined (__irix__) || defined(sgi) || defined (__sgi__)
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen#if !defined(_AIX) && !defined(_XOPEN_SOURCE_EXTENDED)
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen# define _XOPEN_SOURCE_EXTENDED /* for Tru64, breaks AIX */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (CMSG_ALIGN(len) + CMSG_ALIGN(sizeof(struct cmsghdr)))
db5164c9a1129af0cfb11fc18d88da361a8011fbTimo Sirainenssize_t fd_send(int handle, int send_fd, const void *data, size_t size)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* at least one byte is required to be sent with fd passing */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* set the control and controllen before CMSG_FIRSTHDR() */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* set the real length we want to use. it's different than
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainen sizeof(buf) in 64bit systems. */
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen# define CHECK_MSG(msg) (msg).msg_controllen >= CMSG_SPACE(sizeof(int))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Linux 2.0.x doesn't set any cmsg fields. Note that this might make some
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen attacks possible so don't do it unless you really have to. */
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen ((cmsg) != NULL && (cmsg)->cmsg_len >= CMSG_LEN(sizeof(int)) && \
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen (cmsg)->cmsg_level == SOL_SOCKET && (cmsg)->cmsg_type == SCM_RIGHTS)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenssize_t fd_read(int handle, void *data, size_t size, int *fd)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* at least one byte transferred - we should have the fd now.
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen do extra checks to make sure it really is an fd that is being
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen transferred to avoid potential DoS conditions. some systems don't
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen set all these values correctly however so CHECK_MSG() and
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen CHECK_CMSG() are somewhat system dependent */
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen# warning SCM_RIGHTS not supported, privilege separation not possible
d6a1fa1d65c6d1996937802c2482c0f14dd821a7Timo Sirainenssize_t fd_send(int handle __attr_unused__, int send_fd __attr_unused__,
807b48fe1f6a57b01ed2cc20247d5b5e3facc562Timo Sirainen const void *data __attr_unused__, size_t size __attr_unused__)
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainenssize_t fd_read(int handle __attr_unused__, void *data __attr_unused__,