Advanced Programming in UNIX Environment Episode 107

Clients call recv_fd to receive a descriptor. If all is OK (the sender called send_fd), the non-negative descriptor is returned as the value of the function. Otherwise, the value returned is the status that was sent by send_err (a negative value in the range −1 through −255). Additionally, if an error message was sent by the server,
the client’s userfunc is called to process the message. The first argument to userfunc is the constant STDERR_FILENO, followed by a pointer to the error message and its length. The return value from userfunc is the number of bytes written or a negative number on error. Often, the client specifies the normal write function as the userfunc.

#include "apue.h"

int send_err(int fd, int errcode, const char *msg)
{
    int n;
    if((n=strlen(msg))>0)
        if(writen(fd,msg,n)!=n)
            return -1;
    
    if(errcode>=0)
        errcode=-1;
    
    if(send_fd(fd, errcode)<0)
        return -1;
    
    return 0;
}

The send_err function

To exchange file descriptors using UNIX domain sockets, we call the sendmsg(2) and recvmsg(2) functions (Section 16.5). Both functions take a pointer to a msghdr structure that contains all the information on what to send or receive. The structure on your system might look similar to the following:

struct msghdr {
	void *msg_name; /* optional address */
	socklen_t msg_namelen; /* address size in bytes */
	struct iovec *msg_iov; /* array of I/O buffers */
	int msg_iovlen; /* number of elements in array */
	void *msg_control; /* ancillary data */
	socklen_t msg_controllen; /* number of ancillary bytes */
	int msg_flags; /* flags for received message */
};

The first two elements are normally used for sending datagrams on a network connection, where the destination address can be specified with each datagram. The next two elements allow us to specify an array of buffers (scatter read or gather write), as we described for the readv and writev functions (Section 14.6). The msg_flags field contains flags describing the message received, as summarized in Figure 16.15.

Two elements deal with the passing or receiving of control information. The msg_control field points to a cmsghdr (control message header) structure, and the msg_controllen field contains the number of bytes of control information.

struct cmsghdr {
	socklen_t cmsg_len; /* data byte count, including header */
	int cmsg_level; /* originating protocol */
	int cmsg_type; /* protocol-specific type */
	/* followed by the actual control message data */
};

To send a file descriptor, we set cmsg_len to the size of the cmsghdr structure, plus the size of an integer (the descriptor). The cmsg_level field is set to SOL_SOCKET, and cmsg_type is set to SCM_RIGHTS, to indicate that we are passing access rights. (SCM stands for socket-level control message.) Access rights can be passed only across a UNIX domain socket. The descriptor is stored right after the cmsg_type field, using the macro CMSG_DATA to obtain the pointer to this integer.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值