Skip to content

Commit

Permalink
Merge pull request #207 from nbd168/fs
Browse files Browse the repository at this point in the history
Add fs module utility functions
  • Loading branch information
jow- authored Jun 18, 2024
2 parents 2a0240f + 5d305cf commit 5c26244
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
94 changes: 94 additions & 0 deletions lib/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -738,6 +739,97 @@ uc_fs_seek(uc_vm_t *vm, size_t nargs)
return ucv_boolean_new(true);
}

/**
* Truncate file to a given size
*
* Returns `true` if the file was successfully truncated.
*
* Returns `null` if an error occurred.
*
* @function module:fs.file#truncate
*
* @param {number} [offset=0]
* The offset in bytes.
*
* @returns {?boolean}
*/
static uc_value_t *
uc_fs_truncate(uc_vm_t *vm, size_t nargs)
{
FILE *fp = uc_fn_thisval("fs.file");
uc_value_t *ofs = uc_fn_arg(0);
off_t offset;

if (!fp)
err_return(EBADF);

if (!ofs)
offset = 0;
else if (ucv_type(ofs) != UC_INTEGER)
err_return(EINVAL);
else
offset = (off_t)ucv_int64_get(ofs);

if (ftruncate(fileno(fp), offset) < 0)
err_return(errno);

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.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.
*
Expand Down Expand Up @@ -2571,6 +2663,8 @@ static const uc_function_list_t file_fns[] = {
{ "fileno", uc_fs_fileno },
{ "error", uc_fs_error },
{ "isatty", uc_fs_isatty },
{ "truncate", uc_fs_truncate },
{ "lock", uc_fs_lock },
};

static const uc_function_list_t dir_fns[] = {
Expand Down
2 changes: 2 additions & 0 deletions tests/custom/03_stdlib/40_proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ 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] }",
"fileno": "function fileno(...) { [native code] }",
Expand Down

0 comments on commit 5c26244

Please sign in to comment.