Sync ax_have_epoll.m4 with autoconf-archive
[lttng-tools.git] / src / common / compat / socket.h
CommitLineData
b17231c6
DG
1/*
2 * Copyright (C) 2011 - David Goulet <dgoulet@efficios.com>
3 *
d14d33bf
AM
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
b17231c6
DG
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
d14d33bf
AM
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
b17231c6
DG
16 */
17
18#ifndef _COMPAT_SOCKET_H
19#define _COMPAT_SOCKET_H
20
21#include <sys/socket.h>
22#include <sys/un.h>
23
24#include <common/macros.h>
25
fbb1fd3a
MJ
26#ifndef MSG_NOSIGNAL
27# ifdef SO_NOSIGPIPE
28# define MSG_NOSIGNAL SO_NOSIGPIPE
29# endif
30#endif
31
32#if defined(MSG_NOSIGNAL)
33static inline
34ssize_t lttng_recvmsg_nosigpipe(int sockfd, struct msghdr *msg)
35{
36 return recvmsg(sockfd, msg, MSG_NOSIGNAL);
37}
38#else
39
40#include <signal.h>
41#include <errno.h>
42
43static inline
44ssize_t lttng_recvmsg_nosigpipe(int sockfd, struct msghdr *msg)
45{
46 ssize_t received;
47 int saved_err;
48 sigset_t sigpipe_set, pending_set, old_set;
49 int sigpipe_was_pending;
50
51 /*
52 * Discard the SIGPIPE from send(), not disturbing any SIGPIPE
53 * that might be already pending. If a bogus SIGPIPE is sent to
54 * the entire process concurrently by a malicious user, it may
55 * be simply discarded.
56 */
57 if (sigemptyset(&pending_set)) {
58 return -1;
59 }
60 /*
61 * sigpending returns the mask of signals that are _both_
62 * blocked for the thread _and_ pending for either the thread or
63 * the entire process.
64 */
65 if (sigpending(&pending_set)) {
66 return -1;
67 }
68 sigpipe_was_pending = sigismember(&pending_set, SIGPIPE);
69 /*
70 * If sigpipe was pending, it means it was already blocked, so
71 * no need to block it.
72 */
73 if (!sigpipe_was_pending) {
74 if (sigemptyset(&sigpipe_set)) {
75 return -1;
76 }
77 if (sigaddset(&sigpipe_set, SIGPIPE)) {
78 return -1;
79 }
80 if (pthread_sigmask(SIG_BLOCK, &sigpipe_set, &old_set)) {
81 return -1;
82 }
83 }
84
85 /* Send and save errno. */
86 received = recvmsg(sockfd, msg, 0);
87 saved_err = errno;
88
89 if (received == -1 && errno == EPIPE && !sigpipe_was_pending) {
90 struct timespec timeout = { 0, 0 };
91 int ret;
92
93 do {
94 ret = sigtimedwait(&sigpipe_set, NULL,
95 &timeout);
96 } while (ret == -1 && errno == EINTR);
97 }
98 if (!sigpipe_was_pending) {
99 if (pthread_sigmask(SIG_SETMASK, &old_set, NULL)) {
100 return -1;
101 }
102 }
103 /* Restore send() errno */
104 errno = saved_err;
105
106 return received;
107}
108#endif
109
110
b17231c6
DG
111#ifdef __linux__
112
113#define LTTNG_SOCK_CREDS SCM_CREDENTIALS
b17231c6
DG
114
115typedef struct ucred lttng_sock_cred;
116
1268b9d6
DG
117#define LTTNG_SOCK_SET_UID_CRED(c, u) LTTNG_REF(c)->uid = u
118#define LTTNG_SOCK_SET_GID_CRED(c, g) LTTNG_REF(c)->gid = g
119#define LTTNG_SOCK_SET_PID_CRED(c, p) LTTNG_REF(c)->pid = p
120
121#define LTTNG_SOCK_GET_UID_CRED(c) LTTNG_REF(c)->uid
122#define LTTNG_SOCK_GET_GID_CRED(c) LTTNG_REF(c)->gid
123#define LTTNG_SOCK_GET_PID_CRED(c) LTTNG_REF(c)->pid
b17231c6 124
d05d6fe1 125#elif (defined(__FreeBSD__) || defined(__CYGWIN__) || defined(__sun__) || defined(__APPLE__))
b17231c6 126
d27c42b8
MD
127struct lttng_sock_cred {
128 uid_t uid;
129 gid_t gid;
130};
b17231c6 131
d27c42b8 132typedef struct lttng_sock_cred lttng_sock_cred;
b17231c6 133
d27c42b8
MD
134#define LTTNG_SOCK_GET_UID_CRED(c) LTTNG_REF(c)->uid
135#define LTTNG_SOCK_GET_GID_CRED(c) LTTNG_REF(c)->gid
136#define LTTNG_SOCK_GET_PID_CRED(c) -1
b17231c6
DG
137
138#else
7657ae75 139#error "Please add support for your OS."
b17231c6
DG
140#endif /* __linux__ , __FreeBSD__ */
141
28105b32
MJ
142
143#ifdef __sun__
144
145# ifndef CMSG_ALIGN
146# ifdef _CMSG_DATA_ALIGN
147# define CMSG_ALIGN(len) _CMSG_DATA_ALIGN(len)
148# else
149 /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
150# define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & ~(sizeof (long) - 1))
151# endif
152# ifndef CMSG_SPACE
153# define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + CMSG_ALIGN (len))
154# endif
155# ifndef CMSG_LEN
156# define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
157# endif
158# endif
159
160
161#include <ucred.h>
11a2fd46
MJ
162
163static inline
164int getpeereid(int s, uid_t *euid, gid_t *gid)
28105b32
MJ
165{
166 int ret = 0;
167 ucred_t *ucred = NULL;
168
169 ret = getpeerucred(s, &ucred);
170 if (ret == -1) {
171 goto end;
172 }
173
174 ret = ucred_geteuid(ucred);
175 if (ret == -1) {
176 goto free;
177 }
178 *euid = ret;
179
180 ret = ucred_getrgid(ucred);
181 if (ret == -1) {
182 goto free;
183 }
184 *gid = ret;
185 ret = 0;
186free:
187 ucred_free(ucred);
188end:
189 return ret;
190}
191
192#endif /* __sun__ */
193
b17231c6 194#endif /* _COMPAT_SOCKET_H */
This page took 0.052892 seconds and 4 git commands to generate.