* SOFTWARE.
*/
-/* $Id: socket.c,v 1.142.2.5 2000/08/25 01:16:55 gson Exp $ */
+/* $Id: socket.c,v 1.142.2.6 2000/09/08 22:17:27 gson Exp $ */
#include <config.h>
ISC_LINK(isc_socket_t) link;
unsigned int references;
int fd;
- isc_result_t recv_result;
- isc_result_t send_result;
ISC_LIST(isc_socketevent_t) send_list;
ISC_LIST(isc_socketevent_t) recv_list;
#define SOFT_OR_HARD(_system, _isc) \
if (errno == _system) { \
if (sock->connected) { \
- if (sock->type == isc_sockettype_tcp) \
- sock->recv_result = _isc; \
send_recvdone_event(sock, &dev, _isc); \
return (DOIO_HARD); \
} \
}
#define ALWAYS_HARD(_system, _isc) \
if (errno == _system) { \
- sock->recv_result = _isc; \
send_recvdone_event(sock, &dev, _isc); \
return (DOIO_HARD); \
}
#undef SOFT_OR_HARD
#undef ALWAYS_HARD
- sock->recv_result = ISC_R_UNEXPECTED;
send_recvdone_event(sock, &dev, ISC_R_UNEXPECTED);
return (DOIO_SUCCESS);
}
* UDP, zero length reads are perfectly valid, although
* strange.
*/
- if ((sock->type == isc_sockettype_tcp) && (cc == 0)) {
- sock->recv_result = ISC_R_EOF;
+ if ((sock->type == isc_sockettype_tcp) && (cc == 0))
return (DOIO_EOF);
- }
if (sock->type == isc_sockettype_udp)
dev->address.length = msghdr.msg_namelen;
#define SOFT_OR_HARD(_system, _isc) \
if (errno == _system) { \
if (sock->connected) { \
- if (sock->type == isc_sockettype_tcp) \
- sock->send_result = _isc; \
send_senddone_event(sock, &dev, _isc); \
return (DOIO_HARD); \
} \
}
#define ALWAYS_HARD(_system, _isc) \
if (errno == _system) { \
- if (sock->connected && sock->type == isc_sockettype_tcp) \
- sock->send_result = _isc; \
send_senddone_event(sock, &dev, _isc); \
return (DOIO_HARD); \
}
SOFT_OR_HARD(ECONNREFUSED, ISC_R_CONNREFUSED);
+ SOFT_OR_HARD(EACCES, ISC_R_NOPERM);
+ SOFT_OR_HARD(EAFNOSUPPORT, ISC_R_ADDRNOTAVAIL);
ALWAYS_HARD(ENETUNREACH, ISC_R_NETUNREACH);
ALWAYS_HARD(EHOSTUNREACH, ISC_R_HOSTUNREACH);
ALWAYS_HARD(ENOBUFS, ISC_R_NORESOURCES);
ALWAYS_HARD(EADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL);
ALWAYS_HARD(EPERM, ISC_R_HOSTUNREACH);
+ ALWAYS_HARD(EPIPE, ISC_R_NOTCONNECTED);
#undef SOFT_OR_HARD
#undef ALWAYS_HARD
UNEXPECTED_ERROR(__FILE__, __LINE__,
"internal_send: %s",
strerror(errno));
- if (sock->connected && sock->type == isc_sockettype_tcp)
- sock->send_result = ISC_R_UNEXPECTED;
send_senddone_event(sock, &dev, ISC_R_UNEXPECTED);
return (DOIO_HARD);
}
sock->connecting = 0;
sock->bound = 0;
- sock->recv_result = ISC_R_SUCCESS;
- sock->send_result = ISC_R_SUCCESS;
-
/*
* initialize the lock
*/
if (ISC_LINK_LINKED(*dev, ev_link))
ISC_LIST_DEQUEUE(sock->recv_list, *dev, ev_link);
- if (sock->recv_result != ISC_R_SUCCESS)
- (*dev)->attributes |= ISC_SOCKEVENTATTR_FATALERROR;
-
if (((*dev)->attributes & ISC_SOCKEVENTATTR_ATTACHED)
== ISC_SOCKEVENTATTR_ATTACHED)
isc_task_sendanddetach(&task, (isc_event_t **)dev);
if (ISC_LINK_LINKED(*dev, ev_link))
ISC_LIST_DEQUEUE(sock->send_list, *dev, ev_link);
- if (sock->send_result != ISC_R_SUCCESS)
- (*dev)->attributes |= ISC_SOCKEVENTATTR_FATALERROR;
-
if (((*dev)->attributes & ISC_SOCKEVENTATTR_ATTACHED)
== ISC_SOCKEVENTATTR_ATTACHED)
isc_task_sendanddetach(&task, (isc_event_t **)dev);
* continue the loop.
*/
if (dev->ev_type == ISC_SOCKEVENT_RECVMARK) {
- send_recvdone_event(sock, &dev, sock->recv_result);
- goto next;
- }
-
- if (sock->recv_result != ISC_R_SUCCESS) {
- socket_log(sock, NULL, IOEVENT,
- "STICKY RESULT: %d", sock->recv_result);
- send_recvdone_event(sock, &dev, sock->recv_result);
+ send_recvdone_event(sock, &dev, ISC_R_SUCCESS);
goto next;
}
* continue the loop.
*/
if (dev->ev_type == ISC_SOCKEVENT_SENDMARK) {
- send_senddone_event(sock, &dev, sock->send_result);
- goto next;
- }
-
- if (sock->send_result != ISC_R_SUCCESS) {
- send_senddone_event(sock, &dev, sock->send_result);
+ send_senddone_event(sock, &dev, ISC_R_SUCCESS);
goto next;
}
if (!was_empty)
goto queue;
- if (sock->recv_result != ISC_R_SUCCESS) {
- send_recvdone_event(sock, &dev, sock->recv_result);
- UNLOCK(&sock->lock);
- return (ISC_R_SUCCESS);
- }
-
switch (doio_recv(sock, dev)) {
case DOIO_SOFT:
goto queue;
if (!was_empty)
goto queue;
- if (sock->recv_result != ISC_R_SUCCESS) {
- send_recvdone_event(sock, &dev, sock->recv_result);
- UNLOCK(&sock->lock);
- return (ISC_R_SUCCESS);
- }
-
switch (doio_recv(sock, dev)) {
case DOIO_SOFT:
goto queue;
if (!was_empty)
goto queue;
- if (sock->send_result != ISC_R_SUCCESS) {
- send_senddone_event(sock, &dev, sock->send_result);
- UNLOCK(&sock->lock);
- return (ISC_R_SUCCESS);
- }
-
switch (doio_send(sock, dev)) {
case DOIO_SOFT:
goto queue;
if (!was_empty)
goto queue;
- if (sock->send_result != ISC_R_SUCCESS) {
- send_senddone_event(sock, &dev, sock->send_result);
- UNLOCK(&sock->lock);
- return (ISC_R_SUCCESS);
- }
-
switch (doio_send(sock, dev)) {
case DOIO_SOFT:
goto queue;
dev->result = ISC_R_SUCCESS;
dev->minimum = 0;
- /*
- * If the queue is empty, simply return the last error we got on
- * this socket as the result code, and send off the done event.
- */
- if (ISC_LIST_EMPTY(sock->recv_list)) {
- send_recvdone_event(sock, &dev, sock->recv_result);
- UNLOCK(&sock->lock);
- return (ISC_R_SUCCESS);
- }
-
/*
* Bad luck. The queue wasn't empty. Insert this in the proper
* place.
dev->result = ISC_R_SUCCESS;
dev->minimum = 0;
- /*
- * If the queue is empty, simply return the last error we got on
- * this socket as the result code, and send off the done event.
- */
- if (ISC_LIST_EMPTY(sock->send_list)) {
- send_senddone_event(sock, &dev, sock->send_result);
- UNLOCK(&sock->lock);
- return (ISC_R_SUCCESS);
- }
-
/*
* Bad luck. The queue wasn't empty. Insert this in the proper
* place.