UDS: split off from PFS

Change-Id: I769cbd64aa6e5e85a797caf0f8bbb4c20e145263
This commit is contained in:
David van Moolenbroek 2013-10-04 16:29:40 +02:00 committed by Lionel Sambuc
parent 6d466f941b
commit b003ed0929
22 changed files with 399 additions and 447 deletions

View file

@ -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

View file

@ -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
View 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>

View file

@ -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;

View file

@ -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);
}

View file

@ -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 */

View file

@ -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
};

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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, "

View file

@ -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

View file

@ -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) = {

View file

@ -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
*/

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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;

View file

@ -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];