1 /* assuan-io.c - Wraps the read and write functions.
2 * Copyright (C) 2002, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
4 * This file is part of Assuan.
6 * Assuan is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
11 * Assuan is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
26 #include <sys/types.h>
27 #ifdef HAVE_SYS_SOCKET_H
28 # include <sys/socket.h>
32 #ifdef HAVE_W32_SYSTEM
35 # include <sys/wait.h>
38 #include "assuan-defs.h"
41 #ifndef HAVE_W32_SYSTEM
43 _assuan_waitpid (pid_t pid
, int *status
, int options
)
45 return waitpid (pid
, status
, options
);
51 do_io_read (assuan_fd_t fd
, void *buffer
, size_t size
)
53 #ifdef HAVE_W32_SYSTEM
54 /* Due to the peculiarities of the W32 API we can't use read for a
55 network socket and thus we try to use recv first and fallback to
56 read if recv detects that it is not a network socket. */
59 n
= recv (HANDLE2SOCKET(fd
), buffer
, size
, 0);
62 switch (WSAGetLastError ())
68 n
= ReadFile (fd
, buffer
, size
, &nread
, NULL
);
71 switch (GetLastError())
73 case ERROR_BROKEN_PIPE
: errno
= EPIPE
; break;
83 case WSAEWOULDBLOCK
: errno
= EAGAIN
; break;
84 case ERROR_BROKEN_PIPE
: errno
= EPIPE
; break;
85 default: errno
= EIO
; break;
89 #else /*!HAVE_W32_SYSTEM*/
90 return read (fd
, buffer
, size
);
91 #endif /*!HAVE_W32_SYSTEM*/
96 _assuan_io_read (assuan_fd_t fd
, void *buffer
, size_t size
)
100 if (_assuan_io_hooks
.read_hook
101 && _assuan_io_hooks
.read_hook (NULL
, fd
, buffer
, size
, &retval
) == 1)
104 return do_io_read (fd
, buffer
, size
);
108 _assuan_simple_read (assuan_context_t ctx
, void *buffer
, size_t size
)
112 if (_assuan_io_hooks
.read_hook
113 && _assuan_io_hooks
.read_hook (ctx
, ctx
->inbound
.fd
,
114 buffer
, size
, &retval
) == 1)
117 return do_io_read (ctx
->inbound
.fd
, buffer
, size
);
123 do_io_write (assuan_fd_t fd
, const void *buffer
, size_t size
)
125 #ifdef HAVE_W32_SYSTEM
126 /* Due to the peculiarities of the W32 API we can't use write for a
127 network socket and thus we try to use send first and fallback to
128 write if send detects that it is not a network socket. */
131 n
= send (HANDLE2SOCKET(fd
), buffer
, size
, 0);
132 if (n
== -1 && WSAGetLastError () == WSAENOTSOCK
)
136 n
= WriteFile (fd
, buffer
, size
, &nwrite
, NULL
);
139 switch (GetLastError ())
141 case ERROR_BROKEN_PIPE
:
142 case ERROR_NO_DATA
: errno
= EPIPE
; break;
143 default: errno
= EIO
; break;
151 #else /*!HAVE_W32_SYSTEM*/
152 return write (fd
, buffer
, size
);
153 #endif /*!HAVE_W32_SYSTEM*/
157 _assuan_io_write (assuan_fd_t fd
, const void *buffer
, size_t size
)
161 if (_assuan_io_hooks
.write_hook
162 && _assuan_io_hooks
.write_hook (NULL
, fd
, buffer
, size
, &retval
) == 1)
164 return do_io_write (fd
, buffer
, size
);
168 _assuan_simple_write (assuan_context_t ctx
, const void *buffer
, size_t size
)
172 if (_assuan_io_hooks
.write_hook
173 && _assuan_io_hooks
.write_hook (ctx
, ctx
->outbound
.fd
,
174 buffer
, size
, &retval
) == 1)
177 return do_io_write (ctx
->outbound
.fd
, buffer
, size
);
181 #ifdef HAVE_W32_SYSTEM
183 _assuan_simple_sendmsg (assuan_context_t ctx
, void *msg
)
186 _assuan_simple_sendmsg (assuan_context_t ctx
, struct msghdr
*msg
)
189 #ifdef HAVE_W32_SYSTEM
190 return _assuan_error (ASSUAN_Not_Implemented
);
193 while ( (ret
= sendmsg (ctx
->outbound
.fd
, msg
, 0)) == -1 && errno
== EINTR
)
200 #ifdef HAVE_W32_SYSTEM
202 _assuan_simple_recvmsg (assuan_context_t ctx
, void *msg
)
205 _assuan_simple_recvmsg (assuan_context_t ctx
, struct msghdr
*msg
)
208 #ifdef HAVE_W32_SYSTEM
209 return _assuan_error (ASSUAN_Not_Implemented
);
212 while ( (ret
= recvmsg (ctx
->inbound
.fd
, msg
, 0)) == -1 && errno
== EINTR
)
220 _assuan_usleep (unsigned int usec
)
224 #ifdef HAVE_NANOSLEEP
229 req
.tv_nsec
= usec
* 1000;
231 while (nanosleep (&req
, &rem
) < 0 && errno
== EINTR
)
234 #elif defined(HAVE_W32_SYSTEM)
239 tv
.tv_sec
= usec
/ 1000000;
240 tv
.tv_usec
= usec
% 1000000;
241 select (0, NULL
, NULL
, NULL
, &tv
);