X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/f7aa4b367eaf2c1e928f97263bcf4da74680aff3..f9520103d3b3a1a36fdb30a46aa4f6c1cd3f1c9e:/unix/uxmisc.c diff --git a/unix/uxmisc.c b/unix/uxmisc.c index 300fc543..473aa94e 100644 --- a/unix/uxmisc.c +++ b/unix/uxmisc.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -168,14 +169,70 @@ void pgp_fingerprints(void) } /* - * Set FD_CLOEXEC on a file descriptor + * Set and clear fcntl options on a file descriptor. We don't + * realistically expect any of these operations to fail (the most + * plausible error condition is EBADF, but we always believe ourselves + * to be passing a valid fd so even that's an assertion-fail sort of + * response), so we don't make any effort to return sensible error + * codes to the caller - we just log to standard error and die + * unceremoniously. However, nonblock and no_nonblock do return the + * previous state of O_NONBLOCK. */ -int cloexec(int fd) { +void cloexec(int fd) { int fdflags; fdflags = fcntl(fd, F_GETFD); - if (fdflags == -1) return -1; - return fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC); + if (fdflags < 0) { + fprintf(stderr, "%d: fcntl(F_GETFD): %s\n", fd, strerror(errno)); + exit(1); + } + if (fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC) < 0) { + fprintf(stderr, "%d: fcntl(F_SETFD): %s\n", fd, strerror(errno)); + exit(1); + } +} +void noncloexec(int fd) { + int fdflags; + + fdflags = fcntl(fd, F_GETFD); + if (fdflags < 0) { + fprintf(stderr, "%d: fcntl(F_GETFD): %s\n", fd, strerror(errno)); + exit(1); + } + if (fcntl(fd, F_SETFD, fdflags & ~FD_CLOEXEC) < 0) { + fprintf(stderr, "%d: fcntl(F_SETFD): %s\n", fd, strerror(errno)); + exit(1); + } +} +int nonblock(int fd) { + int fdflags; + + fdflags = fcntl(fd, F_GETFL); + if (fdflags < 0) { + fprintf(stderr, "%d: fcntl(F_GETFL): %s\n", fd, strerror(errno)); + exit(1); + } + if (fcntl(fd, F_SETFL, fdflags | O_NONBLOCK) < 0) { + fprintf(stderr, "%d: fcntl(F_SETFL): %s\n", fd, strerror(errno)); + exit(1); + } + + return fdflags & O_NONBLOCK; +} +int no_nonblock(int fd) { + int fdflags; + + fdflags = fcntl(fd, F_GETFL); + if (fdflags < 0) { + fprintf(stderr, "%d: fcntl(F_GETFL): %s\n", fd, strerror(errno)); + exit(1); + } + if (fcntl(fd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) { + fprintf(stderr, "%d: fcntl(F_SETFL): %s\n", fd, strerror(errno)); + exit(1); + } + + return fdflags & O_NONBLOCK; } FILE *f_open(const Filename *filename, char const *mode, int is_private)