summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2024-06-17 12:05:23 +0200
committerFelix Fietkau <nbd@nbd.name>2024-06-17 12:52:54 +0200
commit5d305cfb2ab7b997dc1314cb6d4483683275680c (patch)
treedb065147b1319098802454549e574f24f033c07f
parente0bab40c85780f765bed78bd2e67f376b6883594 (diff)
fs: add lock() file method
Implements file based locking on a given file handle. Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r--lib/fs.c56
-rw-r--r--tests/custom/03_stdlib/40_proto1
2 files changed, 57 insertions, 0 deletions
diff --git a/lib/fs.c b/lib/fs.c
index f237102..d0d97ac 100644
--- a/lib/fs.c
+++ b/lib/fs.c
@@ -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[] = {
diff --git a/tests/custom/03_stdlib/40_proto b/tests/custom/03_stdlib/40_proto
index 6fed529..d96d124 100644
--- a/tests/custom/03_stdlib/40_proto
+++ b/tests/custom/03_stdlib/40_proto
@@ -38,6 +38,7 @@ When invoked with two arguments, returns the given value.
Hello, World!
[
{
+ "lock": "function lock(...) { [native code] }",
"truncate": "function truncate(...) { [native code] }",
"isatty": "function isatty(...) { [native code] }",
"error": "function error(...) { [native code] }",