gpt4 book ai didi

c - sendmsg() 无效参数(??)

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:41:18 24 4
gpt4 key购买 nike

首先是一些上下文:有一个主程序(一个网络服务器),它派生了一堆工作人员,并等待传入​​的连接。当它接受一个时,它通过 sendmsg() 原语将套接字描述符发送给其中一个工作人员。

这是应该发送描述符的代码:

int send_msg (worker_t * l, struct message_t * m)
{
#ifdef __WIN32__

#else
struct msghdr msg;
struct cmsghdr * cmsg;
char anc [CMSG_SPACE (sizeof(int))];
int * fd_ptr;

int buf [1] = {m->msg};
struct iovec vec;
vec.iov_base = buf;
vec.iov_len = sizeof (int);

msg.msg_iov = &vec;
msg.msg_iovlen = 1;

msg.msg_control = NULL;
msg.msg_controllen = 0;

if (m->msg == GC_SOCKET) {
msg.msg_control = anc;
msg.msg_controllen = sizeof anc;

cmsg = CMSG_FIRSTHDR (&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN (sizeof (int));
fd_ptr = (int *) CMSG_DATA (cmsg);
*fd_ptr = m->sockfd;
msg.msg_controllen = cmsg->cmsg_len;
}

msg.msg_flags = 0;

if (sendmsg (l->channel.chan, &msg, 0) == -1) {
i_log (1, "Unable to send message to listener.");
return -1;
}
else {
if (m->msg == GC_SOCKET && m->sockfd)
close (m->sockfd);

return 1;
}
#endif
}

上面代码中,l->channel.chanAF_UNIX套接字,struct message_t是:

struct message_t {
int msg;
int sockfd;
};

msg 可以获取值 GC_SOCKETGC_CLOSE。在前一种情况下,字段 sockfd 包含传递的套接字的描述符,而在后一种情况下,不发送辅助数据(并且工作人员应该自杀)。

现在,这些东西不起作用。当主程序将 GC_CLOSE 发送给 worker 时,strace 是这么说的:

    ...
[pid 6229] sendmsg(5, {msg_name(6229)={...}, msg_iov(1)=[{"\1\0\0\0", 4}],
msg_controllen=0, msg_flags=0}, 0) = -1 EINVAL (Invalid argument)
...

非常感谢任何帮助。

最佳答案

我认为您没有初始化 msg.msg_namemsg.msg_namelen。如果你这样做会更安全:

struct msghdr msg = {}

这相当于调用 memset(0) 或 bzero(),但更简洁。无论如何,现在看起来您正在传递未初始化的谁知道什么,这很容易导致 EINVAL。

此外,现在和将来,请尝试在 valgrind 下运行您的程序——它可以帮助捕获此类错误。

关于c - sendmsg() 无效参数(??),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9370479/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com