diff options
author | Thomas Haller <thaller@redhat.com> | 2023-04-03 17:49:33 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-04-04 08:43:20 +0200 |
commit | f4943e07f1ae89c97c1fca8469b846831cab4ef8 (patch) | |
tree | 0cf58faf8a82f4544077f453f008f5a43677fa94 | |
parent | 31fd8f60cf21ab8fca232ef0d2dcd65f71b1c03e (diff) | |
download | NetworkManager-f4943e07f1ae89c97c1fca8469b846831cab4ef8.tar.gz |
glib-aux: add nm_io_fcntl_setfl_update_nonblock() helper
-rw-r--r-- | src/libnm-glib-aux/nm-io-utils.c | 80 | ||||
-rw-r--r-- | src/libnm-glib-aux/nm-io-utils.h | 10 |
2 files changed, 90 insertions, 0 deletions
diff --git a/src/libnm-glib-aux/nm-io-utils.c b/src/libnm-glib-aux/nm-io-utils.c index 1340e1b45f..ec016ed8a3 100644 --- a/src/libnm-glib-aux/nm-io-utils.c +++ b/src/libnm-glib-aux/nm-io-utils.c @@ -21,6 +21,86 @@ /*****************************************************************************/ +int +nm_io_fcntl_getfl(int fd) +{ + int f; + + nm_assert(fd >= 0); + + f = fcntl(fd, F_GETFL, 0); + + /* The caller really must provide a valid FD. For a valid FD, there is not + * reason why this call could fail (or how we could handle the failure). + * + * Unlike plain fcntl(), nm_io_fcntl_getfl() cannot fail. */ + nm_assert(f != -1); + + /* We not only assert that the return value is "!= -1", but that it's not + * negative. Negative flags would be very odd, and not something we would + * expect for a successful call. */ + nm_assert(f >= 0); + + return f; +} + +int +nm_io_fcntl_setfl(int fd, int flags) +{ + int f; + int errsv; + + nm_assert(fd >= 0); + nm_assert(flags >= 0); + + f = fcntl(fd, F_SETFL, flags); + if (f != 0) { + errsv = errno; + + nm_assert(errsv != EBADF); + + return -NM_ERRNO_NATIVE(errsv); + } + + return 0; +} + +int +nm_io_fcntl_setfl_update(int fd, int flags_mask, int flags_value) +{ + int flags_current; + + nm_assert(fd >= 0); + nm_assert(flags_mask > 0); + nm_assert(flags_value >= 0); + nm_assert(((~flags_mask) & flags_value) == 0); + + flags_current = nm_io_fcntl_getfl(fd); + return nm_io_fcntl_setfl(fd, (flags_current & ~flags_mask) | (flags_mask & flags_value)); +} + +void +nm_io_fcntl_setfl_update_nonblock(int fd) +{ + int r; + + nm_assert(fd >= 0); + + r = nm_io_fcntl_setfl_update(fd, O_NONBLOCK, O_NONBLOCK); + + /* nm_io_fcntl_setfl_update() already asserts that it cannot fail with + * EBADF. + * + * In nm_io_fcntl_setfl_update_nonblock() only sts O_NONBLOCK, where we + * don't expect any other error. Kernel should never reject setting this + * flags, and if it did, we have to find out how to handle that. Currently + * we don't handle it and assert against failure. */ + + nm_assert(r == 0); +} + +/*****************************************************************************/ + _nm_printf(4, 5) static int _get_contents_error(GError **error, int errsv, int *out_errsv, diff --git a/src/libnm-glib-aux/nm-io-utils.h b/src/libnm-glib-aux/nm-io-utils.h index 5401814018..0021138f46 100644 --- a/src/libnm-glib-aux/nm-io-utils.h +++ b/src/libnm-glib-aux/nm-io-utils.h @@ -10,6 +10,16 @@ /*****************************************************************************/ +int nm_io_fcntl_getfl(int fd); + +int nm_io_fcntl_setfl(int fd, int flags); + +int nm_io_fcntl_setfl_update(int fd, int flags_mask, int flags_value); + +void nm_io_fcntl_setfl_update_nonblock(int fd); + +/*****************************************************************************/ + /** * NMUtilsFileGetContentsFlags: * @NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE: no flag |