UDS: split off from PFS
Change-Id: I769cbd64aa6e5e85a797caf0f8bbb4c20e145263
This commit is contained in:
parent
6d466f941b
commit
b003ed0929
22 changed files with 399 additions and 447 deletions
|
@ -4758,6 +4758,7 @@
|
||||||
./usr/sbin/rs minix-sys
|
./usr/sbin/rs minix-sys
|
||||||
./usr/sbin/sched minix-sys
|
./usr/sbin/sched minix-sys
|
||||||
./usr/sbin/tty minix-sys
|
./usr/sbin/tty minix-sys
|
||||||
|
./usr/sbin/uds minix-sys
|
||||||
./usr/sbin/unlink minix-sys
|
./usr/sbin/unlink minix-sys
|
||||||
./usr/sbin/user minix-sys
|
./usr/sbin/user minix-sys
|
||||||
./usr/sbin/useradd minix-sys
|
./usr/sbin/useradd minix-sys
|
||||||
|
|
|
@ -18,13 +18,13 @@ SUBDIR= tty
|
||||||
.if ${MACHINE_ARCH} == "i386"
|
.if ${MACHINE_ARCH} == "i386"
|
||||||
SUBDIR= ahci amddev atl2 at_wini audio dec21140A dp8390 dpeth \
|
SUBDIR= ahci amddev atl2 at_wini audio dec21140A dp8390 dpeth \
|
||||||
e1000 fbd filter floppy fxp hello lance log mmc orinoco pci pckbd \
|
e1000 fbd filter floppy fxp hello lance log mmc orinoco pci pckbd \
|
||||||
printer random readclock rtl8139 rtl8169 ti1225 tty vbox acpi \
|
printer random readclock rtl8139 rtl8169 ti1225 tty uds vbox acpi \
|
||||||
virtio_blk virtio_net vnd
|
virtio_blk virtio_net vnd
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${MACHINE_ARCH} == "earm"
|
.if ${MACHINE_ARCH} == "earm"
|
||||||
SUBDIR= bmp085 cat24c256 fb gpio i2c mmc lan8710a log readclock \
|
SUBDIR= bmp085 cat24c256 fb gpio i2c mmc lan8710a log readclock \
|
||||||
sht21 tda19988 tps65217 tps65950 tsl2550 tty random vnd
|
sht21 tda19988 tps65217 tps65950 tsl2550 tty random uds vnd
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.endif # ${MKIMAGEONLY} != "yes"
|
.endif # ${MKIMAGEONLY} != "yes"
|
||||||
|
|
12
drivers/uds/Makefile
Normal file
12
drivers/uds/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Makefile for the UNIX Domain Sockets driver (UDS)
|
||||||
|
PROG= uds
|
||||||
|
SRCS= uds.c ioc_uds.c
|
||||||
|
|
||||||
|
DPADD+= ${LIBCHARDRIVER} ${LIBSYS}
|
||||||
|
LDADD+= -lchardriver -lsys
|
||||||
|
|
||||||
|
MAN=
|
||||||
|
|
||||||
|
BINDIR?= /usr/sbin
|
||||||
|
|
||||||
|
.include <minix.service.mk>
|
|
@ -5,37 +5,17 @@
|
||||||
*
|
*
|
||||||
* The entry points into this file are...
|
* The entry points into this file are...
|
||||||
*
|
*
|
||||||
* uds_init: initialize the descriptor table.
|
|
||||||
* uds_do_ioctl: process an IOCTL request.
|
* uds_do_ioctl: process an IOCTL request.
|
||||||
* uds_clear_fds: calls put_filp for undelivered FDs.
|
* uds_clear_fds: calls put_filp for undelivered FDs.
|
||||||
*
|
|
||||||
* Also see...
|
|
||||||
*
|
|
||||||
* dev_uds.c, uds.h
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DEBUG 0
|
|
||||||
|
|
||||||
#include "inc.h"
|
|
||||||
#include "const.h"
|
|
||||||
#include "glo.h"
|
|
||||||
#include "uds.h"
|
#include "uds.h"
|
||||||
|
|
||||||
/* File Descriptor Table */
|
|
||||||
uds_fd_t uds_fd_table[NR_FDS];
|
|
||||||
|
|
||||||
/* initialize the descriptor table */
|
|
||||||
void uds_init(void)
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Setting everything to NULL implicitly sets the
|
* Check the permissions of a socket file.
|
||||||
* state to UDS_FREE.
|
|
||||||
*/
|
*/
|
||||||
memset(uds_fd_table, '\0', sizeof(uds_fd_t) * NR_FDS);
|
static int
|
||||||
}
|
check_perms(devminor_t minor, struct sockaddr_un *addr)
|
||||||
|
|
||||||
/* check the permissions of a socket file */
|
|
||||||
static int check_perms(devminor_t minor, struct sockaddr_un *addr)
|
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
message vfs_m;
|
message vfs_m;
|
||||||
|
@ -47,10 +27,10 @@ static int check_perms(devminor_t minor, struct sockaddr_un *addr)
|
||||||
/* ask the VFS to verify the permissions */
|
/* ask the VFS to verify the permissions */
|
||||||
memset(&vfs_m, '\0', sizeof(message));
|
memset(&vfs_m, '\0', sizeof(message));
|
||||||
|
|
||||||
vfs_m.m_type = VFS_PFS_CHECK_PERMS;
|
vfs_m.m_type = VFS_UDS_CHECK_PERMS;
|
||||||
vfs_m.VFS_PFS_ENDPT = uds_fd_table[minor].owner;
|
vfs_m.VFS_UDS_ENDPT = uds_fd_table[minor].owner;
|
||||||
vfs_m.VFS_PFS_GRANT = grant_id;
|
vfs_m.VFS_UDS_GRANT = grant_id;
|
||||||
vfs_m.VFS_PFS_COUNT = UNIX_PATH_MAX;
|
vfs_m.VFS_UDS_COUNT = UNIX_PATH_MAX;
|
||||||
|
|
||||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||||
cpf_revoke(grant_id);
|
cpf_revoke(grant_id);
|
||||||
|
@ -69,7 +49,8 @@ static int check_perms(devminor_t minor, struct sockaddr_un *addr)
|
||||||
return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
|
return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static filp_id_t verify_fd(endpoint_t ep, int fd)
|
static filp_id_t
|
||||||
|
verify_fd(endpoint_t ep, int fd)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
message vfs_m;
|
message vfs_m;
|
||||||
|
@ -82,9 +63,9 @@ static filp_id_t verify_fd(endpoint_t ep, int fd)
|
||||||
|
|
||||||
memset(&vfs_m, '\0', sizeof(message));
|
memset(&vfs_m, '\0', sizeof(message));
|
||||||
|
|
||||||
vfs_m.m_type = VFS_PFS_VERIFY_FD;
|
vfs_m.m_type = VFS_UDS_VERIFY_FD;
|
||||||
vfs_m.VFS_PFS_ENDPT = ep;
|
vfs_m.VFS_UDS_ENDPT = ep;
|
||||||
vfs_m.VFS_PFS_FD = fd;
|
vfs_m.VFS_UDS_FD = fd;
|
||||||
|
|
||||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||||
if (OK != rc) {
|
if (OK != rc) {
|
||||||
|
@ -97,10 +78,11 @@ static filp_id_t verify_fd(endpoint_t ep, int fd)
|
||||||
printf("(uds) VFS reply => %d\n", vfs_m.m_type);
|
printf("(uds) VFS reply => %d\n", vfs_m.m_type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return vfs_m.VFS_PFS_FILP;
|
return vfs_m.VFS_UDS_FILP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_filp(filp_id_t sfilp)
|
static int
|
||||||
|
set_filp(filp_id_t sfilp)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
message vfs_m;
|
message vfs_m;
|
||||||
|
@ -112,8 +94,8 @@ static int set_filp(filp_id_t sfilp)
|
||||||
|
|
||||||
memset(&vfs_m, '\0', sizeof(message));
|
memset(&vfs_m, '\0', sizeof(message));
|
||||||
|
|
||||||
vfs_m.m_type = VFS_PFS_SET_FILP;
|
vfs_m.m_type = VFS_UDS_SET_FILP;
|
||||||
vfs_m.VFS_PFS_FILP = sfilp;
|
vfs_m.VFS_UDS_FILP = sfilp;
|
||||||
|
|
||||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||||
if (OK != rc) {
|
if (OK != rc) {
|
||||||
|
@ -128,7 +110,8 @@ static int set_filp(filp_id_t sfilp)
|
||||||
return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
|
return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int copy_filp(endpoint_t to_ep, filp_id_t cfilp)
|
static int
|
||||||
|
copy_filp(endpoint_t to_ep, filp_id_t cfilp)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
message vfs_m;
|
message vfs_m;
|
||||||
|
@ -141,9 +124,9 @@ static int copy_filp(endpoint_t to_ep, filp_id_t cfilp)
|
||||||
|
|
||||||
memset(&vfs_m, '\0', sizeof(message));
|
memset(&vfs_m, '\0', sizeof(message));
|
||||||
|
|
||||||
vfs_m.m_type = VFS_PFS_COPY_FILP;
|
vfs_m.m_type = VFS_UDS_COPY_FILP;
|
||||||
vfs_m.VFS_PFS_ENDPT = to_ep;
|
vfs_m.VFS_UDS_ENDPT = to_ep;
|
||||||
vfs_m.VFS_PFS_FILP = cfilp;
|
vfs_m.VFS_UDS_FILP = cfilp;
|
||||||
|
|
||||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||||
if (OK != rc) {
|
if (OK != rc) {
|
||||||
|
@ -158,7 +141,8 @@ static int copy_filp(endpoint_t to_ep, filp_id_t cfilp)
|
||||||
return vfs_m.m_type;
|
return vfs_m.m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int put_filp(filp_id_t pfilp)
|
static int
|
||||||
|
put_filp(filp_id_t pfilp)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
message vfs_m;
|
message vfs_m;
|
||||||
|
@ -170,8 +154,8 @@ static int put_filp(filp_id_t pfilp)
|
||||||
|
|
||||||
memset(&vfs_m, '\0', sizeof(message));
|
memset(&vfs_m, '\0', sizeof(message));
|
||||||
|
|
||||||
vfs_m.m_type = VFS_PFS_PUT_FILP;
|
vfs_m.m_type = VFS_UDS_PUT_FILP;
|
||||||
vfs_m.VFS_PFS_FILP = pfilp;
|
vfs_m.VFS_UDS_FILP = pfilp;
|
||||||
|
|
||||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||||
if (OK != rc) {
|
if (OK != rc) {
|
||||||
|
@ -186,7 +170,8 @@ static int put_filp(filp_id_t pfilp)
|
||||||
return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
|
return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cancel_fd(endpoint_t ep, int fd)
|
static int
|
||||||
|
cancel_fd(endpoint_t ep, int fd)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
message vfs_m;
|
message vfs_m;
|
||||||
|
@ -198,9 +183,9 @@ static int cancel_fd(endpoint_t ep, int fd)
|
||||||
|
|
||||||
memset(&vfs_m, '\0', sizeof(message));
|
memset(&vfs_m, '\0', sizeof(message));
|
||||||
|
|
||||||
vfs_m.m_type = VFS_PFS_CANCEL_FD;
|
vfs_m.m_type = VFS_UDS_CANCEL_FD;
|
||||||
vfs_m.VFS_PFS_ENDPT = ep;
|
vfs_m.VFS_UDS_ENDPT = ep;
|
||||||
vfs_m.VFS_PFS_FD = fd;
|
vfs_m.VFS_UDS_FD = fd;
|
||||||
|
|
||||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||||
if (OK != rc) {
|
if (OK != rc) {
|
||||||
|
@ -215,7 +200,8 @@ static int cancel_fd(endpoint_t ep, int fd)
|
||||||
return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
|
return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int perform_connection(devminor_t minorx, devminor_t minory,
|
static int
|
||||||
|
perform_connection(devminor_t minorx, devminor_t minory,
|
||||||
struct sockaddr_un *addr)
|
struct sockaddr_un *addr)
|
||||||
{
|
{
|
||||||
/* there are several places were a connection is established. */
|
/* there are several places were a connection is established. */
|
||||||
|
@ -251,7 +237,8 @@ static int perform_connection(devminor_t minorx, devminor_t minory,
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_accept(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
static int
|
||||||
|
do_accept(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
devminor_t minorparent; /* minor number of parent (server) */
|
devminor_t minorparent; /* minor number of parent (server) */
|
||||||
devminor_t minorpeer;
|
devminor_t minorpeer;
|
||||||
|
@ -370,7 +357,8 @@ static int do_accept(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_connect(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
static int
|
||||||
|
do_connect(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int child;
|
int child;
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
|
@ -509,7 +497,8 @@ static int do_connect(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
return EDONTREPLY;
|
return EDONTREPLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_listen(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
static int
|
||||||
|
do_listen(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
int backlog_size;
|
int backlog_size;
|
||||||
|
@ -585,7 +574,8 @@ static int do_listen(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_socket(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
static int
|
||||||
|
do_socket(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -629,7 +619,8 @@ static int do_socket(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_bind(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
static int
|
||||||
|
do_bind(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
int rc, i;
|
int rc, i;
|
||||||
|
@ -690,8 +681,8 @@ static int do_bind(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_getsockname(devminor_t minor, endpoint_t endpt,
|
static int
|
||||||
cp_grant_id_t grant)
|
do_getsockname(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -714,8 +705,8 @@ static int do_getsockname(devminor_t minor, endpoint_t endpt,
|
||||||
return rc ? EIO : OK;
|
return rc ? EIO : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_getpeername(devminor_t minor, endpoint_t endpt,
|
static int
|
||||||
cp_grant_id_t grant)
|
do_getpeername(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -748,7 +739,8 @@ static int do_getpeername(devminor_t minor, endpoint_t endpt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_shutdown(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
static int
|
||||||
|
do_shutdown(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc, how;
|
int rc, how;
|
||||||
|
|
||||||
|
@ -784,12 +776,12 @@ static int do_shutdown(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
switch (how) {
|
switch (how) {
|
||||||
case SHUT_RD:
|
case SHUT_RD:
|
||||||
/* take away read permission */
|
/* take away read permission */
|
||||||
uds_fd_table[minor].mode &= ~S_IRUSR;
|
uds_fd_table[minor].mode &= ~R_BIT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHUT_WR:
|
case SHUT_WR:
|
||||||
/* take away write permission */
|
/* take away write permission */
|
||||||
uds_fd_table[minor].mode &= ~S_IWUSR;
|
uds_fd_table[minor].mode &= ~W_BIT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHUT_RDWR:
|
case SHUT_RDWR:
|
||||||
|
@ -805,8 +797,8 @@ static int do_shutdown(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_socketpair(devminor_t minorx, endpoint_t endpt,
|
static int
|
||||||
cp_grant_id_t grant)
|
do_socketpair(devminor_t minorx, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
dev_t minorin;
|
dev_t minorin;
|
||||||
|
@ -848,8 +840,8 @@ static int do_socketpair(devminor_t minorx, endpoint_t endpt,
|
||||||
return perform_connection(minorx, minory, &addr);
|
return perform_connection(minorx, minory, &addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_getsockopt_sotype(devminor_t minor, endpoint_t endpt,
|
static int
|
||||||
cp_grant_id_t grant)
|
do_getsockopt_sotype(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -872,8 +864,8 @@ static int do_getsockopt_sotype(devminor_t minor, endpoint_t endpt,
|
||||||
return rc ? EIO : OK;
|
return rc ? EIO : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_getsockopt_peercred(devminor_t minor, endpoint_t endpt,
|
static int
|
||||||
cp_grant_id_t grant)
|
do_getsockopt_peercred(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int peer_minor;
|
int peer_minor;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -911,8 +903,8 @@ static int do_getsockopt_peercred(devminor_t minor, endpoint_t endpt,
|
||||||
return rc ? EIO : OK;
|
return rc ? EIO : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_getsockopt_sndbuf(devminor_t minor, endpoint_t endpt,
|
static int
|
||||||
cp_grant_id_t grant)
|
do_getsockopt_sndbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
size_t sndbuf = PIPE_BUF;
|
size_t sndbuf = PIPE_BUF;
|
||||||
|
@ -929,8 +921,8 @@ static int do_getsockopt_sndbuf(devminor_t minor, endpoint_t endpt,
|
||||||
return rc ? EIO : OK;
|
return rc ? EIO : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_setsockopt_sndbuf(devminor_t minor, endpoint_t endpt,
|
static int
|
||||||
cp_grant_id_t grant)
|
do_setsockopt_sndbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
size_t sndbuf;
|
size_t sndbuf;
|
||||||
|
@ -959,8 +951,8 @@ static int do_setsockopt_sndbuf(devminor_t minor, endpoint_t endpt,
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_getsockopt_rcvbuf(devminor_t minor, endpoint_t endpt,
|
static int
|
||||||
cp_grant_id_t grant)
|
do_getsockopt_rcvbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
size_t rcvbuf = PIPE_BUF;
|
size_t rcvbuf = PIPE_BUF;
|
||||||
|
@ -977,8 +969,8 @@ static int do_getsockopt_rcvbuf(devminor_t minor, endpoint_t endpt,
|
||||||
return rc ? EIO : OK;
|
return rc ? EIO : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_setsockopt_rcvbuf(devminor_t minor, endpoint_t endpt,
|
static int
|
||||||
cp_grant_id_t grant)
|
do_setsockopt_rcvbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
size_t rcvbuf;
|
size_t rcvbuf;
|
||||||
|
@ -1007,7 +999,8 @@ static int do_setsockopt_rcvbuf(devminor_t minor, endpoint_t endpt,
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_sendto(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
static int
|
||||||
|
do_sendto(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
|
@ -1046,7 +1039,8 @@ static int do_sendto(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_recvfrom(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
static int
|
||||||
|
do_recvfrom(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -1063,8 +1057,9 @@ static int do_recvfrom(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
return rc ? EIO : OK;
|
return rc ? EIO : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int msg_control_read(struct msg_control *msg_ctrl,
|
static int
|
||||||
struct ancillary *data, devminor_t minor)
|
msg_control_read(struct msg_control *msg_ctrl, struct ancillary *data,
|
||||||
|
devminor_t minor)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct msghdr msghdr;
|
struct msghdr msghdr;
|
||||||
|
@ -1122,7 +1117,8 @@ static int msg_control_read(struct msg_control *msg_ctrl,
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_fds(devminor_t minor, struct ancillary *data)
|
static int
|
||||||
|
send_fds(devminor_t minor, struct ancillary *data)
|
||||||
{
|
{
|
||||||
int rc, i, j;
|
int rc, i, j;
|
||||||
|
|
||||||
|
@ -1156,13 +1152,15 @@ static int send_fds(devminor_t minor, struct ancillary *data)
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uds_clear_fds(devminor_t minor, struct ancillary *data)
|
/*
|
||||||
{
|
* This function calls put_filp() for all of the FDs in data.
|
||||||
/* This function calls put_filp() for all of the FDs in data.
|
|
||||||
* This is used when a Unix Domain Socket is closed and there
|
* This is used when a Unix Domain Socket is closed and there
|
||||||
* exists references to file descriptors that haven't been received
|
* exists references to file descriptors that haven't been received
|
||||||
* with recvmsg().
|
* with recvmsg().
|
||||||
*/
|
*/
|
||||||
|
int
|
||||||
|
uds_clear_fds(devminor_t minor, struct ancillary *data)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#if DEBUG == 1
|
#if DEBUG == 1
|
||||||
|
@ -1185,7 +1183,8 @@ int uds_clear_fds(devminor_t minor, struct ancillary *data)
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int recv_fds(devminor_t minor, struct ancillary *data,
|
static int
|
||||||
|
recv_fds(devminor_t minor, struct ancillary *data,
|
||||||
struct msg_control *msg_ctrl)
|
struct msg_control *msg_ctrl)
|
||||||
{
|
{
|
||||||
int rc, i, j;
|
int rc, i, j;
|
||||||
|
@ -1241,7 +1240,8 @@ static int recv_fds(devminor_t minor, struct ancillary *data,
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int recv_cred(devminor_t minor, struct ancillary *data,
|
static int
|
||||||
|
recv_cred(devminor_t minor, struct ancillary *data,
|
||||||
struct msg_control *msg_ctrl)
|
struct msg_control *msg_ctrl)
|
||||||
{
|
{
|
||||||
struct msghdr msghdr;
|
struct msghdr msghdr;
|
||||||
|
@ -1269,7 +1269,8 @@ static int recv_cred(devminor_t minor, struct ancillary *data,
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_sendmsg(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
static int
|
||||||
|
do_sendmsg(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int peer, rc, i;
|
int peer, rc, i;
|
||||||
struct msg_control msg_ctrl;
|
struct msg_control msg_ctrl;
|
||||||
|
@ -1339,7 +1340,8 @@ static int do_sendmsg(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
return send_fds(minor, &uds_fd_table[peer].ancillary_data);
|
return send_fds(minor, &uds_fd_table[peer].ancillary_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_recvmsg(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
static int
|
||||||
|
do_recvmsg(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct msg_control msg_ctrl;
|
struct msg_control msg_ctrl;
|
||||||
|
@ -1403,7 +1405,8 @@ static int do_recvmsg(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||||
return rc ? EIO : OK;
|
return rc ? EIO : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uds_do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
|
int
|
||||||
|
uds_do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
|
||||||
cp_grant_id_t grant)
|
cp_grant_id_t grant)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
|
@ -4,41 +4,31 @@
|
||||||
*
|
*
|
||||||
* The entry points into this file are...
|
* The entry points into this file are...
|
||||||
*
|
*
|
||||||
* uds_request: process a character device request
|
* uds_unsuspend: resume a previously suspended socket call
|
||||||
*
|
* main: driver main loop
|
||||||
* Also See...
|
|
||||||
*
|
|
||||||
* uds.c, uds.h
|
|
||||||
*
|
|
||||||
* Overview
|
|
||||||
*
|
*
|
||||||
* The interface to unix domain sockets is similar to the interface to network
|
* The interface to unix domain sockets is similar to the interface to network
|
||||||
* sockets. There is a character device (/dev/uds) and this server is a
|
* sockets. There is a character device (/dev/uds) and this server is a
|
||||||
* 'driver' for that device.
|
* 'driver' for that device.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DEBUG 0
|
|
||||||
|
|
||||||
#include "inc.h"
|
|
||||||
#include "const.h"
|
|
||||||
#include "glo.h"
|
|
||||||
#include "uds.h"
|
#include "uds.h"
|
||||||
|
|
||||||
static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
|
static ssize_t uds_perform_read(devminor_t, endpoint_t, cp_grant_id_t, size_t,
|
||||||
cp_grant_id_t grant, size_t size, int pretend);
|
int);
|
||||||
static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
static ssize_t uds_perform_write(devminor_t, endpoint_t, cp_grant_id_t, size_t,
|
||||||
cp_grant_id_t grant, size_t size, int pretend);
|
int);
|
||||||
|
|
||||||
static int uds_open(devminor_t orig_minor, int access, endpoint_t user_endpt);
|
static int uds_open(devminor_t, int, endpoint_t);
|
||||||
static int uds_close(devminor_t minor);
|
static int uds_close(devminor_t);
|
||||||
static ssize_t uds_read(devminor_t minor, u64_t position, endpoint_t endpt,
|
static ssize_t uds_read(devminor_t, u64_t, endpoint_t, cp_grant_id_t, size_t,
|
||||||
cp_grant_id_t grant, size_t size, int flags, cdev_id_t id);
|
int, cdev_id_t);
|
||||||
static ssize_t uds_write(devminor_t minor, u64_t position, endpoint_t endpt,
|
static ssize_t uds_write(devminor_t, u64_t, endpoint_t, cp_grant_id_t, size_t,
|
||||||
cp_grant_id_t grant, size_t size, int flags, cdev_id_t id);
|
int, cdev_id_t);
|
||||||
static int uds_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
|
static int uds_ioctl(devminor_t, unsigned long, endpoint_t, cp_grant_id_t, int,
|
||||||
cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id);
|
endpoint_t, cdev_id_t);
|
||||||
static int uds_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id);
|
static int uds_cancel(devminor_t, endpoint_t, cdev_id_t);
|
||||||
static int uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt);
|
static int uds_select(devminor_t, unsigned int, endpoint_t);
|
||||||
|
|
||||||
static struct chardriver uds_tab = {
|
static struct chardriver uds_tab = {
|
||||||
.cdr_open = uds_open,
|
.cdr_open = uds_open,
|
||||||
|
@ -50,19 +40,18 @@ static struct chardriver uds_tab = {
|
||||||
.cdr_select = uds_select
|
.cdr_select = uds_select
|
||||||
};
|
};
|
||||||
|
|
||||||
void uds_request(message *m_ptr, int ipc_status)
|
/* File Descriptor Table */
|
||||||
{
|
uds_fd_t uds_fd_table[NR_FDS];
|
||||||
/* Use libchardriver to process character device requests. */
|
|
||||||
chardriver_process(&uds_tab, m_ptr, ipc_status);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int uds_open(devminor_t UNUSED(orig_minor), int access,
|
static unsigned int uds_exit_left;
|
||||||
|
|
||||||
|
static int
|
||||||
|
uds_open(devminor_t UNUSED(orig_minor), int access,
|
||||||
endpoint_t user_endpt)
|
endpoint_t user_endpt)
|
||||||
{
|
{
|
||||||
message fs_m_in, fs_m_out;
|
|
||||||
struct uucred ucred;
|
|
||||||
devminor_t minor;
|
devminor_t minor;
|
||||||
int rc, i;
|
int i;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
#if DEBUG == 1
|
#if DEBUG == 1
|
||||||
static int call_count = 0;
|
static int call_count = 0;
|
||||||
|
@ -77,7 +66,6 @@ static int uds_open(devminor_t UNUSED(orig_minor), int access,
|
||||||
* minor number. The minor number must be different from the
|
* minor number. The minor number must be different from the
|
||||||
* the /dev/uds device's minor number (currently 0).
|
* the /dev/uds device's minor number (currently 0).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
minor = -1; /* to trap error */
|
minor = -1; /* to trap error */
|
||||||
|
|
||||||
for (i = 1; i < NR_FDS; i++) {
|
for (i = 1; i < NR_FDS; i++) {
|
||||||
|
@ -91,8 +79,14 @@ static int uds_open(devminor_t UNUSED(orig_minor), int access,
|
||||||
return ENFILE;
|
return ENFILE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We found a slot in uds_fd_table, now initialize the descriptor
|
* Allocate memory for the ringer buffer. In order to save on memory
|
||||||
|
* in the common case, the buffer is allocated only when the socket is
|
||||||
|
* in use. We use mmap instead of malloc to allow the memory to be
|
||||||
|
* actually freed later.
|
||||||
*/
|
*/
|
||||||
|
if ((buf = minix_mmap(NULL, PIPE_BUF, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_ANON | MAP_PRIVATE, -1, 0)) == MAP_FAILED)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
/* mark this one as 'in use' so that it doesn't get assigned to
|
/* mark this one as 'in use' so that it doesn't get assigned to
|
||||||
* another socket
|
* another socket
|
||||||
|
@ -105,8 +99,7 @@ static int uds_open(devminor_t UNUSED(orig_minor), int access,
|
||||||
/* setup select(2) framework */
|
/* setup select(2) framework */
|
||||||
uds_fd_table[minor].sel_endpt = NONE;
|
uds_fd_table[minor].sel_endpt = NONE;
|
||||||
uds_fd_table[minor].sel_ops = 0;
|
uds_fd_table[minor].sel_ops = 0;
|
||||||
|
uds_fd_table[minor].buf = buf;
|
||||||
/* initialize the data pointer (pos) to the start of the PIPE */
|
|
||||||
uds_fd_table[minor].pos = 0;
|
uds_fd_table[minor].pos = 0;
|
||||||
|
|
||||||
/* the PIPE is initially empty */
|
/* the PIPE is initially empty */
|
||||||
|
@ -115,7 +108,7 @@ static int uds_open(devminor_t UNUSED(orig_minor), int access,
|
||||||
/* the default for a new socket is to allow reading and writing.
|
/* the default for a new socket is to allow reading and writing.
|
||||||
* shutdown(2) will remove one or both flags.
|
* shutdown(2) will remove one or both flags.
|
||||||
*/
|
*/
|
||||||
uds_fd_table[minor].mode = S_IRUSR|S_IWUSR;
|
uds_fd_table[minor].mode = R_BIT | W_BIT;
|
||||||
|
|
||||||
/* In libc socket(2) sets this to the actual value later with the
|
/* In libc socket(2) sets this to the actual value later with the
|
||||||
* NWIOSUDSTYPE ioctl().
|
* NWIOSUDSTYPE ioctl().
|
||||||
|
@ -156,46 +149,13 @@ static int uds_open(devminor_t UNUSED(orig_minor), int access,
|
||||||
/* Initially the socket isn't suspended. */
|
/* Initially the socket isn't suspended. */
|
||||||
uds_fd_table[minor].suspended = UDS_NOT_SUSPENDED;
|
uds_fd_table[minor].suspended = UDS_NOT_SUSPENDED;
|
||||||
|
|
||||||
/* get the effective user id and effective group id from the endpoint */
|
|
||||||
/* this is needed in the REQ_NEWNODE request to PFS. */
|
|
||||||
rc = getnucred(user_endpt, &ucred);
|
|
||||||
if (rc == -1) {
|
|
||||||
/* roll back the changes we made to the descriptor */
|
|
||||||
memset(&(uds_fd_table[minor]), '\0', sizeof(uds_fd_t));
|
|
||||||
|
|
||||||
/* likely error: invalid endpoint / proc doesn't exist */
|
|
||||||
return EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare Request to the FS side of PFS */
|
|
||||||
|
|
||||||
fs_m_in.m_type = REQ_NEWNODE;
|
|
||||||
fs_m_in.REQ_MODE = I_NAMED_PIPE;
|
|
||||||
fs_m_in.REQ_DEV = NO_DEV;
|
|
||||||
fs_m_in.REQ_UID = ucred.cr_uid;
|
|
||||||
fs_m_in.REQ_GID = ucred.cr_gid;
|
|
||||||
|
|
||||||
/* Request a new inode on the pipe file system */
|
|
||||||
|
|
||||||
rc = fs_newnode(&fs_m_in, &fs_m_out);
|
|
||||||
if (rc != OK) {
|
|
||||||
/* roll back the changes we made to the descriptor */
|
|
||||||
memset(&(uds_fd_table[minor]), '\0', sizeof(uds_fd_t));
|
|
||||||
|
|
||||||
/* likely error: get_block() failed */
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Process the response */
|
|
||||||
uds_fd_table[minor].inode_nr = fs_m_out.RES_INODE_NR;
|
|
||||||
|
|
||||||
return CDEV_CLONED | minor;
|
return CDEV_CLONED | minor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uds_close(devminor_t minor)
|
static int
|
||||||
|
uds_close(devminor_t minor)
|
||||||
{
|
{
|
||||||
message fs_m_in, fs_m_out;
|
int peer;
|
||||||
int rc;
|
|
||||||
|
|
||||||
#if DEBUG == 1
|
#if DEBUG == 1
|
||||||
static int call_count = 0;
|
static int call_count = 0;
|
||||||
|
@ -213,7 +173,7 @@ static int uds_close(devminor_t minor)
|
||||||
|
|
||||||
/* if the socket is connected, disconnect it */
|
/* if the socket is connected, disconnect it */
|
||||||
if (uds_fd_table[minor].peer != -1) {
|
if (uds_fd_table[minor].peer != -1) {
|
||||||
int peer = uds_fd_table[minor].peer;
|
peer = uds_fd_table[minor].peer;
|
||||||
|
|
||||||
/* set peer of this peer to -1 */
|
/* set peer of this peer to -1 */
|
||||||
uds_fd_table[peer].peer = -1;
|
uds_fd_table[peer].peer = -1;
|
||||||
|
@ -230,28 +190,23 @@ static int uds_close(devminor_t minor)
|
||||||
uds_clear_fds(minor, &uds_fd_table[minor].ancillary_data);
|
uds_clear_fds(minor, &uds_fd_table[minor].ancillary_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare Request to the FS side of PFS */
|
/* Release the memory for the ring buffer. */
|
||||||
|
minix_munmap(uds_fd_table[minor].buf, PIPE_BUF);
|
||||||
|
|
||||||
fs_m_in.m_type = REQ_PUTNODE;
|
/* Set the socket back to its original UDS_FREE state. */
|
||||||
fs_m_in.REQ_INODE_NR = uds_fd_table[minor].inode_nr;
|
memset(&uds_fd_table[minor], '\0', sizeof(uds_fd_t));
|
||||||
fs_m_in.REQ_COUNT = 1;
|
|
||||||
|
|
||||||
/* set the socket back to its original UDS_FREE state */
|
/* If terminating, and this was the last open socket, exit now. */
|
||||||
memset(&(uds_fd_table[minor]), '\0', sizeof(uds_fd_t));
|
if (uds_exit_left > 0) {
|
||||||
|
if (--uds_exit_left == 0)
|
||||||
/* Request the removal of the inode from the pipe file system */
|
chardriver_terminate();
|
||||||
|
|
||||||
rc = fs_putnode(&fs_m_in, &fs_m_out);
|
|
||||||
if (rc != OK) {
|
|
||||||
printf("PFS: fs_putnode returned %d\n", rc);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
|
static int
|
||||||
|
uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
|
||||||
{
|
{
|
||||||
unsigned int ready_ops;
|
unsigned int ready_ops;
|
||||||
int i, bytes, watch;
|
int i, bytes, watch;
|
||||||
|
@ -297,8 +252,7 @@ static int uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
|
||||||
|
|
||||||
/* check if we can write without blocking */
|
/* check if we can write without blocking */
|
||||||
if (ops & CDEV_OP_WR) {
|
if (ops & CDEV_OP_WR) {
|
||||||
bytes = uds_perform_write(minor, NONE, GRANT_INVALID, PIPE_BUF,
|
bytes = uds_perform_write(minor, NONE, GRANT_INVALID, 1, 1);
|
||||||
1);
|
|
||||||
if (bytes != 0 && bytes != SUSPEND) {
|
if (bytes != 0 && bytes != SUSPEND) {
|
||||||
/* There is room to write or there is an error
|
/* There is room to write or there is an error
|
||||||
* condition.
|
* condition.
|
||||||
|
@ -319,12 +273,12 @@ static int uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
|
||||||
return ready_ops;
|
return ready_ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
|
static ssize_t
|
||||||
cp_grant_id_t grant, size_t size, int pretend)
|
uds_perform_read(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant,
|
||||||
|
size_t size, int pretend)
|
||||||
{
|
{
|
||||||
int rc, peer;
|
size_t pos, subsize;
|
||||||
message fs_m_in;
|
int r, peer;
|
||||||
message fs_m_out;
|
|
||||||
|
|
||||||
#if DEBUG == 1
|
#if DEBUG == 1
|
||||||
static int call_count = 0;
|
static int call_count = 0;
|
||||||
|
@ -340,7 +294,7 @@ static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if we are allowed to read */
|
/* check if we are allowed to read */
|
||||||
if (!(uds_fd_table[minor].mode & S_IRUSR)) {
|
if (!(uds_fd_table[minor].mode & R_BIT)) {
|
||||||
/* socket is shutdown for reading */
|
/* socket is shutdown for reading */
|
||||||
return EPIPE;
|
return EPIPE;
|
||||||
}
|
}
|
||||||
|
@ -352,6 +306,7 @@ static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
|
||||||
if (uds_fd_table[minor].type == SOCK_STREAM ||
|
if (uds_fd_table[minor].type == SOCK_STREAM ||
|
||||||
uds_fd_table[minor].type == SOCK_SEQPACKET) {
|
uds_fd_table[minor].type == SOCK_SEQPACKET) {
|
||||||
if (uds_fd_table[minor].err == ECONNRESET) {
|
if (uds_fd_table[minor].err == ECONNRESET) {
|
||||||
|
if (!pretend)
|
||||||
uds_fd_table[minor].err = 0;
|
uds_fd_table[minor].err = 0;
|
||||||
return ECONNRESET;
|
return ECONNRESET;
|
||||||
} else {
|
} else {
|
||||||
|
@ -361,7 +316,7 @@ static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if process is reading from a closed pipe */
|
/* Check if process is reading from a closed pipe */
|
||||||
if (peer != -1 && !(uds_fd_table[peer].mode & S_IWUSR) &&
|
if (peer != -1 && !(uds_fd_table[peer].mode & W_BIT) &&
|
||||||
uds_fd_table[minor].size == 0) {
|
uds_fd_table[minor].size == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -386,40 +341,34 @@ static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
|
||||||
return EDONTREPLY;
|
return EDONTREPLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretend) {
|
/* How much can we get from the ring buffer? */
|
||||||
return (size > uds_fd_table[minor].size) ?
|
if (size > uds_fd_table[minor].size)
|
||||||
uds_fd_table[minor].size : size;
|
size = uds_fd_table[minor].size;
|
||||||
|
|
||||||
|
if (pretend)
|
||||||
|
return size;
|
||||||
|
|
||||||
|
/* Get the data from the tail of the ring buffer. */
|
||||||
|
pos = uds_fd_table[minor].pos;
|
||||||
|
|
||||||
|
subsize = PIPE_BUF - pos;
|
||||||
|
if (subsize > size)
|
||||||
|
subsize = size;
|
||||||
|
|
||||||
|
if ((r = sys_safecopyto(endpt, grant, 0,
|
||||||
|
(vir_bytes) &uds_fd_table[minor].buf[pos], subsize)) != OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (subsize < size) {
|
||||||
|
if ((r = sys_safecopyto(endpt, grant, subsize,
|
||||||
|
(vir_bytes) uds_fd_table[minor].buf,
|
||||||
|
size - subsize)) != OK)
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare Request to the FS side of PFS */
|
/* Advance the buffer tail. */
|
||||||
fs_m_in.m_source = endpt;
|
uds_fd_table[minor].pos = (pos + size) % PIPE_BUF;
|
||||||
fs_m_in.m_type = REQ_READ;
|
uds_fd_table[minor].size -= size;
|
||||||
fs_m_in.REQ_INODE_NR = uds_fd_table[minor].inode_nr;
|
|
||||||
fs_m_in.REQ_GRANT = grant;
|
|
||||||
fs_m_in.REQ_SEEK_POS_HI = 0;
|
|
||||||
fs_m_in.REQ_SEEK_POS_LO = uds_fd_table[minor].pos;
|
|
||||||
fs_m_in.REQ_NBYTES = (size > uds_fd_table[minor].size) ?
|
|
||||||
uds_fd_table[minor].size : size;
|
|
||||||
|
|
||||||
/* perform the read */
|
|
||||||
rc = fs_readwrite(&fs_m_in, &fs_m_out);
|
|
||||||
if (rc != OK) {
|
|
||||||
printf("PFS: fs_readwrite returned %d\n", rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Process the response */
|
|
||||||
#if DEBUG == 1
|
|
||||||
printf("(uds) [%d] read complete\n", minor);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* move the position of the data pointer up to data we haven't
|
|
||||||
* read yet
|
|
||||||
*/
|
|
||||||
uds_fd_table[minor].pos += fs_m_out.RES_NBYTES;
|
|
||||||
|
|
||||||
/* decrease the number of unread bytes */
|
|
||||||
uds_fd_table[minor].size -= fs_m_out.RES_NBYTES;
|
|
||||||
|
|
||||||
/* if we have 0 unread bytes, move the data pointer back to the
|
/* if we have 0 unread bytes, move the data pointer back to the
|
||||||
* start of the buffer
|
* start of the buffer
|
||||||
|
@ -439,22 +388,22 @@ static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
|
||||||
* and it doesn't know about it already, then let the peer know.
|
* and it doesn't know about it already, then let the peer know.
|
||||||
*/
|
*/
|
||||||
if (peer != -1 && (uds_fd_table[peer].sel_ops & CDEV_OP_WR) &&
|
if (peer != -1 && (uds_fd_table[peer].sel_ops & CDEV_OP_WR) &&
|
||||||
(uds_fd_table[minor].size+uds_fd_table[minor].pos + 1 < PIPE_BUF)){
|
size > 0) {
|
||||||
/* a write on peer is possible now */
|
/* a write on peer is possible now */
|
||||||
chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer,
|
chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer,
|
||||||
CDEV_OP_WR);
|
CDEV_OP_WR);
|
||||||
uds_fd_table[peer].sel_ops &= ~CDEV_OP_WR;
|
uds_fd_table[peer].sel_ops &= ~CDEV_OP_WR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs_m_out.RES_NBYTES; /* return number of bytes read */
|
return size; /* return number of bytes read */
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
static ssize_t
|
||||||
cp_grant_id_t grant, size_t size, int pretend)
|
uds_perform_write(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant,
|
||||||
|
size_t size, int pretend)
|
||||||
{
|
{
|
||||||
int rc, peer, i;
|
size_t subsize, pos;
|
||||||
message fs_m_in;
|
int i, r, peer;
|
||||||
message fs_m_out;
|
|
||||||
|
|
||||||
#if DEBUG == 1
|
#if DEBUG == 1
|
||||||
static int call_count = 0;
|
static int call_count = 0;
|
||||||
|
@ -462,13 +411,12 @@ static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
||||||
++call_count);
|
++call_count);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* skip reads and writes of 0 (or less!) bytes */
|
/* Skip writes of zero bytes. */
|
||||||
if (size <= 0) {
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* check if we are allowed to write */
|
/* check if we are allowed to write */
|
||||||
if (!(uds_fd_table[minor].mode & S_IWUSR)) {
|
if (!(uds_fd_table[minor].mode & W_BIT)) {
|
||||||
/* socket is shutdown for writing */
|
/* socket is shutdown for writing */
|
||||||
return EPIPE;
|
return EPIPE;
|
||||||
}
|
}
|
||||||
|
@ -522,7 +470,7 @@ static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if we write to a closed pipe */
|
/* check if we write to a closed pipe */
|
||||||
if (!(uds_fd_table[peer].mode & S_IRUSR)) {
|
if (!(uds_fd_table[peer].mode & R_BIT)) {
|
||||||
return EPIPE;
|
return EPIPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,14 +483,13 @@ static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if write would overrun buffer. check if message
|
/*
|
||||||
* SEQPACKET wouldn't write to an empty buffer. check if
|
* Check if the ring buffer is already full, and if the SEQPACKET
|
||||||
* connectionless sockets have a target to write to.
|
* message wouldn't write to an empty buffer.
|
||||||
*/
|
*/
|
||||||
if ((uds_fd_table[peer].pos+uds_fd_table[peer].size+size > PIPE_BUF) ||
|
if (uds_fd_table[peer].size == PIPE_BUF ||
|
||||||
((uds_fd_table[minor].type == SOCK_SEQPACKET) &&
|
(uds_fd_table[minor].type == SOCK_SEQPACKET &&
|
||||||
uds_fd_table[peer].size > 0)) {
|
uds_fd_table[peer].size > 0)) {
|
||||||
|
|
||||||
if (pretend) {
|
if (pretend) {
|
||||||
return SUSPEND;
|
return SUSPEND;
|
||||||
}
|
}
|
||||||
|
@ -561,33 +508,32 @@ static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
||||||
return EDONTREPLY;
|
return EDONTREPLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretend) {
|
/* How much can we add to the ring buffer? */
|
||||||
|
if (size > PIPE_BUF - uds_fd_table[peer].size)
|
||||||
|
size = PIPE_BUF - uds_fd_table[peer].size;
|
||||||
|
|
||||||
|
if (pretend)
|
||||||
return size;
|
return size;
|
||||||
|
|
||||||
|
/* Put the data at the head of the ring buffer. */
|
||||||
|
pos = (uds_fd_table[peer].pos + uds_fd_table[peer].size) % PIPE_BUF;
|
||||||
|
|
||||||
|
subsize = PIPE_BUF - pos;
|
||||||
|
if (subsize > size)
|
||||||
|
subsize = size;
|
||||||
|
|
||||||
|
if ((r = sys_safecopyfrom(endpt, grant, 0,
|
||||||
|
(vir_bytes) &uds_fd_table[peer].buf[pos], subsize)) != OK)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (subsize < size) {
|
||||||
|
if ((r = sys_safecopyfrom(endpt, grant, subsize,
|
||||||
|
(vir_bytes) uds_fd_table[peer].buf, size - subsize)) != OK)
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare Request to the FS side of PFS */
|
/* Advance the buffer head. */
|
||||||
fs_m_in.m_source = endpt;
|
uds_fd_table[peer].size += size;
|
||||||
fs_m_in.m_type = REQ_WRITE;
|
|
||||||
fs_m_in.REQ_INODE_NR = uds_fd_table[peer].inode_nr;
|
|
||||||
fs_m_in.REQ_GRANT = grant;
|
|
||||||
fs_m_in.REQ_SEEK_POS_HI = 0;
|
|
||||||
fs_m_in.REQ_SEEK_POS_LO = uds_fd_table[peer].pos +
|
|
||||||
uds_fd_table[peer].size;
|
|
||||||
fs_m_in.REQ_NBYTES = size;
|
|
||||||
|
|
||||||
/* Request the write */
|
|
||||||
rc = fs_readwrite(&fs_m_in, &fs_m_out);
|
|
||||||
if (rc != OK) {
|
|
||||||
printf("PFS: fs_readwrite returned %d\n", rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Process the response */
|
|
||||||
#if DEBUG == 1
|
|
||||||
printf("(uds) [%d] write complete\n", minor);
|
|
||||||
#endif
|
|
||||||
/* increase the count of unread bytes */
|
|
||||||
uds_fd_table[peer].size += fs_m_out.RES_NBYTES;
|
|
||||||
|
|
||||||
/* fill in the source address to be returned by recvfrom & recvmsg */
|
/* fill in the source address to be returned by recvfrom & recvmsg */
|
||||||
if (uds_fd_table[minor].type == SOCK_DGRAM) {
|
if (uds_fd_table[minor].type == SOCK_DGRAM) {
|
||||||
|
@ -603,18 +549,18 @@ static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
||||||
* data ready to read and it doesn't know about it already, then let
|
* data ready to read and it doesn't know about it already, then let
|
||||||
* the peer know we have data for it.
|
* the peer know we have data for it.
|
||||||
*/
|
*/
|
||||||
if ((uds_fd_table[peer].sel_ops & CDEV_OP_RD) &&
|
if ((uds_fd_table[peer].sel_ops & CDEV_OP_RD) && size > 0) {
|
||||||
fs_m_out.RES_NBYTES > 0) {
|
|
||||||
/* a read on peer is possible now */
|
/* a read on peer is possible now */
|
||||||
chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer,
|
chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer,
|
||||||
CDEV_OP_RD);
|
CDEV_OP_RD);
|
||||||
uds_fd_table[peer].sel_ops &= ~CDEV_OP_RD;
|
uds_fd_table[peer].sel_ops &= ~CDEV_OP_RD;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs_m_out.RES_NBYTES; /* return number of bytes written */
|
return size; /* return number of bytes written */
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t uds_read(devminor_t minor, u64_t position, endpoint_t endpt,
|
static ssize_t
|
||||||
|
uds_read(devminor_t minor, u64_t position, endpoint_t endpt,
|
||||||
cp_grant_id_t grant, size_t size, int flags, cdev_id_t id)
|
cp_grant_id_t grant, size_t size, int flags, cdev_id_t id)
|
||||||
{
|
{
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
|
@ -654,7 +600,8 @@ static ssize_t uds_read(devminor_t minor, u64_t position, endpoint_t endpt,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t uds_write(devminor_t minor, u64_t position, endpoint_t endpt,
|
static ssize_t
|
||||||
|
uds_write(devminor_t minor, u64_t position, endpoint_t endpt,
|
||||||
cp_grant_id_t grant, size_t size, int flags, cdev_id_t id)
|
cp_grant_id_t grant, size_t size, int flags, cdev_id_t id)
|
||||||
{
|
{
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
|
@ -694,7 +641,8 @@ static ssize_t uds_write(devminor_t minor, u64_t position, endpoint_t endpt,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uds_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
|
static int
|
||||||
|
uds_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
|
||||||
cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id)
|
cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -740,7 +688,8 @@ static int uds_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uds_unsuspend(devminor_t minor)
|
void
|
||||||
|
uds_unsuspend(devminor_t minor)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
uds_fd_t *fdp;
|
uds_fd_t *fdp;
|
||||||
|
@ -784,7 +733,8 @@ void uds_unsuspend(devminor_t minor)
|
||||||
fdp->suspended = UDS_NOT_SUSPENDED;
|
fdp->suspended = UDS_NOT_SUSPENDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uds_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id)
|
static int
|
||||||
|
uds_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id)
|
||||||
{
|
{
|
||||||
uds_fd_t *fdp;
|
uds_fd_t *fdp;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
@ -799,7 +749,7 @@ static int uds_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id)
|
||||||
fdp = &uds_fd_table[minor];
|
fdp = &uds_fd_table[minor];
|
||||||
|
|
||||||
if (fdp->state != UDS_INUSE) {
|
if (fdp->state != UDS_INUSE) {
|
||||||
printf("PFS: cancel request for closed minor %d\n", minor);
|
printf("UDS: cancel request for closed minor %d\n", minor);
|
||||||
return EDONTREPLY;
|
return EDONTREPLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -863,3 +813,63 @@ static int uds_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id)
|
||||||
|
|
||||||
return EINTR; /* reply to the original request */
|
return EINTR; /* reply to the original request */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the server.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
uds_init(int UNUSED(type), sef_init_info_t *UNUSED(info))
|
||||||
|
{
|
||||||
|
/* Setting everything to NULL implicitly sets the state to UDS_FREE. */
|
||||||
|
memset(uds_fd_table, '\0', sizeof(uds_fd_t) * NR_FDS);
|
||||||
|
|
||||||
|
uds_exit_left = 0;
|
||||||
|
|
||||||
|
return(OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
uds_signal(int signo)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Only check for termination signal, ignore anything else. */
|
||||||
|
if (signo != SIGTERM) return;
|
||||||
|
|
||||||
|
/* Only exit once all sockets have been closed. */
|
||||||
|
uds_exit_left = 0;
|
||||||
|
for (i = 0; i < NR_FDS; i++)
|
||||||
|
if (uds_fd_table[i].state == UDS_INUSE)
|
||||||
|
uds_exit_left++;
|
||||||
|
|
||||||
|
if (uds_exit_left == 0)
|
||||||
|
chardriver_terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
uds_startup(void)
|
||||||
|
{
|
||||||
|
/* Register init callbacks. */
|
||||||
|
sef_setcb_init_fresh(uds_init);
|
||||||
|
|
||||||
|
/* No live update support for now. */
|
||||||
|
|
||||||
|
/* Register signal callbacks. */
|
||||||
|
sef_setcb_signal_handler(uds_signal);
|
||||||
|
|
||||||
|
/* Let SEF perform startup. */
|
||||||
|
sef_startup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The UNIX domain sockets driver.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
uds_startup();
|
||||||
|
|
||||||
|
chardriver_task(&uds_tab);
|
||||||
|
|
||||||
|
return(OK);
|
||||||
|
}
|
|
@ -1,25 +1,24 @@
|
||||||
#ifndef __PFS_UDS_H__
|
#ifndef __UDS_UDS_H
|
||||||
#define __PFS_UDS_H__
|
#define __UDS_UDS_H
|
||||||
|
|
||||||
/*
|
#include <minix/drivers.h>
|
||||||
* Unix Domain Sockets Implementation (PF_UNIX, PF_LOCAL)
|
#include <minix/chardriver.h>
|
||||||
*
|
#undef send
|
||||||
* Also See...
|
#include <sys/socket.h>
|
||||||
*
|
#include <sys/ioctl.h>
|
||||||
* dev_uds.c, table.c, uds.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/ucred.h>
|
#include <sys/ucred.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include <minix/endpoint.h>
|
/* Maximum number of UNIX domain sockets. */
|
||||||
#include <minix/chardriver.h>
|
#define NR_FDS 256
|
||||||
|
|
||||||
/* max connection backlog for incoming connections */
|
/* Connection backlog size for incoming connections. */
|
||||||
#define UDS_SOMAXCONN 64
|
#define UDS_SOMAXCONN 64
|
||||||
|
|
||||||
|
/* Output debugging information? */
|
||||||
|
#define DEBUG 0
|
||||||
|
|
||||||
typedef void* filp_id_t;
|
typedef void* filp_id_t;
|
||||||
|
|
||||||
/* ancillary data to be sent */
|
/* ancillary data to be sent */
|
||||||
|
@ -57,26 +56,16 @@ struct uds_fd {
|
||||||
|
|
||||||
/* Pipe Housekeeping */
|
/* Pipe Housekeeping */
|
||||||
|
|
||||||
/* inode number on PFS -- each descriptor is backed by 1
|
char *buf; /* ring buffer */
|
||||||
* PIPE which is allocated in uds_open() and freed in
|
size_t pos; /* tail position into ring buffer */
|
||||||
* uds_close(). Data is sent/written to a peer's PIPE.
|
size_t size; /* size of used part of ring buffer */
|
||||||
* Data is recv/read from this PIPE.
|
|
||||||
*/
|
|
||||||
pino_t inode_nr;
|
|
||||||
|
|
||||||
|
|
||||||
/* position in the PIPE where the data starts */
|
|
||||||
off_t pos;
|
|
||||||
|
|
||||||
/* size of data in the PIPE */
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
/* control read/write, set by uds_open() and shutdown(2).
|
/* control read/write, set by uds_open() and shutdown(2).
|
||||||
* Can be set to S_IRUSR|S_IWUSR, S_IRUSR, S_IWUSR, or 0
|
* Can be set to R_BIT|W_BIT, R_BIT, W_BIT, or 0
|
||||||
* for read and write, read only, write only, or neither.
|
* for read and write, read only, write only, or neither.
|
||||||
* default is S_IRUSR|S_IWUSR.
|
* default is R_BIT|W_BIT.
|
||||||
*/
|
*/
|
||||||
pmode_t mode;
|
int mode;
|
||||||
|
|
||||||
/* Socket Info */
|
/* Socket Info */
|
||||||
|
|
||||||
|
@ -188,4 +177,14 @@ typedef struct uds_fd uds_fd_t;
|
||||||
/* File Descriptor Table -- Defined in uds.c */
|
/* File Descriptor Table -- Defined in uds.c */
|
||||||
EXTERN uds_fd_t uds_fd_table[NR_FDS];
|
EXTERN uds_fd_t uds_fd_table[NR_FDS];
|
||||||
|
|
||||||
#endif
|
/* Function prototypes. */
|
||||||
|
|
||||||
|
/* dev_uds.c */
|
||||||
|
void uds_unsuspend(devminor_t minor);
|
||||||
|
|
||||||
|
/* uds.c */
|
||||||
|
int uds_clear_fds(devminor_t minor, struct ancillary *data);
|
||||||
|
int uds_do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
|
||||||
|
cp_grant_id_t grant);
|
||||||
|
|
||||||
|
#endif /* !__UDS_UDS_H */
|
|
@ -687,7 +687,7 @@ service vbox
|
||||||
service fbd
|
service fbd
|
||||||
{
|
{
|
||||||
ipc
|
ipc
|
||||||
SYSTEM VFS RS DS VM
|
SYSTEM vfs rs ds vm
|
||||||
ahci
|
ahci
|
||||||
at_wini
|
at_wini
|
||||||
;
|
;
|
||||||
|
@ -696,7 +696,15 @@ service fbd
|
||||||
service vnd
|
service vnd
|
||||||
{
|
{
|
||||||
ipc
|
ipc
|
||||||
SYSTEM VFS RS VM
|
SYSTEM vfs rs vm
|
||||||
;
|
;
|
||||||
uid 0; # only for dupfrom(2)
|
uid 0; # only for dupfrom(2)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
service uds
|
||||||
|
{
|
||||||
|
ipc
|
||||||
|
SYSTEM vfs rs vm
|
||||||
|
;
|
||||||
|
uid 0; # for various VFS backcalls, until we have ACLs
|
||||||
|
};
|
||||||
|
|
|
@ -193,6 +193,8 @@ start)
|
||||||
up inet -script /etc/rs.inet -dev /dev/ip
|
up inet -script /etc/rs.inet -dev /dev/ip
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
up uds -dev /dev/uds
|
||||||
|
|
||||||
up -n ipc
|
up -n ipc
|
||||||
|
|
||||||
up log -dev /dev/klog
|
up log -dev /dev/klog
|
||||||
|
|
|
@ -112,9 +112,9 @@
|
||||||
#define MAPDRIVER 122 /* to VFS, map a device */
|
#define MAPDRIVER 122 /* to VFS, map a device */
|
||||||
#define GETRUSAGE 123 /* to PM, VFS */
|
#define GETRUSAGE 123 /* to PM, VFS */
|
||||||
|
|
||||||
#define VFS_PFS_CHECK_PERMS 124 /* to VFS */
|
#define VFS_UDS_CHECK_PERMS 124 /* to VFS */
|
||||||
#define VFS_PFS_VERIFY_FD 125 /* to VFS */
|
#define VFS_UDS_VERIFY_FD 125 /* to VFS */
|
||||||
#define VFS_PFS_SET_FILP 126 /* to VFS */
|
#define VFS_UDS_SET_FILP 126 /* to VFS */
|
||||||
#define VFS_PFS_COPY_FILP 127 /* to VFS */
|
#define VFS_UDS_COPY_FILP 127 /* to VFS */
|
||||||
#define VFS_PFS_PUT_FILP 128 /* to VFS */
|
#define VFS_UDS_PUT_FILP 128 /* to VFS */
|
||||||
#define VFS_PFS_CANCEL_FD 129 /* to VFS */
|
#define VFS_UDS_CANCEL_FD 129 /* to VFS */
|
||||||
|
|
|
@ -882,12 +882,12 @@
|
||||||
#define VFS_IOCTL_REQ m2_i3
|
#define VFS_IOCTL_REQ m2_i3
|
||||||
#define VFS_IOCTL_ARG m2_p1
|
#define VFS_IOCTL_ARG m2_p1
|
||||||
|
|
||||||
/* Field names for the PFS backcalls to VFS. */
|
/* Field names for the UDS backcalls to VFS. */
|
||||||
#define VFS_PFS_ENDPT m2_i1
|
#define VFS_UDS_ENDPT m2_i1
|
||||||
#define VFS_PFS_GRANT m2_i2
|
#define VFS_UDS_GRANT m2_i2
|
||||||
#define VFS_PFS_COUNT m2_i3
|
#define VFS_UDS_COUNT m2_i3
|
||||||
#define VFS_PFS_FD m2_i3
|
#define VFS_UDS_FD m2_i3
|
||||||
#define VFS_PFS_FILP m2_p1
|
#define VFS_UDS_FILP m2_p1
|
||||||
|
|
||||||
/* Field names for the dupfrom(2) call. */
|
/* Field names for the dupfrom(2) call. */
|
||||||
#define VFS_DUPFROM_ENDPT m1_i1
|
#define VFS_DUPFROM_ENDPT m1_i1
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
# Makefile for Pipe File System (PFS)
|
# Makefile for Pipe File System (PFS)
|
||||||
PROG= pfs
|
PROG= pfs
|
||||||
SRCS= open.c table.c inode.c main.c super.c link.c \
|
SRCS= open.c table.c inode.c main.c super.c link.c \
|
||||||
buffer.c read.c misc.c mount.c utility.c stadir.c \
|
buffer.c read.c misc.c mount.c utility.c stadir.c
|
||||||
uds.c dev_uds.c
|
|
||||||
|
|
||||||
DPADD+= ${LIBCHARDRIVER} ${LIBSYS}
|
DPADD+= ${LIBCHARDRIVER} ${LIBSYS}
|
||||||
LDADD+= -lchardriver -lsys
|
LDADD+= -lchardriver -lsys
|
||||||
|
|
|
@ -3,40 +3,20 @@
|
||||||
|
|
||||||
#define PFS_NR_INODES 512 /* # slots in "in core" inode table */
|
#define PFS_NR_INODES 512 /* # slots in "in core" inode table */
|
||||||
|
|
||||||
/* Size of descriptor table for unix domain sockets. This should be
|
|
||||||
* equal to the maximum number of minor devices (currently 256).
|
|
||||||
*/
|
|
||||||
#define NR_FDS 256
|
|
||||||
|
|
||||||
#define INODE_HASH_LOG2 7 /* 2 based logarithm of the inode hash size */
|
#define INODE_HASH_LOG2 7 /* 2 based logarithm of the inode hash size */
|
||||||
#define INODE_HASH_SIZE ((unsigned long)1<<INODE_HASH_LOG2)
|
#define INODE_HASH_SIZE ((unsigned long)1<<INODE_HASH_LOG2)
|
||||||
#define INODE_HASH_MASK (((unsigned long)1<<INODE_HASH_LOG2)-1)
|
#define INODE_HASH_MASK (((unsigned long)1<<INODE_HASH_LOG2)-1)
|
||||||
|
|
||||||
|
|
||||||
/* The type of sizeof may be (unsigned) long. Use the following macro for
|
|
||||||
* taking the sizes of small objects so that there are no surprises like
|
|
||||||
* (small) long constants being passed to routines expecting an int.
|
|
||||||
*/
|
|
||||||
#define usizeof(t) ((unsigned) sizeof(t))
|
|
||||||
|
|
||||||
/* Miscellaneous constants */
|
|
||||||
#define INVAL_UID ((uid_t) -1) /* Invalid user ID */
|
|
||||||
#define INVAL_GID ((gid_t) -1) /* Invalid group ID */
|
|
||||||
#define NORMAL 0 /* forces get_block to do disk read */
|
|
||||||
#define NO_READ 1 /* prevents get_block from doing disk read */
|
|
||||||
#define PREFETCH 2 /* tells get_block not to read or mark dev */
|
|
||||||
|
|
||||||
#define NO_BIT ((bit_t) 0) /* returned by alloc_bit() to signal failure */
|
#define NO_BIT ((bit_t) 0) /* returned by alloc_bit() to signal failure */
|
||||||
|
|
||||||
#define ATIME 002 /* set if atime field needs updating */
|
#define ATIME 002 /* set if atime field needs updating */
|
||||||
#define CTIME 004 /* set if ctime field needs updating */
|
#define CTIME 004 /* set if ctime field needs updating */
|
||||||
#define MTIME 010 /* set if mtime field needs updating */
|
#define MTIME 010 /* set if mtime field needs updating */
|
||||||
|
|
||||||
#define FS_BITMAP_CHUNKS(b) ((b)/usizeof (bitchunk_t))/* # map chunks/blk */
|
#define FS_BITMAP_CHUNKS(b) ((b)/sizeof (bitchunk_t))/* # map chunks/blk */
|
||||||
#define FS_BITCHUNK_BITS (usizeof(bitchunk_t) * CHAR_BIT)
|
#define FS_BITCHUNK_BITS (sizeof(bitchunk_t) * CHAR_BIT)
|
||||||
#define FS_BITS_PER_BLOCK(b) (FS_BITMAP_CHUNKS(b) * FS_BITCHUNK_BITS)
|
#define FS_BITS_PER_BLOCK(b) (FS_BITMAP_CHUNKS(b) * FS_BITCHUNK_BITS)
|
||||||
|
|
||||||
#define FS_CALL_VEC_SIZE 31
|
#define FS_CALL_VEC_SIZE 31
|
||||||
#define DEV_CALL_VEC_SIZE 25
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
|
|
||||||
#define _SYSTEM 1 /* get OK and negative error codes */
|
|
||||||
#define _NETBSD_SOURCE 1 /* tell headers to include MINIX stuff */
|
|
||||||
|
|
||||||
#define VERBOSE 0 /* display diagnostics */
|
|
||||||
|
|
||||||
#include <sys/ioc_net.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/ucred.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <minix/callnr.h>
|
|
||||||
#include <minix/config.h>
|
|
||||||
#include <minix/dmap.h>
|
|
||||||
#include <minix/type.h>
|
|
||||||
#include <minix/const.h>
|
|
||||||
#include <minix/com.h>
|
|
||||||
#include <minix/syslib.h>
|
|
||||||
#include <minix/sysutil.h>
|
|
||||||
#include <minix/bitmap.h>
|
|
||||||
#include <minix/vfsif.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include "proto.h"
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
#include "inode.h"
|
#include "inode.h"
|
||||||
#include "uds.h"
|
|
||||||
|
|
||||||
static void get_work(message *m_in, int *status);
|
static void get_work(message *m_in, int *status);
|
||||||
|
|
||||||
|
@ -41,13 +40,6 @@ int main(int argc, char *argv[])
|
||||||
/* Wait for request message. */
|
/* Wait for request message. */
|
||||||
get_work(&pfs_m_in, &ipc_status);
|
get_work(&pfs_m_in, &ipc_status);
|
||||||
|
|
||||||
/* If this is a UDS device request, process it and continue. */
|
|
||||||
if (IS_CDEV_RQ(pfs_m_in.m_type)) {
|
|
||||||
uds_request(&pfs_m_in, ipc_status);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
transid = TRNS_GET_ID(pfs_m_in.m_type);
|
transid = TRNS_GET_ID(pfs_m_in.m_type);
|
||||||
pfs_m_in.m_type = TRNS_DEL_ID(pfs_m_in.m_type);
|
pfs_m_in.m_type = TRNS_DEL_ID(pfs_m_in.m_type);
|
||||||
if (pfs_m_in.m_type == 0) {
|
if (pfs_m_in.m_type == 0) {
|
||||||
|
@ -119,10 +111,8 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info)
|
||||||
}
|
}
|
||||||
|
|
||||||
init_inode_cache();
|
init_inode_cache();
|
||||||
uds_init();
|
|
||||||
buf_pool();
|
buf_pool();
|
||||||
|
|
||||||
|
|
||||||
/* Drop root privileges */
|
/* Drop root privileges */
|
||||||
if ((pw = getpwnam(SERVICE_LOGIN)) == NULL) {
|
if ((pw = getpwnam(SERVICE_LOGIN)) == NULL) {
|
||||||
printf("PFS: unable to retrieve uid of SERVICE_LOGIN, "
|
printf("PFS: unable to retrieve uid of SERVICE_LOGIN, "
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
/* Structs used in prototypes must be declared as such first. */
|
/* Structs used in prototypes must be declared as such first. */
|
||||||
struct buf;
|
struct buf;
|
||||||
struct inode;
|
struct inode;
|
||||||
struct sockaddr_un;
|
|
||||||
struct ancillary;
|
|
||||||
|
|
||||||
/* buffer.c */
|
/* buffer.c */
|
||||||
struct buf *get_block(dev_t dev, pino_t inum);
|
struct buf *get_block(dev_t dev, pino_t inum);
|
||||||
|
@ -32,7 +30,6 @@ void wipe_inode(struct inode *rip);
|
||||||
int fs_ftrunc(message *fs_m_in, message *fs_m_out);
|
int fs_ftrunc(message *fs_m_in, message *fs_m_out);
|
||||||
int truncate_inode(struct inode *rip, off_t newsize);
|
int truncate_inode(struct inode *rip, off_t newsize);
|
||||||
|
|
||||||
|
|
||||||
/* main.c */
|
/* main.c */
|
||||||
void reply(endpoint_t who, message *m_out);
|
void reply(endpoint_t who, message *m_out);
|
||||||
|
|
||||||
|
@ -60,13 +57,4 @@ int fs_stat(message *fs_m_in, message *fs_m_out);
|
||||||
bit_t alloc_bit(void);
|
bit_t alloc_bit(void);
|
||||||
void free_bit(bit_t bit_returned);
|
void free_bit(bit_t bit_returned);
|
||||||
|
|
||||||
/* dev_uds.c */
|
|
||||||
void uds_request(message *m_ptr, int ipc_status);
|
|
||||||
void uds_unsuspend(devminor_t minor);
|
|
||||||
|
|
||||||
/* uds.c */
|
|
||||||
void uds_init(void);
|
|
||||||
int uds_clear_fds(devminor_t minor, struct ancillary *data);
|
|
||||||
int uds_do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
|
|
||||||
cp_grant_id_t grant);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,11 +5,9 @@
|
||||||
|
|
||||||
#define _TABLE
|
#define _TABLE
|
||||||
|
|
||||||
#include "inc.h"
|
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "inode.h"
|
#include "inode.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
#include "uds.h"
|
|
||||||
|
|
||||||
/* File System Handlers (pfs) */
|
/* File System Handlers (pfs) */
|
||||||
int (*fs_call_vec[])(message *fs_m_in, message *fs_m_out) = {
|
int (*fs_call_vec[])(message *fs_m_in, message *fs_m_out) = {
|
||||||
|
|
|
@ -45,7 +45,6 @@ struct boot_image_dev boot_image_dev_table[] = {
|
||||||
/*endpoint, flags, dev_nr, dev_style, dev_style2 */
|
/*endpoint, flags, dev_nr, dev_style, dev_style2 */
|
||||||
{ TTY_PROC_NR, SRV_DF, TTY_MAJOR, STYLE_TTY, STYLE_CTTY },
|
{ TTY_PROC_NR, SRV_DF, TTY_MAJOR, STYLE_TTY, STYLE_CTTY },
|
||||||
{ MEM_PROC_NR, SRV_DF, MEMORY_MAJOR, STYLE_DEV, STYLE_NDEV },
|
{ MEM_PROC_NR, SRV_DF, MEMORY_MAJOR, STYLE_DEV, STYLE_NDEV },
|
||||||
{ PFS_PROC_NR, SRV_DF, UDS_MAJOR, STYLE_DEV, STYLE_NDEV },
|
|
||||||
{ DEFAULT_BOOT_NR, SRV_DF, 0, STYLE_NDEV, STYLE_NDEV } /* default
|
{ DEFAULT_BOOT_NR, SRV_DF, 0, STYLE_NDEV, STYLE_NDEV } /* default
|
||||||
* entry
|
* entry
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -380,13 +380,13 @@ int do_verify_fd(message *m_out)
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* This should be replaced with an ACL check. */
|
/* This should be replaced with an ACL check. */
|
||||||
if (who_e != PFS_PROC_NR) return EPERM;
|
if (!super_user) return EPERM;
|
||||||
|
|
||||||
proc_e = job_m_in.VFS_PFS_ENDPT;
|
proc_e = job_m_in.VFS_UDS_ENDPT;
|
||||||
fd = job_m_in.VFS_PFS_FD;
|
fd = job_m_in.VFS_UDS_FD;
|
||||||
|
|
||||||
rfilp = (struct filp *) verify_fd(proc_e, fd);
|
rfilp = (struct filp *) verify_fd(proc_e, fd);
|
||||||
m_out->VFS_PFS_FILP = (void *) rfilp;
|
m_out->VFS_UDS_FILP = (void *) rfilp;
|
||||||
if (rfilp != NULL) unlock_filp(rfilp);
|
if (rfilp != NULL) unlock_filp(rfilp);
|
||||||
return (rfilp != NULL) ? OK : EINVAL;
|
return (rfilp != NULL) ? OK : EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -414,9 +414,9 @@ int do_set_filp(message *UNUSED(m_out))
|
||||||
filp_id_t f;
|
filp_id_t f;
|
||||||
|
|
||||||
/* This should be replaced with an ACL check. */
|
/* This should be replaced with an ACL check. */
|
||||||
if (who_e != PFS_PROC_NR) return EPERM;
|
if (!super_user) return EPERM;
|
||||||
|
|
||||||
f = (filp_id_t) job_m_in.VFS_PFS_FILP;
|
f = (filp_id_t) job_m_in.VFS_UDS_FILP;
|
||||||
return set_filp(f);
|
return set_filp(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,10 +457,10 @@ int do_copy_filp(message *UNUSED(m_out))
|
||||||
filp_id_t f;
|
filp_id_t f;
|
||||||
|
|
||||||
/* This should be replaced with an ACL check. */
|
/* This should be replaced with an ACL check. */
|
||||||
if (who_e != PFS_PROC_NR) return EPERM;
|
if (!super_user) return EPERM;
|
||||||
|
|
||||||
proc_e = job_m_in.VFS_PFS_ENDPT;
|
proc_e = job_m_in.VFS_UDS_ENDPT;
|
||||||
f = (filp_id_t) job_m_in.VFS_PFS_FILP;
|
f = (filp_id_t) job_m_in.VFS_UDS_FILP;
|
||||||
|
|
||||||
return copy_filp(proc_e, f);
|
return copy_filp(proc_e, f);
|
||||||
}
|
}
|
||||||
|
@ -488,9 +488,9 @@ int do_put_filp(message *UNUSED(m_out))
|
||||||
filp_id_t f;
|
filp_id_t f;
|
||||||
|
|
||||||
/* This should be replaced with an ACL check. */
|
/* This should be replaced with an ACL check. */
|
||||||
if (who_e != PFS_PROC_NR) return EPERM;
|
if (!super_user) return EPERM;
|
||||||
|
|
||||||
f = (filp_id_t) job_m_in.VFS_PFS_FILP;
|
f = (filp_id_t) job_m_in.VFS_UDS_FILP;
|
||||||
return put_filp(f);
|
return put_filp(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,10 +537,10 @@ int do_cancel_fd(message *UNUSED(m_out))
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* This should be replaced with an ACL check. */
|
/* This should be replaced with an ACL check. */
|
||||||
if (who_e != PFS_PROC_NR) return EPERM;
|
if (!super_user) return EPERM;
|
||||||
|
|
||||||
proc_e = job_m_in.VFS_PFS_ENDPT;
|
proc_e = job_m_in.VFS_UDS_ENDPT;
|
||||||
fd = job_m_in.VFS_PFS_FD;
|
fd = job_m_in.VFS_UDS_FD;
|
||||||
|
|
||||||
return cancel_fd(proc_e, fd);
|
return cancel_fd(proc_e, fd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,9 +238,9 @@ static void do_work(void)
|
||||||
} else {
|
} else {
|
||||||
/* At this point we assume that we're dealing with a call that has been
|
/* At this point we assume that we're dealing with a call that has been
|
||||||
* made specifically to VFS. Typically it will be a POSIX call from a
|
* made specifically to VFS. Typically it will be a POSIX call from a
|
||||||
* normal process, but we also handle a few calls made by system
|
* normal process, but we also handle a few calls made by drivers such
|
||||||
* processes (such as PFS) through here. Call the internal function
|
* such as UDS and VND through here. Call the internal function that
|
||||||
* that does the work.
|
* does the work.
|
||||||
*/
|
*/
|
||||||
if (job_call_nr < 0 || job_call_nr >= NCALLS) {
|
if (job_call_nr < 0 || job_call_nr >= NCALLS) {
|
||||||
error = ENOSYS;
|
error = ENOSYS;
|
||||||
|
|
|
@ -834,8 +834,8 @@ size_t pathlen;
|
||||||
if (pathlen < UNIX_PATH_MAX || pathlen >= PATH_MAX) return(EINVAL);
|
if (pathlen < UNIX_PATH_MAX || pathlen >= PATH_MAX) return(EINVAL);
|
||||||
|
|
||||||
rfp = &(fproc[slot]);
|
rfp = &(fproc[slot]);
|
||||||
r = sys_safecopyfrom(PFS_PROC_NR, io_gr, (vir_bytes) 0,
|
r = sys_safecopyfrom(who_e, io_gr, (vir_bytes) 0, (vir_bytes) canon_path,
|
||||||
(vir_bytes) canon_path, pathlen);
|
pathlen);
|
||||||
if (r != OK) return(r);
|
if (r != OK) return(r);
|
||||||
canon_path[pathlen] = '\0';
|
canon_path[pathlen] = '\0';
|
||||||
|
|
||||||
|
@ -843,8 +843,8 @@ size_t pathlen;
|
||||||
if ((r = canonical_path(canon_path, rfp)) != OK) return(r);
|
if ((r = canonical_path(canon_path, rfp)) != OK) return(r);
|
||||||
if (strlen(canon_path) >= pathlen) return(ENAMETOOLONG);
|
if (strlen(canon_path) >= pathlen) return(ENAMETOOLONG);
|
||||||
|
|
||||||
/* copy canon_path back to PFS */
|
/* copy canon_path back to the caller */
|
||||||
r = sys_safecopyto(PFS_PROC_NR, (cp_grant_id_t) io_gr, (vir_bytes) 0,
|
r = sys_safecopyto(who_e, (cp_grant_id_t) io_gr, (vir_bytes) 0,
|
||||||
(vir_bytes) canon_path, pathlen);
|
(vir_bytes) canon_path, pathlen);
|
||||||
if (r != OK) return(r);
|
if (r != OK) return(r);
|
||||||
|
|
||||||
|
@ -870,8 +870,8 @@ size_t pathlen;
|
||||||
int do_check_perms(message *UNUSED(m_out))
|
int do_check_perms(message *UNUSED(m_out))
|
||||||
{
|
{
|
||||||
/* This should be replaced by an ACL check. */
|
/* This should be replaced by an ACL check. */
|
||||||
if (who_e != PFS_PROC_NR) return EPERM;
|
if (!super_user) return EPERM;
|
||||||
|
|
||||||
return check_perms(job_m_in.VFS_PFS_ENDPT, job_m_in.VFS_PFS_GRANT,
|
return check_perms(job_m_in.VFS_UDS_ENDPT, job_m_in.VFS_UDS_GRANT,
|
||||||
(size_t) job_m_in.VFS_PFS_COUNT);
|
(size_t) job_m_in.VFS_UDS_COUNT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,11 +188,10 @@ int do_select(message *UNUSED(m_out))
|
||||||
*
|
*
|
||||||
* In our case, terminal and pseudo-terminal devices are handled by the
|
* In our case, terminal and pseudo-terminal devices are handled by the
|
||||||
* TTY major and sockets by either INET major (socket type AF_INET) or
|
* TTY major and sockets by either INET major (socket type AF_INET) or
|
||||||
* PFS major (socket type AF_UNIX). PFS acts as an FS when it handles
|
* UDS major (socket type AF_UNIX). Additionally, we give other
|
||||||
* pipes and as a driver when it handles sockets. Additionally, we
|
* character drivers the chance to handle select for any of their
|
||||||
* give other character drivers the chance to handle select for any of
|
* device nodes. Some may not implement support for select and let
|
||||||
* their device nodes. Some may not implement support for select and
|
* libchardriver return EBADF, which we then pass to the calling
|
||||||
* let libchardriver return EBADF, which we then pass to the calling
|
|
||||||
* process once we receive the reply.
|
* process once we receive the reply.
|
||||||
*/
|
*/
|
||||||
se->type[fd] = -1;
|
se->type[fd] = -1;
|
||||||
|
|
|
@ -138,12 +138,12 @@ int (*call_vec[])(message *m_out) = {
|
||||||
no_sys, /* 121 = (task reply) */
|
no_sys, /* 121 = (task reply) */
|
||||||
do_mapdriver, /* 122 = mapdriver */
|
do_mapdriver, /* 122 = mapdriver */
|
||||||
do_getrusage, /* 123 = getrusage */
|
do_getrusage, /* 123 = getrusage */
|
||||||
do_check_perms, /* 124 = from PFS: check_perms */
|
do_check_perms, /* 124 = from UDS: check_perms */
|
||||||
do_verify_fd, /* 125 = from PFS: verify_fd */
|
do_verify_fd, /* 125 = from UDS: verify_fd */
|
||||||
do_set_filp, /* 126 = from PFS: set_filp */
|
do_set_filp, /* 126 = from UDS: set_filp */
|
||||||
do_copy_filp, /* 127 = from PFS: copy_filp */
|
do_copy_filp, /* 127 = from UDS: copy_filp */
|
||||||
do_put_filp, /* 128 = from PFS: put_filp */
|
do_put_filp, /* 128 = from UDS: put_filp */
|
||||||
do_cancel_fd, /* 129 = from PFS: cancel_fd */
|
do_cancel_fd, /* 129 = from UDS: cancel_fd */
|
||||||
};
|
};
|
||||||
/* This should not fail with "array size is negative": */
|
/* This should not fail with "array size is negative": */
|
||||||
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];
|
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];
|
||||||
|
|
Loading…
Reference in a new issue