So errno is not thread local on Solaris and is set to 0 by default on error. Really Solaris? On Solaris, compile using POSIX mode which requires c99 mode which fixes errno, uses void* instead of c_addr_t* for iovec and various other errors. Add solaris constants for dgram, stream and raw which differ from other unix platforms. Make the send/recvmsg example work on Solaris. Platform dependent constants need to be fixed in the future. This could be done either by adding a lookup table to the NIF or writing a small program in C to generate an erlang module at compile time. Bump version to 0.6.1.
Some small fixes and interface changes to sendmsg/5 and recvmsg/4 based on the pull request by Andrew Thompson: #18 * recvmsg: the msg_namelen field is value-result. Resize the source address binary to this length. Fixes einval on FreeBSD when passing in an overlong socket address as noted in the sendmsg/recvmsg echo example * recvmsg: account for padding in cmsghdr structure when calculating the cmsg data length. * recvmsg: reverse the list of cmsg tuples so the order is the same as returned using the CMSG_NXTHDR() macro * recvmsg: if bufsize or ctrlsize are 0, set the iov_base or msg_name to NULL instead of a 0 byte binary * sendmsg: if buf or sa are empty binaries, set iov_base or msg_name to NULL * cleanup: fix pasto in arg order, memory leaks, change recvmsg to return msg_flags as a signed int The following alterations were made to the interface: * recvmsg/5: add an extra argument to recvmsg to specify the size of sockaddr recvmsg() with a connected socket and a non-NULL msg_name field in the msghdr structure will return EISCONN. Allow the caller to specify the length of the sockaddr structure (for example, 128 bytes is the size of sockaddr_storage which is large enough to hold any socket address). Add recvmsg/4, a version of recvmsg for connected sockets that defaults to setting msg_name to NULL. * recvmsg/sendmsg: make the arg order consistent Change the order of arguments so the input and output values are in the same order and position, recvmsg and sendmsg provide the same order and the order reflects sendto()/recvfrom(). The order for arguments and return values is: * buffer * flags * control data * socket address TODO: Solaris support Thanks @Vagabond!
Instead of passing in a binary that is treated as the 'msghdr' struct, pass in data needed to construct an appropriate msghdr struct and also return useful result data, including the control data. Documentation and an example are also included.
In preparation for support of socket ancillary data (RFC3542, Unix sockets, ...), add support for sendmsg(2) and recvmsg(2). recvmsg/3 and sendmsg/3 require a struct msghdr to be prepared containing pointers to allocated memory (to be read into and to be read from respectively). This buffer will have to be allocated using procket:alloc/1.
Modify the way the procket external setuid helper binary is called based on: * whether a progname has explicitly been passed in (run the command immediately) * if the procket helper is setuid/setgid (run the command immediately) * if a device is requested to be opened, check the access rights of the process (if read/write, run command immediately) * otherwise, use sudo
Transferring fd's between processes was failing. Disabling compiler optimizations resulted in a segfault when ancil_send_fd was called and on one occasion, a kernel panic (after playing with the cmsg lengths). Align the buffer using a union as suggested in UNP. Don't use the libancillary structure for holding the fd's; use a union allocated on the stack and calculate lengths using the macros. This change only supports passing a single fd between processes so it isn't a proper fix.
The third argument to ioctl is usually a pointer but the FreeBSD man page clarifies: Most uses of ioctl(), however, require the third argument to be a caddr_t or an int. (The size and signedness of the int is not specified.) For example, tun/tap devices on Linux set persist mode using the integer value 0 or non-zero. Unfortunately, allowing integer values allows the caller to mistakenly pass in an integer where a pointer is required. While this will probably result in EFAULT or EINVAL, there's a chance the memory of the process could be corrupted. Whitelisting ioctl requests with integer values wouldn't be practical since procket would need to know about every driver.