Skip to content

Commit

Permalink
fs: add flock() function
Browse files Browse the repository at this point in the history
Implements file based locking on a given file descriptor

Signed-off-by: Felix Fietkau <[email protected]>
  • Loading branch information
nbd168 committed Jun 17, 2024
1 parent 2b45488 commit cad8c20
Showing 1 changed file with 56 additions and 0 deletions.
56 changes: 56 additions & 0 deletions lib/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,61 @@ uc_fs_ftruncate(uc_vm_t *vm, size_t nargs)
return ucv_boolean_new(true);
}

/**
* 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#flock
*
* @param {number} [fd]
* The file descriptor.
*
* @param {string} [op]
* The lock operation flags
*
* @returns {?boolean}
*/
static uc_value_t *
uc_fs_flock(uc_vm_t *vm, size_t nargs)
{
uc_value_t *fd = uc_fn_arg(0);
uc_value_t *mode = uc_fn_arg(1);
int i, op = 0;
char *m;

if (ucv_type(fd) != UC_INTEGER ||
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(ucv_int64_get(fd), op) < 0)
err_return(errno);

return ucv_boolean_new(true);
}

/**
* Obtain current read position.
*
Expand Down Expand Up @@ -2650,6 +2705,7 @@ static const uc_function_list_t global_fns[] = {
{ "realpath", uc_fs_realpath },
{ "pipe", uc_fs_pipe },
{ "ftruncate", uc_fs_ftruncate },
{ "flock", uc_fs_flock },
};


Expand Down

0 comments on commit cad8c20

Please sign in to comment.