* Eric Blake: > int open_safer (const char *name, int flags, int mode) > { > int fd = open (name, flags | O_CLOEXEC, mode); > if (0 <= fd && fd <= 2) > { > int dup = fcntl (fd, ((flags & O_CLOEXEC) > ? F_DUPFD_CLOEXEC : F_DUPFD), 3); > int saved_errno = errno; > close (fd); > errno = saved_errno; > fd = dup; > } > else if (!(flags & O_CLOEXEC)) > { > if ((flags = fcntl (fd, F_GETFD)) < 0 > || fcntl (fd, F_SETFD, flags & ~FD_CLOEXEC) == -1) > { > int saved_errno = errno; > close (fd); > fd = -1; > errno = saved_errno; > } > } > return fd; > }
> This solves the fd leak, It's still buggy. You need something like this: int open_safer(const char *name, int flags, int mode) { int opened_fd[3] = {0, 0, 0}; int fd, i, errno_saved; while (1) { fd = open(name, flags | O_CLOEXEC, mode); if (fd < 0 || fd > 2) { break; } opened_fd[fd] = 1; } for (int i = 0; i <= 2; ++i) { if (opened_fd[i]) { errno_saved = errno; close(i); errno = errno_saved; } } return fd; } It's untested, so it's probably still buggy. (O_CLOEXEC should have been a thread attribute, like the base path in the *_at functions. *sigh*) -- Florian Weimer <fwei...@bfk.de> BFK edv-consulting GmbH http://www.bfk.de/ Kriegsstraße 100 tel: +49-721-96201-1 D-76133 Karlsruhe fax: +49-721-96201-99