00001 #ifndef __XRDSYS_FD_H__
00002 #define __XRDSYS_FD_H__
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00038
00039
00040 #include <sys/types.h>
00041 #include <sys/socket.h>
00042 #include <unistd.h>
00043 #include <sys/stat.h>
00044 #include <fcntl.h>
00045 #include <dirent.h>
00046 #include <errno.h>
00047
00048 namespace
00049 {
00050 #if defined(__linux__) && defined(SOCK_CLOEXEC) && defined(O_CLOEXEC)
00051 inline int XrdSysFD_Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
00052 {return accept4(sockfd, addr, addrlen, SOCK_CLOEXEC);}
00053
00054 inline int XrdSysFD_Dup(int oldfd)
00055 {return fcntl(oldfd, F_DUPFD_CLOEXEC, 0);}
00056
00057 inline int XrdSysFD_Dup1(int oldfd, int minfd)
00058 {return fcntl(oldfd, F_DUPFD_CLOEXEC, minfd);}
00059
00060 inline int XrdSysFD_Dup2(int oldfd, int newfd)
00061 {return dup3(oldfd, newfd, O_CLOEXEC);}
00062
00063 inline int XrdSysFD_Open(const char *path, int flags)
00064 {return open(path, flags|O_CLOEXEC);}
00065
00066 inline int XrdSysFD_Open(const char *path, int flags, mode_t mode)
00067 {return open(path, flags|O_CLOEXEC, mode);}
00068
00069 inline DIR* XrdSysFD_OpenDir(const char *path)
00070 {int fd;
00071 if ((fd = open(path, O_RDONLY|O_CLOEXEC)) < 0) return 0;
00072 DIR *dP = fdopendir(fd);
00073 if (!dP) {int rc = errno; close(fd); errno = rc;}
00074 return dP;
00075 }
00076
00077 inline int XrdSysFD_Pipe(int pipefd[2])
00078 {return pipe2(pipefd, O_CLOEXEC);}
00079
00080 inline int XrdSysFD_Socket(int domain, int type, int protocol)
00081 {return socket(domain, type|SOCK_CLOEXEC, protocol);}
00082
00083 inline int XrdSysFD_Socketpair(int domain, int type, int protocol, int sfd[2])
00084 {return socketpair(domain, type|SOCK_CLOEXEC, protocol, sfd);}
00085 #else
00086 inline int XrdSysFD_Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
00087 {int newfd = accept(sockfd, addr, addrlen);
00088 if (newfd >= 0) fcntl(newfd, F_SETFD, FD_CLOEXEC);
00089 return newfd;
00090 }
00091
00092 inline int XrdSysFD_Dup(int oldfd)
00093 {int newfd = dup(oldfd);
00094 if (newfd >= 0) fcntl(newfd, F_SETFD, FD_CLOEXEC);
00095 return newfd;
00096 }
00097
00098 inline int XrdSysFD_Dup1(int oldfd, int minfd)
00099 {int newfd = fcntl(oldfd, F_DUPFD, minfd);
00100 if (newfd >= 0) fcntl(newfd, F_SETFD, FD_CLOEXEC);
00101 return newfd;
00102 }
00103
00104 inline int XrdSysFD_Dup2(int oldfd, int newfd)
00105 {int rc = dup2(oldfd, newfd);
00106 if (!rc) fcntl(newfd, F_SETFD, FD_CLOEXEC);
00107 return rc;
00108 }
00109
00110 inline int XrdSysFD_Open(const char *path, int flags)
00111 {int newfd = open(path, flags);
00112 if (newfd >= 0) fcntl(newfd, F_SETFD, FD_CLOEXEC);
00113 return newfd;
00114 }
00115
00116 inline int XrdSysFD_Open(const char *path, int flags, mode_t mode)
00117 {int newfd = open(path, flags, mode);
00118 if (newfd >= 0) fcntl(newfd, F_SETFD, FD_CLOEXEC);
00119 return newfd;
00120 }
00121
00122 inline DIR* XrdSysFD_OpenDir(const char *path)
00123 {int fd = XrdSysFD_Open(path, O_RDONLY);
00124 if (fd < 0) return 0;
00125 fcntl(fd, F_SETFD, FD_CLOEXEC);
00126 DIR *dP = fdopendir(fd);
00127 if (!dP) {int rc = errno, close(fd); errno = rc;}
00128 return dP;
00129 }
00130
00131 inline int XrdSysFD_Pipe(int pipefd[2])
00132 {int rc = pipe(pipefd);
00133 if (!rc) {fcntl(pipefd[0], F_SETFD, FD_CLOEXEC);
00134 fcntl(pipefd[1], F_SETFD, FD_CLOEXEC);
00135 }
00136 return rc;
00137 }
00138
00139 inline int XrdSysFD_Socket(int domain, int type, int protocol)
00140 {int newfd = socket(domain, type, protocol);
00141 if (newfd >= 0) fcntl(newfd, F_SETFD, FD_CLOEXEC);
00142 return newfd;
00143 }
00144
00145 inline int XrdSysFD_Socketpair(int domain, int type, int protocol, int sfd[2])
00146 {int rc = socketpair(domain, type, protocol, sfd);
00147 if (!rc) {fcntl(sfd[0], F_SETFD, FD_CLOEXEC);
00148 fcntl(sfd[1], F_SETFD, FD_CLOEXEC);
00149 }
00150 return rc;
00151 }
00152 #endif
00153
00154 inline bool XrdSysFD_Yield(int fd)
00155 {int fdFlags = fcntl(fd, F_GETFD);
00156 if (fdFlags < 0) return false;
00157 return 0 == fcntl(fd, F_SETFD, fdFlags & ~FD_CLOEXEC);
00158 }
00159 }
00160 #endif