diff options
-rw-r--r-- | src/ChangeLog | 6 | ||||
-rw-r--r-- | src/assuan-buffer.c | 20 | ||||
-rw-r--r-- | src/assuan-defs.h | 4 | ||||
-rw-r--r-- | src/assuan-socket.c | 47 | ||||
-rw-r--r-- | src/assuan-uds.c | 23 |
5 files changed, 69 insertions, 31 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index e9589ff..fb4325b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,11 @@ 2007-10-05 Marcus Brinkmann <[email protected]> + * assuan-defs.h (_assuan_sock_wsa2errno) [HAVE_W32_SYSTEM]: Add prototype. + * assuan-uds.c (wsa2errno) [HAVE_W32_SYSTEM]: Move and rename to ... + * assuan-socket.c (_assuan_sock_wsa2errno) [HAVE_W32_SYSTEM]: ... this. + (_assuan_close, _assuan_sock_new, _assuan_sock_connect, _assuan_sock_bind): + Always set errno on error. + * assuan-uds.c (wsa2errno) [HAVE_W32_SYSTEM]: New function. (uds_reader, uds_writer) [HAVE_W32_SYSTEM]: Set errno. diff --git a/src/assuan-buffer.c b/src/assuan-buffer.c index 8a9faf1..2016864 100644 --- a/src/assuan-buffer.c +++ b/src/assuan-buffer.c @@ -51,9 +51,10 @@ writen (assuan_context_t ctx, const char *buffer, size_t length) return 0; /* okay */ } -/* Read an entire line. Returns 0 on success or -1 and ERRNo on +/* Read an entire line. Returns 0 on success or -1 and ERRNO on failure. EOF is indictated by setting the integer at address - R_EOF. */ + R_EOF. Note: BUF, R_NREAD and R_EOF contain a valid result even if + an error is returned. */ static int readline (assuan_context_t ctx, char *buf, size_t buflen, int *r_nread, int *r_eof) @@ -132,12 +133,23 @@ _assuan_read_line (assuan_context_t ctx) &nread, &ctx->inbound.eof); if (rc) { + int saved_errno = errno; + if (ctx->log_fp) - fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s]\n", + fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s]\n", assuan_get_assuan_log_prefix (), (unsigned int)getpid (), (int)ctx->inbound.fd, strerror (errno)); - + + if (saved_errno == EAGAIN) + { + /* We have to save a partial line. */ + memcpy (ctx->inbound.attic.line, line, atticlen + nread); + ctx->inbound.attic.pending = 0; + ctx->inbound.attic.linelen = atticlen + nread; + } + + errno = saved_errno; return _assuan_error (ASSUAN_Read_Error); } if (!nread) diff --git a/src/assuan-defs.h b/src/assuan-defs.h index 3c06436..1e31c43 100644 --- a/src/assuan-defs.h +++ b/src/assuan-defs.h @@ -305,7 +305,9 @@ int _assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen); int _assuan_sock_get_nonce (struct sockaddr *addr, int addrlen, assuan_sock_nonce_t *nonce); int _assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce); - +#ifdef HAVE_W32_SYSTEM +int _assuan_sock_wsa2errno (int err); +#endif #ifdef HAVE_FOPENCOOKIE /* We have to implement funopen in terms of glibc's fopencookie. */ diff --git a/src/assuan-socket.c b/src/assuan-socket.c index d2a01f7..81beacd 100644 --- a/src/assuan-socket.c +++ b/src/assuan-socket.c @@ -57,8 +57,25 @@ #ifdef HAVE_W32_SYSTEM +int +_assuan_sock_wsa2errno (int err) +{ + switch (err) + { + case WSAENOTSOCK: + return EINVAL; + case WSAEWOULDBLOCK: + return EAGAIN; + case ERROR_BROKEN_PIPE: + return EPIPE; + default: + return EIO; + } +} + + /* W32: Fill BUFFER with LENGTH bytes of random. Returns -1 on - failure, 0 on success. */ + failure, 0 on success. Sets errno on failure. */ static int get_nonce (char *buffer, size_t nbytes) { @@ -81,7 +98,7 @@ get_nonce (char *buffer, size_t nbytes) /* W32: The buffer for NONCE needs to be at least 16 bytes. Returns 0 on - success. */ + success and sets errno on failure. */ static int read_port_and_nonce (const char *fname, unsigned short *port, char *nonce) { @@ -128,9 +145,14 @@ _assuan_close (assuan_fd_t fd) { #ifdef HAVE_W32_SYSTEM int rc = closesocket (HANDLE2SOCKET(fd)); + if (rc) + errno = _assuan_sock_wsa2errno (WSAGetLastError ()); if (rc && WSAGetLastError () == WSAENOTSOCK) { rc = CloseHandle (fd); + if (rc) + /* FIXME. */ + errno = EIO; } return rc; #else @@ -146,9 +168,13 @@ assuan_fd_t _assuan_sock_new (int domain, int type, int proto) { #ifdef HAVE_W32_SYSTEM + int res; if (domain == AF_UNIX || domain == AF_LOCAL) domain = AF_INET; - return SOCKET2HANDLE(socket (domain, type, proto)); + res = SOCKET2HANDLE(socket (domain, type, proto)); + if (res < 0) + errno = _assuan_sock_wsa2errno (WSAGetLastError ()); + return res; #else return socket (domain, type, proto); #endif @@ -195,7 +221,13 @@ _assuan_sock_connect (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen) return ret; } else - return connect (HANDLE2SOCKET (sockfd), addr, addrlen); + { + int res; + res = connect (HANDLE2SOCKET (sockfd), addr, addrlen); + if (res < 0) + errno = _assuan_sock_wsa2errno (WSAGetLastError ()); + return res; + } #else return connect (sockfd, addr, addrlen); #endif @@ -262,7 +294,12 @@ _assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen) return 0; } else - return bind (HANDLE2SOCKET(sockfd), addr, addrlen); + { + int res = bind (HANDLE2SOCKET(sockfd), addr, addrlen); + if (res < 0) + errno = _assuan_sock_wsa2errno (WSAGetLastError ()); + return res; + } #else return bind (sockfd, addr, addrlen); #endif diff --git a/src/assuan-uds.c b/src/assuan-uds.c index f31ee36..02f77a5 100644 --- a/src/assuan-uds.c +++ b/src/assuan-uds.c @@ -63,25 +63,6 @@ #endif /*USE_DESCRIPTOR_PASSING*/ -#ifdef HAVE_W32_SYSTEM -int -wsa2errno (int err) -{ - switch (err) - { - case WSAENOTSOCK: - return EINVAL; - case WSAEWOULDBLOCK: - return EAGAIN; - case ERROR_BROKEN_PIPE: - return EPIPE; - default: - return EIO; - } -} -#endif - - /* Read from a unix domain socket using sendmsg. FIXME: We don't need the buffering. It is a leftover from the time @@ -173,7 +154,7 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen) #else /*HAVE_W32_SYSTEM*/ int res = recvfrom (HANDLE2SOCKET(ctx->inbound.fd), buf, buflen, 0, NULL, NULL); if (res < 0) - errno = wsa2errno (WSAGetLastError ()); + errno = _assuan_sock_wsa2errno (WSAGetLastError ()); return res; #endif /*HAVE_W32_SYSTEM*/ } @@ -205,7 +186,7 @@ uds_writer (assuan_context_t ctx, const void *buf, size_t buflen) (struct sockaddr *)&ctx->serveraddr, sizeof (struct sockaddr_in)); if (res < 0) - errno = wsa2errno (WSAGetLastError ()); + errno = _assuan_sock_wsa2errno (WSAGetLastError ()); return res; #endif /*HAVE_W32_SYSTEM*/ } |