Do not link rxvtc to ev_cpp.o, it does not use libev.
[dana/urxvt.git] / src / fdpass.C
1 // This file is part of libptytty. Do not make local modifications.
2 // http://software.schmorp.de/pkg/libptytty
3
4 /*----------------------------------------------------------------------*
5  * File:        fdpass.C
6  *----------------------------------------------------------------------*
7  *
8  * All portions of code are copyright by their respective author/s.
9  * Copyright (c) 2005-2006 Marc Lehmann <pcg@goof.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *----------------------------------------------------------------------*/
25
26 #include "../config.h"
27
28 #include <cstddef> // needed by broken bsds for NULL used in sys/uio.h
29 #include <cstdlib>
30
31 #include <sys/types.h>
32 #include <sys/uio.h>
33 #include <sys/socket.h>
34
35 #include "libptytty.h"
36
37 // CMSG_SPACE & CMSG_LEN are rfc2292 extensions to unix
38 #ifndef CMSG_SPACE
39 # define CMSG_SPACE(len) (sizeof (cmsghdr) + len)
40 #endif
41
42 #ifndef CMSG_LEN
43 # define CMSG_LEN(len) (sizeof (cmsghdr) + len)
44 #endif
45
46 bool
47 ptytty::send_fd (int socket, int fd)
48 {
49   void *buf = malloc (CMSG_SPACE (sizeof (int)));
50
51   if (!buf)
52     return 0;
53
54   msghdr msg;
55   iovec iov;
56   cmsghdr *cmsg;
57   char data = 0;
58
59   iov.iov_base = &data;
60   iov.iov_len  = 1;
61
62   msg.msg_name       = 0;
63   msg.msg_namelen    = 0;
64   msg.msg_iov        = &iov;
65   msg.msg_iovlen     = 1;
66   msg.msg_control    = buf;
67   msg.msg_controllen = CMSG_SPACE (sizeof (int));
68
69   cmsg = CMSG_FIRSTHDR (&msg);
70   cmsg->cmsg_level = SOL_SOCKET;
71   cmsg->cmsg_type  = SCM_RIGHTS;
72   cmsg->cmsg_len   = CMSG_LEN (sizeof (int));
73
74   *(int *)CMSG_DATA (cmsg) = fd;
75
76   ssize_t result = sendmsg (socket, &msg, 0);
77
78   free (buf);
79
80   return result >= 0;
81 }
82
83 int
84 ptytty::recv_fd (int socket)
85 {
86   void *buf = malloc (CMSG_SPACE (sizeof (int)));
87
88   if (!buf)
89     return -1;
90
91   msghdr msg;
92   iovec iov;
93   char data = 1;
94
95   iov.iov_base = &data;
96   iov.iov_len  = 1;
97
98   msg.msg_name       = 0;
99   msg.msg_namelen    = 0;
100   msg.msg_iov        = &iov;
101   msg.msg_iovlen     = 1;
102   msg.msg_control    = buf;
103   msg.msg_controllen = CMSG_SPACE (sizeof (int));
104
105   int fd = -1;
106
107   if (recvmsg (socket, &msg, 0) >  0
108       && data                   == 0
109       && msg.msg_controllen     >= CMSG_SPACE (sizeof (int)))
110     {
111       cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
112
113       if (cmsg->cmsg_level   == SOL_SOCKET
114           && cmsg->cmsg_type == SCM_RIGHTS
115           && cmsg->cmsg_len  >= CMSG_LEN (sizeof (int)))
116         fd = *(int *)CMSG_DATA (cmsg);
117     }
118
119   free (buf);
120
121   return fd;
122 }
123