Add UNIX Domain Sockets internals to PFS. Contributed by Thomas Cort

This commit is contained in:
Thomas Veerman 2010-07-15 13:39:57 +00:00
parent ecc8a52f82
commit ea19830de1
18 changed files with 2949 additions and 76 deletions

View file

@ -1,10 +1,11 @@
# Makefile for Pipe File System (PFS) # Makefile for Pipe File System (PFS)
PROG= pfs PROG= pfs
SRCS= open.c table.c inode.c main.c super.c link.c \ SRCS= open.c table.c inode.c main.c super.c link.c \
buffer.c read.c misc.c utility.c stadir.c buffer.c read.c misc.c utility.c stadir.c \
uds.c dev_uds.c
DPADD+= ${LIBSYS} DPADD+= ${LIBDRIVER} ${LIBSYS}
LDADD+= -lsys LDADD+= -ldriver -lsys
MAN= MAN=

View file

@ -3,6 +3,11 @@
#define NR_INODES 256 /* # slots in "in core" inode table */ #define NR_INODES 256 /* # slots in "in core" inode table */
/* Size of descriptor table for unix domain sockets. This should be
* equal to the maximum number of minor devices (currently 256).
*/
#define NR_FDS 256
#define INODE_HASH_LOG2 7 /* 2 based logarithm of the inode hash size */ #define INODE_HASH_LOG2 7 /* 2 based logarithm of the inode hash size */
#define INODE_HASH_SIZE ((unsigned long)1<<INODE_HASH_LOG2) #define INODE_HASH_SIZE ((unsigned long)1<<INODE_HASH_LOG2)
#define INODE_HASH_MASK (((unsigned long)1<<INODE_HASH_LOG2)-1) #define INODE_HASH_MASK (((unsigned long)1<<INODE_HASH_LOG2)-1)
@ -31,5 +36,8 @@
#define FS_BITCHUNK_BITS (usizeof(bitchunk_t) * CHAR_BIT) #define FS_BITCHUNK_BITS (usizeof(bitchunk_t) * CHAR_BIT)
#define FS_BITS_PER_BLOCK(b) (FS_BITMAP_CHUNKS(b) * FS_BITCHUNK_BITS) #define FS_BITS_PER_BLOCK(b) (FS_BITMAP_CHUNKS(b) * FS_BITCHUNK_BITS)
#define FS_CALL_VEC_SIZE 31
#define DEV_CALL_VEC_SIZE 25
#endif #endif

1191
servers/pfs/dev_uds.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -15,6 +15,7 @@
#include <minix/const.h> #include <minix/const.h>
#include <minix/type.h> #include <minix/type.h>
#include <minix/dmap.h> #include <minix/dmap.h>
#include <minix/vfsif.h>
#include <limits.h> #include <limits.h>
#include <errno.h> #include <errno.h>
#include <minix/syslib.h> #include <minix/syslib.h>

View file

@ -12,10 +12,8 @@
/* The following variables are used for returning results to the caller. */ /* The following variables are used for returning results to the caller. */
EXTERN int err_code; /* temporary storage for error number */ EXTERN int err_code; /* temporary storage for error number */
EXTERN _PROTOTYPE (int (*fs_call_vec[]), (void) ); /* fs call table */ EXTERN _PROTOTYPE (int (*fs_call_vec[]), (message *fs_m_in, message *fs_m_out) ); /* fs call table */
EXTERN _PROTOTYPE (int (*dev_call_vec[]), (message *fs_m_in, message *fs_m_out) ); /* dev call table */
EXTERN message fs_m_in;
EXTERN message fs_m_out;
EXTERN uid_t caller_uid; EXTERN uid_t caller_uid;
EXTERN gid_t caller_gid; EXTERN gid_t caller_gid;

View file

