./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
.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"
--- /dev/null
+# 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>
*
* 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;
/* 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);
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;
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) {
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;
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) {
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;
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) {
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;
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) {
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;
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) {
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. */
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;
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;
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;
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;
}
}
-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;
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;
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;
}
}
-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;
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:
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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
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;
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;
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;
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;
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;
*
* 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 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 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, 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,
.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 unsigned int uds_exit_left;
-static int uds_open(devminor_t UNUSED(orig_minor), int access,
+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;
* 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++) {
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
/* 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 */
/* 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().
/* 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;
/* 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;
uds_clear_fds(minor, &uds_fd_table[minor].ancillary_data);
}
- /* Prepare Request to the FS side of PFS */
-
- 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));
+ /* Release the memory for the ring buffer. */
+ minix_munmap(uds_fd_table[minor].buf, PIPE_BUF);
- /* Request the removal of the inode from the pipe file system */
+ /* Set the socket back to its original UDS_FREE state. */
+ memset(&uds_fd_table[minor], '\0', sizeof(uds_fd_t));
- 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;
/* 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.
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;
}
/* 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;
}
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;
}
/* 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;
}
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;
- /* 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;
+ if (pretend)
+ return 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;
- }
+ /* Get the data from the tail of the ring buffer. */
+ pos = uds_fd_table[minor].pos;
- /* Process the response */
-#if DEBUG == 1
- printf("(uds) [%d] read complete\n", minor);
-#endif
+ subsize = PIPE_BUF - pos;
+ if (subsize > size)
+ subsize = size;
- /* 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;
+ 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;
+ }
- /* 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
* 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;
++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;
}
}
/* check if we write to a closed pipe */
- if (!(uds_fd_table[peer].mode & S_IRUSR)) {
+ if (!(uds_fd_table[peer].mode & R_BIT)) {
return EPIPE;
}
return 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;
}
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,
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;
- }
- /* 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;
+ /* 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;
- /* 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;
+ 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;
}
- /* 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) {
* 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;
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;
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;
return rc;
}
-void uds_unsuspend(devminor_t minor)
+void
+uds_unsuspend(devminor_t minor)
{
int r;
uds_fd_t *fdp;
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;
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;
}
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);
+}
-#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
+
+/* Connection backlog size for incoming connections. */
+#define UDS_SOMAXCONN 64
-/* max connection backlog for incoming connections */
-#define UDS_SOMAXCONN 64
+/* Output debugging information? */
+#define DEBUG 0
typedef void* filp_id_t;
/* 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 */
/* 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 */
service fbd
{
ipc
- SYSTEM VFS RS DS VM
+ SYSTEM vfs rs ds vm
ahci
at_wini
;
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
+};
up inet -script /etc/rs.inet -dev /dev/ip
fi
+ up uds -dev /dev/uds
+
up -n ipc
up log -dev /dev/klog
#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 */
#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
# 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
#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
+++ /dev/null
-
-#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"
#include <pwd.h>
#include "buf.h"
#include "inode.h"
-#include "uds.h"
static void get_work(message *m_in, int *status);
/* 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) {
}
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, "
/* 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);
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);
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
#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) = {
/*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
*/
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;
}
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);
}
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);
}
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);
}
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);
}
} 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;
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';
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 */
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);
}
*
* 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;
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];