2 * daemon-messages.c: Communications to and from the handle daemon
5 * Dick Porter (dick@ximian.com)
7 * (C) 2002 Ximian, Inc.
16 #ifndef HAVE_MSG_NOSIGNAL
20 #include <mono/io-layer/wapi.h>
21 #include <mono/io-layer/daemon-messages.h>
23 /* Send request on fd, wait for response (called by applications, not
24 * the daemon, indirectly through _wapi_daemon_request_response and
25 * _wapi_daemon_request_response_with_fds)
27 static void _wapi_daemon_request_response_internal (int fd,
29 WapiHandleResponse *resp)
31 static pthread_mutex_t req_mutex=PTHREAD_MUTEX_INITIALIZER;
33 #ifndef HAVE_MSG_NOSIGNAL
34 void (*old_sigpipe)(int);
37 /* Serialise requests to the daemon from the same process. We
38 * rely on request turnaround time being minimal anyway, so
39 * performance shouldnt suffer from the mutex.
41 pthread_mutex_lock (&req_mutex);
43 #ifdef HAVE_MSG_NOSIGNAL
44 ret=sendmsg (fd, msg, MSG_NOSIGNAL);
46 old_sigpipe = signal (SIGPIPE, SIG_IGN);
47 ret=sendmsg (fd, msg, 0);
49 if(ret!=sizeof(WapiHandleRequest)) {
51 g_critical (G_GNUC_PRETTY_FUNCTION ": The handle daemon vanished!");
54 g_warning (G_GNUC_PRETTY_FUNCTION ": Send error: %s",
56 g_assert_not_reached ();
60 #ifdef HAVE_MSG_NOSIGNAL
61 ret=recv (fd, resp, sizeof(WapiHandleResponse), MSG_NOSIGNAL);
63 ret=recv (fd, resp, sizeof(WapiHandleResponse), 0);
64 signal (SIGPIPE, old_sigpipe);
68 g_critical (G_GNUC_PRETTY_FUNCTION ": The handle daemon vanished!");
71 g_warning (G_GNUC_PRETTY_FUNCTION ": Send error: %s",
73 g_assert_not_reached ();
77 pthread_mutex_unlock (&req_mutex);
80 /* Send request on fd with filedescriptors, wait for response (called
81 * by applications, not the daemon)
83 void _wapi_daemon_request_response_with_fds (int fd, WapiHandleRequest *req,
84 WapiHandleResponse *resp,
85 int in_fd, int out_fd, int err_fd)
87 struct msghdr msg={0};
90 char cmsgdata[CMSG_SPACE (sizeof(int)*3)];
97 msg.msg_control=cmsgdata;
98 msg.msg_controllen=sizeof(cmsgdata);
102 iov.iov_len=sizeof(WapiHandleRequest);
104 cmsg=CMSG_FIRSTHDR (&msg);
105 cmsg->cmsg_len=CMSG_LEN (sizeof(int)*3);
106 cmsg->cmsg_level=SOL_SOCKET;
107 cmsg->cmsg_type=SCM_RIGHTS;
108 fdptr=(int *)CMSG_DATA (cmsg);
113 msg.msg_controllen=CMSG_SPACE (sizeof(int)*3);
115 _wapi_daemon_request_response_internal (fd, &msg, resp);
118 /* Send request on fd, wait for response (called by applications, not
121 void _wapi_daemon_request_response (int fd, WapiHandleRequest *req,
122 WapiHandleResponse *resp)
124 struct msghdr msg={0};
131 msg.msg_control=NULL;
132 msg.msg_controllen=0;
136 iov.iov_len=sizeof(WapiHandleRequest);
138 _wapi_daemon_request_response_internal (fd, &msg, resp);
141 /* Read request on fd (called by the daemon) */
142 void _wapi_daemon_request (int fd, WapiHandleRequest *req, int *fds,
148 struct cmsghdr *cmsg;
149 guchar cmsgdata[CMSG_SPACE (sizeof(int)*3)];
155 msg.msg_control=cmsgdata;
156 msg.msg_controllen=sizeof(cmsgdata);
159 iov.iov_len=sizeof(WapiHandleRequest);
161 #ifdef HAVE_MSG_NOSIGNAL
162 ret=recvmsg (fd, &msg, MSG_NOSIGNAL);
164 ret=recvmsg (fd, &msg, MSG_NOSIGNAL);
166 if(ret==-1 || ret!= sizeof(WapiHandleRequest)) {
167 /* Make sure we dont do anything with this response */
168 req->type=WapiHandleRequestType_Error;
171 g_warning (G_GNUC_PRETTY_FUNCTION ": Recv error: %s",
174 /* The next loop around poll() should tidy up */
178 if(msg.msg_flags & MSG_OOB) {
179 g_message (G_GNUC_PRETTY_FUNCTION ": OOB data received");
181 if(msg.msg_flags & MSG_CTRUNC) {
182 g_message (G_GNUC_PRETTY_FUNCTION ": ancillary data was truncated");
184 g_message (G_GNUC_PRETTY_FUNCTION ": msg.msg_controllen=%d",
188 cmsg=CMSG_FIRSTHDR (&msg);
189 if(cmsg!=NULL && cmsg->cmsg_level==SOL_SOCKET &&
190 cmsg->cmsg_type==SCM_RIGHTS) {
192 g_message (G_GNUC_PRETTY_FUNCTION ": cmsg->cmsg_len=%d",
194 g_message (G_GNUC_PRETTY_FUNCTION
195 ": cmsg->level=%d cmsg->type=%d", cmsg->cmsg_level,
199 memcpy (fds, (int *)CMSG_DATA (cmsg), sizeof(int)*3);
203 g_message (G_GNUC_PRETTY_FUNCTION
204 ": fd[0]=%d, fd[1]=%d, fd[2]=%d", fds[0], fds[1],
209 g_message (G_GNUC_PRETTY_FUNCTION ": no ancillary data");
215 /* Send response on fd (called by the daemon) */
216 void _wapi_daemon_response (int fd, WapiHandleResponse *resp)
220 #ifdef HAVE_MSG_NOSIGNAL
221 ret=send (fd, resp, sizeof(WapiHandleResponse), MSG_NOSIGNAL);
223 ret=send (fd, resp, sizeof(WapiHandleResponse), 0);
226 if(ret==-1 || ret != sizeof(WapiHandleResponse)) {
227 g_warning (G_GNUC_PRETTY_FUNCTION ": Send error: %s",
229 /* The next loop around poll() should tidy up */