diff --git a/lib/isc/include/isc/result.h b/lib/isc/include/isc/result.h index 9f6cdd5fa1..e3fcd5bf7a 100644 --- a/lib/isc/include/isc/result.h +++ b/lib/isc/include/isc/result.h @@ -23,7 +23,9 @@ typedef unsigned int isc_result_t; #define ISC_R_TASKSHUTDOWN 16 /* task was shut down */ #define ISC_R_LOCKBUSY 17 #define ISC_R_EXISTS 18 -#define ISC_R_LASTENTRY 18 /* last entry in the list */ +#define ISC_R_TOOSMALL 19 /* buffer is too small */ +#define ISC_R_CANCELED 20 +#define ISC_R_LASTENTRY 20 /* last entry in the list */ #define ISC_R_UNEXPECTED 0xFFFFFFFFL diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h index 143e7c9dd5..86f58e18b0 100644 --- a/lib/isc/include/isc/socket.h +++ b/lib/isc/include/isc/socket.h @@ -1,4 +1,4 @@ -/* $Id: socket.h,v 1.8 1998/12/01 17:58:34 explorer Exp $ */ +/* $Id: socket.h,v 1.9 1998/12/01 23:59:39 explorer Exp $ */ #ifndef ISC_SOCKET_H #define ISC_SOCKET_H 1 @@ -153,46 +153,56 @@ isc_socket_create(isc_socketmgr_t manager, * ISC_R_UNEXPECTED */ +int +isc_socket_cancel(isc_socket_t socket, isc_task_t task, + int how); +/* + * Cancel pending I/O of the type specified by "how". + * + * Note: if "task" is NULL, then the cancel applies to all tasks using the + * socket. + * + * Requires: + * + * "socket" is a valid socket + * + * "task" is NULL or a valid task + * + * "how" is a bitmask describing the type of cancelation to perform. + * The type ISC_SOCKCANCEL_ALL will cancel all pending I/O on this + * socket. + * + * ISC_SOCKCANCEL_RECV: + * Cancel pending isc_socket_recv() calls. + * + * ISC_SOCKCANCEL_SEND: + * Cancel pending isc_socket_send() and isc_socket_sendto() calls. + * + * ISC_SOCKCANCEL_ + */ void -isc_socket_shutdown(isc_socket_t socket, isc_task_t task, - isc_socketshutdown_t how); +isc_socket_shutdown(isc_socket_t socket, isc_socketshutdown_t how); /* * Shutdown 'socket' according to 'how'. * - * Note: if 'task' is NULL, then the shutdown applies to all tasks using the - * socket. - * * Requires: * * 'socket' is a valid socket. * * 'task' is NULL or is a valid task. * - * Ensures: - * * If 'how' is 'isc_sockshut_reading' or 'isc_sockshut_all' then * - * Any pending read completion events for the task are - * removed from the task's event queue. - * - * No further read completion events will be delivered to the - * task. + * The read queue must be empty. * * No further read requests may be made. * * If 'how' is 'isc_sockshut_writing' or 'isc_sockshut_all' then * - * Any pending write completion events for the task are - * removed from the task's event queue. - * - * No further write completion events will be delivered to the - * task. + * The write queue must be empty. * * No further write requests may be made. - * - * If 'socket' is a TCP socket, then when the last currently - * pending write completes, TCP FIN will sent to the remote peer. */ void @@ -357,8 +367,9 @@ isc_socket_getpeername(isc_socket_t socket, struct isc_sockaddr *addressp, * * Returns: * - * Success - * Address buffer too small + * ISC_R_SUCCESS + * ISC_R_TOOSMALL + * ISC_R_UNEXPECTED */ isc_result_t @@ -375,8 +386,9 @@ isc_socket_getsockname(isc_socket_t socket, struct isc_sockaddr *addressp, * * Returns: * - * Success - * Address buffer too small + * ISC_R_SUCCESS + * ISC_R_TOOSMALL + * ISC_R_UNEXPECTED */ isc_result_t diff --git a/lib/isc/result.c b/lib/isc/result.c index bed6ca1ba4..3aaa597953 100644 --- a/lib/isc/result.c +++ b/lib/isc/result.c @@ -21,6 +21,8 @@ static char *text_table[ISC_R_LASTENTRY + 1] = { "task was shut down", /* 16 */ "lock busy", /* 17 */ "already exists", /* 18 */ + "buffer too small", /* 19 */ + "operation canceled", /* 20 */ }; char * diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index 43b4c580a2..9f2fe645ba 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -1,4 +1,4 @@ -/* $Id: socket.c,v 1.13 1998/12/01 21:39:00 explorer Exp $ */ +/* $Id: socket.c,v 1.14 1998/12/01 23:59:39 explorer Exp $ */ #include "attribute.h" @@ -110,7 +110,7 @@ struct isc_socket { isc_socket_intev_t wiev; isc_socket_connintev_t ciev; struct isc_sockaddr address; - unsigned int addrlength; + int addrlength; }; #define SOCKET_MANAGER_MAGIC 0x494f6d67U /* IOmg */ @@ -1983,3 +1983,44 @@ internal_connect(isc_task_t task, isc_event_t ev) return (0); } + +/* + * Locking should not be necessary + */ +isc_result_t +isc_socket_getpeername(isc_socket_t sock, struct isc_sockaddr *addressp, + int *lengthp) +{ + if (*lengthp < sock->addrlength) + return (ISC_R_TOOSMALL); + memcpy(addressp, &sock->address, sock->addrlength); + *lengthp = sock->addrlength; + + return (ISC_R_SUCCESS); +} + +/* + * Locking should not be necessary + */ +isc_result_t +isc_socket_getsockname(isc_socket_t sock, struct isc_sockaddr *addressp, + int *lengthp) +{ + struct isc_sockaddr addr; + int len; + + len = sizeof(addr); + if (getsockname(sock->fd, (struct sockaddr *)&addr, &len) < 0) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "getsockname: %s", strerror(errno)); + return (ISC_R_UNEXPECTED); + } + + if (*lengthp < sock->addrlength) + return (ISC_R_TOOSMALL); + + memcpy(addressp, &sock->address, sock->addrlength); + *lengthp = sock->addrlength; + + return (ISC_R_SUCCESS); +}