/*
- * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2 only,
- * as published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
*
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _LGPL_SOURCE
* Receive data of size len in put that data into the buf param. Using recvmsg
* API. Only use with sockets set in non-blocking mode.
*
+ * NOTE: EPIPE errors are NOT reported. This call expects the socket to be in a
+ * poll set. The poll loop will handle the EPIPE original cause.
+ *
* Return the size of received data.
*/
LTTNG_HIDDEN
goto retry;
} else {
/*
- * Only warn about EPIPE when quiet mode is
- * deactivated.
- * We consider EPIPE as expected.
+ * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
*/
- if (errno != EPIPE || !lttng_opt_quiet) {
- PERROR("recvmsg");
+ if (errno == EAGAIN || errno == EWOULDBLOCK ||
+ errno == EPIPE) {
+ /*
+ * Nothing was recv.
+ */
+ ret = 0;
+ goto end;
}
+
+ /* Unexpected error */
+ PERROR("recvmsg");
+ ret = -1;
goto end;
}
}
- ret = len;
+
end:
return ret;
}
* of the function is that this one does not retry to send on partial sends,
* except if the interruption was caused by a signal (EINTR).
*
+ * NOTE: EPIPE errors are NOT reported. This call expects the socket to be in a
+ * poll set. The poll loop will handle the EPIPE original cause.
+ *
* Return the size of sent data.
*/
LTTNG_HIDDEN
goto retry;
} else {
/*
- * Only warn about EPIPE when quiet mode is
- * deactivated.
- * We consider EPIPE as expected.
+ * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
*/
- if (errno != EPIPE || !lttng_opt_quiet) {
- PERROR("sendmsg");
+ if (errno == EAGAIN || errno == EWOULDBLOCK ||
+ errno == EPIPE) {
+ /*
+ * This can happen in non blocking mode.
+ * Nothing was sent.
+ */
+ ret = 0;
+ goto end;
}
+
+ /* Unexpected error */
+ PERROR("sendmsg");
+ ret = -1;
goto end;
}
}
- ret = len;
end:
return ret;
}
struct cmsghdr *cmsg;
size_t sizeof_fds = nb_fd * sizeof(int);
- /* Account for the struct ucred cmsg in the buffer size */
- char recv_buf[CMSG_SPACE(sizeof_fds) + CMSG_SPACE(sizeof(struct ucred))];
+#ifdef __linux__
+/* Account for the struct ucred cmsg in the buffer size */
+#define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds) + CMSG_SPACE(sizeof(struct ucred))
+#else
+#define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds)
+#endif /* __linux__ */
+
+ char recv_buf[LTTNG_SOCK_RECV_FDS_BUF_SIZE];
struct msghdr msg;
char dummy;
* message.
*/
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- if (!cmsg) {
- fprintf(stderr, "Error: Invalid control message header\n");
- ret = -1;
- goto end;
- }
if (cmsg->cmsg_level != SOL_SOCKET) {
fprintf(stderr, "Error: The socket needs to be of type SOL_SOCKET\n");
ret = -1;
ret = sizeof_fds;
goto end;
}
+#ifdef __linux__
if (cmsg->cmsg_type == SCM_CREDENTIALS) {
/*
* Expect credentials to be sent when expecting fds even
*/
ret = -1;
}
+#endif /* __linux__ */
}
end:
return ret;