summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2014-09-11 10:17:06 +0200
committerAndreas Schneider <asn@samba.org>2014-10-01 14:06:27 +0200
commit045689644b87a3f6a3f4c2baeb70d22d3f6c441c (patch)
treeeb22899966706593d27f2c7280b34d9c57c26b60
parent7dad23ab56c707a0c5e3780436259781375be0e0 (diff)
downloadsocket_wrapper-045689644b87a3f6a3f4c2baeb70d22d3f6c441c.tar.gz
socket_wrapper-045689644b87a3f6a3f4c2baeb70d22d3f6c441c.tar.xz
socket_wrapper-045689644b87a3f6a3f4c2baeb70d22d3f6c441c.zip
swrap: Implement fcntl() to catch F_DUPFD.
Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
-rw-r--r--src/socket_wrapper.c87
1 files changed, 86 insertions, 1 deletions
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index e0942ed..8a7b572 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -339,6 +339,7 @@ struct swrap_libc_fns {
socklen_t addrlen);
int (*libc_dup)(int fd);
int (*libc_dup2)(int oldfd, int newfd);
+ int (*libc_fcntl)(int fd, int cmd, ...);
FILE *(*libc_fopen)(const char *name, const char *mode);
#ifdef HAVE_EVENTFD
int (*libc_eventfd)(int count, int flags);
@@ -591,6 +592,28 @@ static int libc_eventfd(int count, int flags)
}
#endif
+static int libc_vfcntl(int fd, int cmd, va_list ap)
+{
+ long int args[4];
+ int rc;
+ int i;
+
+ swrap_load_lib_function(SWRAP_LIBC, fcntl);
+
+ for (i = 0; i < 4; i++) {
+ args[i] = va_arg(ap, long int);
+ }
+
+ rc = swrap.fns.libc_fcntl(fd,
+ cmd,
+ args[0],
+ args[1],
+ args[2],
+ args[3]);
+
+ return rc;
+}
+
static int libc_getpeername(int sockfd,
struct sockaddr *addr,
socklen_t *addrlen)
@@ -4918,7 +4941,69 @@ int dup2(int fd, int newfd)
}
/****************************
- * DUP2
+ * FCNTL
+ ***************************/
+
+static int swrap_vfcntl(int fd, int cmd, va_list va)
+{
+ struct socket_info_fd *fi;
+ struct socket_info *si;
+ int rc;
+
+ si = find_socket_info(fd);
+ if (si == NULL) {
+ rc = libc_vfcntl(fd, cmd, va);
+
+ return rc;
+ }
+
+ switch (cmd) {
+ case F_DUPFD:
+ fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
+ if (fi == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ fi->fd = libc_vfcntl(fd, cmd, va);
+ if (fi->fd == -1) {
+ int saved_errno = errno;
+ free(fi);
+ errno = saved_errno;
+ return -1;
+ }
+
+ /* Make sure we don't have an entry for the fd */
+ swrap_remove_stale(fi->fd);
+
+ SWRAP_DLIST_ADD(si->fds, fi);
+
+ rc = fi->fd;
+ break;
+ default:
+ rc = libc_vfcntl(fd, cmd, va);
+ break;
+ }
+
+ return rc;
+}
+
+int fcntl(int fd, int cmd, ...)
+{
+ va_list va;
+ int rc;
+
+ va_start(va, cmd);
+
+ rc = swrap_vfcntl(fd, cmd, va);
+
+ va_end(va);
+
+ return rc;
+}
+
+/****************************
+ * EVENTFD
***************************/
#ifdef HAVE_EVENTFD