Date: Thu, 22 Jul 2004 21:35:33 GMT From: Timo Sirainen <tss@iki.fi> To: freebsd-gnats-submit@FreeBSD.org Subject: misc/69448: cmsghdr macros don't work with Alpha (and other 64bit systems?) Message-ID: <200407222135.i6MLZXt5097142@www.freebsd.org> Resent-Message-ID: <200407222140.i6MLeNdk088493@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 69448 >Category: misc >Synopsis: cmsghdr macros don't work with Alpha (and other 64bit systems?) >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Jul 22 21:40:23 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Timo Sirainen >Release: 4.10 >Organization: >Environment: Alpha (not mine) >Description: CMSG_DATA and CMSG_LEN macros do 64bit alignment but kernel seems to want 32bit alignment. After overriding them it started working: #define CMSG_LEN(l) (sizeof(struct cmsghdr) + (l)) #define CMSG_DATA(cmsg) ((u_char *)(cmsg) + sizeof(struct cmsghdr)) >How-To-Repeat: This breaks: #include <sys/types.h> #include <sys/socket.h> #include <sys/wait.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <limits.h> #include <sys/un.h> #include <sys/uio.h> ssize_t fd_send(int handle, int send_fd, const void *data, size_t size) { struct msghdr msg; struct iovec iov; struct cmsghdr *cmsg; char buf[CMSG_SPACE(sizeof(int))]; memset(&msg, 0, sizeof(struct msghdr)); iov.iov_base = (void *) data; iov.iov_len = size; msg.msg_iov = &iov; msg.msg_iovlen = 1; if (send_fd != -1) { memset(buf, 0, sizeof(buf)); msg.msg_control = buf; msg.msg_controllen = sizeof(buf); cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(int)); *((int *) CMSG_DATA(cmsg)) = send_fd; msg.msg_controllen = cmsg->cmsg_len; } return sendmsg(handle, &msg, 0); } ssize_t fd_read(int handle, void *data, size_t size, int *fd) { struct msghdr msg; struct iovec iov; struct cmsghdr *cmsg; ssize_t ret; char buf[CMSG_SPACE(sizeof(int))]; memset(&msg, 0, sizeof (struct msghdr)); iov.iov_base = data; iov.iov_len = size; msg.msg_iov = &iov; msg.msg_iovlen = 1; memset(buf, 0, sizeof(buf)); msg.msg_control = buf; msg.msg_controllen = sizeof(buf); ret = recvmsg(handle, &msg, 0); if (ret <= 0) { *fd = -1; return ret; } cmsg = CMSG_FIRSTHDR(&msg); if (cmsg == NULL) *fd = -1; else *fd = *((int *) CMSG_DATA(cmsg)); return ret; } int main(void) { int fd[2], send_fd, recv_fd, status; struct stat st, st2; char data; send_fd = open("conftest.fdpass", O_CREAT|O_WRONLY); if (send_fd == -1) { perror("open()"); return 2; } unlink("conftest.fdpass"); if (fstat(send_fd, &st) < 0) { perror("fstat()"); return 2; } if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0) { perror("socketpair()"); return 2; } switch (fork()) { case -1: perror("fork()"); return 2; case 0: if (fd_send(fd[0], send_fd, &data, 1) != 1) { perror("fd_send()"); return 2; } wait(&status); return status; default: if (fd_read(fd[1], &data, 1, &recv_fd) != 1) { perror("fd_read()"); return 1; } if (fstat(recv_fd, &st2) < 0) { perror("fstat(recv_fd)"); return 2; } return st.st_ino == st2.st_ino ? 0 : 1; } } >Fix: >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200407222135.i6MLZXt5097142>