ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/IO-FDPass/FDPass.xs
(Generate patch)

Comparing IO-FDPass/FDPass.xs (file contents):
Revision 1.3 by root, Fri Apr 5 04:32:50 2013 UTC vs.
Revision 1.6 by root, Fri Oct 31 07:09:43 2014 UTC

17 17
18 #include <windows.h> 18 #include <windows.h>
19 #include <io.h> 19 #include <io.h>
20 #include <sys/cygwin.h> 20 #include <sys/cygwin.h>
21 21
22 #define ioctlsocket(a,b,c) ioctl (a, b, c)
23 #define _open_osfhandle(h,m) cygwin_attach_handle_to_fd ("/dev/pipe", -1, (HANDLE)h, 1, GENERIC_READ | GENERIC_WRITE) 22 #define _open_osfhandle(h,m) cygwin_attach_handle_to_fd ("/dev/tcp", -1, (HANDLE)h, 1, GENERIC_READ | GENERIC_WRITE)
24 typedef int SOCKET; 23 typedef int SOCKET;
25 24
26#else 25#else
27 26
28 #include <stddef.h> // needed by broken bsds for NULL used in sys/uio.h 27 #include <stddef.h> // needed by broken bsds for NULL used in sys/uio.h
55 int got = 0; 54 int got = 0;
56 55
57 while (got != len) 56 while (got != len)
58 { 57 {
59 int sze = wr 58 int sze = wr
60 ? send ((SOCKET)fd, buf, len, 0) /* we assume send and recv are macros with arguments */ 59 ? send ((SOCKET)fd, buf, len - got, 0) /* we assume send and recv are macros with arguments */
61 : recv ((SOCKET)fd, buf, len, 0); /* to be on the safe side */ 60 : recv ((SOCKET)fd, buf, len - got, 0); /* to be on the safe side */
62 61
63 if (sze <= 0) 62 if (sze < 0)
64 { 63 {
65 if (errno == EAGAIN || errno == WSAEWOULDBLOCK) 64 if (errno == EAGAIN || errno == WSAEWOULDBLOCK)
66 { 65 {
67 ioctlsocket (fd, FIONBIO, &nbio); 66 ioctl (fd, FIONBIO, (void *)&nbio);
68 nbio = 1; 67 nbio = 1;
69 } 68 }
70 else 69 else
71 break; 70 break;
72 } 71 }
72 else if (sze == 0)
73 break;
73 else 74 else
74 got += sze; 75 got += sze;
75 } 76 }
76 77
77 if (nbio) 78 if (nbio)
78 ioctlsocket (fd, FIONBIO, &nbio); 79 ioctl (fd, FIONBIO, (void *)&nbio);
79 80
80 return got == len; 81 return got == len;
81} 82}
82#endif 83#endif
83 84
84static int 85static int
85fd_send (int socket, int fd) 86fd_send (int socket, int fd)
86{ 87{
87#if defined(WIN32) 88#if defined(WIN32)
88 DWORD pid; 89 DWORD pid;
89 HANDLE target, h; 90 HANDLE hdl;
91
92 pid = GetCurrentProcessId ();
90 93
91 /* seriously, there is no way to query whether a socket is non-blocking?? */
92 if (!rw (0, socket, (char *)&pid, sizeof (pid))) 94 if (!rw (1, socket, (char *)&pid, sizeof (pid)))
93 return 0; 95 return 0;
94 96
95 target = OpenProcess (PROCESS_DUP_HANDLE, FALSE, pid); 97 errno = EBADF;
96 if (!target)
97 croak ("AnyEvent::ProcessPool::fd_recv: OpenProcess failed");
98
99 if (!DuplicateHandle ((HANDLE)-1, (HANDLE)_get_osfhandle (fd), target, &h, 0, FALSE, DUPLICATE_SAME_ACCESS)) 98 if (!DuplicateHandle ((HANDLE)-1, (HANDLE)_get_osfhandle (fd), (HANDLE)-1, &hdl, 0, FALSE, DUPLICATE_SAME_ACCESS))
100 croak ("AnyEvent::ProcessPool::fd_recv: DuplicateHandle failed");
101
102 CloseHandle (target);
103
104 if (!rw (1, socket, (char *)&h , sizeof (h )))
105 return 0; 99 return 0;
100
101 if (!rw (1, socket, (char *)&hdl, sizeof (hdl)))
102 {
103 CloseHandle (hdl);
104 return 0;
105 }
106 106
107 return 1; 107 return 1;
108 108
109#else 109#else
110 void *buf = malloc (CMSG_SPACE (sizeof (int))); 110 void *buf = malloc (CMSG_SPACE (sizeof (int)));
144 144
145static int 145static int
146fd_recv (int socket) 146fd_recv (int socket)
147{ 147{
148#if defined(WIN32) 148#if defined(WIN32)
149 DWORD pid = GetCurrentProcessId (); 149 DWORD pid;
150 HANDLE h; 150 HANDLE source, rhd, lhd;
151 151
152 if (!rw (1, socket, (char *)&pid, sizeof (pid))) 152 if (!rw (0, socket, (char *)&pid, sizeof (pid)))
153 return -1; 153 return -1;
154 154
155 if (!rw (0, socket, (char *)&h , sizeof (h ))) 155 if (!rw (0, socket, (char *)&rhd, sizeof (rhd)))
156 return -1; 156 return -1;
157 157
158 source = OpenProcess (PROCESS_DUP_HANDLE, FALSE, pid);
159 errno = EACCES;
160 if (!source)
161 return -1;
162
163 pid = DuplicateHandle (source, rhd, (HANDLE)-1, &lhd,
164 0, FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
165
166 CloseHandle (source);
167
168 errno = EBADF;
169 if (!pid)
170 return -1;
171
158 return _open_osfhandle ((intptr_t)h, 0); 172 return _open_osfhandle ((intptr_t)lhd, 0);
159#else 173#else
160 void *buf = malloc (CMSG_SPACE (sizeof (int))); 174 void *buf = malloc (CMSG_SPACE (sizeof (int)));
161 175
162 if (!buf) 176 if (!buf)
163 return -1; 177 return -1;
178 192
179 if (recvmsg (socket, &msg, 0) <= 0) 193 if (recvmsg (socket, &msg, 0) <= 0)
180 return -1; 194 return -1;
181 195
182 int fd = -1; 196 int fd = -1;
183
184 errno = EDOM; 197 errno = EDOM;
185 198
186 if (
187 data == 0
188#if __OpenBSD__
189 && msg.msg_controllen >= CMSG_LEN (sizeof (int)) /* work around a bug in at least openbsd 4.5 and 4.8 */
190#else
191 && msg.msg_controllen >= CMSG_SPACE (sizeof (int))
192#endif
193 ) {
194 struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg); 199 struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
195 200
201 if (data == 0
202 && cmsg
196 if (cmsg->cmsg_level == SOL_SOCKET 203 && cmsg->cmsg_level == SOL_SOCKET
197 && cmsg->cmsg_type == SCM_RIGHTS 204 && cmsg->cmsg_type == SCM_RIGHTS
198 && cmsg->cmsg_len >= CMSG_LEN (sizeof (int))) 205 && cmsg->cmsg_len >= CMSG_LEN (sizeof (int)))
199 fd = *(int *)CMSG_DATA (cmsg); 206 fd = *(int *)CMSG_DATA (cmsg);
200 }
201 207
202 free (buf); 208 free (buf);
203 209
204 return fd; 210 return fd;
205#endif 211#endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines