#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
int connected;
int defer_connect;
- char *path;
char *tmp_path;
struct sockaddr *myname;
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) {
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;
+}
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
#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__ */