EBADF, EOPNOTSUPP, EMFILE error repoarting for accept()

This commit is contained in:
Joseph Henry 2015-10-13 17:57:17 -04:00
parent da536cc311
commit 8a05efa365
3 changed files with 32 additions and 14 deletions

View File

@ -494,18 +494,18 @@ int NetconEthernetTap::send_return_value(int fd, int retval, int _errno = 0)
to be accepted. POSIX.1-2001 allows either error to be returned for to be accepted. POSIX.1-2001 allows either error to be returned for
this case, and does not require these constants to have the same value, this case, and does not require these constants to have the same value,
so a portable application should check for both possibilities. so a portable application should check for both possibilities.
[ ] EBADF - The descriptor is invalid. [I] EBADF - The descriptor is invalid.
[i] ECONNABORTED - A connection has been aborted. [I] ECONNABORTED - A connection has been aborted.
[i] EFAULT - The addr argument is not in a writable part of the user address space. [i] EFAULT - The addr argument is not in a writable part of the user address space.
[ ] EINTR - The system call was interrupted by a signal that was caught before a valid connection arrived; see signal(7). [ ] EINTR - The system call was interrupted by a signal that was caught before a valid connection arrived; see signal(7).
[ ] EINVAL - Socket is not listening for connections, or addrlen is invalid (e.g., is negative). [ ] EINVAL - Socket is not listening for connections, or addrlen is invalid (e.g., is negative).
[ ] EINVAL - (accept4()) invalid value in flags. [ ] EINVAL - (accept4()) invalid value in flags.
[ ] EMFILE - The per-process limit of open file descriptors has been reached. [I] EMFILE - The per-process limit of open file descriptors has been reached.
[ ] ENFILE - The system limit on the total number of open files has been reached. [ ] ENFILE - The system limit on the total number of open files has been reached.
[ ] ENOBUFS, ENOMEM - Not enough free memory. This often means that the memory allocation is [ ] ENOBUFS, ENOMEM - Not enough free memory. This often means that the memory allocation is
limited by the socket buffer limits, not by the system memory. limited by the socket buffer limits, not by the system memory.
[i] ENOTSOCK - The descriptor references a file, not a socket. [i] ENOTSOCK - The descriptor references a file, not a socket.
[i] EOPNOTSUPP - The referenced socket is not of type SOCK_STREAM. [I] EOPNOTSUPP - The referenced socket is not of type SOCK_STREAM.
[ ] EPROTO - Protocol error. [ ] EPROTO - Protocol error.
* *
@ -675,8 +675,8 @@ void NetconEthernetTap::nc_err(void *arg, err_t err)
l->tap->send_return_value(l->conn, -1, EISCONN); l->tap->send_return_value(l->conn, -1, EISCONN);
break; break;
case ERR_ABRT: case ERR_ABRT:
fprintf(stderr, "nc_err(): ERR_ABRT->ETIMEDOUT\n"); // FIXME: Correct? fprintf(stderr, "nc_err(): ERR_ABRT->ECONNREFUSED\n");
l->tap->send_return_value(l->conn, -1, ETIMEDOUT); l->tap->send_return_value(l->conn, -1, ECONNREFUSED);
break; break;
// FIXME: Below are errors which don't have a standard errno correlate // FIXME: Below are errors which don't have a standard errno correlate

View File

@ -73,6 +73,8 @@ char *progname = "";
#include "common.h" #include "common.h"
#ifdef CHECKS #ifdef CHECKS
//#include <sys/time.h>
#include <sys/resource.h>
#include <linux/net.h> /* for NPROTO */ #include <linux/net.h> /* for NPROTO */
#define SOCK_MAX (SOCK_PACKET + 1) #define SOCK_MAX (SOCK_PACKET + 1)
@ -763,6 +765,30 @@ int accept4(ACCEPT4_SIG)
accept() intercept function */ accept() intercept function */
int accept(ACCEPT_SIG) int accept(ACCEPT_SIG)
{ {
#ifdef CHECKS
/* Check that this is a valid fd */
if(fcntl(sockfd, F_GETFD) < 0) {
return -1;
errno = EBADF;
}
int sock_type = -1;
socklen_t sock_type_len = sizeof(sock_type);
getsockopt(sockfd, SOL_SOCKET, SO_TYPE,
(void *) &sock_type, &sock_type_len);
/* Check that this socket supports accept() */
if(!(sock_type & (SOCK_STREAM | SOCK_SEQPACKET))) {
errno = EOPNOTSUPP;
return -1;
}
/* Check that we haven't hit the soft-limit file descriptors allowed */
struct rlimit rl;
getrlimit(RLIMIT_NOFILE, &rl);
if(sockfd >= rl.rlim_cur){
errno = EMFILE;
return -1;
}
#endif
#ifdef DUMMY #ifdef DUMMY
return realaccept(sockfd, addr, addrlen); return realaccept(sockfd, addr, addrlen);
#else #else
@ -770,17 +796,9 @@ int accept(ACCEPT_SIG)
if(sockfd == STDIN_FILENO || sockfd == STDOUT_FILENO || sockfd == STDERR_FILENO) if(sockfd == STDIN_FILENO || sockfd == STDOUT_FILENO || sockfd == STDERR_FILENO)
return(realaccept(sockfd, addr, addrlen)); return(realaccept(sockfd, addr, addrlen));
int sock_type = -1;
socklen_t sock_type_len = sizeof(sock_type);
getsockopt(sockfd, SOL_SOCKET, SO_TYPE,
(void *) &sock_type, &sock_type_len);
addr->sa_family = AF_INET; addr->sa_family = AF_INET;
/* TODO: also get address info */ /* TODO: also get address info */
/* FIXME: Check that socket is type SOCK_STREAM */
char cmd[BUF_SZ]; char cmd[BUF_SZ];
if(realaccept == NULL) { if(realaccept == NULL) {
dwr( "Unresolved symbol: accept()\n"); dwr( "Unresolved symbol: accept()\n");

Binary file not shown.