1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-26 10:04:02 +03:00

socket-wrapped: added wrappers for dup() and dup2()

The Samba4 standard process model uses dup() on incoming sockets as an
optimisation (it makes select() a tiny bit faster when used).

Adding dup() to socket wrapper allows us to use the standard process
model in selftest

Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Andrew Tridgell 2011-08-12 14:28:03 +10:00
parent b4a730d353
commit 63e5b395d0
2 changed files with 131 additions and 2 deletions

View File

@ -127,6 +127,8 @@
#define real_writev writev
#define real_socket socket
#define real_close close
#define real_dup dup
#define real_dup2 dup2
#endif
#ifdef HAVE_GETTIMEOFDAY_TZ
@ -225,7 +227,6 @@ struct socket_info
int connected;
int defer_connect;
char *path;
char *tmp_path;
struct sockaddr *myname;
@ -2523,7 +2524,6 @@ _PUBLIC_ int swrap_close(int fd)
swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
}
if (si->path) free(si->path);
if (si->myname) free(si->myname);
if (si->peername) free(si->peername);
if (si->tmp_path) {
@ -2534,3 +2534,121 @@ _PUBLIC_ int swrap_close(int fd)
return ret;
}
_PUBLIC_ int swrap_dup(int fd)
{
struct socket_info *si, *si2;
int fd2;
si = find_socket_info(fd);
if (!si) {
return real_dup(fd);
}
if (si->tmp_path) {
/* we would need reference counting to handle this */
errno = EINVAL;
return -1;
}
fd2 = real_dup(fd);
if (fd2 == -1) {
return -1;
}
si2 = (struct socket_info *)malloc(sizeof(struct socket_info));
if (si2 == NULL) {
real_close(fd2);
errno = ENOMEM;
return -1;
}
/* copy the whole structure, then duplicate pointer elements */
*si2 = *si;
si2->fd = fd2;
if (si2->myname) {
si2->myname = sockaddr_dup(si2->myname, si2->myname_len);
if (si2->myname == NULL) {
real_close(fd2);
errno = ENOMEM;
return -1;
}
}
if (si2->peername) {
si2->peername = sockaddr_dup(si2->peername, si2->peername_len);
if (si2->peername == NULL) {
real_close(fd2);
errno = ENOMEM;
return -1;
}
}
SWRAP_DLIST_ADD(sockets, si2);
return fd2;
}
_PUBLIC_ int swrap_dup2(int fd, int newfd)
{
struct socket_info *si, *si2;
int fd2;
si = find_socket_info(fd);
if (!si) {
return real_dup2(fd, newfd);
}
if (si->tmp_path) {
/* we would need reference counting to handle this */
errno = EINVAL;
return -1;
}
if (find_socket_info(newfd)) {
/* dup2() does an implicit close of newfd, which we
* need to emulate */
swrap_close(newfd);
}
fd2 = real_dup2(fd, newfd);
if (fd2 == -1) {
return -1;
}
si2 = (struct socket_info *)malloc(sizeof(struct socket_info));
if (si2 == NULL) {
real_close(fd2);
errno = ENOMEM;
return -1;
}
/* copy the whole structure, then duplicate pointer elements */
*si2 = *si;
si2->fd = fd2;
if (si2->myname) {
si2->myname = sockaddr_dup(si2->myname, si2->myname_len);
if (si2->myname == NULL) {
real_close(fd2);
errno = ENOMEM;
return -1;
}
}
if (si2->peername) {
si2->peername = sockaddr_dup(si2->peername, si2->peername_len);
if (si2->peername == NULL) {
real_close(fd2);
errno = ENOMEM;
return -1;
}
}
SWRAP_DLIST_ADD(sockets, si2);
return fd2;
}

View File

@ -58,6 +58,8 @@ ssize_t swrap_send(int s, const void *buf, size_t len, int flags);
int swrap_readv(int s, const struct iovec *vector, size_t count);
int swrap_writev(int s, const struct iovec *vector, size_t count);
int swrap_close(int);
int swrap_dup(int oldfd);
int swrap_dup2(int oldfd, int newfd);
#ifdef SOCKET_WRAPPER_REPLACE
@ -160,7 +162,16 @@ int swrap_close(int);
#undef close
#endif
#define close(s) swrap_close(s)
#ifdef dup
#undef dup
#endif
#define dup(s) swrap_dup(s)
#ifdef dup2
#undef dup2
#endif
#define dup2(s, s2) swrap_dup2(s, s2)
#endif /* SOCKET_WRAPPER_REPLACE */
#endif /* __SOCKET_WRAPPER_H__ */