2 * Copyright (C) 2011 EfficiOS Inc.
3 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 * SPDX-License-Identifier: LGPL-2.1-only
12 #include <common/common.hpp>
13 #include <common/compat/errno.hpp>
14 #include <common/fd-handle.hpp>
15 #include <common/sessiond-comm/sessiond-comm.hpp>
22 #include <sys/types.h>
26 * Connect to unix socket using the path name.
28 int lttcomm_connect_unix_sock(const char *pathname
)
30 struct sockaddr_un s_un
;
31 int fd
, ret
, closeret
;
33 if (strlen(pathname
) >= sizeof(s_un
.sun_path
)) {
34 ERR("unix socket address (\"%s\") is longer than the platform's limit (%zu > %zu).",
37 sizeof(s_un
.sun_path
));
42 fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
49 memset(&s_un
, 0, sizeof(s_un
));
50 s_un
.sun_family
= AF_UNIX
;
51 strncpy(s_un
.sun_path
, pathname
, sizeof(s_un
.sun_path
));
52 s_un
.sun_path
[sizeof(s_un
.sun_path
) - 1] = '\0';
54 ret
= connect(fd
, (struct sockaddr
*) &s_un
, sizeof(s_un
));
57 * Don't print message on connect error, because connect is used in
58 * normal execution to detect if sessiond is alive.
75 * Do an accept(2) on the sock and return the new file descriptor. The socket
76 * MUST be bind(2) before.
78 int lttcomm_accept_unix_sock(int sock
)
81 struct sockaddr_un s_un
;
82 socklen_t len
= sizeof(s_un
);
85 new_fd
= accept(sock
, (struct sockaddr
*) &s_un
, &len
);
93 int lttcomm_create_anon_unix_socketpair(int *fds
)
95 if (socketpair(PF_UNIX
, SOCK_STREAM
, 0, fds
) < 0) {
103 * Creates a AF_UNIX local socket using pathname bind the socket upon creation
106 int lttcomm_create_unix_sock(const char *pathname
)
108 struct sockaddr_un s_un
;
112 if (strlen(pathname
) >= sizeof(s_un
.sun_path
)) {
113 ERR("unix socket address (\"%s\") is longer than the platform's limit (%zu > %zu).",
115 strlen(pathname
) + 1,
116 sizeof(s_un
.sun_path
));
121 /* Create server socket */
122 if ((fd
= socket(PF_UNIX
, SOCK_STREAM
, 0)) < 0) {
127 memset(&s_un
, 0, sizeof(s_un
));
128 s_un
.sun_family
= AF_UNIX
;
129 strncpy(s_un
.sun_path
, pathname
, sizeof(s_un
.sun_path
));
130 s_un
.sun_path
[sizeof(s_un
.sun_path
) - 1] = '\0';
132 /* Unlink the old file if present */
133 (void) unlink(pathname
);
134 ret
= bind(fd
, (struct sockaddr
*) &s_un
, sizeof(s_un
));
145 PERROR("close create unix sock");
152 * Make the socket listen using LTTNG_SESSIOND_COMM_MAX_LISTEN.
154 int lttcomm_listen_unix_sock(int sock
)
158 ret
= listen(sock
, LTTNG_SESSIOND_COMM_MAX_LISTEN
);
167 * Receive data of size len in put that data into the buf param. Using recvmsg
170 * Return the size of received data.
172 ssize_t
lttcomm_recv_unix_sock(int sock
, void *buf
, size_t len
)
181 LTTNG_ASSERT(len
> 0);
183 memset(&msg
, 0, sizeof(msg
));
185 iov
[0].iov_base
= buf
;
186 iov
[0].iov_len
= len
;
191 len_last
= iov
[0].iov_len
;
192 ret
= lttng_recvmsg_nosigpipe(sock
, &msg
);
194 iov
[0].iov_base
= (char *) iov
[0].iov_base
+ ret
;
195 iov
[0].iov_len
-= ret
;
196 LTTNG_ASSERT(ret
<= len_last
);
198 } while ((ret
> 0 && ret
< len_last
) || (ret
< 0 && errno
== EINTR
));
201 } else if (ret
> 0) {
204 /* Else ret = 0 meaning an orderly shutdown. */
210 * Receive data of size len in put that data into the buf param. Using recvmsg
211 * API. Only use with sockets set in non-blocking mode.
213 * NOTE: EPIPE errors are NOT reported. This call expects the socket to be in a
214 * poll set. The poll loop will handle the EPIPE original cause.
216 * Return the size of received data.
218 ssize_t
lttcomm_recv_unix_sock_non_block(int sock
, void *buf
, size_t len
)
226 LTTNG_ASSERT(len
> 0);
228 memset(&msg
, 0, sizeof(msg
));
230 iov
[0].iov_base
= buf
;
231 iov
[0].iov_len
= len
;
236 ret
= lttng_recvmsg_nosigpipe(sock
, &msg
);
238 if (errno
== EINTR
) {
242 * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
245 DIAGNOSTIC_IGNORE_LOGICAL_OP
246 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
|| errno
== EPIPE
) {
255 /* Unexpected error */
267 * Send buf data of size len. Using sendmsg API.
269 * Return the size of sent data.
271 ssize_t
lttcomm_send_unix_sock(int sock
, const void *buf
, size_t len
)
279 LTTNG_ASSERT(len
> 0);
281 memset(&msg
, 0, sizeof(msg
));
283 iov
[0].iov_base
= (void *) buf
;
284 iov
[0].iov_len
= len
;
288 while (iov
[0].iov_len
) {
289 ret
= sendmsg(sock
, &msg
, 0);
291 if (errno
== EINTR
) {
295 * Only warn about EPIPE when quiet mode is
297 * We consider EPIPE as expected.
299 if (errno
!= EPIPE
|| !lttng_opt_quiet
) {
305 iov
[0].iov_len
-= ret
;
306 iov
[0].iov_base
= (char *) iov
[0].iov_base
+ ret
;
314 * Send buf data of size len. Using sendmsg API.
315 * Only use with non-blocking sockets. The difference with the blocking version
316 * of the function is that this one does not retry to send on partial sends,
317 * except if the interruption was caused by a signal (EINTR).
319 * NOTE: EPIPE errors are NOT reported. This call expects the socket to be in a
320 * poll set. The poll loop will handle the EPIPE original cause.
322 * Return the size of sent data.
324 ssize_t
lttcomm_send_unix_sock_non_block(int sock
, const void *buf
, size_t len
)
332 LTTNG_ASSERT(len
> 0);
334 memset(&msg
, 0, sizeof(msg
));
336 iov
[0].iov_base
= (void *) buf
;
337 iov
[0].iov_len
= len
;
342 ret
= sendmsg(sock
, &msg
, 0);
344 if (errno
== EINTR
) {
348 * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
351 DIAGNOSTIC_IGNORE_LOGICAL_OP
352 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
|| errno
== EPIPE
) {
355 * This can happen in non blocking mode.
362 /* Unexpected error */
373 * Shutdown cleanly a unix socket.
375 int lttcomm_close_unix_sock(int sock
)
379 /* Shutdown receptions and transmissions */
380 ret
= shutdown(sock
, SHUT_RDWR
);
383 * The socket is already disconnected, don't error out.
384 * This doesn't happen on Linux, but it does on FreeBSD, see:
385 * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=227259
387 if (errno
== ENOTCONN
) {
394 closeret
= close(sock
);
403 * Send a message accompanied by fd(s) over a unix socket.
405 * Returns the size of data sent, or negative error value.
407 ssize_t
lttcomm_send_fds_unix_sock(int sock
, const int *fds
, size_t nb_fd
)
410 struct cmsghdr
*cmptr
;
413 unsigned int sizeof_fds
= nb_fd
* sizeof(int);
414 char tmp
[CMSG_SPACE(sizeof_fds
)];
419 LTTNG_ASSERT(nb_fd
> 0);
421 memset(&msg
, 0, sizeof(msg
));
422 memset(tmp
, 0, sizeof(tmp
));
424 if (nb_fd
> LTTCOMM_MAX_SEND_FDS
)
427 msg
.msg_control
= (caddr_t
) tmp
;
428 msg
.msg_controllen
= CMSG_LEN(sizeof_fds
);
430 cmptr
= CMSG_FIRSTHDR(&msg
);
435 cmptr
->cmsg_level
= SOL_SOCKET
;
436 cmptr
->cmsg_type
= SCM_RIGHTS
;
437 cmptr
->cmsg_len
= CMSG_LEN(sizeof_fds
);
438 memcpy(CMSG_DATA(cmptr
), fds
, sizeof_fds
);
439 /* Sum of the length of all control messages in the buffer: */
440 msg
.msg_controllen
= cmptr
->cmsg_len
;
442 iov
[0].iov_base
= &dummy
;
448 ret
= sendmsg(sock
, &msg
, 0);
449 } while (ret
< 0 && errno
== EINTR
);
452 * Only warn about EPIPE when quiet mode is deactivated.
453 * We consider EPIPE as expected.
455 if (errno
!= EPIPE
|| !lttng_opt_quiet
) {
463 * Send the fd(s) of a payload view over a unix socket.
465 * Returns the size of data sent, or negative error value.
468 _lttcomm_send_payload_view_fds_unix_sock(int sock
, struct lttng_payload_view
*view
, bool blocking
)
472 struct lttng_dynamic_array raw_fds
;
473 const int fd_count
= lttng_payload_view_get_fd_handle_count(view
);
475 lttng_dynamic_array_init(&raw_fds
, sizeof(int), nullptr);
478 ret
= -LTTNG_ERR_INVALID
;
483 * Prepare a contiguous array of file descriptors to send them.
485 * Note that the reference to each fd is released during the iteration;
486 * we're just getting the numerical value of the fds to conform to the
487 * syscall's interface. We rely on the fact that "view" must remain
488 * valid for the duration of the call and that the underlying payload
489 * owns a reference to the fd_handles.
491 for (i
= 0; i
< fd_count
; i
++) {
492 struct fd_handle
*handle
= lttng_payload_view_pop_fd_handle(view
);
493 const int raw_fd
= fd_handle_get_fd(handle
);
494 const int add_ret
= lttng_dynamic_array_add_element(&raw_fds
, &raw_fd
);
496 fd_handle_put(handle
);
498 ret
= -LTTNG_ERR_NOMEM
;
504 ret
= lttcomm_send_fds_unix_sock(sock
, (const int *) raw_fds
.buffer
.data
, fd_count
);
506 ret
= lttcomm_send_fds_unix_sock_non_block(
507 sock
, (const int *) raw_fds
.buffer
.data
, fd_count
);
511 lttng_dynamic_array_reset(&raw_fds
);
515 ssize_t
lttcomm_send_payload_view_fds_unix_sock(int sock
, struct lttng_payload_view
*view
)
517 return _lttcomm_send_payload_view_fds_unix_sock(sock
, view
, true);
520 ssize_t
lttcomm_send_payload_view_fds_unix_sock_non_block(int sock
, struct lttng_payload_view
*view
)
522 return _lttcomm_send_payload_view_fds_unix_sock(sock
, view
, false);
526 * Send a message accompanied by fd(s) over a unix socket.
527 * Only use for non blocking socket.
529 * Returns the size of data sent, or negative error value.
531 ssize_t
lttcomm_send_fds_unix_sock_non_block(int sock
, const int *fds
, size_t nb_fd
)
534 struct cmsghdr
*cmptr
;
537 unsigned int sizeof_fds
= nb_fd
* sizeof(int);
538 char tmp
[CMSG_SPACE(sizeof_fds
)];
543 LTTNG_ASSERT(nb_fd
> 0);
545 memset(&msg
, 0, sizeof(msg
));
546 memset(tmp
, 0, sizeof(tmp
));
548 if (nb_fd
> LTTCOMM_MAX_SEND_FDS
)
551 msg
.msg_control
= (caddr_t
) tmp
;
552 msg
.msg_controllen
= CMSG_LEN(sizeof_fds
);
554 cmptr
= CMSG_FIRSTHDR(&msg
);
559 cmptr
->cmsg_level
= SOL_SOCKET
;
560 cmptr
->cmsg_type
= SCM_RIGHTS
;
561 cmptr
->cmsg_len
= CMSG_LEN(sizeof_fds
);
562 memcpy(CMSG_DATA(cmptr
), fds
, sizeof_fds
);
563 /* Sum of the length of all control messages in the buffer: */
564 msg
.msg_controllen
= cmptr
->cmsg_len
;
566 iov
[0].iov_base
= &dummy
;
572 ret
= sendmsg(sock
, &msg
, 0);
574 if (errno
== EINTR
) {
578 * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
581 DIAGNOSTIC_IGNORE_LOGICAL_OP
582 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
) {
585 * This can happen in non blocking mode.
592 if (errno
== EPIPE
) {
593 /* Expected error, pass error to caller */
594 DBG3("EPIPE on sendmsg");
599 /* Unexpected error */
611 * Recv a message accompanied by fd(s) from a unix socket.
613 * Returns the size of received data, or negative error value.
615 * Expect at most "nb_fd" file descriptors. Returns the number of fd
616 * actually received in nb_fd.
618 ssize_t
lttcomm_recv_fds_unix_sock(int sock
, int *fds
, size_t nb_fd
)
622 struct cmsghdr
*cmsg
;
623 size_t sizeof_fds
= nb_fd
* sizeof(int);
626 /* Account for the struct ucred cmsg in the buffer size */
627 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds) + CMSG_SPACE(sizeof(struct ucred))
629 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds)
630 #endif /* __linux__ */
632 char recv_buf
[LTTNG_SOCK_RECV_FDS_BUF_SIZE
];
638 LTTNG_ASSERT(nb_fd
> 0);
640 memset(&msg
, 0, sizeof(msg
));
642 /* Prepare to receive the structures */
643 iov
[0].iov_base
= &dummy
;
648 cmsg
= (struct cmsghdr
*) recv_buf
;
649 cmsg
->cmsg_len
= CMSG_LEN(sizeof_fds
);
650 cmsg
->cmsg_level
= SOL_SOCKET
;
651 cmsg
->cmsg_type
= SCM_RIGHTS
;
653 msg
.msg_control
= cmsg
;
654 msg
.msg_controllen
= CMSG_LEN(sizeof(recv_buf
));
658 ret
= lttng_recvmsg_nosigpipe(sock
, &msg
);
660 if (errno
== EINTR
) {
663 /* We consider EPIPE and EAGAIN as expected. */
664 if (!lttng_opt_quiet
&& (errno
!= EPIPE
&& errno
!= EAGAIN
)) {
672 fprintf(stderr
, "Error: Received %zd bytes, expected %d\n", ret
, 1);
676 if (msg
.msg_flags
& MSG_CTRUNC
) {
677 fprintf(stderr
, "Error: Control message truncated.\n");
683 * If the socket was configured with SO_PASSCRED, the kernel will add a
684 * control message (cmsg) to the ancillary data of the unix socket. We
685 * need to expect a cmsg of the SCM_CREDENTIALS as the first control
688 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
!= nullptr; cmsg
= CMSG_NXTHDR(&msg
, cmsg
)) {
689 if (cmsg
->cmsg_level
!= SOL_SOCKET
) {
690 fprintf(stderr
, "Error: The socket needs to be of type SOL_SOCKET\n");
694 if (cmsg
->cmsg_type
== SCM_RIGHTS
) {
696 * We found the controle message for file descriptors,
697 * now copy the fds to the fds ptr and return success.
699 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof_fds
)) {
701 "Error: Received %zu bytes of"
702 "ancillary data for FDs, expected %zu\n",
703 (size_t) cmsg
->cmsg_len
,
704 (size_t) CMSG_LEN(sizeof_fds
));
708 memcpy(fds
, CMSG_DATA(cmsg
), sizeof_fds
);
713 if (cmsg
->cmsg_type
== SCM_CREDENTIALS
) {
715 * Expect credentials to be sent when expecting fds even
716 * if no credential were include in the send(). The
717 * kernel adds them...
721 #endif /* __linux__ */
727 static void close_raw_fd(void *ptr
)
729 const int raw_fd
= *((const int *) ptr
);
732 const int ret
= close(raw_fd
);
735 PERROR("Failed to close file descriptor %d", raw_fd
);
740 static enum lttng_error_code
add_fds_to_payload(struct lttng_dynamic_array
*raw_fds
,
741 struct lttng_payload
*payload
)
744 enum lttng_error_code ret_code
= LTTNG_OK
;
745 const int fd_count
= lttng_dynamic_array_get_count(raw_fds
);
747 for (i
= 0; i
< fd_count
; i
++) {
749 struct fd_handle
*handle
;
750 int *raw_fd
= (int *) lttng_dynamic_array_get_element(raw_fds
, i
);
752 LTTNG_ASSERT(*raw_fd
!= -1);
754 handle
= fd_handle_create(*raw_fd
);
756 ret_code
= LTTNG_ERR_NOMEM
;
760 /* FD ownership transferred to the handle. */
763 ret
= lttng_payload_push_fd_handle(payload
, handle
);
764 fd_handle_put(handle
);
766 ret_code
= LTTNG_ERR_NOMEM
;
775 static ssize_t
_lttcomm_recv_payload_fds_unix_sock(int sock
,
777 struct lttng_payload
*payload
,
781 enum lttng_error_code add_ret
;
783 int default_value
= -1;
784 struct lttng_dynamic_array raw_fds
;
787 LTTNG_ASSERT(payload
);
788 LTTNG_ASSERT(nb_fd
> 0);
790 lttng_dynamic_array_init(&raw_fds
, sizeof(int), close_raw_fd
);
792 for (i
= 0; i
< nb_fd
; i
++) {
793 if (lttng_dynamic_array_add_element(&raw_fds
, &default_value
)) {
794 ret
= -LTTNG_ERR_NOMEM
;
800 ret
= lttcomm_recv_fds_unix_sock(sock
, (int *) raw_fds
.buffer
.data
, nb_fd
);
802 ret
= lttcomm_recv_fds_unix_sock_non_block(
803 sock
, (int *) raw_fds
.buffer
.data
, nb_fd
);
810 add_ret
= add_fds_to_payload(&raw_fds
, payload
);
811 if (add_ret
!= LTTNG_OK
) {
812 ret
= -(int) add_ret
;
817 lttng_dynamic_array_reset(&raw_fds
);
821 ssize_t
lttcomm_recv_payload_fds_unix_sock(int sock
, size_t nb_fd
, struct lttng_payload
*payload
)
823 return _lttcomm_recv_payload_fds_unix_sock(sock
, nb_fd
, payload
, true);
827 lttcomm_recv_payload_fds_unix_sock_non_block(int sock
, size_t nb_fd
, struct lttng_payload
*payload
)
829 return _lttcomm_recv_payload_fds_unix_sock(sock
, nb_fd
, payload
, false);
833 * Recv a message accompanied by fd(s) from a non-blocking unix socket.
834 * Only use with non-blocking sockets.
836 * Returns the size of received data, or negative error value.
838 * Expect at most "nb_fd" file descriptors.
840 * Note that based on our comprehension, partial reception of fds is not
841 * possible since the FDs are actually in the control message. It is all or
842 * nothing, still the sender side can send the wrong number of fds.
844 ssize_t
lttcomm_recv_fds_unix_sock_non_block(int sock
, int *fds
, size_t nb_fd
)
848 struct cmsghdr
*cmsg
;
849 size_t sizeof_fds
= nb_fd
* sizeof(int);
853 LTTNG_ASSERT(nb_fd
> 0);
856 /* Account for the struct ucred cmsg in the buffer size */
857 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds) + CMSG_SPACE(sizeof(struct ucred))
859 #define LTTNG_SOCK_RECV_FDS_BUF_SIZE CMSG_SPACE(sizeof_fds)
860 #endif /* __linux__ */
862 char recv_buf
[LTTNG_SOCK_RECV_FDS_BUF_SIZE
];
866 memset(&msg
, 0, sizeof(msg
));
868 /* Prepare to receive the structures */
869 iov
[0].iov_base
= &dummy
;
874 cmsg
= (struct cmsghdr
*) recv_buf
;
875 cmsg
->cmsg_len
= CMSG_LEN(sizeof_fds
);
876 cmsg
->cmsg_level
= SOL_SOCKET
;
877 cmsg
->cmsg_type
= SCM_RIGHTS
;
879 msg
.msg_control
= cmsg
;
880 msg
.msg_controllen
= CMSG_LEN(sizeof(recv_buf
));
884 ret
= lttng_recvmsg_nosigpipe(sock
, &msg
);
886 if (errno
== EINTR
) {
890 * We consider EPIPE and EAGAIN/EWOULDBLOCK as expected.
893 DIAGNOSTIC_IGNORE_LOGICAL_OP
894 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
) {
897 * This can happen in non blocking mode.
904 if (errno
== EPIPE
) {
905 /* Expected error, pass error to caller */
906 DBG3("EPIPE on recvmsg");
911 /* Unexpected error */
919 fprintf(stderr
, "Error: Received %zd bytes, expected %d\n", ret
, 1);
923 if (msg
.msg_flags
& MSG_CTRUNC
) {
924 fprintf(stderr
, "Error: Control message truncated.\n");
930 * If the socket was configured with SO_PASSCRED, the kernel will add a
931 * control message (cmsg) to the ancillary data of the unix socket. We
932 * need to expect a cmsg of the SCM_CREDENTIALS as the first control
935 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
!= nullptr; cmsg
= CMSG_NXTHDR(&msg
, cmsg
)) {
936 if (cmsg
->cmsg_level
!= SOL_SOCKET
) {
937 fprintf(stderr
, "Error: The socket needs to be of type SOL_SOCKET\n");
941 if (cmsg
->cmsg_type
== SCM_RIGHTS
) {
943 * We found the controle message for file descriptors,
944 * now copy the fds to the fds ptr and return success.
946 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof_fds
)) {
948 "Error: Received %zu bytes of"
949 "ancillary data for FDs, expected %zu\n",
950 (size_t) cmsg
->cmsg_len
,
951 (size_t) CMSG_LEN(sizeof_fds
));
955 memcpy(fds
, CMSG_DATA(cmsg
), sizeof_fds
);
960 if (cmsg
->cmsg_type
== SCM_CREDENTIALS
) {
962 * Expect credentials to be sent when expecting fds even
963 * if no credential were include in the send(). The
964 * kernel adds them...
968 #endif /* __linux__ */
975 * Send a message with credentials over a unix socket.
977 * Returns the size of data sent, or negative error value.
979 ssize_t
lttcomm_send_creds_unix_sock(int sock
, const void *buf
, size_t len
)
984 #if defined(__linux__) || defined(__CYGWIN__)
985 struct cmsghdr
*cmptr
;
986 size_t sizeof_cred
= sizeof(lttng_sock_cred
);
987 char anc_buf
[CMSG_SPACE(sizeof_cred
)];
988 lttng_sock_cred
*creds
;
990 memset(anc_buf
, 0, CMSG_SPACE(sizeof_cred
) * sizeof(char));
991 #endif /* __linux__, __CYGWIN__ */
993 memset(&msg
, 0, sizeof(msg
));
997 LTTNG_ASSERT(len
> 0);
999 iov
[0].iov_base
= (void *) buf
;
1000 iov
[0].iov_len
= len
;
1004 #if defined(__linux__) || defined(__CYGWIN__)
1005 msg
.msg_control
= (caddr_t
) anc_buf
;
1006 msg
.msg_controllen
= CMSG_LEN(sizeof_cred
);
1008 cmptr
= CMSG_FIRSTHDR(&msg
);
1012 cmptr
->cmsg_level
= SOL_SOCKET
;
1013 cmptr
->cmsg_type
= LTTNG_SOCK_CREDS
;
1014 cmptr
->cmsg_len
= CMSG_LEN(sizeof_cred
);
1016 creds
= (lttng_sock_cred
*) CMSG_DATA(cmptr
);
1018 LTTNG_SOCK_SET_UID_CRED(creds
, geteuid());
1019 LTTNG_SOCK_SET_GID_CRED(creds
, getegid());
1020 LTTNG_SOCK_SET_PID_CRED(creds
, getpid());
1021 #endif /* __linux__, __CYGWIN__ */
1024 ret
= sendmsg(sock
, &msg
, 0);
1025 } while (ret
< 0 && errno
== EINTR
);
1028 * Only warn about EPIPE when quiet mode is deactivated.
1029 * We consider EPIPE as expected.
1031 if (errno
!= EPIPE
|| !lttng_opt_quiet
) {
1039 * Recv a message accompanied with credentials from a unix socket.
1041 * Returns the size of received data, or negative error value.
1043 ssize_t
lttcomm_recv_creds_unix_sock(int sock
, void *buf
, size_t len
, lttng_sock_cred
*creds
)
1046 struct iovec iov
[1];
1049 #if defined(__linux__) || defined(__CYGWIN__)
1050 struct cmsghdr
*cmptr
;
1051 size_t sizeof_cred
= sizeof(lttng_sock_cred
);
1052 char anc_buf
[CMSG_SPACE(sizeof_cred
)];
1053 #endif /* __linux__, __CYGWIN__ */
1057 LTTNG_ASSERT(len
> 0);
1058 LTTNG_ASSERT(creds
);
1060 memset(&msg
, 0, sizeof(msg
));
1062 /* Prepare to receive the structures */
1063 iov
[0].iov_base
= buf
;
1064 iov
[0].iov_len
= len
;
1068 #if defined(__linux__) || defined(__CYGWIN__)
1069 msg
.msg_control
= anc_buf
;
1070 msg
.msg_controllen
= sizeof(anc_buf
);
1071 #endif /* __linux__, __CYGWIN__ */
1074 len_last
= iov
[0].iov_len
;
1075 ret
= recvmsg(sock
, &msg
, 0);
1077 iov
[0].iov_base
= (char *) iov
[0].iov_base
+ ret
;
1078 iov
[0].iov_len
-= ret
;
1079 LTTNG_ASSERT(ret
<= len_last
);
1081 } while ((ret
> 0 && ret
< len_last
) || (ret
< 0 && errno
== EINTR
));
1083 PERROR("recvmsg fds");
1085 } else if (ret
> 0) {
1088 /* Else ret = 0 meaning an orderly shutdown. */
1090 #if defined(__linux__) || defined(__CYGWIN__)
1091 if (msg
.msg_flags
& MSG_CTRUNC
) {
1092 fprintf(stderr
, "Error: Control message truncated.\n");
1097 cmptr
= CMSG_FIRSTHDR(&msg
);
1098 if (cmptr
== nullptr) {
1099 fprintf(stderr
, "Error: Invalid control message header\n");
1104 if (cmptr
->cmsg_level
!= SOL_SOCKET
|| cmptr
->cmsg_type
!= LTTNG_SOCK_CREDS
) {
1105 fprintf(stderr
, "Didn't received any credentials\n");
1110 if (cmptr
->cmsg_len
!= CMSG_LEN(sizeof_cred
)) {
1112 "Error: Received %zu bytes of ancillary data, expected %zu\n",
1113 (size_t) cmptr
->cmsg_len
,
1114 (size_t) CMSG_LEN(sizeof_cred
));
1119 memcpy(creds
, CMSG_DATA(cmptr
), sizeof_cred
);
1120 #elif (defined(__FreeBSD__) || defined(__sun__) || defined(__APPLE__))
1121 if (lttng_get_unix_socket_peer_creds(sock
, creds
)) {
1122 fprintf(stderr
, "ARG\n");
1127 #error "Please implement credential support for your OS."
1128 #endif /* __linux__, __CYGWIN__ */
1135 * Set socket option to use credentials passing.
1137 #if defined(__linux__) || defined(__CYGWIN__)
1138 int lttcomm_setsockopt_creds_unix_sock(int sock
)
1142 /* Set socket for credentials retrieval */
1143 ret
= setsockopt(sock
, SOL_SOCKET
, SO_PASSCRED
, &on
, sizeof(on
));
1145 PERROR("setsockopt creds unix sock");
1149 #elif (defined(__FreeBSD__) || defined(__sun__) || defined(__APPLE__))
1150 int lttcomm_setsockopt_creds_unix_sock(int sock
__attribute__((unused
)))
1155 #error "Please implement credential support for your OS."
1156 #endif /* __linux__ */