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:
parent
b4a730d353
commit
63e5b395d0
@ -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;
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user