diff options
author | Felix Fietkau <nbd@nbd.name> | 2024-06-17 12:05:23 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2024-06-17 12:52:54 +0200 |
commit | 5d305cfb2ab7b997dc1314cb6d4483683275680c (patch) | |
tree | db065147b1319098802454549e574f24f033c07f /lib | |
parent | e0bab40c85780f765bed78bd2e67f376b6883594 (diff) |
fs: add lock() file method
Implements file based locking on a given file handle.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fs.c | 56 |
1 files changed, 56 insertions, 0 deletions
@@ -53,6 +53,7 @@ #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> +#include <sys/file.h> #include <grp.h> #include <pwd.h> #include <glob.h> @@ -776,6 +777,60 @@ uc_fs_truncate(uc_vm_t *vm, size_t nargs) } /** + * Locks or unlocks a file. + * + * The mode argument specifies lock/unlock operation flags. + * + * | Flag | Description | + * |---------|------------------------------| + * | "s" | shared lock | + * | "x" | exclusive lock | + * | "n" | don't block when locking | + * | "u" | unlock | + * + * Returns `true` if the file was successfully locked/unlocked. + * + * Returns `null` if an error occurred. + * + * @function module:fs.file#lock + * + * @param {string} [op] + * The lock operation flags + * + * @returns {?boolean} + */ +static uc_value_t * +uc_fs_lock(uc_vm_t *vm, size_t nargs) +{ + FILE *fp = uc_fn_thisval("fs.file"); + uc_value_t *mode = uc_fn_arg(0); + int i, op = 0; + char *m; + + if (!fp) + err_return(EBADF); + + if (ucv_type(mode) != UC_STRING) + err_return(EINVAL); + + m = ucv_string_get(mode); + for (i = 0; m[i]; i++) { + switch (m[i]) { + case 's': op |= LOCK_SH; break; + case 'x': op |= LOCK_EX; break; + case 'n': op |= LOCK_NB; break; + case 'u': op |= LOCK_UN; break; + default: err_return(EINVAL); + } + } + + if (flock(fileno(fp), op) < 0) + err_return(errno); + + return ucv_boolean_new(true); +} + +/** * Obtain current read position. * * Obtains the current, absolute read position of the open file. @@ -2609,6 +2664,7 @@ static const uc_function_list_t file_fns[] = { { "error", uc_fs_error }, { "isatty", uc_fs_isatty }, { "truncate", uc_fs_truncate }, + { "lock", uc_fs_lock }, }; static const uc_function_list_t dir_fns[] = { |