@ -4,8 +4,13 @@
#define VERBOSE 0 /* display diagnostics */ #define VERBOSE 0 /* display diagnostics */
#include <net/ioctl.h>
#include <ansi.h> #include <ansi.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <limits.h> #include <limits.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
@ -13,6 +18,7 @@
#include <minix/callnr.h> #include <minix/callnr.h>
#include <minix/config.h> #include <minix/config.h>
#include <minix/dmap.h>
#include <minix/type.h> #include <minix/type.h>
#include <minix/const.h> #include <minix/const.h>
#include <minix/com.h> #include <minix/com.h>

View file

@ -26,7 +26,7 @@ FORWARD _PROTOTYPE( void unhash_inode, (struct inode * const node) );
/*===========================================================================* /*===========================================================================*
* fs_putnode * * fs_putnode *
*===========================================================================*/ *===========================================================================*/
PUBLIC int fs_putnode() PUBLIC int fs_putnode(message *fs_m_in, message *fs_m_out)
{ {
/* Find the inode specified by the request message and decrease its counter.*/ /* Find the inode specified by the request message and decrease its counter.*/
@ -35,15 +35,15 @@ PUBLIC int fs_putnode()
dev_t dev; dev_t dev;
ino_t inum; ino_t inum;
rip = find_inode( (ino_t) fs_m_in.REQ_INODE_NR); rip = find_inode( (ino_t) fs_m_in->REQ_INODE_NR);
if(!rip) { if(!rip) {
printf("%s:%d put_inode: inode #%ld dev: %d not found\n", __FILE__, printf("%s:%d put_inode: inode #%ld dev: %d not found\n", __FILE__,
__LINE__, fs_m_in.REQ_INODE_NR, (dev_t) fs_m_in.REQ_DEV); __LINE__, fs_m_in->REQ_INODE_NR, (dev_t) fs_m_in->REQ_DEV);
panic("fs_putnode failed"); panic("fs_putnode failed");
} }
count = fs_m_in.REQ_COUNT; count = fs_m_in->REQ_COUNT;
if (count <= 0) { if (count <= 0) {
printf("%s:%d put_inode: bad value for count: %d\n", __FILE__, printf("%s:%d put_inode: bad value for count: %d\n", __FILE__,
__LINE__, count); __LINE__, count);

View file

@ -6,18 +6,18 @@
/*===========================================================================* /*===========================================================================*
* fs_ftrunc * * fs_ftrunc *
*===========================================================================*/ *===========================================================================*/
PUBLIC int fs_ftrunc(void) PUBLIC int fs_ftrunc(message *fs_m_in, message *fs_m_out)
{ {
struct inode *rip; struct inode *rip;
off_t start, end; off_t start, end;
ino_t inumb; ino_t inumb;
inumb = (ino_t) fs_m_in.REQ_INODE_NR; inumb = (ino_t) fs_m_in->REQ_INODE_NR;
if( (rip = find_inode(inumb)) == NULL) return(EINVAL); if( (rip = find_inode(inumb)) == NULL) return(EINVAL);
start = fs_m_in.REQ_TRC_START_LO; start = fs_m_in->REQ_TRC_START_LO;
end = fs_m_in.REQ_TRC_END_LO; end = fs_m_in->REQ_TRC_END_LO;
return truncate_inode(rip, start); return truncate_inode(rip, start);
} }

View file

@ -6,6 +6,7 @@
#include <minix/vfsif.h> #include <minix/vfsif.h>
#include "buf.h" #include "buf.h"
#include "inode.h" #include "inode.h"
#include "uds.h"
FORWARD _PROTOTYPE(void get_work, (message *m_in) ); FORWARD _PROTOTYPE(void get_work, (message *m_in) );
@ -23,7 +24,9 @@ PUBLIC int main(int argc, char *argv[])
* three major activities: getting new work, processing the work, and * three major activities: getting new work, processing the work, and
* sending the reply. The loop never terminates, unless a panic occurs. * sending the reply. The loop never terminates, unless a panic occurs.
*/ */
int error, ind; int ind;
message pfs_m_in;
message pfs_m_out;
/* SEF local startup. */ /* SEF local startup. */
env_setargs(argc, argv); env_setargs(argc, argv);
@ -33,31 +36,36 @@ PUBLIC int main(int argc, char *argv[])
endpoint_t src; endpoint_t src;
/* Wait for request message. */ /* Wait for request message. */
get_work(&fs_m_in); get_work(&pfs_m_in);
src = fs_m_in.m_source; src = pfs_m_in.m_source;
error = OK;
caller_uid = INVAL_UID; /* To trap errors */ caller_uid = INVAL_UID; /* To trap errors */
caller_gid = INVAL_GID; caller_gid = INVAL_GID;
req_nr = fs_m_in.m_type; req_nr = pfs_m_in.m_type;
if (req_nr < VFS_BASE) { if (IS_DEV_RQ(req_nr)) {
fs_m_in.m_type += VFS_BASE; ind = req_nr - DEV_RQ_BASE;
req_nr = fs_m_in.m_type; if (ind < 0 || ind >= DEV_CALL_VEC_SIZE) {
printf("PFS: bad request (no VFS_BASE) %d\n", req_nr); printf("pfs: bad DEV request %d\n", req_nr);
} pfs_m_out.m_type = EINVAL;
ind = req_nr - VFS_BASE; } else {
(*dev_call_vec[ind])(&pfs_m_in, &pfs_m_out);
if (ind < 0 || ind >= NREQS) { }
printf("pfs: bad request %d\n", req_nr); } else if (IS_VFS_RQ(req_nr)) {
error = EINVAL; ind = req_nr - VFS_BASE;
if (ind < 0 || ind >= FS_CALL_VEC_SIZE) {
printf("pfs: bad FS request %d\n", req_nr);
pfs_m_out.m_type = EINVAL;
} else {
pfs_m_out.m_type =
(*fs_call_vec[ind])(&pfs_m_in, &pfs_m_out);
}
} else { } else {
error = (*fs_call_vec[ind])(); printf("pfs: bad request %d\n", req_nr);
pfs_m_out.m_type = EINVAL;
} }
fs_m_out.m_type = error; reply(src, &pfs_m_out);
reply(src, &fs_m_out);
} }
return(OK); return(OK);
} }
@ -98,10 +106,13 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
} }
init_inode_cache(); init_inode_cache();
uds_init();
SELF_E = getprocnr(); SELF_E = getprocnr();
buf_pool(); buf_pool();
driver_announce();
return(OK); return(OK);
} }
@ -122,12 +133,13 @@ PRIVATE void sef_cb_signal_handler(int signo)
PRIVATE void get_work(m_in) PRIVATE void get_work(m_in)
message *m_in; /* pointer to message */ message *m_in; /* pointer to message */
{ {
int r, srcok = 0; int r, srcok = 0, status;
endpoint_t src; endpoint_t src;
do { do {
if ((r = sef_receive(ANY, m_in)) != OK) /* wait for message */ /* wait for a message */
panic("sef_receive failed: %d", r); if ((r = sef_receive_status(ANY, m_in, &status)) != OK)
panic("sef_receive_status failed: %d", r);
src = m_in->m_source; src = m_in->m_source;
if(src == VFS_PROC_NR) { if(src == VFS_PROC_NR) {
@ -148,4 +160,3 @@ message *m_out; /* report result */
if (OK != send(who, m_out)) /* send the message */ if (OK != send(who, m_out)) /* send the message */
printf("PFS(%d) was unable to send reply\n", SELF_E); printf("PFS(%d) was unable to send reply\n", SELF_E);
} }

View file

@ -4,7 +4,7 @@
/*===========================================================================* /*===========================================================================*
* fs_sync * * fs_sync *
*===========================================================================*/ *===========================================================================*/
PUBLIC int fs_sync() PUBLIC int fs_sync(message *fs_m_in, message *fs_m_out)
{ {
/* Perform the sync() system call. No-op on this FS. */ /* Perform the sync() system call. No-op on this FS. */

View file

@ -8,17 +8,17 @@
/*===========================================================================* /*===========================================================================*
* fs_newnode * * fs_newnode *
*===========================================================================*/ *===========================================================================*/
PUBLIC int fs_newnode() PUBLIC int fs_newnode(message *fs_m_in, message *fs_m_out)
{ {
register int r = OK; register int r = OK;
mode_t bits; mode_t bits;
struct inode *rip; struct inode *rip;
dev_t dev; dev_t dev;
caller_uid = (uid_t) fs_m_in.REQ_UID; caller_uid = (uid_t) fs_m_in->REQ_UID;
caller_gid = (gid_t) fs_m_in.REQ_GID; caller_gid = (gid_t) fs_m_in->REQ_GID;
bits = (mode_t) fs_m_in.REQ_MODE; bits = (mode_t) fs_m_in->REQ_MODE;
dev = (dev_t) fs_m_in.REQ_DEV; dev = (dev_t) fs_m_in->REQ_DEV;
/* Try to allocate the inode */ /* Try to allocate the inode */
if( (rip = alloc_inode(dev, bits) ) == NULL) return(err_code); if( (rip = alloc_inode(dev, bits) ) == NULL) return(err_code);
@ -40,12 +40,12 @@ PUBLIC int fs_newnode()
free_inode(rip); free_inode(rip);
} else { } else {
/* Fill in the fields of the response message */ /* Fill in the fields of the response message */
fs_m_out.RES_INODE_NR = rip->i_num; fs_m_out->RES_INODE_NR = rip->i_num;
fs_m_out.RES_MODE = rip->i_mode; fs_m_out->RES_MODE = rip->i_mode;
fs_m_out.RES_FILE_SIZE_LO = rip->i_size; fs_m_out->RES_FILE_SIZE_LO = rip->i_size;
fs_m_out.RES_UID = rip->i_uid; fs_m_out->RES_UID = rip->i_uid;
fs_m_out.RES_GID = rip->i_gid; fs_m_out->RES_GID = rip->i_gid;
fs_m_out.RES_DEV = dev; fs_m_out->RES_DEV = dev;
} }
return(r); return(r);

View file

@ -6,10 +6,11 @@
/* Structs used in prototypes must be declared as such first. */ /* Structs used in prototypes must be declared as such first. */
struct buf; struct buf;
struct inode; struct inode;
struct sockaddr_un;
/* buffer.c */ /* buffer.c */
_PROTOTYPE( struct buf *get_block, (dev_t dev, ino_t inum) ); _PROTOTYPE( struct buf *get_block, (dev_t dev, ino_t inum) );
_PROTOTYPE( void put_block, (dev_t dev, ino_t inum) ); _PROTOTYPE( void put_block, (dev_t dev, ino_t inum) );
/* cache.c */ /* cache.c */
_PROTOTYPE( void buf_pool, (void) ); _PROTOTYPE( void buf_pool, (void) );
@ -19,7 +20,7 @@ _PROTOTYPE( struct inode *alloc_inode, (dev_t dev, mode_t mode) );
_PROTOTYPE( void dup_inode, (struct inode *ip) ); _PROTOTYPE( void dup_inode, (struct inode *ip) );
_PROTOTYPE( struct inode *find_inode, (ino_t numb) ); _PROTOTYPE( struct inode *find_inode, (ino_t numb) );
_PROTOTYPE( void free_inode, (struct inode *rip) ); _PROTOTYPE( void free_inode, (struct inode *rip) );
_PROTOTYPE( int fs_putnode, (void) ); _PROTOTYPE( int fs_putnode, (message *fs_m_in, message *fs_m_out) );
_PROTOTYPE( void init_inode_cache, (void) ); _PROTOTYPE( void init_inode_cache, (void) );
_PROTOTYPE( struct inode *get_inode, (dev_t dev, ino_t numb) ); _PROTOTYPE( struct inode *get_inode, (dev_t dev, ino_t numb) );
_PROTOTYPE( void put_inode, (struct inode *rip) ); _PROTOTYPE( void put_inode, (struct inode *rip) );
@ -27,31 +28,71 @@ _PROTOTYPE( void update_times, (struct inode *rip) );
_PROTOTYPE( void wipe_inode, (struct inode *rip) ); _PROTOTYPE( void wipe_inode, (struct inode *rip) );
/* link.c */ /* link.c */
_PROTOTYPE( int fs_ftrunc, (void) ); _PROTOTYPE( int fs_ftrunc, (message *fs_m_in, message *fs_m_out) );
_PROTOTYPE( int truncate_inode, (struct inode *rip, off_t newsize) ); _PROTOTYPE( int truncate_inode, (struct inode *rip, off_t newsize) );
/* main.c */ /* main.c */
_PROTOTYPE( void reply, (endpoint_t who, message *m_out) ); _PROTOTYPE( void reply, (endpoint_t who, message *m_out) );
/* misc.c */ /* misc.c */
_PROTOTYPE( int fs_sync, (void) ); _PROTOTYPE( int fs_sync, (message *fs_m_in, message *fs_m_out) );
/* open.c */ /* open.c */
_PROTOTYPE( int fs_newnode, (void) ); _PROTOTYPE( int fs_newnode, (message *fs_m_in, message *fs_m_out) );
/* read.c */ /* read.c */
_PROTOTYPE( int fs_readwrite, (void) ); _PROTOTYPE( int fs_readwrite, (message *fs_m_in, message *fs_m_out) );
/* utility.c */ /* utility.c */
_PROTOTYPE( time_t clock_time, (void) ); _PROTOTYPE( time_t clock_time, (void) );
_PROTOTYPE( int no_sys, (void) ); _PROTOTYPE( int no_sys, (message *pfs_m_in, message *pfs_m_out) );
/* stadir.c */ /* stadir.c */
_PROTOTYPE( int fs_stat, (void) ); _PROTOTYPE( int fs_stat, (message *fs_m_in, message *fs_m_out) );
/* super.c */ /* super.c */
_PROTOTYPE( bit_t alloc_bit, (void) ); _PROTOTYPE( bit_t alloc_bit, (void) );
_PROTOTYPE( void free_bit, (bit_t bit_returned) ); _PROTOTYPE( void free_bit, (bit_t bit_returned) );
/* dev_uds.c */
_PROTOTYPE( int uds_open, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int uds_close, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int uds_read, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int uds_write, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int uds_ioctl, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int uds_select, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int uds_status, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int uds_cancel, (message *dev_m_in, message *dev_m_out) );
/* uds.c */
_PROTOTYPE( void uds_init, (void) );
_PROTOTYPE( int do_accept, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_connect, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_listen, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_socket, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_bind, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_getsockname, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_getpeername, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_shutdown, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_socketpair, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_getsockopt_sotype,
(message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_getsockopt_peercred,
(message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_getsockopt_sndbuf,
(message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_setsockopt_sndbuf,
(message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_getsockopt_rcvbuf,
(message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_setsockopt_rcvbuf,
(message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_sendto, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int do_recvfrom, (message *dev_m_in, message *dev_m_out) );
_PROTOTYPE( int perform_connection,
(message *dev_m_in, message *dev_m_out,
struct sockaddr_un *addr, int minorx,
int minory) );
#endif #endif

View file

@ -7,7 +7,7 @@
/*===========================================================================* /*===========================================================================*
* fs_readwrite * * fs_readwrite *
*===========================================================================*/ *===========================================================================*/
PUBLIC int fs_readwrite(void) PUBLIC int fs_readwrite(message *fs_m_in, message *fs_m_out)
{ {
int r, rw_flag; int r, rw_flag;
struct buf *bp; struct buf *bp;
@ -20,7 +20,7 @@ PUBLIC int fs_readwrite(void)
r = OK; r = OK;
cum_io = 0; cum_io = 0;
inumb = (ino_t) fs_m_in.REQ_INODE_NR; inumb = (ino_t) fs_m_in->REQ_INODE_NR;
/* Find the inode referred */ /* Find the inode referred */
if ((rip = find_inode(inumb)) == NULL) return(EINVAL); if ((rip = find_inode(inumb)) == NULL) return(EINVAL);
@ -30,10 +30,10 @@ PUBLIC int fs_readwrite(void)
f_size = rip->i_size; f_size = rip->i_size;
/* Get the values from the request message */ /* Get the values from the request message */
rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING); rw_flag = (fs_m_in->m_type == REQ_READ ? READING : WRITING);
gid = (cp_grant_id_t) fs_m_in.REQ_GRANT; gid = (cp_grant_id_t) fs_m_in->REQ_GRANT;
position = fs_m_in.REQ_SEEK_POS_LO; position = fs_m_in->REQ_SEEK_POS_LO;
nrbytes = (unsigned) fs_m_in.REQ_NBYTES; nrbytes = (unsigned) fs_m_in->REQ_NBYTES;
/* We can't read beyond the max file position */ /* We can't read beyond the max file position */
if (nrbytes > MAX_FILE_POS) return(EFBIG); if (nrbytes > MAX_FILE_POS) return(EFBIG);
@ -64,7 +64,7 @@ PUBLIC int fs_readwrite(void)
cum_io += nrbytes; cum_io += nrbytes;
} }
fs_m_out.RES_SEEK_POS_LO = position; /* It might change later and the VFS fs_m_out->RES_SEEK_POS_LO = position; /* It might change later and the VFS
has to know this value */ has to know this value */
/* On write, update file size and access time. */ /* On write, update file size and access time. */
@ -81,7 +81,7 @@ PUBLIC int fs_readwrite(void)
bp->b_bytes = position; bp->b_bytes = position;
if (rw_flag == READING) rip->i_update |= ATIME; if (rw_flag == READING) rip->i_update |= ATIME;
if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME; if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
fs_m_out.RES_NBYTES = (size_t) cum_io; fs_m_out->RES_NBYTES = (size_t) cum_io;
put_inode(rip); put_inode(rip);
put_block(rip->i_dev, rip->i_num); put_block(rip->i_dev, rip->i_num);

View file

@ -47,14 +47,14 @@ PRIVATE int stat_inode(
/*===========================================================================* /*===========================================================================*
* fs_stat * * fs_stat *
*===========================================================================*/ *===========================================================================*/
PUBLIC int fs_stat() PUBLIC int fs_stat(message *fs_m_in, message *fs_m_out)
{ {
register int r; /* return value */ register int r; /* return value */
register struct inode *rip; /* target inode */ register struct inode *rip; /* target inode */
if( (rip = find_inode(fs_m_in.REQ_INODE_NR)) == NULL) return(EINVAL); if( (rip = find_inode(fs_m_in->REQ_INODE_NR)) == NULL) return(EINVAL);
get_inode(rip->i_dev, rip->i_num); /* mark inode in use */ get_inode(rip->i_dev, rip->i_num); /* mark inode in use */
r = stat_inode(rip, fs_m_in.m_source, (cp_grant_id_t) fs_m_in.REQ_GRANT); r = stat_inode(rip, fs_m_in->m_source, (cp_grant_id_t) fs_m_in->REQ_GRANT);
put_inode(rip); /* release the inode */ put_inode(rip); /* release the inode */
return(r); return(r);
} }

View file

@ -8,8 +8,12 @@
#include "fs.h" #include "fs.h"
#include "inode.h" #include "inode.h"
#include "buf.h" #include "buf.h"
#include "uds.h"
/* File System Handlers (pfs) */
PUBLIC _PROTOTYPE (int (*fs_call_vec[]),
(message *fs_m_in, message *fs_m_out) ) = {
PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = {
no_sys, /* 0 not used */ no_sys, /* 0 not used */
no_sys, /* 1 */ no_sys, /* 1 */
fs_putnode, /* 2 */ fs_putnode, /* 2 */
@ -42,6 +46,37 @@ PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = {
fs_newnode, /* 29 */ fs_newnode, /* 29 */
no_sys, /* 30 */ no_sys, /* 30 */
no_sys, /* 31 */ no_sys, /* 31 */
no_sys, /* 32 */ no_sys, /* 32 */
}; };
/* Device Handlers (/dev/uds) */
PUBLIC _PROTOTYPE (int (*dev_call_vec[]),
(message *dev_m_in, message *dev_m_out) ) = {
uds_cancel, /* 0 */
no_sys, /* 1 */
no_sys, /* 2 */
no_sys, /* 3 */
no_sys, /* 4 */
no_sys, /* 5 */
uds_open, /* 6 */
uds_close, /* 7 */
no_sys, /* 8 */
no_sys, /* 9 */
no_sys, /* 10 */
no_sys, /* 11 */
uds_select, /* 12 */
uds_status, /* 13 */
uds_open, /* 14 */
no_sys, /* 15 */
no_sys, /* 16 */
no_sys, /* 17 */
no_sys, /* 18 */
no_sys, /* 19 */
uds_read, /* 20 */
uds_write, /* 21 */
no_sys, /* 22 */
no_sys, /* 23 */
uds_ioctl, /* 24 */
no_sys, /* 25 */
};

1354
servers/pfs/uds.c Normal file

File diff suppressed because it is too large Load diff

227
servers/pfs/uds.h Normal file
View file

@ -0,0 +1,227 @@
#ifndef __PFS_UDS_H__
#define __PFS_UDS_H__
/*
* Unix Domain Sockets Implementation (PF_UNIX, PF_LOCAL)
*
* Also See...
*
* dev_uds.c, table.c, uds.c
*/
#include <sys/types.h>
#include <sys/un.h>
#include <minix/endpoint.h>
/* max connection backlog for incoming connections */
#define UDS_SOMAXCONN 64
/* UDS FD state Flags */
#define UDS_CONNECTING 0x10
/*
* Internal State Information for a socket descriptor.
*/
struct uds_fd {
/* Flags */
enum UDS_STATE {
/* This file descriptor is UDS_FREE and can be allocated. */
UDS_FREE = 0,
/* OR it is UDS_INUSE and can't be allocated. */
UDS_INUSE = 1
/* state is set to UDS_INUSE in uds_open(). state is Set to
* UDS_FREE in uds_init() and uds_close(). state should be
* checked prior to all operations.
*/
} state;
/* Owner Info */
/* Socket Owner */
endpoint_t owner;
/* endpoint for suspend/resume */
endpoint_t endpoint;
/* 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.
*/
ino_t inode_nr;
/* position in the PIPE where the data starts */
off_t pos;
/* size of data in the PIPE */
size_t size;
/* control read/write, set by uds_open() and shutdown(2).
* Can be set to S_IRUSR|S_IWUSR, S_IRUSR, S_IWUSR, or 0
* for read and write, read only, write only, or neither.
* default is S_IRUSR|S_IWUSR.
*/
mode_t mode;
/* Socket Info */
/* socket type - SOCK_STREAM, SOCK_DGRAM, or SOCK_SEQPACKET
* Set by uds_ioctl(NWIOSUDSTYPE). It defaults to -1 in
* uds_open(). Any action on a socket with type -1 besides
* uds_ioctl(NWIOSUDSTYPE) and uds_close() will result in
* an error.
*/
int type;
/* queue of pending connections for server sockets.
* connect(2) inserts and accept(2) removes from the queue
*/
int backlog[UDS_SOMAXCONN];
/* requested connection backlog size. Set by listen(2)
* Bounds (0 <= backlog_size <= UDS_SOMAXCONN)
* Defaults to UDS_SOMAXCONN which is defined above.
*/
unsigned char backlog_size;
/* index of peer in uds_fd_table for connected sockets.
* -1 is used to mean no peer. Assumptions: peer != -1 means
* connected.
*/
int peer;
/* index of child (client sd returned by accept(2))
* -1 is used to mean no child.
*/
int child;
/* address -- the address the socket is bound to.
* Assumptions: addr.sun_family == AF_UNIX means its bound.
*/
struct sockaddr_un addr;
/* target -- where DGRAMs are sent to on the next uds_write(). */
struct sockaddr_un target;
/* source -- address where DGRAMs are from. used to fill in the
* from address in recvfrom(2) and recvmsg(2).
*/
struct sockaddr_un source;
/* Flag (1 or 0) - listening for incoming connections.
* Default to 0. Set to 1 by do_listen()
*/
int listening;
/* Holds an errno. This is set when a connected socket is
* closed and we need to pass ECONNRESET on to a suspended
* peer.
*/
int err;
/* Suspend/Revive Housekeeping */
/* SUSPEND State Flags */
enum UDS_SUSPENDED {
/* Socket isn't blocked. */
UDS_NOT_SUSPENDED = 0,
/* Socket is blocked on read(2) waiting for data to read. */
UDS_SUSPENDED_READ = 1,
/* Socket is blocked on write(2) for space to write data. */
UDS_SUSPENDED_WRITE = 2,
/* Socket is blocked on connect(2) waiting for the server. */
UDS_SUSPENDED_CONNECT = 4,
/* Socket is blocked on accept(2) waiting for clients. */
UDS_SUSPENDED_ACCEPT = 8
} suspended;
/* Flag (1 or 0) - thing socket was waiting for is ready.
* If 1, then uds_status() will attempt the operation that
* the socket was blocked on.
*/
int ready_to_revive;
/* i/o grant, saved for later use by suspended procs */
cp_grant_id_t io_gr;
/* is of i/o grant, saved for later use by suspended procs */
size_t io_gr_size;
/* Save the call number so that uds_cancel() can unwind the
* call properly.
*/
int call_nr;
/* Save the IOCTL so uds_cancel() knows what got cancelled. */
int ioctl;
/* Flag (1 or 0) - the system call completed.
* A doc I read said DEV_CANCEL might be called even though
* the operation is finished. We use this variable to
* determine if we should rollback the changes or not.
*/
int syscall_done;
/* select() */
/* Flag (1 or 0) - the process blocked on select(2). When
* selecting is 1 and I/O happens on this socket, then
* select_proc should be notified.
*/
int selecting;
/* when a select is in progress, we notify() this endpoint
* of new data.
*/
endpoint_t select_proc;
/* Options (SEL_RD, SEL_WR, SEL_ERR) that are requested. */
int sel_ops_in;
/* Options that are available for this socket. */
int sel_ops_out;
/* Flag (1 or 0) to be set to one before calling notify().
* uds_status() will use the flag to locate this descriptor.
*/
int status_updated;
};
typedef struct uds_fd uds_fd_t;
/* File Descriptor Table -- Defined in uds.c */
EXTERN uds_fd_t uds_fd_table[NR_FDS];
/*
* Take message m and get the index in uds_fd_table.
*/
#define uds_minor(m) (minor((dev_t) m->DEVICE) & BYTE)
/*
* Fill in a reply message.
*/
#define uds_set_reply(msg,type,endpoint,io_gr,status) \
do { \
msg->m_type = type; \
msg->REP_ENDPT = endpoint; \
msg->REP_IO_GRANT = io_gr; \
msg->REP_STATUS = status; \
} while (0)
#endif

View file

@ -4,10 +4,10 @@
/*===========================================================================* /*===========================================================================*
* no_sys * * no_sys *
*===========================================================================*/ *===========================================================================*/
PUBLIC int no_sys() PUBLIC int no_sys(message *pfs_m_in, message *pfs_m_out)
{ {
/* Somebody has used an illegal system call number */ /* Somebody has used an illegal system call number */
printf("no_sys: invalid call %d\n", req_nr); printf("no_sys: invalid call 0x%x to pfs\n", req_nr);
return(EINVAL); return(EINVAL);
} }