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/sched minix-sys
|
||||
./usr/sbin/tty minix-sys
|
||||
./usr/sbin/uds minix-sys
|
||||
./usr/sbin/unlink minix-sys
|
||||
./usr/sbin/user minix-sys
|
||||
./usr/sbin/useradd minix-sys
|
||||
|
|
|
@ -18,13 +18,13 @@ SUBDIR= tty
|
|||
.if ${MACHINE_ARCH} == "i386"
|
||||
SUBDIR= ahci amddev atl2 at_wini audio dec21140A dp8390 dpeth \
|
||||
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
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_ARCH} == "earm"
|
||||
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 # ${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...
|
||||
*
|
||||
* uds_init: initialize the descriptor table.
|
||||
* uds_do_ioctl: process an IOCTL request.
|
||||
* 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"
|
||||
|
||||
/* 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
|
||||
* state to UDS_FREE.
|
||||
*/
|
||||
memset(uds_fd_table, '\0', sizeof(uds_fd_t) * NR_FDS);
|
||||
}
|
||||
|
||||
/* check the permissions of a socket file */
|
||||
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;
|
||||
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 */
|
||||
memset(&vfs_m, '\0', sizeof(message));
|
||||
|
||||
vfs_m.m_type = VFS_PFS_CHECK_PERMS;
|
||||
vfs_m.VFS_PFS_ENDPT = uds_fd_table[minor].owner;
|
||||
vfs_m.VFS_PFS_GRANT = grant_id;
|
||||
vfs_m.VFS_PFS_COUNT = UNIX_PATH_MAX;
|
||||
vfs_m.m_type = VFS_UDS_CHECK_PERMS;
|
||||
vfs_m.VFS_UDS_ENDPT = uds_fd_table[minor].owner;
|
||||
vfs_m.VFS_UDS_GRANT = grant_id;
|
||||
vfs_m.VFS_UDS_COUNT = UNIX_PATH_MAX;
|
||||
|
||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||
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. */
|
||||
}
|
||||
|
||||
static filp_id_t verify_fd(endpoint_t ep, int fd)
|
||||
static filp_id_t
|
||||
verify_fd(endpoint_t ep, int fd)
|
||||
{
|
||||
int rc;
|
||||
message vfs_m;
|
||||
|
@ -82,9 +63,9 @@ static filp_id_t verify_fd(endpoint_t ep, int fd)
|
|||
|
||||
memset(&vfs_m, '\0', sizeof(message));
|
||||
|
||||
vfs_m.m_type = VFS_PFS_VERIFY_FD;
|
||||
vfs_m.VFS_PFS_ENDPT = ep;
|
||||
vfs_m.VFS_PFS_FD = fd;
|
||||
vfs_m.m_type = VFS_UDS_VERIFY_FD;
|
||||
vfs_m.VFS_UDS_ENDPT = ep;
|
||||
vfs_m.VFS_UDS_FD = fd;
|
||||
|
||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||
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);
|
||||
#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;
|
||||
message vfs_m;
|
||||
|
@ -112,8 +94,8 @@ static int set_filp(filp_id_t sfilp)
|
|||
|
||||
memset(&vfs_m, '\0', sizeof(message));
|
||||
|
||||
vfs_m.m_type = VFS_PFS_SET_FILP;
|
||||
vfs_m.VFS_PFS_FILP = sfilp;
|
||||
vfs_m.m_type = VFS_UDS_SET_FILP;
|
||||
vfs_m.VFS_UDS_FILP = sfilp;
|
||||
|
||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||
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. */
|
||||
}
|
||||
|
||||
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;
|
||||
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));
|
||||
|
||||
vfs_m.m_type = VFS_PFS_COPY_FILP;
|
||||
vfs_m.VFS_PFS_ENDPT = to_ep;
|
||||
vfs_m.VFS_PFS_FILP = cfilp;
|
||||
vfs_m.m_type = VFS_UDS_COPY_FILP;
|
||||
vfs_m.VFS_UDS_ENDPT = to_ep;
|
||||
vfs_m.VFS_UDS_FILP = cfilp;
|
||||
|
||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||
if (OK != rc) {
|
||||
|
@ -158,7 +141,8 @@ static int copy_filp(endpoint_t to_ep, filp_id_t cfilp)
|
|||
return vfs_m.m_type;
|
||||
}
|
||||
|
||||
static int put_filp(filp_id_t pfilp)
|
||||
static int
|
||||
put_filp(filp_id_t pfilp)
|
||||
{
|
||||
int rc;
|
||||
message vfs_m;
|
||||
|
@ -170,8 +154,8 @@ static int put_filp(filp_id_t pfilp)
|
|||
|
||||
memset(&vfs_m, '\0', sizeof(message));
|
||||
|
||||
vfs_m.m_type = VFS_PFS_PUT_FILP;
|
||||
vfs_m.VFS_PFS_FILP = pfilp;
|
||||
vfs_m.m_type = VFS_UDS_PUT_FILP;
|
||||
vfs_m.VFS_UDS_FILP = pfilp;
|
||||
|
||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||
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. */
|
||||
}
|
||||
|
||||
static int cancel_fd(endpoint_t ep, int fd)
|
||||
static int
|
||||
cancel_fd(endpoint_t ep, int fd)
|
||||
{
|
||||
int rc;
|
||||
message vfs_m;
|
||||
|
@ -198,9 +183,9 @@ static int cancel_fd(endpoint_t ep, int fd)
|
|||
|
||||
memset(&vfs_m, '\0', sizeof(message));
|
||||
|
||||
vfs_m.m_type = VFS_PFS_CANCEL_FD;
|
||||
vfs_m.VFS_PFS_ENDPT = ep;
|
||||
vfs_m.VFS_PFS_FD = fd;
|
||||
vfs_m.m_type = VFS_UDS_CANCEL_FD;
|
||||
vfs_m.VFS_UDS_ENDPT = ep;
|
||||
vfs_m.VFS_UDS_FD = fd;
|
||||
|
||||
rc = sendrec(VFS_PROC_NR, &vfs_m);
|
||||
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. */
|
||||
}
|
||||
|
||||
static int perform_connection(devminor_t minorx, devminor_t minory,
|
||||
static int
|
||||
perform_connection(devminor_t minorx, devminor_t minory,
|
||||
struct sockaddr_un *addr)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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 minorpeer;
|
||||
|
@ -370,7 +357,8 @@ static int do_accept(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
|||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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 backlog_size;
|
||||
|
@ -585,7 +574,8 @@ static int do_listen(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
|||
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;
|
||||
|
||||
|
@ -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;
|
||||
int rc, i;
|
||||
|
@ -690,8 +681,8 @@ static int do_bind(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
|||
return OK;
|
||||
}
|
||||
|
||||
static int do_getsockname(devminor_t minor, endpoint_t endpt,
|
||||
cp_grant_id_t grant)
|
||||
static int
|
||||
do_getsockname(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
@ -714,8 +705,8 @@ static int do_getsockname(devminor_t minor, endpoint_t endpt,
|
|||
return rc ? EIO : OK;
|
||||
}
|
||||
|
||||
static int do_getpeername(devminor_t minor, endpoint_t endpt,
|
||||
cp_grant_id_t grant)
|
||||
static int
|
||||
do_getpeername(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -784,12 +776,12 @@ static int do_shutdown(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
|||
switch (how) {
|
||||
case SHUT_RD:
|
||||
/* take away read permission */
|
||||
uds_fd_table[minor].mode &= ~S_IRUSR;
|
||||
uds_fd_table[minor].mode &= ~R_BIT;
|
||||
break;
|
||||
|
||||
case SHUT_WR:
|
||||
/* take away write permission */
|
||||
uds_fd_table[minor].mode &= ~S_IWUSR;
|
||||
uds_fd_table[minor].mode &= ~W_BIT;
|
||||
break;
|
||||
|
||||
case SHUT_RDWR:
|
||||
|
@ -805,8 +797,8 @@ static int do_shutdown(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
|||
return OK;
|
||||
}
|
||||
|
||||
static int do_socketpair(devminor_t minorx, endpoint_t endpt,
|
||||
cp_grant_id_t grant)
|
||||
static int
|
||||
do_socketpair(devminor_t minorx, endpoint_t endpt, cp_grant_id_t grant)
|
||||
{
|
||||
int rc;
|
||||
dev_t minorin;
|
||||
|
@ -848,8 +840,8 @@ static int do_socketpair(devminor_t minorx, endpoint_t endpt,
|
|||
return perform_connection(minorx, minory, &addr);
|
||||
}
|
||||
|
||||
static int do_getsockopt_sotype(devminor_t minor, endpoint_t endpt,
|
||||
cp_grant_id_t grant)
|
||||
static int
|
||||
do_getsockopt_sotype(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
@ -872,8 +864,8 @@ static int do_getsockopt_sotype(devminor_t minor, endpoint_t endpt,
|
|||
return rc ? EIO : OK;
|
||||
}
|
||||
|
||||
static int do_getsockopt_peercred(devminor_t minor, endpoint_t endpt,
|
||||
cp_grant_id_t grant)
|
||||
static int
|
||||
do_getsockopt_peercred(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||
{
|
||||
int peer_minor;
|
||||
int rc;
|
||||
|
@ -911,8 +903,8 @@ static int do_getsockopt_peercred(devminor_t minor, endpoint_t endpt,
|
|||
return rc ? EIO : OK;
|
||||
}
|
||||
|
||||
static int do_getsockopt_sndbuf(devminor_t minor, endpoint_t endpt,
|
||||
cp_grant_id_t grant)
|
||||
static int
|
||||
do_getsockopt_sndbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||
{
|
||||
int rc;
|
||||
size_t sndbuf = PIPE_BUF;
|
||||
|
@ -929,8 +921,8 @@ static int do_getsockopt_sndbuf(devminor_t minor, endpoint_t endpt,
|
|||
return rc ? EIO : OK;
|
||||
}
|
||||
|
||||
static int do_setsockopt_sndbuf(devminor_t minor, endpoint_t endpt,
|
||||
cp_grant_id_t grant)
|
||||
static int
|
||||
do_setsockopt_sndbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||
{
|
||||
int rc;
|
||||
size_t sndbuf;
|
||||
|
@ -959,8 +951,8 @@ static int do_setsockopt_sndbuf(devminor_t minor, endpoint_t endpt,
|
|||
return OK;
|
||||
}
|
||||
|
||||
static int do_getsockopt_rcvbuf(devminor_t minor, endpoint_t endpt,
|
||||
cp_grant_id_t grant)
|
||||
static int
|
||||
do_getsockopt_rcvbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||
{
|
||||
int rc;
|
||||
size_t rcvbuf = PIPE_BUF;
|
||||
|
@ -977,8 +969,8 @@ static int do_getsockopt_rcvbuf(devminor_t minor, endpoint_t endpt,
|
|||
return rc ? EIO : OK;
|
||||
}
|
||||
|
||||
static int do_setsockopt_rcvbuf(devminor_t minor, endpoint_t endpt,
|
||||
cp_grant_id_t grant)
|
||||
static int
|
||||
do_setsockopt_rcvbuf(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
||||
{
|
||||
int rc;
|
||||
size_t rcvbuf;
|
||||
|
@ -1007,7 +999,8 @@ static int do_setsockopt_rcvbuf(devminor_t minor, endpoint_t endpt,
|
|||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -1063,8 +1057,9 @@ static int do_recvfrom(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant)
|
|||
return rc ? EIO : OK;
|
||||
}
|
||||
|
||||
static int msg_control_read(struct msg_control *msg_ctrl,
|
||||
struct ancillary *data, devminor_t minor)
|
||||
static int
|
||||
msg_control_read(struct msg_control *msg_ctrl, struct ancillary *data,
|
||||
devminor_t minor)
|
||||
{
|
||||
int rc;
|
||||
struct msghdr msghdr;
|
||||
|
@ -1122,7 +1117,8 @@ static int msg_control_read(struct msg_control *msg_ctrl,
|
|||
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;
|
||||
|
||||
|
@ -1156,13 +1152,15 @@ static int send_fds(devminor_t minor, struct ancillary *data)
|
|||
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
|
||||
* exists references to file descriptors that haven't been received
|
||||
* with recvmsg().
|
||||
*/
|
||||
int
|
||||
uds_clear_fds(devminor_t minor, struct ancillary *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
#if DEBUG == 1
|
||||
|
@ -1185,8 +1183,9 @@ int uds_clear_fds(devminor_t minor, struct ancillary *data)
|
|||
return OK;
|
||||
}
|
||||
|
||||
static int recv_fds(devminor_t minor, struct ancillary *data,
|
||||
struct msg_control *msg_ctrl)
|
||||
static int
|
||||
recv_fds(devminor_t minor, struct ancillary *data,
|
||||
struct msg_control *msg_ctrl)
|
||||
{
|
||||
int rc, i, j;
|
||||
struct msghdr msghdr;
|
||||
|
@ -1241,8 +1240,9 @@ static int recv_fds(devminor_t minor, struct ancillary *data,
|
|||
return OK;
|
||||
}
|
||||
|
||||
static int recv_cred(devminor_t minor, struct ancillary *data,
|
||||
struct msg_control *msg_ctrl)
|
||||
static int
|
||||
recv_cred(devminor_t minor, struct ancillary *data,
|
||||
struct msg_control *msg_ctrl)
|
||||
{
|
||||
struct msghdr msghdr;
|
||||
struct cmsghdr *cmsg;
|
||||
|
@ -1269,7 +1269,8 @@ static int recv_cred(devminor_t minor, struct ancillary *data,
|
|||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int rc;
|
|
@ -4,41 +4,31 @@
|
|||
*
|
||||
* The entry points into this file are...
|
||||
*
|
||||
* uds_request: process a character device request
|
||||
*
|
||||
* Also See...
|
||||
*
|
||||
* uds.c, uds.h
|
||||
*
|
||||
* Overview
|
||||
* uds_unsuspend: resume a previously suspended socket call
|
||||
* main: driver main loop
|
||||
*
|
||||
* 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
|
||||
* 'driver' for that device.
|
||||
*/
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#include "inc.h"
|
||||
#include "const.h"
|
||||
#include "glo.h"
|
||||
#include "uds.h"
|
||||
|
||||
static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
|
||||
cp_grant_id_t grant, size_t size, int pretend);
|
||||
static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
||||
cp_grant_id_t grant, size_t size, int pretend);
|
||||
static ssize_t uds_perform_read(devminor_t, endpoint_t, cp_grant_id_t, size_t,
|
||||
int);
|
||||
static ssize_t uds_perform_write(devminor_t, endpoint_t, cp_grant_id_t, size_t,
|
||||
int);
|
||||
|
||||
static int uds_open(devminor_t orig_minor, int access, endpoint_t user_endpt);
|
||||
static int uds_close(devminor_t minor);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
static int uds_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id);
|
||||
static int uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt);
|
||||
static int uds_open(devminor_t, int, endpoint_t);
|
||||
static int uds_close(devminor_t);
|
||||
static ssize_t uds_read(devminor_t, u64_t, endpoint_t, cp_grant_id_t, size_t,
|
||||
int, cdev_id_t);
|
||||
static ssize_t uds_write(devminor_t, u64_t, endpoint_t, cp_grant_id_t, size_t,
|
||||
int, cdev_id_t);
|
||||
static int uds_ioctl(devminor_t, unsigned long, endpoint_t, cp_grant_id_t, int,
|
||||
endpoint_t, cdev_id_t);
|
||||
static int uds_cancel(devminor_t, endpoint_t, cdev_id_t);
|
||||
static int uds_select(devminor_t, unsigned int, endpoint_t);
|
||||
|
||||
static struct chardriver uds_tab = {
|
||||
.cdr_open = uds_open,
|
||||
|
@ -50,19 +40,18 @@ static struct chardriver uds_tab = {
|
|||
.cdr_select = uds_select
|
||||
};
|
||||
|
||||
void uds_request(message *m_ptr, int ipc_status)
|
||||
{
|
||||
/* Use libchardriver to process character device requests. */
|
||||
chardriver_process(&uds_tab, m_ptr, ipc_status);
|
||||
}
|
||||
/* File Descriptor Table */
|
||||
uds_fd_t uds_fd_table[NR_FDS];
|
||||
|
||||
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)
|
||||
{
|
||||
message fs_m_in, fs_m_out;
|
||||
struct uucred ucred;
|
||||
devminor_t minor;
|
||||
int rc, i;
|
||||
int i;
|
||||
char *buf;
|
||||
|
||||
#if DEBUG == 1
|
||||
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
|
||||
* the /dev/uds device's minor number (currently 0).
|
||||
*/
|
||||
|
||||
minor = -1; /* to trap error */
|
||||
|
||||
for (i = 1; i < NR_FDS; i++) {
|
||||
|
@ -91,8 +79,14 @@ static int uds_open(devminor_t UNUSED(orig_minor), int access,
|
|||
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
|
||||
* another socket
|
||||
|
@ -105,8 +99,7 @@ static int uds_open(devminor_t UNUSED(orig_minor), int access,
|
|||
/* setup select(2) framework */
|
||||
uds_fd_table[minor].sel_endpt = NONE;
|
||||
uds_fd_table[minor].sel_ops = 0;
|
||||
|
||||
/* initialize the data pointer (pos) to the start of the PIPE */
|
||||
uds_fd_table[minor].buf = buf;
|
||||
uds_fd_table[minor].pos = 0;
|
||||
|
||||
/* 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.
|
||||
* 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
|
||||
* NWIOSUDSTYPE ioctl().
|
||||
|
@ -156,46 +149,13 @@ static int uds_open(devminor_t UNUSED(orig_minor), int access,
|
|||
/* Initially the socket isn't 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;
|
||||
}
|
||||
|
||||
static int uds_close(devminor_t minor)
|
||||
static int
|
||||
uds_close(devminor_t minor)
|
||||
{
|
||||
message fs_m_in, fs_m_out;
|
||||
int rc;
|
||||
int peer;
|
||||
|
||||
#if DEBUG == 1
|
||||
static int call_count = 0;
|
||||
|
@ -213,7 +173,7 @@ static int uds_close(devminor_t minor)
|
|||
|
||||
/* if the socket is connected, disconnect it */
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
fs_m_in.REQ_INODE_NR = uds_fd_table[minor].inode_nr;
|
||||
fs_m_in.REQ_COUNT = 1;
|
||||
/* Set the socket back to its original UDS_FREE state. */
|
||||
memset(&uds_fd_table[minor], '\0', sizeof(uds_fd_t));
|
||||
|
||||
/* set the socket back to its original UDS_FREE state */
|
||||
memset(&(uds_fd_table[minor]), '\0', sizeof(uds_fd_t));
|
||||
|
||||
/* Request the removal of the inode from the pipe file system */
|
||||
|
||||
rc = fs_putnode(&fs_m_in, &fs_m_out);
|
||||
if (rc != OK) {
|
||||
printf("PFS: fs_putnode returned %d\n", rc);
|
||||
|
||||
return rc;
|
||||
/* If terminating, and this was the last open socket, exit now. */
|
||||
if (uds_exit_left > 0) {
|
||||
if (--uds_exit_left == 0)
|
||||
chardriver_terminate();
|
||||
}
|
||||
|
||||
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;
|
||||
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 */
|
||||
if (ops & CDEV_OP_WR) {
|
||||
bytes = uds_perform_write(minor, NONE, GRANT_INVALID, PIPE_BUF,
|
||||
1);
|
||||
bytes = uds_perform_write(minor, NONE, GRANT_INVALID, 1, 1);
|
||||
if (bytes != 0 && bytes != SUSPEND) {
|
||||
/* There is room to write or there is an error
|
||||
* condition.
|
||||
|
@ -319,12 +273,12 @@ static int uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt)
|
|||
return ready_ops;
|
||||
}
|
||||
|
||||
static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
|
||||
cp_grant_id_t grant, size_t size, int pretend)
|
||||
static ssize_t
|
||||
uds_perform_read(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant,
|
||||
size_t size, int pretend)
|
||||
{
|
||||
int rc, peer;
|
||||
message fs_m_in;
|
||||
message fs_m_out;
|
||||
size_t pos, subsize;
|
||||
int r, peer;
|
||||
|
||||
#if DEBUG == 1
|
||||
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 */
|
||||
if (!(uds_fd_table[minor].mode & S_IRUSR)) {
|
||||
if (!(uds_fd_table[minor].mode & R_BIT)) {
|
||||
/* socket is shutdown for reading */
|
||||
return EPIPE;
|
||||
}
|
||||
|
@ -352,7 +306,8 @@ static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
|
|||
if (uds_fd_table[minor].type == SOCK_STREAM ||
|
||||
uds_fd_table[minor].type == SOCK_SEQPACKET) {
|
||||
if (uds_fd_table[minor].err == ECONNRESET) {
|
||||
uds_fd_table[minor].err = 0;
|
||||
if (!pretend)
|
||||
uds_fd_table[minor].err = 0;
|
||||
return ECONNRESET;
|
||||
} else {
|
||||
return ENOTCONN;
|
||||
|
@ -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 */
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -386,40 +341,34 @@ static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt,
|
|||
return EDONTREPLY;
|
||||
}
|
||||
|
||||
if (pretend) {
|
||||
return (size > uds_fd_table[minor].size) ?
|
||||
uds_fd_table[minor].size : size;
|
||||
/* How much can we get from the ring buffer? */
|
||||
if (size > uds_fd_table[minor].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 */
|
||||
fs_m_in.m_source = endpt;
|
||||
fs_m_in.m_type = REQ_READ;
|
||||
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;
|
||||
/* Advance the buffer tail. */
|
||||
uds_fd_table[minor].pos = (pos + size) % PIPE_BUF;
|
||||
uds_fd_table[minor].size -= size;
|
||||
|
||||
/* if we have 0 unread bytes, move the data pointer back to the
|
||||
* 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.
|
||||
*/
|
||||
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 */
|
||||
chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer,
|
||||
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,
|
||||
cp_grant_id_t grant, size_t size, int pretend)
|
||||
static ssize_t
|
||||
uds_perform_write(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant,
|
||||
size_t size, int pretend)
|
||||
{
|
||||
int rc, peer, i;
|
||||
message fs_m_in;
|
||||
message fs_m_out;
|
||||
size_t subsize, pos;
|
||||
int i, r, peer;
|
||||
|
||||
#if DEBUG == 1
|
||||
static int call_count = 0;
|
||||
|
@ -462,13 +411,12 @@ static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
|||
++call_count);
|
||||
#endif
|
||||
|
||||
/* skip reads and writes of 0 (or less!) bytes */
|
||||
if (size <= 0) {
|
||||
/* Skip writes of zero bytes. */
|
||||
if (size == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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 */
|
||||
if (!(uds_fd_table[peer].mode & S_IRUSR)) {
|
||||
if (!(uds_fd_table[peer].mode & R_BIT)) {
|
||||
return EPIPE;
|
||||
}
|
||||
|
||||
|
@ -535,14 +483,13 @@ static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
|||
return size;
|
||||
}
|
||||
|
||||
/* check if write would overrun buffer. check if message
|
||||
* SEQPACKET wouldn't write to an empty buffer. check if
|
||||
* connectionless sockets have a target to write to.
|
||||
/*
|
||||
* Check if the ring buffer is already full, and if the SEQPACKET
|
||||
* message wouldn't write to an empty buffer.
|
||||
*/
|
||||
if ((uds_fd_table[peer].pos+uds_fd_table[peer].size+size > PIPE_BUF) ||
|
||||
((uds_fd_table[minor].type == SOCK_SEQPACKET) &&
|
||||
uds_fd_table[peer].size > 0)) {
|
||||
|
||||
if (uds_fd_table[peer].size == PIPE_BUF ||
|
||||
(uds_fd_table[minor].type == SOCK_SEQPACKET &&
|
||||
uds_fd_table[peer].size > 0)) {
|
||||
if (pretend) {
|
||||
return SUSPEND;
|
||||
}
|
||||
|
@ -552,7 +499,7 @@ static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
|||
uds_unsuspend(peer);
|
||||
|
||||
#if DEBUG == 1
|
||||
printf("(uds) [%d] suspending write request\n", minor);
|
||||
printf("(uds) [%d] suspending write request\n", minor);
|
||||
#endif
|
||||
|
||||
/* Process is reading from an empty pipe,
|
||||
|
@ -561,33 +508,32 @@ static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt,
|
|||
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;
|
||||
|
||||
/* 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 */
|
||||
fs_m_in.m_source = endpt;
|
||||
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;
|
||||
/* Advance the buffer head. */
|
||||
uds_fd_table[peer].size += size;
|
||||
|
||||
/* fill in the source address to be returned by recvfrom & recvmsg */
|
||||
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
|
||||
* the peer know we have data for it.
|
||||
*/
|
||||
if ((uds_fd_table[peer].sel_ops & CDEV_OP_RD) &&
|
||||
fs_m_out.RES_NBYTES > 0) {
|
||||
if ((uds_fd_table[peer].sel_ops & CDEV_OP_RD) && size > 0) {
|
||||
/* a read on peer is possible now */
|
||||
chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer,
|
||||
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)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
@ -654,7 +600,8 @@ static ssize_t uds_read(devminor_t minor, u64_t position, endpoint_t endpt,
|
|||
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)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
@ -694,7 +641,8 @@ static ssize_t uds_write(devminor_t minor, u64_t position, endpoint_t endpt,
|
|||
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)
|
||||
{
|
||||
int rc;
|
||||
|
@ -740,7 +688,8 @@ static int uds_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
|
|||
return rc;
|
||||
}
|
||||
|
||||
void uds_unsuspend(devminor_t minor)
|
||||
void
|
||||
uds_unsuspend(devminor_t minor)
|
||||
{
|
||||
int r;
|
||||
uds_fd_t *fdp;
|
||||
|
@ -784,7 +733,8 @@ void uds_unsuspend(devminor_t minor)
|
|||
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;
|
||||
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];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,24 +1,23 @@
|
|||
#ifndef __PFS_UDS_H__
|
||||
#define __PFS_UDS_H__
|
||||
#ifndef __UDS_UDS_H
|
||||
#define __UDS_UDS_H
|
||||
|
||||
/*
|
||||
* Unix Domain Sockets Implementation (PF_UNIX, PF_LOCAL)
|
||||
*
|
||||
* Also See...
|
||||
*
|
||||
* dev_uds.c, table.c, uds.c
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <minix/drivers.h>
|
||||
#include <minix/chardriver.h>
|
||||
#undef send
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/chardriver.h>
|
||||
/* Maximum number of UNIX domain sockets. */
|
||||
#define NR_FDS 256
|
||||
|
||||
/* max connection backlog for incoming connections */
|
||||
#define UDS_SOMAXCONN 64
|
||||
/* Connection backlog size for incoming connections. */
|
||||
#define UDS_SOMAXCONN 64
|
||||
|
||||
/* Output debugging information? */
|
||||
#define DEBUG 0
|
||||
|
||||
typedef void* filp_id_t;
|
||||
|
||||
|
@ -57,26 +56,16 @@ struct uds_fd {
|
|||
|
||||
/* Pipe Housekeeping */
|
||||
|
||||
/* inode number on PFS -- each descriptor is backed by 1
|
||||
* PIPE which is allocated in uds_open() and freed in
|
||||
* uds_close(). Data is sent/written to a peer's PIPE.
|
||||
* 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;
|
||||
char *buf; /* ring buffer */
|
||||
size_t pos; /* tail position into ring buffer */
|
||||
size_t size; /* size of used part of ring buffer */
|
||||
|
||||
/* 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.
|
||||
* default is S_IRUSR|S_IWUSR.
|
||||
* default is R_BIT|W_BIT.
|
||||
*/
|
||||
pmode_t mode;
|
||||
int mode;
|
||||
|
||||
/* Socket Info */
|
||||
|
||||
|
@ -188,4 +177,14 @@ typedef struct uds_fd uds_fd_t;
|
|||
/* File Descriptor Table -- Defined in uds.c */
|
||||
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
|
||||
{
|
||||
ipc
|
||||
SYSTEM VFS RS DS VM
|
||||
SYSTEM vfs rs ds vm
|
||||
ahci
|
||||
at_wini
|
||||
;
|
||||
|
@ -696,7 +696,15 @@ service fbd
|
|||
service vnd
|
||||
{
|
||||
ipc
|
||||
SYSTEM VFS RS VM
|
||||
SYSTEM vfs rs vm
|
||||
;
|
||||
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
|
||||
fi
|
||||
|
||||
up uds -dev /dev/uds
|
||||
|
||||
up -n ipc
|
||||
|
||||
up log -dev /dev/klog
|
||||
|
|
|
@ -112,9 +112,9 @@
|
|||
#define MAPDRIVER 122 /* to VFS, map a device */
|
||||
#define GETRUSAGE 123 /* to PM, VFS */
|
||||
|
||||
#define VFS_PFS_CHECK_PERMS 124 /* to VFS */
|
||||
#define VFS_PFS_VERIFY_FD 125 /* to VFS */
|
||||
#define VFS_PFS_SET_FILP 126 /* to VFS */
|
||||
#define VFS_PFS_COPY_FILP 127 /* to VFS */
|
||||
#define VFS_PFS_PUT_FILP 128 /* to VFS */
|
||||
#define VFS_PFS_CANCEL_FD 129 /* to VFS */
|
||||
#define VFS_UDS_CHECK_PERMS 124 /* to VFS */
|
||||
#define VFS_UDS_VERIFY_FD 125 /* to VFS */
|
||||
#define VFS_UDS_SET_FILP 126 /* to VFS */
|
||||
#define VFS_UDS_COPY_FILP 127 /* to VFS */
|
||||
#define VFS_UDS_PUT_FILP 128 /* to VFS */
|
||||
#define VFS_UDS_CANCEL_FD 129 /* to VFS */
|
||||
|
|
|
@ -882,12 +882,12 @@
|
|||
#define VFS_IOCTL_REQ m2_i3
|
||||
#define VFS_IOCTL_ARG m2_p1
|
||||
|
||||
/* Field names for the PFS backcalls to VFS. */
|
||||
#define VFS_PFS_ENDPT m2_i1
|
||||
#define VFS_PFS_GRANT m2_i2
|
||||
#define VFS_PFS_COUNT m2_i3
|
||||
#define VFS_PFS_FD m2_i3
|
||||
#define VFS_PFS_FILP m2_p1
|
||||
/* Field names for the UDS backcalls to VFS. */
|
||||
#define VFS_UDS_ENDPT m2_i1
|
||||
#define VFS_UDS_GRANT m2_i2
|
||||
#define VFS_UDS_COUNT m2_i3
|
||||
#define VFS_UDS_FD m2_i3
|
||||
#define VFS_UDS_FILP m2_p1
|
||||
|
||||
/* Field names for the dupfrom(2) call. */
|
||||
#define VFS_DUPFROM_ENDPT m1_i1
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
# Makefile for Pipe File System (PFS)
|
||||
PROG= pfs
|
||||
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 \
|
||||
uds.c dev_uds.c
|
||||
buffer.c read.c misc.c mount.c utility.c stadir.c
|
||||
|
||||
DPADD+= ${LIBCHARDRIVER} ${LIBSYS}
|
||||
LDADD+= -lchardriver -lsys
|
||||
|
|
|
@ -3,40 +3,20 @@
|
|||
|
||||
#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_SIZE ((unsigned long)1<<INODE_HASH_LOG2)
|
||||
#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 ATIME 002 /* set if atime field needs updating */
|
||||
#define CTIME 004 /* set if ctime 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_BITCHUNK_BITS (usizeof(bitchunk_t) * CHAR_BIT)
|
||||
#define FS_BITMAP_CHUNKS(b) ((b)/sizeof (bitchunk_t))/* # map chunks/blk */
|
||||
#define FS_BITCHUNK_BITS (sizeof(bitchunk_t) * CHAR_BIT)
|
||||
#define FS_BITS_PER_BLOCK(b) (FS_BITMAP_CHUNKS(b) * FS_BITCHUNK_BITS)
|
||||
|
||||
#define FS_CALL_VEC_SIZE 31
|
||||
#define DEV_CALL_VEC_SIZE 25
|
||||
|
||||
#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 "buf.h"
|
||||
#include "inode.h"
|
||||
#include "uds.h"
|
||||
|
||||
static void get_work(message *m_in, int *status);
|
||||
|
||||
|
@ -41,13 +40,6 @@ int main(int argc, char *argv[])
|
|||
/* Wait for request message. */
|
||||
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);
|
||||
pfs_m_in.m_type = TRNS_DEL_ID(pfs_m_in.m_type);
|
||||
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();
|
||||
uds_init();
|
||||
buf_pool();
|
||||
|
||||
|
||||
/* Drop root privileges */
|
||||
if ((pw = getpwnam(SERVICE_LOGIN)) == NULL) {
|
||||
printf("PFS: unable to retrieve uid of SERVICE_LOGIN, "
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
/* Structs used in prototypes must be declared as such first. */
|
||||
struct buf;
|
||||
struct inode;
|
||||
struct sockaddr_un;
|
||||
struct ancillary;
|
||||
|
||||
/* buffer.c */
|
||||
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 truncate_inode(struct inode *rip, off_t newsize);
|
||||
|
||||
|
||||
/* main.c */
|
||||
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);
|
||||
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
|
||||
|
|
|
@ -5,11 +5,9 @@
|
|||
|
||||
#define _TABLE
|
||||
|
||||
#include "inc.h"
|
||||
#include "fs.h"
|
||||
#include "inode.h"
|
||||
#include "buf.h"
|
||||
#include "uds.h"
|
||||
|
||||
/* File System Handlers (pfs) */
|
||||
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 */
|
||||
{ TTY_PROC_NR, SRV_DF, TTY_MAJOR, STYLE_TTY, STYLE_CTTY },
|
||||
{ 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
|
||||
* entry
|
||||
*/
|
||||
|
|
|
@ -380,13 +380,13 @@ int do_verify_fd(message *m_out)
|
|||
int fd;
|
||||
|
||||
/* 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;
|
||||
fd = job_m_in.VFS_PFS_FD;
|
||||
proc_e = job_m_in.VFS_UDS_ENDPT;
|
||||
fd = job_m_in.VFS_UDS_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);
|
||||
return (rfilp != NULL) ? OK : EINVAL;
|
||||
}
|
||||
|
@ -414,9 +414,9 @@ int do_set_filp(message *UNUSED(m_out))
|
|||
filp_id_t f;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
@ -457,10 +457,10 @@ int do_copy_filp(message *UNUSED(m_out))
|
|||
filp_id_t f;
|
||||
|
||||
/* 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;
|
||||
f = (filp_id_t) job_m_in.VFS_PFS_FILP;
|
||||
proc_e = job_m_in.VFS_UDS_ENDPT;
|
||||
f = (filp_id_t) job_m_in.VFS_UDS_FILP;
|
||||
|
||||
return copy_filp(proc_e, f);
|
||||
}
|
||||
|
@ -488,9 +488,9 @@ int do_put_filp(message *UNUSED(m_out))
|
|||
filp_id_t f;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
@ -537,10 +537,10 @@ int do_cancel_fd(message *UNUSED(m_out))
|
|||
int fd;
|
||||
|
||||
/* 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;
|
||||
fd = job_m_in.VFS_PFS_FD;
|
||||
proc_e = job_m_in.VFS_UDS_ENDPT;
|
||||
fd = job_m_in.VFS_UDS_FD;
|
||||
|
||||
return cancel_fd(proc_e, fd);
|
||||
}
|
||||
|
|
|
@ -238,9 +238,9 @@ static void do_work(void)
|
|||
} else {
|
||||
/* 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
|
||||
* normal process, but we also handle a few calls made by system
|
||||
* processes (such as PFS) through here. Call the internal function
|
||||
* that does the work.
|
||||
* normal process, but we also handle a few calls made by drivers such
|
||||
* such as UDS and VND through here. Call the internal function that
|
||||
* does the work.
|
||||
*/
|
||||
if (job_call_nr < 0 || job_call_nr >= NCALLS) {
|
||||
error = ENOSYS;
|
||||
|
|
|
@ -834,8 +834,8 @@ size_t pathlen;
|
|||
if (pathlen < UNIX_PATH_MAX || pathlen >= PATH_MAX) return(EINVAL);
|
||||
|
||||
rfp = &(fproc[slot]);
|
||||
r = sys_safecopyfrom(PFS_PROC_NR, io_gr, (vir_bytes) 0,
|
||||
(vir_bytes) canon_path, pathlen);
|
||||
r = sys_safecopyfrom(who_e, io_gr, (vir_bytes) 0, (vir_bytes) canon_path,
|
||||
pathlen);
|
||||
if (r != OK) return(r);
|
||||
canon_path[pathlen] = '\0';
|
||||
|
||||
|
@ -843,9 +843,9 @@ size_t pathlen;
|
|||
if ((r = canonical_path(canon_path, rfp)) != OK) return(r);
|
||||
if (strlen(canon_path) >= pathlen) return(ENAMETOOLONG);
|
||||
|
||||
/* copy canon_path back to PFS */
|
||||
r = sys_safecopyto(PFS_PROC_NR, (cp_grant_id_t) io_gr, (vir_bytes) 0,
|
||||
(vir_bytes) canon_path, pathlen);
|
||||
/* copy canon_path back to the caller */
|
||||
r = sys_safecopyto(who_e, (cp_grant_id_t) io_gr, (vir_bytes) 0,
|
||||
(vir_bytes) canon_path, pathlen);
|
||||
if (r != OK) return(r);
|
||||
|
||||
/* Now do permissions checking */
|
||||
|
@ -870,8 +870,8 @@ size_t pathlen;
|
|||
int do_check_perms(message *UNUSED(m_out))
|
||||
{
|
||||
/* 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,
|
||||
(size_t) job_m_in.VFS_PFS_COUNT);
|
||||
return check_perms(job_m_in.VFS_UDS_ENDPT, job_m_in.VFS_UDS_GRANT,
|
||||
(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
|
||||
* 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
|
||||
* pipes and as a driver when it handles sockets. Additionally, we
|
||||
* give other character drivers the chance to handle select for any of
|
||||
* their device nodes. Some may not implement support for select and
|
||||
* let libchardriver return EBADF, which we then pass to the calling
|
||||
* UDS major (socket type AF_UNIX). Additionally, we give other
|
||||
* character drivers the chance to handle select for any of their
|
||||
* device nodes. Some may not implement support for select and let
|
||||
* libchardriver return EBADF, which we then pass to the calling
|
||||
* process once we receive the reply.
|
||||
*/
|
||||
se->type[fd] = -1;
|
||||
|
|
|
@ -138,12 +138,12 @@ int (*call_vec[])(message *m_out) = {
|
|||
no_sys, /* 121 = (task reply) */
|
||||
do_mapdriver, /* 122 = mapdriver */
|
||||
do_getrusage, /* 123 = getrusage */
|
||||
do_check_perms, /* 124 = from PFS: check_perms */
|
||||
do_verify_fd, /* 125 = from PFS: verify_fd */
|
||||
do_set_filp, /* 126 = from PFS: set_filp */
|
||||
do_copy_filp, /* 127 = from PFS: copy_filp */
|
||||
do_put_filp, /* 128 = from PFS: put_filp */
|
||||
do_cancel_fd, /* 129 = from PFS: cancel_fd */
|
||||
do_check_perms, /* 124 = from UDS: check_perms */
|
||||
do_verify_fd, /* 125 = from UDS: verify_fd */
|
||||
do_set_filp, /* 126 = from UDS: set_filp */
|
||||
do_copy_filp, /* 127 = from UDS: copy_filp */
|
||||
do_put_filp, /* 128 = from UDS: put_filp */
|
||||
do_cancel_fd, /* 129 = from UDS: cancel_fd */
|
||||
};
|
||||
/* This should not fail with "array size is negative": */
|
||||
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];
|
||||
|
|
Loading…
Reference in a new issue