いくつかのコンテキストが最初にあります:ワーカーの束をフォークし、着信接続を待つメインプログラム(Webサーバー)があります。それを受け入れると、ソケット記述子はsendmsg()プリミティブを介してワーカーの1人に送信されます。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.chan
がAF_UNIX
ソケットである、とstruct message_t
がある:msg
、値を取得することができます
struct message_t {
int msg;
int sockfd;
};
GC_SOCKET
またはGC_CLOSE
。前者の場合、フィールドsockfdには渡されたソケットの記述子が含まれ、後者では補助データは送信されません(従業員は自分自身を殺すことになっています)。
今、このようなことは機能しません。メインプログラムがワーカーにGC_CLOSEを送信したときの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)
...
助けを借りてください。
ああ。さて、あなたの構造を常にゼロにすることが良い理由です。使用しているAPIは、意味のあるエラー(おそらくあなたのケースではENOTCONN)を報告する機会があります。生活し、学びます。 :) –