/*
 * send memfd fd via SCM_RIGHTS
 */

#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

static int send_fd(int sock, int fd)
{
	char buf = 0;
	struct iovec iov = { .iov_base = &buf, .iov_len = 1 };
	union {
		char buf[CMSG_SPACE(sizeof(int))];
		struct cmsghdr align;
	} u;
	memset(&u, 0, sizeof(u));
	struct msghdr msg = {
		.msg_iov = &iov,
		.msg_iovlen = 1,
		.msg_control = u.buf,
		.msg_controllen = sizeof(u.buf),
	};
	struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
	cmsg->cmsg_level = SOL_SOCKET;
	cmsg->cmsg_type = SCM_RIGHTS;
	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
	memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
	return sendmsg(sock, &msg, 0) < 0 ? -1 : 0;
}

int main(void)
{
	int sv[2];
	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0)
		return errno;

	int mfd = memfd_create("t083", 0);
	if (mfd < 0) {
		close(sv[0]);
		close(sv[1]);
		return errno;
	}

	send_fd(sv[0], mfd);

	close(mfd);
	close(sv[0]);
	close(sv[1]);

	return 0;
}
