mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Refactor fcntl(2) ABI.
This is an incompatible ABI change.
This commit is contained in:
parent
4e520c8c36
commit
8c0e0235d6
3 changed files with 68 additions and 30 deletions
|
@ -24,16 +24,26 @@
|
||||||
|
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
DEFN_SYSCALL3(int, sys_fcntl, SYSCALL_FCNTL, int, int, unsigned long);
|
DEFN_SYSCALL3(int, sys_fcntl, SYSCALL_FCNTL, int, int, uintptr_t);
|
||||||
|
|
||||||
extern "C" int fcntl(int fd, int cmd, ...)
|
extern "C" int fcntl(int fd, int cmd, ...)
|
||||||
{
|
{
|
||||||
|
uintptr_t arg;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, cmd);
|
va_start(ap, cmd);
|
||||||
unsigned long arg = va_arg(ap, unsigned long);
|
switch ( F_DECODE_CMD_TYPE(cmd) )
|
||||||
|
{
|
||||||
|
case F_TYPE_VOID: arg = 0; break;
|
||||||
|
case F_TYPE_INT: arg = (uintptr_t) va_arg(ap, int); break;
|
||||||
|
case F_TYPE_LONG: arg = (uintptr_t) va_arg(ap, long); break;
|
||||||
|
case F_TYPE_PTR: arg = (uintptr_t) va_arg(ap, void*); break;
|
||||||
|
default: return errno = EINVAL, -1;
|
||||||
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return sys_fcntl(fd, cmd, arg);
|
return sys_fcntl(fd, cmd, arg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,10 +50,43 @@ __BEGIN_DECLS
|
||||||
|
|
||||||
#define __FD_ALLOWED_FLAGS (FD_CLOEXEC | FD_CLOFORK)
|
#define __FD_ALLOWED_FLAGS (FD_CLOEXEC | FD_CLOFORK)
|
||||||
|
|
||||||
#define F_SETFD 0
|
/* Encode type information about arguments into fcntl commands. Unfortunately
|
||||||
#define F_GETFD 1
|
the fcntl function declaration doesn't include type information, which means
|
||||||
#define F_SETFL 2
|
that the fcntl implementation either needs a list of command type information
|
||||||
#define F_GETFL 3
|
to use va_list correctly - or we can simply embed the information into the
|
||||||
|
commands. */
|
||||||
|
#define F_TYPE_EXP 3 /* 2^3 kinds of argument types supported.*/
|
||||||
|
#define F_TYPE_VOID 0
|
||||||
|
#define F_TYPE_INT 1
|
||||||
|
#define F_TYPE_LONG 2
|
||||||
|
#define F_TYPE_PTR 3
|
||||||
|
/* 5-7 is unused in case of future expansion. */
|
||||||
|
#define F_ENCODE_CMD(cmd_val, arg_type) ((cmd_val) << F_TYPE_EXP | (arg_type))
|
||||||
|
#define F_DECODE_CMD_RAW(cmd) (cmd >> F_TYPE_EXP)
|
||||||
|
#define F_DECODE_CMD_TYPE(cmd) ((cmd) & ((1 << F_TYPE_EXP)-1))
|
||||||
|
|
||||||
|
/* Encode small parameters into fcntl commands. This allows adding some flags
|
||||||
|
and other modifiers to fcntl commands without declaring a heap of new fcntl
|
||||||
|
commands variants. */
|
||||||
|
#define F_ENCODE(cmd, small_param) (((cmd) & 0xFFFF) | ((small_param) << 16))
|
||||||
|
#define F_DECODE_CMD(val) (val & 0xFFFF)
|
||||||
|
#define F_DECODE_FLAGS(val) ((val & ~0xFFFF) >> 16)
|
||||||
|
|
||||||
|
/* Set file descriptor status. */
|
||||||
|
#define F_SETFD_NUM 0
|
||||||
|
#define F_SETFD F_ENCODE_CMD(F_SETFD_NUM, F_TYPE_INT)
|
||||||
|
|
||||||
|
/* Get file descriptor status. */
|
||||||
|
#define F_GETFD_NUM 1
|
||||||
|
#define F_GETFD F_ENCODE_CMD(F_GETFD_NUM, F_TYPE_VOID)
|
||||||
|
|
||||||
|
/* Set descriptor table entry flags. */
|
||||||
|
#define F_SETFL_NUM 3
|
||||||
|
#define F_SETFL F_ENCODE_CMD(F_SETFL_NUM, F_TYPE_INT)
|
||||||
|
|
||||||
|
/* Get descriptor table entry flags. */
|
||||||
|
#define F_GETFL_NUM 3
|
||||||
|
#define F_GETFL F_ENCODE_CMD(F_GETFL_NUM, F_TYPE_VOID)
|
||||||
|
|
||||||
#define AT_FDCWD (-100)
|
#define AT_FDCWD (-100)
|
||||||
#define AT_REMOVEDIR (1<<0)
|
#define AT_REMOVEDIR (1<<0)
|
||||||
|
|
|
@ -316,32 +316,27 @@ static int sys_fstat(int fd, struct stat* st)
|
||||||
return desc->stat(&ctx, st);
|
return desc->stat(&ctx, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_fcntl(int fd, int cmd, unsigned long arg)
|
static int sys_fcntl(int fd, int cmd, uintptr_t arg)
|
||||||
{
|
{
|
||||||
|
// Operations on the descriptor table.
|
||||||
Ref<DescriptorTable> dtable = CurrentProcess()->GetDTable();
|
Ref<DescriptorTable> dtable = CurrentProcess()->GetDTable();
|
||||||
Ref<Descriptor> desc;
|
|
||||||
int ret = -1;
|
// Operations on the file descriptior.
|
||||||
switch ( cmd )
|
if ( cmd == F_SETFD )
|
||||||
{
|
return dtable->SetFlags(fd, (int) arg) ? 0 : -1;;
|
||||||
case F_SETFD:
|
if ( cmd == F_GETFD )
|
||||||
ret = dtable->SetFlags(fd, (int) arg) ? 0 : -1;
|
return dtable->GetFlags(fd);
|
||||||
break;
|
|
||||||
case F_GETFD:
|
// Operations on the file description.
|
||||||
ret = dtable->GetFlags(fd);
|
Ref<Descriptor> desc = dtable->Get(fd);
|
||||||
break;
|
if ( !desc )
|
||||||
case F_SETFL:
|
return -1;
|
||||||
if ( (desc = dtable->Get(fd)) )
|
if ( cmd == F_SETFL )
|
||||||
ret = desc->SetFlags((int) arg) ? 0 : -1;
|
return desc->SetFlags((int) arg);
|
||||||
break;
|
if ( cmd == F_GETFL )
|
||||||
case F_GETFL:
|
return desc->GetFlags();
|
||||||
if ( (desc = dtable->Get(fd)) )
|
|
||||||
ret = desc->GetFlags();
|
return errno = EINVAL, -1;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
errno = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_ioctl(int fd, int cmd, void* /*ptr*/)
|
static int sys_ioctl(int fd, int cmd, void* /*ptr*/)
|
||||||
|
|
Loading…
Add table
Reference in a new issue