view rust/chg/src/sendfds.c @ 47890:3853e6ee160d

dirstatemap: replace `removefile` by an explicit `entry.set_untracked()` All the other caller goes through `reset_state`, so we can safely have an explicit method on `DirstateItem` object. This means that all the logic to preserve the previous state (from p2, merged, etc) is now properly encapsulated within the DirstateItem. This pave the way to using different storage for these information. Differential Revision: https://phab.mercurial-scm.org/D11315
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Fri, 20 Aug 2021 11:27:01 +0200
parents 208cb7a9d0fa
children
line wrap: on
line source

/*
 * Utility to send fds via Unix domain socket
 *
 * Copyright 2011, 2018 Yuya Nishihara <yuya@tcha.org>
 *
 * This software may be used and distributed according to the terms of the
 * GNU General Public License version 2 or any later version.
 */

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>

#define MAX_FD_LEN 10

/*
 * Sends the given fds with 1-byte dummy payload.
 *
 * Returns the number of bytes sent on success, -1 on error and errno is set
 * appropriately.
 */
ssize_t sendfds(int sockfd, const int *fds, size_t fdlen)
{
	char dummy[1] = {0};
	struct iovec iov = {dummy, sizeof(dummy)};
	char fdbuf[CMSG_SPACE(sizeof(fds[0]) * MAX_FD_LEN)];
	struct msghdr msgh;
	struct cmsghdr *cmsg;

	/* just use a fixed-size buffer since we'll never send tons of fds */
	if (fdlen > MAX_FD_LEN) {
		errno = EINVAL;
		return -1;
	}

	memset(&msgh, 0, sizeof(msgh));
	msgh.msg_iov = &iov;
	msgh.msg_iovlen = 1;
	msgh.msg_control = fdbuf;
	msgh.msg_controllen = CMSG_SPACE(sizeof(fds[0]) * fdlen);

	cmsg = CMSG_FIRSTHDR(&msgh);
	cmsg->cmsg_level = SOL_SOCKET;
	cmsg->cmsg_type = SCM_RIGHTS;
	cmsg->cmsg_len = CMSG_LEN(sizeof(fds[0]) * fdlen);
	memcpy(CMSG_DATA(cmsg), fds, sizeof(fds[0]) * fdlen);
	msgh.msg_controllen = cmsg->cmsg_len;
	return sendmsg(sockfd, &msgh, 0);
}