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.2 by root, Fri Apr 5 04:26:41 2013 UTC vs.
Revision 1.5 by root, Fri Apr 5 08:20:36 2013 UTC

1/* GetCurrentProcessId is XP and up, which means in all supported versions */
2/* but older SDK's might need this */
3#define _WIN32_WINNT NTDDI_WINXP
4
5#ifdef __sun 1#ifdef __sun
6 #define _XOPEN_SOURCE 1 2 #define _XOPEN_SOURCE 1
7 #define _XOPEN_SOURCE_EXTENDED 1 3 #define _XOPEN_SOURCE_EXTENDED 1
8 #define __EXTENSIONS__ 1 4 #define __EXTENSIONS__ 1
9#endif 5#endif
21 17
22 #include <windows.h> 18 #include <windows.h>
23 #include <io.h> 19 #include <io.h>
24 #include <sys/cygwin.h> 20 #include <sys/cygwin.h>
25 21
26 #define ioctlsocket(a,b,c) ioctl (a, b, c)
27 #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)
28 typedef int SOCKET; 23 typedef int SOCKET;
29 24
30#else 25#else
31 26
32 #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
59 int got = 0; 54 int got = 0;
60 55
61 while (got != len) 56 while (got != len)
62 { 57 {
63 int sze = wr 58 int sze = wr
64 ? 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 */
65 : 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 */
66 61
67 if (sze <= 0) 62 if (sze < 0)
68 { 63 {
69 if (errno == EAGAIN || errno == WSAEWOULDBLOCK) 64 if (errno == EAGAIN || errno == WSAEWOULDBLOCK)
70 { 65 {
71 ioctlsocket (fd, FIONBIO, &nbio); 66 ioctl (fd, FIONBIO, (void *)&nbio);
72 nbio = 1; 67 nbio = 1;
73 } 68 }
74 else 69 else
75 break; 70 break;
76 } 71 }
72 else if (sze == 0)
73 break;
77 else 74 else
78 got += sze; 75 got += sze;
79 } 76 }
80 77
81 if (nbio) 78 if (nbio)
82 ioctlsocket (fd, FIONBIO, &nbio); 79 ioctl (fd, FIONBIO, (void *)&nbio);
83 80
84 return got == len; 81 return got == len;
85} 82}
86#endif 83#endif
87 84
88static int 85static int
89fd_send (int socket, int fd) 86fd_send (int socket, int fd)
90{ 87{
91#if defined(WIN32) 88#if defined(WIN32)
92 DWORD pid; 89 DWORD pid;
93 HANDLE target, h; 90 HANDLE hdl;
91
92 pid = GetCurrentProcessId ();
94 93
95 /* seriously, there is no way to query whether a socket is non-blocking?? */
96 if (!rw (0, socket, (char *)&pid, sizeof (pid))) 94 if (!rw (1, socket, (char *)&pid, sizeof (pid)))
97 return 0; 95 return 0;
98 96
99 target = OpenProcess (PROCESS_DUP_HANDLE, FALSE, pid); 97 errno = EBADF;
100 if (!target)
101 croak ("AnyEvent::ProcessPool::fd_recv: OpenProcess failed");
102
103 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))
104 croak ("AnyEvent::ProcessPool::fd_recv: DuplicateHandle failed");
105
106 CloseHandle (target);
107
108 if (!rw (1, socket, (char *)&h , sizeof (h )))
109 return 0; 99 return 0;
100
101 if (!rw (1, socket, (char *)&hdl, sizeof (hdl)))
102 {
103 CloseHandle (hdl);
104 return 0;
105 }
110 106
111 return 1; 107 return 1;
112 108
113#else 109#else
114 void *buf = malloc (CMSG_SPACE (sizeof (int))); 110 void *buf = malloc (CMSG_SPACE (sizeof (int)));
148 144
149static int 145static int
150fd_recv (int socket) 146fd_recv (int socket)
151{ 147{
152#if defined(WIN32) 148#if defined(WIN32)
153 DWORD pid = GetCurrentProcessId (); 149 DWORD pid;
154 HANDLE h; 150 HANDLE source, rhd, lhd;
155 151
156 if (!rw (1, socket, (char *)&pid, sizeof (pid))) 152 if (!rw (0, socket, (char *)&pid, sizeof (pid)))
157 return -1; 153 return -1;
158 154
159 if (!rw (0, socket, (char *)&h , sizeof (h ))) 155 if (!rw (0, socket, (char *)&rhd, sizeof (rhd)))
160 return -1; 156 return -1;
161 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
162 return _open_osfhandle ((intptr_t)h, 0); 172 return _open_osfhandle ((intptr_t)lhd, 0);
163#else 173#else
164 void *buf = malloc (CMSG_SPACE (sizeof (int))); 174 void *buf = malloc (CMSG_SPACE (sizeof (int)));
165 175
166 if (!buf) 176 if (!buf)
167 return -1; 177 return -1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines