implemented sys::flock() with fcntl()
This commit is contained in:
parent
388e576ad9
commit
fb1084a045
@ -65,6 +65,10 @@
|
||||
|
||||
#define CLOSE_KEEPFD (1 << 0)
|
||||
|
||||
/* these must not conflict with F_RDLCK, F_WRLCK, F_UNLCK */
|
||||
#define FLOCK_GET (1 << 30)
|
||||
#define FLOCK_WAIT (1 << 31)
|
||||
|
||||
/*
|
||||
* IMPLEMENTATION NOTE:
|
||||
* - hard failure only if it cannot make a final return value. (e.g. fnc_errmsg, fnc_fork, fnc_getpid)
|
||||
@ -909,6 +913,128 @@ done:
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
BEGIN {
|
||||
f1 = sys::open("/tmp/x", sys::O_RDWR | sys::O_CREAT | sys::O_TRUNC, 0644);
|
||||
if (sys::flock(f1, sys::FLOCK_WRITE | sys::FLOCK_GET, 0, 0, sys::SEEK_SET, pid) != sys::FLOCK_UNLOCK) print "locked by", pid;
|
||||
sys::flock(f1, sys::FLOCK_WRITE | sys::FLOCK_WAIT, 0, 0, sys::SEEK_SET);
|
||||
sys::sleep(ARGV[1]);
|
||||
sys::flock(f1, sys::FLOCK_UNLOCK | sys::FLOCK_WAIT, 0, 0, sys::SEEK_SET);
|
||||
sys::sleep(ARGV[1]);
|
||||
sys::close (f1);
|
||||
}
|
||||
*/
|
||||
static int fnc_flock (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
sys_node_t* sys_node;
|
||||
hawk_int_t rx;
|
||||
hawk_val_t* retv;
|
||||
|
||||
HAWK_STATIC_ASSERT (FLOCK_GET != F_RDLCK);
|
||||
HAWK_STATIC_ASSERT (FLOCK_GET != F_WRLCK);
|
||||
HAWK_STATIC_ASSERT (FLOCK_GET != F_UNLCK);
|
||||
HAWK_STATIC_ASSERT (FLOCK_WAIT != F_RDLCK);
|
||||
HAWK_STATIC_ASSERT (FLOCK_WAIT != F_WRLCK);
|
||||
HAWK_STATIC_ASSERT (FLOCK_WAIT != F_UNLCK);
|
||||
|
||||
sys_list = rtx_to_sys_list(rtx, fi);
|
||||
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FILE, &rx);
|
||||
if (sys_node)
|
||||
{
|
||||
hawk_int_t type, start, len, whence;
|
||||
int wait, get;
|
||||
struct flock fl;
|
||||
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &type) <= -1 ||
|
||||
hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &start) <= -1 ||
|
||||
hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 3), &len) <= -1 ||
|
||||
hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 4), &whence) <= -1)
|
||||
{
|
||||
fail:
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
goto done;
|
||||
}
|
||||
|
||||
wait = !!(type & FLOCK_WAIT);
|
||||
get = !!(type & FLOCK_GET);
|
||||
type &= ~(FLOCK_WAIT | FLOCK_GET);
|
||||
|
||||
HAWK_MEMSET (&fl, 0, HAWK_SIZEOF(fl));
|
||||
fl.l_type = type;
|
||||
fl.l_whence = whence;
|
||||
fl.l_start = start;
|
||||
fl.l_len = len;
|
||||
|
||||
rx = fcntl(sys_node->ctx.u.file.fd, (get? F_GETLK: (wait? F_SETLKW: F_SETLK)), &fl);
|
||||
if (rx <= -1)
|
||||
{
|
||||
set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (get && hawk_rtx_getnargs(rtx) >= 6)
|
||||
{
|
||||
hawk_val_t* sv;
|
||||
int x;
|
||||
|
||||
sv = hawk_rtx_makeintval(rtx, fl.l_pid);
|
||||
if (!sv) goto fail;
|
||||
|
||||
hawk_rtx_refupval (rtx, sv);
|
||||
x = hawk_rtx_setrefval(rtx, (hawk_val_ref_t*)hawk_rtx_getarg(rtx, 5), sv);
|
||||
hawk_rtx_refdownval (rtx, sv);
|
||||
if (x <= -1) goto fail;
|
||||
|
||||
rx = fl.l_type; /* for get, it returns the lock type */
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
retv = hawk_rtx_makeintval(rtx, rx);
|
||||
if (!retv) return -1; /* hard failure. unable to make a return value */
|
||||
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_fseek (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) /* this is actually lseek */
|
||||
{
|
||||
sys_list_t* sys_list;
|
||||
sys_node_t* sys_node;
|
||||
hawk_int_t rx;
|
||||
hawk_val_t* retv;
|
||||
|
||||
sys_list = rtx_to_sys_list(rtx, fi);
|
||||
sys_node = get_sys_list_node_with_arg(rtx, sys_list, hawk_rtx_getarg(rtx, 0), SYS_NODE_DATA_TYPE_FILE, &rx);
|
||||
if (sys_node)
|
||||
{
|
||||
hawk_int_t offset, whence;
|
||||
|
||||
if (hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 1), &offset) <= -1 ||
|
||||
hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 2), &whence) <= -1)
|
||||
{
|
||||
rx = copy_error_to_sys_list(rtx, sys_list);
|
||||
goto done;
|
||||
}
|
||||
|
||||
rx = lseek(sys_node->ctx.u.file.fd, offset, whence);
|
||||
if (rx <= -1)
|
||||
{
|
||||
set_error_on_sys_list_with_errno(rtx, sys_list, HAWK_NULL);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
retv = hawk_rtx_makeintval(rtx, rx);
|
||||
if (!retv) return -1; /* hard failure. unable to make a return value */
|
||||
|
||||
hawk_rtx_setretval (rtx, retv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/*
|
||||
@ -4107,13 +4233,15 @@ static fnctab_t fnctab[] =
|
||||
{ HAWK_T("fchmod"), { { 2, 2, HAWK_NULL }, fnc_fchmod, 0 } },
|
||||
{ HAWK_T("fchown"), { { 3, 3, HAWK_NULL }, fnc_fchown, 0 } },
|
||||
{ HAWK_T("fcntl"), { { 2, 3, HAWK_NULL }, fnc_fcntl, 0 } },
|
||||
{ HAWK_T("flock"), { { 5, 6, HAWK_T("vvvvvr")}, fnc_flock, 0 } },
|
||||
{ HAWK_T("fork"), { { 0, 0, HAWK_NULL }, fnc_fork, 0 } },
|
||||
{ HAWK_T("fseek"), { { 3, 3, HAWK_NULL }, fnc_fseek, 0 } },
|
||||
{ HAWK_T("getegid"), { { 0, 0, HAWK_NULL }, fnc_getegid, 0 } },
|
||||
{ HAWK_T("getenv"), { { 2, 2, HAWK_T("vr") }, fnc_getenv, 0 } },
|
||||
{ HAWK_T("geteuid"), { { 0, 0, HAWK_NULL }, fnc_geteuid, 0 } },
|
||||
{ HAWK_T("getgid"), { { 0, 0, HAWK_NULL }, fnc_getgid, 0 } },
|
||||
{ HAWK_T("getifcfg"), { { 3, 3, HAWK_T("vvr") }, fnc_getifcfg, 0 } },
|
||||
{ HAWK_T("getmuxevt"), { { 4, 4, HAWK_T("vvrr")}, fnc_getmuxevt, 0 } },
|
||||
{ HAWK_T("getmuxevt"), { { 4, 4, HAWK_T("vvrr") }, fnc_getmuxevt, 0 } },
|
||||
{ HAWK_T("getnwifcfg"), { { 3, 3, HAWK_T("vvr") }, fnc_getifcfg, 0 } }, /* backward compatibility */
|
||||
{ HAWK_T("getpgid"), { { 0, 0, HAWK_NULL }, fnc_getpgid, 0 } },
|
||||
{ HAWK_T("getpid"), { { 0, 0, HAWK_NULL }, fnc_getpid, 0 } },
|
||||
@ -4134,7 +4262,7 @@ static fnctab_t fnctab[] =
|
||||
{ HAWK_T("pipe"), { { 2, 3, HAWK_T("rrv") }, fnc_pipe, 0 } },
|
||||
{ HAWK_T("read"), { { 2, 3, HAWK_T("vrv") }, fnc_read, 0 } },
|
||||
{ HAWK_T("readdir"), { { 2, 2, HAWK_T("vr") }, fnc_readdir, 0 } },
|
||||
{ HAWK_T("recvfrom"), { { 2, 4, HAWK_T("vrvr")}, fnc_recvfrom, 0 } },
|
||||
{ HAWK_T("recvfrom"), { { 2, 4, HAWK_T("vrvr") }, fnc_recvfrom, 0 } },
|
||||
{ HAWK_T("resetdir"), { { 2, 2, HAWK_NULL }, fnc_resetdir, 0 } },
|
||||
{ HAWK_T("rmdir"), { { 1, 1, HAWK_NULL }, fnc_rmdir, 0 } },
|
||||
{ HAWK_T("sendto"), { { 2, 3, HAWK_NULL }, fnc_sendto, 0 } },
|
||||
@ -4194,6 +4322,12 @@ static inttab_t inttab[] =
|
||||
|
||||
{ HAWK_T("FD_CLOEXEC"), { FD_CLOEXEC } },
|
||||
|
||||
{ HAWK_T("FLOCK_GET"), { FLOCK_GET } }, /* bitwise-OR with another FLOCK_READ/WRITE/WAIT value */
|
||||
{ HAWK_T("FLOCK_READ"), { F_RDLCK } },
|
||||
{ HAWK_T("FLOCK_UNLOCK"), { F_UNLCK } },
|
||||
{ HAWK_T("FLOCK_WAIT"), { FLOCK_WAIT } }, /* bitwise-OR with another FLOCK_READ/WRITE/WAIT value */
|
||||
{ HAWK_T("FLOCK_WRITE"), { F_WRLCK } },
|
||||
|
||||
{ HAWK_T("F_GETFD"), { F_GETFD } },
|
||||
{ HAWK_T("F_GETFL"), { F_GETFL } },
|
||||
{ HAWK_T("F_SETFD"), { F_SETFD } },
|
||||
@ -4322,6 +4456,10 @@ static inttab_t inttab[] =
|
||||
{ HAWK_T("RC_ESYSERR"), { -HAWK_ESYSERR } },
|
||||
{ HAWK_T("RC_ETMOUT"), { -HAWK_ETMOUT } },
|
||||
|
||||
{ HAWK_T("SEEK_CUR"), { SEEK_CUR } },
|
||||
{ HAWK_T("SEEK_END"), { SEEK_END } },
|
||||
{ HAWK_T("SEEK_SET"), { SEEK_SET } },
|
||||
|
||||
{ HAWK_T("SHUT_RD"), { SHUT_RD } },
|
||||
{ HAWK_T("SHUT_RDWR"), { SHUT_RDWR } },
|
||||
{ HAWK_T("SHUT_WR"), { SHUT_WR } },
|
||||
|
Loading…
Reference in New Issue
Block a user