Index: head/sys/conf/files =================================================================== --- head/sys/conf/files (revision 2728) +++ head/sys/conf/files (revision 2729) @@ -1,304 +1,309 @@ ddb/db_access.c optional ddb ddb/db_aout.c optional ddb ddb/db_break.c optional ddb ddb/db_command.c optional ddb ddb/db_examine.c optional ddb ddb/db_expr.c optional ddb ddb/db_input.c optional ddb ddb/db_lex.c optional ddb ddb/db_output.c optional ddb ddb/db_print.c optional ddb ddb/db_ps.c optional ddb ddb/db_run.c optional ddb ddb/db_sym.c optional ddb ddb/db_trap.c optional ddb ddb/db_variables.c optional ddb ddb/db_watch.c optional ddb ddb/db_write_cmd.c optional ddb isofs/cd9660/cd9660_bmap.c optional cd9660 isofs/cd9660/cd9660_lookup.c optional cd9660 isofs/cd9660/cd9660_node.c optional cd9660 isofs/cd9660/cd9660_rrip.c optional cd9660 isofs/cd9660/cd9660_util.c optional cd9660 isofs/cd9660/cd9660_vfsops.c optional cd9660 isofs/cd9660/cd9660_vnops.c optional cd9660 kdb/kdb_access.c optional kadb kdb/kdb_command.c optional kadb kdb/kdb_ctype.c optional kadb kdb/kdb_expr.c optional kadb kdb/kdb_format.c optional kadb kdb/kdb_input.c optional kadb kdb/kdb_message.c optional kadb kdb/kdb_output.c optional kadb kdb/kdb_pcs.c optional kadb kdb/kdb_print.c optional kadb kdb/kdb_runpcs.c optional kadb kdb/kdb_sym.c optional kadb kdb/kdb_trap.c optional kadb kern/imgact_aout.c standard kern/imgact_shell.c standard kern/init_main.c standard kern/init_sysent.c standard kern/kern_acct.c standard kern/kern_clock.c standard kern/kern_descrip.c standard kern/kern_exec.c standard kern/kern_exit.c standard kern/kern_fork.c standard kern/kern_ktrace.c standard kern/kern_lockf.c standard kern/kern_lkm.c optional lkm kern/kern_malloc.c standard kern/kern_physio.c standard kern/kern_proc.c standard kern/kern_prot.c standard kern/kern_resource.c standard kern/kern_sig.c standard kern/kern_subr.c standard kern/kern_synch.c standard kern/kern_sysctl.c standard kern/kern_time.c standard kern/kern_xxx.c standard kern/subr_log.c standard kern/subr_prf.c standard kern/subr_prof.c standard kern/subr_rlist.c standard kern/subr_rmap.c standard kern/subr_xxx.c standard kern/sys_generic.c standard kern/sys_process.c standard kern/sys_socket.c standard +kern/sysv_ipc.c optional sysvshm +kern/sysv_ipc.c optional sysvmsg +kern/sysv_ipc.c optional sysvsem +kern/sysv_msg.c optional sysvmsg +kern/sysv_sem.c optional sysvsem kern/sysv_shm.c optional sysvshm kern/tty.c standard kern/tty_compat.c standard kern/tty_conf.c standard kern/tty_pty.c optional pty kern/tty_subr.c standard kern/tty_tb.c optional tb kern/tty_tty.c standard kern/uipc_domain.c standard kern/uipc_mbuf.c standard kern/uipc_proto.c standard kern/uipc_socket.c standard kern/uipc_socket2.c standard kern/uipc_syscalls.c standard kern/uipc_usrreq.c standard kern/vfs_bio.c standard kern/vfs_cache.c standard kern/vfs_cluster.c standard kern/vfs_conf.c standard kern/vfs_init.c standard kern/vfs_lookup.c standard kern/vfs_subr.c standard kern/vfs_syscalls.c standard kern/vfs_vnops.c standard miscfs/deadfs/dead_vnops.c standard miscfs/fdesc/fdesc_vfsops.c optional fdesc miscfs/fdesc/fdesc_vnops.c optional fdesc miscfs/fifofs/fifo_vnops.c optional fifo miscfs/kernfs/kernfs_vfsops.c optional kernfs miscfs/kernfs/kernfs_vnops.c optional kernfs miscfs/nullfs/null_subr.c optional nullfs miscfs/nullfs/null_vfsops.c optional nullfs miscfs/nullfs/null_vnops.c optional nullfs miscfs/portal/portal_vfsops.c optional portal miscfs/portal/portal_vnops.c optional portal miscfs/procfs/procfs_subr.c optional procfs miscfs/procfs/procfs_vnops.c optional procfs miscfs/procfs/procfs_vfsops.c optional procfs miscfs/procfs/procfs_note.c optional procfs miscfs/procfs/procfs_mem.c optional procfs miscfs/procfs/procfs_ctl.c optional procfs miscfs/procfs/procfs_status.c optional procfs miscfs/procfs/procfs_regs.c optional procfs miscfs/procfs/procfs_fpregs.c optional procfs miscfs/specfs/spec_vnops.c standard miscfs/umapfs/umap_subr.c optional umapfs miscfs/umapfs/umap_vfsops.c optional umapfs miscfs/umapfs/umap_vnops.c optional umapfs miscfs/union/union_subr.c optional union miscfs/union/union_vfsops.c optional union miscfs/union/union_vnops.c optional union net/bpf.c optional bpfilter net/bpf_filter.c optional bpfilter net/if.c standard net/if_ethersubr.c optional ether net/if_loop.c optional loop net/if_sl.c optional sl net/radix.c standard net/raw_cb.c standard net/raw_usrreq.c standard net/route.c standard net/rtsock.c standard net/slcompress.c optional sl netccitt/ccitt_proto.c optional ccitt netccitt/llc_input.c optional llc netccitt/llc_output.c optional llc netccitt/llc_subr.c optional llc netccitt/llc_timer.c optional llc netccitt/pk_llcsubr.c optional llc netccitt/pk_llcsubr.c optional hdlc netccitt/hd_debug.c optional hdlc netccitt/hd_input.c optional hdlc netccitt/hd_output.c optional hdlc netccitt/hd_subr.c optional hdlc netccitt/hd_timer.c optional hdlc netccitt/if_x25subr.c optional ccitt netccitt/pk_acct.c optional ccitt netccitt/pk_debug.c optional ccitt netccitt/pk_input.c optional ccitt netccitt/pk_output.c optional ccitt netccitt/pk_subr.c optional ccitt netccitt/pk_timer.c optional ccitt netccitt/pk_usrreq.c optional ccitt netimp/if_imp.c optional imp netimp/if_imphost.c optional imp netimp/raw_imp.c optional imp netinet/if_ether.c optional ether netinet/igmp.c optional inet netinet/in.c optional inet netinet/in_pcb.c optional inet netinet/in_proto.c optional inet netinet/ip_icmp.c optional inet netinet/ip_input.c optional inet netinet/ip_mroute.c optional inet mrouting netinet/ip_output.c optional inet netinet/raw_ip.c optional inet netinet/tcp_debug.c optional inet netinet/tcp_input.c optional inet netinet/tcp_output.c optional inet netinet/tcp_subr.c optional inet netinet/tcp_timer.c optional inet netinet/tcp_usrreq.c optional inet netinet/udp_usrreq.c optional inet netiso/clnp_debug.c optional iso netiso/clnp_er.c optional iso netiso/clnp_frag.c optional iso netiso/clnp_input.c optional iso netiso/clnp_options.c optional iso netiso/clnp_output.c optional iso netiso/clnp_raw.c optional iso netiso/clnp_subr.c optional iso netiso/clnp_timer.c optional iso netiso/cltp_usrreq.c optional iso netiso/esis.c optional iso netiso/idrp_usrreq.c optional iso netiso/if_eon.c optional eon netiso/iso.c optional iso netiso/iso_chksum.c optional iso netiso/iso_pcb.c optional iso netiso/iso_proto.c optional iso netiso/iso_snpac.c optional iso netiso/tp_astring.c optional iso netiso/tp_astring.c optional tpip netiso/tp_cons.c optional iso netiso/tp_driver.c optional iso netiso/tp_driver.c optional tpip netiso/tp_emit.c optional iso netiso/tp_emit.c optional tpip netiso/tp_inet.c optional iso netiso/tp_inet.c optional tpip netiso/tp_input.c optional iso netiso/tp_input.c optional tpip netiso/tp_iso.c optional iso netiso/tp_meas.c optional iso netiso/tp_meas.c optional tpip netiso/tp_output.c optional iso netiso/tp_output.c optional tpip netiso/tp_pcb.c optional iso netiso/tp_pcb.c optional tpip netiso/tp_subr.c optional iso netiso/tp_subr.c optional tpip netiso/tp_subr2.c optional iso netiso/tp_subr2.c optional tpip netiso/tp_timer.c optional iso netiso/tp_timer.c optional tpip netiso/tp_trace.c optional iso netiso/tp_trace.c optional tpip netiso/tp_usrreq.c optional iso netiso/tp_usrreq.c optional tpip netiso/tuba_subr.c optional iso tuba netiso/tuba_table.c optional iso tuba netiso/tuba_usrreq.c optional iso tuba netns/idp_usrreq.c optional ns netns/ns.c optional ns netns/ns_error.c optional ns netns/ns_input.c optional ns netns/ns_ip.c optional ns netns/ns_output.c optional ns netns/ns_pcb.c optional ns netns/ns_proto.c optional ns netns/spp_debug.c optional ns netns/spp_usrreq.c optional ns nfs/nfs_bio.c optional nfs nfs/nfs_node.c optional nfs nfs/nfs_nqlease.c optional nfs nfs/nfs_serv.c optional nfs nfs/nfs_socket.c optional nfs nfs/nfs_srvcache.c optional nfs nfs/nfs_subs.c optional nfs nfs/nfs_syscalls.c optional nfs nfs/nfs_vfsops.c optional nfs nfs/nfs_vnops.c optional nfs scsi/cd.c optional cd scsi/ch.c optional ch scsi/scsiconf.c optional scbus scsi/scsi_base.c optional scbus scsi/scsi_ioctl.c optional scbus scsi/sd.c optional sd scsi/st.c optional st scsi/su.c optional su scsi/uk.c optional uk ufs/ffs/ffs_alloc.c optional ffs ufs/ffs/ffs_alloc.c optional mfs ufs/ffs/ffs_balloc.c optional ffs ufs/ffs/ffs_balloc.c optional mfs ufs/ffs/ffs_inode.c optional ffs ufs/ffs/ffs_inode.c optional mfs ufs/ffs/ffs_subr.c optional ffs ufs/ffs/ffs_subr.c optional mfs ufs/ffs/ffs_tables.c optional ffs ufs/ffs/ffs_tables.c optional mfs ufs/ffs/ffs_vfsops.c optional ffs ufs/ffs/ffs_vfsops.c optional mfs ufs/ffs/ffs_vnops.c optional ffs ufs/ffs/ffs_vnops.c optional mfs ufs/lfs/lfs_alloc.c optional lfs ufs/lfs/lfs_bio.c optional lfs ufs/lfs/lfs_balloc.c optional lfs ufs/lfs/lfs_cksum.c optional lfs ufs/lfs/lfs_debug.c optional lfs ufs/lfs/lfs_inode.c optional lfs ufs/lfs/lfs_segment.c optional lfs ufs/lfs/lfs_subr.c optional lfs ufs/lfs/lfs_syscalls.c optional lfs ufs/lfs/lfs_vfsops.c optional lfs ufs/lfs/lfs_vnops.c optional lfs ufs/mfs/mfs_vfsops.c optional mfs ufs/mfs/mfs_vnops.c optional mfs ufs/ufs/ufs_bmap.c standard ufs/ufs/ufs_disksubr.c standard ufs/ufs/ufs_ihash.c standard ufs/ufs/ufs_inode.c standard ufs/ufs/ufs_lookup.c standard ufs/ufs/ufs_quota.c standard ufs/ufs/ufs_vfsops.c standard ufs/ufs/ufs_vnops.c standard vm/device_pager.c standard vm/kern_lock.c standard vm/swap_pager.c standard vm/vm_fault.c standard vm/vm_glue.c standard vm/vm_init.c standard vm/vm_kern.c standard vm/vm_map.c standard vm/vm_meter.c standard vm/vm_mmap.c standard vm/vm_object.c standard vm/vm_page.c standard vm/vm_pageout.c standard vm/vm_pager.c standard vm/vm_swap.c standard vm/vm_unix.c standard vm/vm_user.c standard vm/vnode_pager.c standard Index: head/sys/conf/param.c =================================================================== --- head/sys/conf/param.c (revision 2728) +++ head/sys/conf/param.c (revision 2729) @@ -1,147 +1,190 @@ /* * Copyright (c) 1980, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)param.c 8.2 (Berkeley) 1/21/94 - * $Id$ + * $Id: param.c,v 1.3 1994/08/02 07:38:30 davidg Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #ifdef SYSVSHM #include #include #endif +#ifdef SYSVSEM +#include "sys/sem.h" +#endif +#ifdef SYSVMSG +#include "sys/msg.h" +#endif /* * System parameter formulae. * * This file is copied into each directory where we compile * the kernel; it should be modified there to suit local taste * if necessary. * * Compiled with -DHZ=xx -DTIMEZONE=x -DDST=x -DMAXUSERS=xx */ #ifndef HZ #define HZ 100 #endif int hz = HZ; int tick = 1000000 / HZ; int tickadj = 30000 / (60 * HZ); /* can adjust 30ms in 60s */ struct timezone tz = { TIMEZONE, DST }; #define NPROC (20 + 16 * MAXUSERS) int maxproc = NPROC; #define NTEXT NPROC int vm_cache_max = NTEXT/2 + 16; #define NVNODE (NPROC + NTEXT + 100) int desiredvnodes = NVNODE; int maxfiles = 3 * (NPROC + MAXUSERS) + 80; int ncallout = 16 + NPROC; int nclist = 60 + 12 * MAXUSERS; int nmbclusters = NMBCLUSTERS; int fscale = FSCALE; /* kernel uses `FSCALE', user uses `fscale' */ /* * Values in support of System V compatible shared memory. XXX */ #ifdef SYSVSHM #define SHMMAX (SHMMAXPGS*NBPG) #define SHMMIN 1 #define SHMMNI 32 /* <= SHMMMNI in shm.h */ #define SHMSEG 8 #define SHMALL (SHMMAXPGS/CLSIZE) struct shminfo shminfo = { SHMMAX, SHMMIN, SHMMNI, SHMSEG, SHMALL +}; +#endif + +/* + * Values in support of System V compatible semaphores. + */ + +#ifdef SYSVSEM + +struct seminfo seminfo = { + SEMMAP, /* # of entries in semaphore map */ + SEMMNI, /* # of semaphore identifiers */ + SEMMNS, /* # of semaphores in system */ + SEMMNU, /* # of undo structures in system */ + SEMMSL, /* max # of semaphores per id */ + SEMOPM, /* max # of operations per semop call */ + SEMUME, /* max # of undo entries per process */ + SEMUSZ, /* size in bytes of undo structure */ + SEMVMX, /* semaphore maximum value */ + SEMAEM /* adjust on exit max value */ +}; +#endif + +/* + * Values in support of System V compatible messages. + */ + +#ifdef SYSVMSG + +struct msginfo msginfo = { + MSGMAX, /* max chars in a message */ + MSGMNI, /* # of message queue identifiers */ + MSGMNB, /* max chars in a queue */ + MSGTQL, /* max messages in system */ + MSGSSZ, /* size of a message segment */ + /* (must be small power of 2 greater than 4) */ + MSGSEG /* number of message segments */ }; #endif /* * These are initialized at bootstrap time * to values dependent on memory size */ int nbuf, nswbuf; /* * These have to be allocated somewhere; allocating * them here forces loader errors if this file is omitted * (if they've been externed everywhere else; hah!). */ struct callout *callout; struct cblock *cfree; struct buf *buf, *swbuf; char *buffers; /* * Proc/pgrp hashing. * Here so that hash table sizes can depend on MAXUSERS/NPROC. * Hash size must be a power of two. * NOW omission of this file will cause loader errors! */ #if NPROC > 1024 #define PIDHSZ 512 #else #if NPROC > 512 #define PIDHSZ 256 #else #if NPROC > 256 #define PIDHSZ 128 #else #define PIDHSZ 64 #endif #endif #endif struct proc *pidhash[PIDHSZ]; struct pgrp *pgrphash[PIDHSZ]; int pidhashmask = PIDHSZ - 1; Index: head/sys/kern/init_main.c =================================================================== --- head/sys/kern/init_main.c (revision 2728) +++ head/sys/kern/init_main.c (revision 2729) @@ -1,432 +1,447 @@ /* * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)init_main.c 8.9 (Berkeley) 1/21/94 - * $Id: init_main.c,v 1.8 1994/09/01 05:12:37 davidg Exp $ + * $Id: init_main.c,v 1.9 1994/09/01 11:20:11 davidg Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HPFPLIB char copyright[] = "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California.\nCopyright (c) 1992 Hewlett-Packard Company\nCopyright (c) 1992 Motorola Inc.\nAll rights reserved.\n\n"; #else char copyright[] = "Copyright (c) 1982, 1986, 1989, 1991, 1993\n\tThe Regents of the University of California. All rights reserved.\n\n"; #endif /* Components of the first process -- never freed. */ struct session session0; struct pgrp pgrp0; struct proc proc0; struct pcred cred0; struct filedesc0 filedesc0; struct plimit limit0; struct vmspace vmspace0; struct proc *curproc = &proc0; struct proc *initproc, *pageproc, *updateproc; int cmask = CMASK; extern struct user *proc0paddr; struct vnode *rootvp, *swapdev_vp; int boothowto; struct timeval boottime; struct timeval runtime; static void start_init __P((struct proc *p, void *framep)); #if __GNUC__ >= 2 void __main() {} #endif /* * This table is filled in by the linker with functions that need to be * called to initialize various pseudo-devices and whatnot. */ static void dummyinit() {} TEXT_SET(pseudo_set, dummyinit); typedef void (*pseudo_func_t)(void); extern const struct linker_set pseudo_set; static const pseudo_func_t *pseudos = (const pseudo_func_t *)&pseudo_set.ls_items[0]; /* * System startup; initialize the world, create process 0, mount root * filesystem, and fork to create init and pagedaemon. Most of the * hard work is done in the lower-level initialization routines including * startup(), which does memory initialization and autoconfiguration. */ void main(framep) void *framep; { register struct proc *p; register struct filedesc0 *fdp; register struct pdevinit *pdev; register int i; int s, rval[2]; extern int (*mountroot) __P((void)); extern struct pdevinit pdevinit[]; extern void roundrobin __P((void *)); extern void schedcpu __P((void *)); extern struct sysentvec aout_sysvec; /* * Initialize the current process pointer (curproc) before * any possible traps/probes to simplify trap processing. */ p = &proc0; curproc = p; /* * Attempt to find console and initialize * in case of early panic or other messages. */ consinit(); printf(copyright); vm_mem_init(); kmeminit(); cpu_startup(); /* * Create process 0 (the swapper). */ allproc = (volatile struct proc *)p; p->p_prev = (struct proc **)&allproc; p->p_pgrp = &pgrp0; pgrphash[0] = &pgrp0; pgrp0.pg_mem = p; pgrp0.pg_session = &session0; session0.s_count = 1; session0.s_leader = p; p->p_sysent = &aout_sysvec; p->p_flag = P_INMEM | P_SYSTEM; p->p_stat = SRUN; p->p_nice = NZERO; p->p_rtprio = RTPRIO_RTOFF; bcopy("swapper", p->p_comm, sizeof ("swapper")); /* Create credentials. */ cred0.p_refcnt = 1; p->p_cred = &cred0; p->p_ucred = crget(); p->p_ucred->cr_ngroups = 1; /* group 0 */ /* Create the file descriptor table. */ fdp = &filedesc0; p->p_fd = &fdp->fd_fd; fdp->fd_fd.fd_refcnt = 1; fdp->fd_fd.fd_cmask = cmask; fdp->fd_fd.fd_ofiles = fdp->fd_dfiles; fdp->fd_fd.fd_ofileflags = fdp->fd_dfileflags; fdp->fd_fd.fd_nfiles = NDFILE; /* Create the limits structures. */ p->p_limit = &limit0; for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) limit0.pl_rlimit[i].rlim_cur = limit0.pl_rlimit[i].rlim_max = RLIM_INFINITY; limit0.pl_rlimit[RLIMIT_NOFILE].rlim_cur = NOFILE; limit0.pl_rlimit[RLIMIT_NPROC].rlim_cur = MAXUPRC; i = ptoa(cnt.v_free_count); limit0.pl_rlimit[RLIMIT_RSS].rlim_max = i; limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = i; limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = i / 3; limit0.p_refcnt = 1; /* Allocate a prototype map so we have something to fork. */ p->p_vmspace = &vmspace0; vmspace0.vm_refcnt = 1; pmap_pinit(&vmspace0.vm_pmap); vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS), trunc_page(VM_MAX_ADDRESS), TRUE); vmspace0.vm_map.pmap = &vmspace0.vm_pmap; p->p_addr = proc0paddr; /* XXX */ /* * We continue to place resource usage info and signal * actions in the user struct so they're pageable. */ p->p_stats = &p->p_addr->u_stats; p->p_sigacts = &p->p_addr->u_sigacts; /* * Initialize per uid information structure and charge * root for one process. */ usrinfoinit(); (void)chgproccnt(0, 1); rqinit(); /* Configure virtual memory system, set vm rlimits. */ vm_init_limits(p); /* Initialize the file systems. */ vfsinit(); /* Start real time and statistics clocks. */ initclocks(); /* Initialize mbuf's. */ mbinit(); /* Initialize clists. */ clist_init(); + +#ifdef SYSVSHM + /* Initialize System V style shared memory. */ + shminit(); +#endif + +#ifdef SYSVSEM + /* Initialize System V style semaphores. */ + seminit(); +#endif + +#ifdef SYSVMSG + /* Initialize System V style message queues. */ + msginit(); +#endif /* * Attach pseudo-devices. */ while(*pseudos) { (**pseudos++)(); } /* * Initialize protocols. Block reception of incoming packets * until everything is ready. */ s = splimp(); ifinit(); domaininit(); splx(s); #ifdef GPROF /* Initialize kernel profiling. */ kmstartup(); #endif /* Kick off timeout driven events by calling first time. */ roundrobin(NULL); schedcpu(NULL); /* Mount the root file system. */ if ((*mountroot)()) panic("cannot mount root"); /* Get the vnode for '/'. Set fdp->fd_fd.fd_cdir to reference it. */ if (VFS_ROOT(mountlist.tqh_first, &rootvnode)) panic("cannot find root vnode"); fdp->fd_fd.fd_cdir = rootvnode; VREF(fdp->fd_fd.fd_cdir); VOP_UNLOCK(rootvnode); fdp->fd_fd.fd_rdir = NULL; swapinit(); /* * Now can look at time, having had a chance to verify the time * from the file system. Reset p->p_rtime as it may have been * munched in mi_switch() after the time got set. */ p->p_stats->p_start = runtime = mono_time = boottime = time; p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0; /* Initialize signal state for process 0. */ siginit(p); /* Create process 1 (init(8)). */ if (fork(p, NULL, rval)) panic("fork init"); if (rval[1]) { start_init(curproc, framep); return; } /* Create process 2 (the pageout daemon). */ if (fork(p, NULL, rval)) panic("fork pager"); if (rval[1]) { /* * Now in process 2. */ p = curproc; pageproc = p; p->p_flag |= P_INMEM | P_SYSTEM; /* XXX */ bcopy("pagedaemon", curproc->p_comm, sizeof ("pagedaemon")); vm_pageout(); /* NOTREACHED */ } /* * Start update daemon (process 3). */ if (fork(p, (void *) NULL, rval)) panic("failed fork update daemon"); if (rval[1]) { p = curproc; updateproc = p; p->p_flag |= P_INMEM | P_SYSTEM; bcopy("update", p->p_comm, sizeof("update")); vfs_update(); /*NOTREACHED*/ } /* The scheduler is an infinite loop. */ scheduler(); /* NOTREACHED */ } /* * List of paths to try when searching for "init". */ static char *initpaths[] = { "/sbin/init", "/sbin/oinit", "/sbin/init.bak", NULL, }; /* * Start the initial user process; try exec'ing each pathname in "initpaths". * The program is invoked with one argument containing the boot flags. */ static void start_init(p, framep) struct proc *p; void *framep; { vm_offset_t addr; struct execve_args args; int options, i, retval[2], error; char **pathp, *path, *ucp, **uap, *arg0, *arg1; initproc = p; /* * We need to set the system call frame as if we were entered through * a syscall() so that when we call execve() below, it will be able * to set the entry point (see setregs) when it tries to exec. The * startup code in "locore.s" has allocated space for the frame and * passed a pointer to that space as main's argument. */ cpu_set_init_frame(p, framep); /* * Need just enough stack to hold the faked-up "execve()" arguments. */ addr = trunc_page(VM_MAXUSER_ADDRESS - PAGE_SIZE); if (vm_allocate(&p->p_vmspace->vm_map, &addr, PAGE_SIZE, FALSE) != 0) panic("init: couldn't allocate argument space"); p->p_vmspace->vm_maxsaddr = (caddr_t)addr; p->p_vmspace->vm_ssize = 1; for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) { /* * Move out the boot flag argument. */ options = 0; ucp = (char *)USRSTACK; (void)subyte(--ucp, 0); /* trailing zero */ if (boothowto & RB_SINGLE) { (void)subyte(--ucp, 's'); options = 1; } #ifdef notyet if (boothowto & RB_FASTBOOT) { (void)subyte(--ucp, 'f'); options = 1; } #endif if (options == 0) (void)subyte(--ucp, '-'); (void)subyte(--ucp, '-'); /* leading hyphen */ arg1 = ucp; /* * Move out the file name (also arg 0). */ for (i = strlen(path) + 1; i >= 0; i--) (void)subyte(--ucp, path[i]); arg0 = ucp; /* * Move out the arg pointers. */ uap = (char **)((int)ucp & ~(NBPW-1)); (void)suword((caddr_t)--uap, 0); /* terminator */ (void)suword((caddr_t)--uap, (int)arg1); (void)suword((caddr_t)--uap, (int)arg0); /* * Point at the arguments. */ args.fname = arg0; args.argv = uap; args.envv = NULL; /* * Now try to exec the program. If can't for any reason * other than it doesn't exist, complain. */ if ((error = execve(p, &args, &retval)) == 0) return; if (error != ENOENT) printf("exec %s: error %d\n", path, error); } printf("init: not found\n"); panic("no init"); } Index: head/sys/kern/init_sysent.c =================================================================== --- head/sys/kern/init_sysent.c (revision 2728) +++ head/sys/kern/init_sysent.c (revision 2729) @@ -1,527 +1,549 @@ /* * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * created from $Id: syscalls.master,v 1.6 1994/09/01 05:12:42 davidg Exp $ + * created from $Id: syscalls.master,v 1.7 1994/09/13 00:48:19 wollman Exp $ */ #include #include #include int nosys(); int exit(); int fork(); int read(); int write(); int open(); int close(); int wait4(); int link(); int unlink(); int chdir(); int fchdir(); int mknod(); int chmod(); int chown(); int obreak(); int getfsstat(); int getpid(); int mount(); int unmount(); int setuid(); int getuid(); int geteuid(); int ptrace(); int recvmsg(); int sendmsg(); int recvfrom(); int accept(); int getpeername(); int getsockname(); int access(); int chflags(); int fchflags(); int sync(); int kill(); int getppid(); int dup(); int pipe(); int getegid(); int profil(); #ifdef KTRACE int ktrace(); #else #endif int sigaction(); int getgid(); int sigprocmask(); int getlogin(); int setlogin(); int acct(); int sigpending(); int sigaltstack(); int ioctl(); int reboot(); int revoke(); int symlink(); int readlink(); int execve(); int umask(); int chroot(); int msync(); int vfork(); int sbrk(); int sstk(); int ovadvise(); int munmap(); int mprotect(); int madvise(); int mincore(); int getgroups(); int setgroups(); int getpgrp(); int setpgid(); int setitimer(); int swapon(); int getitimer(); int getdtablesize(); int dup2(); int fcntl(); int select(); int fsync(); int setpriority(); int socket(); int connect(); int getpriority(); int sigreturn(); int bind(); int setsockopt(); int listen(); int sigsuspend(); #ifdef TRACE int vtrace(); #else #endif int gettimeofday(); int getrusage(); int getsockopt(); #ifdef vax int resuba(); #else #endif int readv(); int writev(); int settimeofday(); int fchown(); int fchmod(); int rename(); int flock(); int mkfifo(); int sendto(); int shutdown(); int socketpair(); int mkdir(); int rmdir(); int utimes(); int adjtime(); int setsid(); int quotactl(); #ifdef NFS int nfssvc(); #else #endif int statfs(); int fstatfs(); #ifdef NFS int getfh(); #else #endif int getdomainname(); int setdomainname(); int uname(); int sysarch(); int rtprio(); +#ifdef SYSVSEM +int semsys(); +#else +#endif +#ifdef SYSVMSG +int msgsys(); +#else +#endif #ifdef SYSVSHM int shmsys(); #else #endif int setgid(); int setegid(); int seteuid(); #ifdef LFS int lfs_bmapv(); int lfs_markv(); int lfs_segclean(); int lfs_segwait(); #else #endif int stat(); int fstat(); int lstat(); int pathconf(); int fpathconf(); int getrlimit(); int setrlimit(); int getdirentries(); int mmap(); int lseek(); int truncate(); int ftruncate(); int __sysctl(); int mlock(); int munlock(); #ifdef LKM int lkmnosys(); int lkmnosys(); int lkmnosys(); int lkmnosys(); int lkmnosys(); int lkmnosys(); int lkmnosys(); int lkmnosys(); int lkmnosys(); int lkmnosys(); #else #endif #ifdef COMPAT_43 #define compat(n, name) n, __CONCAT(o,name) int ocreat(); int olseek(); int ostat(); int olstat(); #ifdef KTRACE #else #endif int ofstat(); int ogetkerninfo(); int ogetpagesize(); int ommap(); int owait(); int ogethostname(); int osethostname(); int oaccept(); int osend(); int orecv(); int osigvec(); int osigblock(); int osigsetmask(); int osigstack(); int orecvmsg(); int osendmsg(); #ifdef TRACE #else #endif #ifdef vax #else #endif int orecvfrom(); int osetreuid(); int osetregid(); int otruncate(); int oftruncate(); int ogetpeername(); int ogethostid(); int osethostid(); int ogetrlimit(); int osetrlimit(); int okillpg(); int oquota(); int ogetsockname(); #ifdef NFS #else #endif int ogetdirentries(); #ifdef NFS #else #endif +#ifdef SYSVSEM +#else +#endif +#ifdef SYSVMSG +#else +#endif #ifdef SYSVSHM #else #endif #ifdef LFS #else #endif #ifdef LKM #else #endif #else /* COMPAT_43 */ #define compat(n, name) 0, nosys #endif /* COMPAT_43 */ struct sysent sysent[] = { { 0, nosys }, /* 0 = syscall */ { 1, exit }, /* 1 = exit */ { 0, fork }, /* 2 = fork */ { 3, read }, /* 3 = read */ { 3, write }, /* 4 = write */ { 3, open }, /* 5 = open */ { 1, close }, /* 6 = close */ { 4, wait4 }, /* 7 = wait4 */ { compat(2,creat) }, /* 8 = old creat */ { 2, link }, /* 9 = link */ { 1, unlink }, /* 10 = unlink */ { 0, nosys }, /* 11 = obsolete execv */ { 1, chdir }, /* 12 = chdir */ { 1, fchdir }, /* 13 = fchdir */ { 3, mknod }, /* 14 = mknod */ { 2, chmod }, /* 15 = chmod */ { 3, chown }, /* 16 = chown */ { 1, obreak }, /* 17 = break */ { 3, getfsstat }, /* 18 = getfsstat */ { compat(3,lseek) }, /* 19 = old lseek */ { 0, getpid }, /* 20 = getpid */ { 4, mount }, /* 21 = mount */ { 2, unmount }, /* 22 = unmount */ { 1, setuid }, /* 23 = setuid */ { 0, getuid }, /* 24 = getuid */ { 0, geteuid }, /* 25 = geteuid */ { 4, ptrace }, /* 26 = ptrace */ { 3, recvmsg }, /* 27 = recvmsg */ { 3, sendmsg }, /* 28 = sendmsg */ { 6, recvfrom }, /* 29 = recvfrom */ { 3, accept }, /* 30 = accept */ { 3, getpeername }, /* 31 = getpeername */ { 3, getsockname }, /* 32 = getsockname */ { 2, access }, /* 33 = access */ { 2, chflags }, /* 34 = chflags */ { 2, fchflags }, /* 35 = fchflags */ { 0, sync }, /* 36 = sync */ { 2, kill }, /* 37 = kill */ { compat(2,stat) }, /* 38 = old stat */ { 0, getppid }, /* 39 = getppid */ { compat(2,lstat) }, /* 40 = old lstat */ { 2, dup }, /* 41 = dup */ { 0, pipe }, /* 42 = pipe */ { 0, getegid }, /* 43 = getegid */ { 4, profil }, /* 44 = profil */ #ifdef KTRACE { 4, ktrace }, /* 45 = ktrace */ #else { 0, nosys }, /* 45 = ktrace */ #endif { 3, sigaction }, /* 46 = sigaction */ { 0, getgid }, /* 47 = getgid */ { 2, sigprocmask }, /* 48 = sigprocmask */ { 2, getlogin }, /* 49 = getlogin */ { 1, setlogin }, /* 50 = setlogin */ { 1, acct }, /* 51 = acct */ { 0, sigpending }, /* 52 = sigpending */ { 2, sigaltstack }, /* 53 = sigaltstack */ { 3, ioctl }, /* 54 = ioctl */ { 1, reboot }, /* 55 = reboot */ { 1, revoke }, /* 56 = revoke */ { 2, symlink }, /* 57 = symlink */ { 3, readlink }, /* 58 = readlink */ { 3, execve }, /* 59 = execve */ { 1, umask }, /* 60 = umask */ { 1, chroot }, /* 61 = chroot */ { compat(2,fstat) }, /* 62 = old fstat */ { compat(4,getkerninfo) }, /* 63 = old getkerninfo */ { compat(0,getpagesize) }, /* 64 = old getpagesize */ { 2, msync }, /* 65 = msync */ { 0, vfork }, /* 66 = vfork */ { 0, nosys }, /* 67 = obsolete vread */ { 0, nosys }, /* 68 = obsolete vwrite */ { 1, sbrk }, /* 69 = sbrk */ { 1, sstk }, /* 70 = sstk */ { compat(6,mmap) }, /* 71 = old mmap */ { 1, ovadvise }, /* 72 = vadvise */ { 2, munmap }, /* 73 = munmap */ { 3, mprotect }, /* 74 = mprotect */ { 3, madvise }, /* 75 = madvise */ { 0, nosys }, /* 76 = obsolete vhangup */ { 0, nosys }, /* 77 = obsolete vlimit */ { 3, mincore }, /* 78 = mincore */ { 2, getgroups }, /* 79 = getgroups */ { 2, setgroups }, /* 80 = setgroups */ { 0, getpgrp }, /* 81 = getpgrp */ { 2, setpgid }, /* 82 = setpgid */ { 3, setitimer }, /* 83 = setitimer */ { compat(0,wait) }, /* 84 = old wait */ { 1, swapon }, /* 85 = swapon */ { 2, getitimer }, /* 86 = getitimer */ { compat(2,gethostname) }, /* 87 = old gethostname */ { compat(2,sethostname) }, /* 88 = old sethostname */ { 0, getdtablesize }, /* 89 = getdtablesize */ { 2, dup2 }, /* 90 = dup2 */ { 0, nosys }, /* 91 = getdopt */ { 3, fcntl }, /* 92 = fcntl */ { 5, select }, /* 93 = select */ { 0, nosys }, /* 94 = setdopt */ { 1, fsync }, /* 95 = fsync */ { 3, setpriority }, /* 96 = setpriority */ { 3, socket }, /* 97 = socket */ { 3, connect }, /* 98 = connect */ { compat(3,accept) }, /* 99 = old accept */ { 2, getpriority }, /* 100 = getpriority */ { compat(4,send) }, /* 101 = old send */ { compat(4,recv) }, /* 102 = old recv */ { 1, sigreturn }, /* 103 = sigreturn */ { 3, bind }, /* 104 = bind */ { 5, setsockopt }, /* 105 = setsockopt */ { 2, listen }, /* 106 = listen */ { 0, nosys }, /* 107 = obsolete vtimes */ { compat(3,sigvec) }, /* 108 = old sigvec */ { compat(1,sigblock) }, /* 109 = old sigblock */ { compat(1,sigsetmask) }, /* 110 = old sigsetmask */ { 1, sigsuspend }, /* 111 = sigsuspend */ { compat(2,sigstack) }, /* 112 = old sigstack */ { compat(3,recvmsg) }, /* 113 = old recvmsg */ { compat(3,sendmsg) }, /* 114 = old sendmsg */ #ifdef TRACE { 2, vtrace }, /* 115 = vtrace */ #else { 0, nosys }, /* 115 = obsolete vtrace */ #endif { 2, gettimeofday }, /* 116 = gettimeofday */ { 2, getrusage }, /* 117 = getrusage */ { 5, getsockopt }, /* 118 = getsockopt */ #ifdef vax { 1, resuba }, /* 119 = resuba */ #else { 0, nosys }, /* 119 = nosys */ #endif { 3, readv }, /* 120 = readv */ { 3, writev }, /* 121 = writev */ { 2, settimeofday }, /* 122 = settimeofday */ { 3, fchown }, /* 123 = fchown */ { 2, fchmod }, /* 124 = fchmod */ { compat(6,recvfrom) }, /* 125 = old recvfrom */ { compat(2,setreuid) }, /* 126 = old setreuid */ { compat(2,setregid) }, /* 127 = old setregid */ { 2, rename }, /* 128 = rename */ { compat(2,truncate) }, /* 129 = old truncate */ { compat(2,ftruncate) }, /* 130 = old ftruncate */ { 2, flock }, /* 131 = flock */ { 2, mkfifo }, /* 132 = mkfifo */ { 6, sendto }, /* 133 = sendto */ { 2, shutdown }, /* 134 = shutdown */ { 5, socketpair }, /* 135 = socketpair */ { 2, mkdir }, /* 136 = mkdir */ { 1, rmdir }, /* 137 = rmdir */ { 2, utimes }, /* 138 = utimes */ { 0, nosys }, /* 139 = obsolete 4.2 sigreturn */ { 2, adjtime }, /* 140 = adjtime */ { compat(3,getpeername) }, /* 141 = old getpeername */ { compat(0,gethostid) }, /* 142 = old gethostid */ { compat(1,sethostid) }, /* 143 = old sethostid */ { compat(2,getrlimit) }, /* 144 = old getrlimit */ { compat(2,setrlimit) }, /* 145 = old setrlimit */ { compat(2,killpg) }, /* 146 = old killpg */ { 0, setsid }, /* 147 = setsid */ { 4, quotactl }, /* 148 = quotactl */ { compat(4,quota) }, /* 149 = old quota */ { compat(3,getsockname) }, /* 150 = old getsockname */ { 0, nosys }, /* 151 = nosys */ { 0, nosys }, /* 152 = nosys */ { 0, nosys }, /* 153 = nosys */ { 0, nosys }, /* 154 = nosys */ #ifdef NFS { 2, nfssvc }, /* 155 = nfssvc */ #else { 0, nosys }, /* 155 = nosys */ #endif { compat(4,getdirentries) }, /* 156 = old getdirentries */ { 2, statfs }, /* 157 = statfs */ { 2, fstatfs }, /* 158 = fstatfs */ { 0, nosys }, /* 159 = nosys */ { 0, nosys }, /* 160 = nosys */ #ifdef NFS { 2, getfh }, /* 161 = getfh */ #else { 0, nosys }, /* 161 = nosys */ #endif { 2, getdomainname }, /* 162 = getdomainname */ { 2, setdomainname }, /* 163 = setdomainname */ { 1, uname }, /* 164 = uname */ { 2, sysarch }, /* 165 = sysarch */ { 2, rtprio }, /* 166 = rtprio */ { 0, nosys }, /* 167 = nosys */ { 0, nosys }, /* 168 = nosys */ +#ifdef SYSVSEM + { 5, semsys }, /* 169 = semsys */ +#else { 0, nosys }, /* 169 = nosys */ +#endif +#ifdef SYSVMSG + { 6, msgsys }, /* 170 = msgsys */ +#else { 0, nosys }, /* 170 = nosys */ +#endif #ifdef SYSVSHM { 4, shmsys }, /* 171 = shmsys */ #else { 0, nosys }, /* 171 = nosys */ #endif { 0, nosys }, /* 172 = nosys */ { 0, nosys }, /* 173 = nosys */ { 0, nosys }, /* 174 = nosys */ { 1, nosys }, /* 175 = ntp_gettime */ { 1, nosys }, /* 176 = ntp_adjtime */ { 0, nosys }, /* 177 = nosys */ { 0, nosys }, /* 178 = nosys */ { 0, nosys }, /* 179 = nosys */ { 0, nosys }, /* 180 = nosys */ { 1, setgid }, /* 181 = setgid */ { 1, setegid }, /* 182 = setegid */ { 1, seteuid }, /* 183 = seteuid */ #ifdef LFS { 3, lfs_bmapv }, /* 184 = lfs_bmapv */ { 3, lfs_markv }, /* 185 = lfs_markv */ { 2, lfs_segclean }, /* 186 = lfs_segclean */ { 2, lfs_segwait }, /* 187 = lfs_segwait */ #else { 0, nosys }, /* 184 = nosys */ { 0, nosys }, /* 185 = nosys */ { 0, nosys }, /* 186 = nosys */ { 0, nosys }, /* 187 = nosys */ #endif { 2, stat }, /* 188 = stat */ { 2, fstat }, /* 189 = fstat */ { 2, lstat }, /* 190 = lstat */ { 2, pathconf }, /* 191 = pathconf */ { 2, fpathconf }, /* 192 = fpathconf */ { 0, nosys }, /* 193 = nosys */ { 2, getrlimit }, /* 194 = getrlimit */ { 2, setrlimit }, /* 195 = setrlimit */ { 4, getdirentries }, /* 196 = getdirentries */ { 8, mmap }, /* 197 = mmap */ { 0, nosys }, /* 198 = __syscall */ { 5, lseek }, /* 199 = lseek */ { 4, truncate }, /* 200 = truncate */ { 4, ftruncate }, /* 201 = ftruncate */ { 6, __sysctl }, /* 202 = __sysctl */ { 2, mlock }, /* 203 = mlock */ { 2, munlock }, /* 204 = munlock */ { 0, nosys }, /* 205 = nosys */ { 0, nosys }, /* 206 = nosys */ { 0, nosys }, /* 207 = nosys */ { 0, nosys }, /* 208 = nosys */ { 0, nosys }, /* 209 = nosys */ #ifdef LKM { 0, lkmnosys }, /* 210 = lkmnosys */ { 0, lkmnosys }, /* 211 = lkmnosys */ { 0, lkmnosys }, /* 212 = lkmnosys */ { 0, lkmnosys }, /* 213 = lkmnosys */ { 0, lkmnosys }, /* 214 = lkmnosys */ { 0, lkmnosys }, /* 215 = lkmnosys */ { 0, lkmnosys }, /* 216 = lkmnosys */ { 0, lkmnosys }, /* 217 = lkmnosys */ { 0, lkmnosys }, /* 218 = lkmnosys */ { 0, lkmnosys }, /* 219 = lkmnosys */ #else { 0, nosys }, /* 210 = nosys */ { 0, nosys }, /* 211 = nosys */ { 0, nosys }, /* 212 = nosys */ { 0, nosys }, /* 213 = nosys */ { 0, nosys }, /* 214 = nosys */ { 0, nosys }, /* 215 = nosys */ { 0, nosys }, /* 216 = nosys */ { 0, nosys }, /* 217 = nosys */ { 0, nosys }, /* 218 = nosys */ { 0, nosys }, /* 219 = nosys */ #endif }; struct sysentvec aout_sysvec = { sizeof (sysent) / sizeof (sysent[0]), sysent, 0, 0, 0 }; \ No newline at end of file Index: head/sys/kern/kern_exec.c =================================================================== --- head/sys/kern/kern_exec.c (revision 2728) +++ head/sys/kern/kern_exec.c (revision 2729) @@ -1,554 +1,556 @@ /* * Copyright (c) 1993, David Greenman * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by David Greenman * 4. The name of the developer may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: kern_exec.c,v 1.4 1994/08/18 22:34:59 wollman Exp $ + * $Id: kern_exec.c,v 1.5 1994/08/24 10:53:53 davidg Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int *exec_copyout_strings __P((struct image_params *)); static int exec_check_permissions(struct image_params *); /* * execsw_set is constructed for us by the linker. Each of the items * is a pointer to a `const struct execsw', hence the double pointer here. */ extern const struct linker_set execsw_set; const struct execsw **execsw = (const struct execsw **)&execsw_set.ls_items[0]; /* * execve() system call. */ int execve(p, uap, retval) struct proc *p; register struct execve_args *uap; int *retval; { struct nameidata nd, *ndp; char *stringbase, *stringp; int *stack_base; int error, resid, len, i; struct image_params image_params, *iparams; struct vnode *vnodep; struct vattr attr; char *image_header; iparams = &image_params; bzero((caddr_t)iparams, sizeof(struct image_params)); image_header = (char *)0; /* * Initialize a few constants in the common area */ iparams->proc = p; iparams->uap = uap; iparams->attr = &attr; /* * Allocate temporary demand zeroed space for argument and * environment strings */ error = vm_allocate(kernel_map, (vm_offset_t *)&iparams->stringbase, ARG_MAX, TRUE); if (error) { log(LOG_WARNING, "execve: failed to allocate string space\n"); return (error); } if (!iparams->stringbase) { error = ENOMEM; goto exec_fail; } iparams->stringp = iparams->stringbase; iparams->stringspace = ARG_MAX; /* * Translate the file name. namei() returns a vnode pointer * in ni_vp amoung other things. */ ndp = &nd; ndp->ni_cnd.cn_nameiop = LOOKUP; ndp->ni_cnd.cn_flags = LOCKLEAF | FOLLOW | SAVENAME; ndp->ni_cnd.cn_proc = curproc; ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred; ndp->ni_segflg = UIO_USERSPACE; ndp->ni_dirp = uap->fname; interpret: error = namei(ndp); if (error) { vm_deallocate(kernel_map, (vm_offset_t)iparams->stringbase, ARG_MAX); goto exec_fail; } iparams->vnodep = vnodep = ndp->ni_vp; if (vnodep == NULL) { error = ENOEXEC; goto exec_fail_dealloc; } /* * Check file permissions (also 'opens' file) */ error = exec_check_permissions(iparams); if (error) goto exec_fail_dealloc; /* * Map the image header (first page) of the file into * kernel address space */ error = vm_mmap(kernel_map, /* map */ (vm_offset_t *)&image_header, /* address */ PAGE_SIZE, /* size */ VM_PROT_READ, /* protection */ VM_PROT_READ, /* max protection */ 0, /* flags */ (caddr_t)vnodep, /* vnode */ 0); /* offset */ if (error) { uprintf("mmap failed: %d\n",error); goto exec_fail_dealloc; } iparams->image_header = image_header; /* * Loop through list of image activators, calling each one. * If there is no match, the activator returns -1. If there * is a match, but there was an error during the activation, * the error is returned. Otherwise 0 means success. If the * image is interpreted, loop back up and try activating * the interpreter. */ for (i = 0; execsw[i]; ++i) { if (execsw[i]->ex_imgact) error = (*execsw[i]->ex_imgact)(iparams); else continue; if (error == -1) continue; if (error) goto exec_fail_dealloc; if (iparams->interpreted) { /* free old vnode and name buffer */ vput(ndp->ni_vp); FREE(ndp->ni_cnd.cn_pnbuf, M_NAMEI); if (vm_deallocate(kernel_map, (vm_offset_t)image_header, PAGE_SIZE)) panic("execve: header dealloc failed (1)"); /* set new name to that of the interpreter */ ndp->ni_segflg = UIO_SYSSPACE; ndp->ni_dirp = iparams->interpreter_name; ndp->ni_cnd.cn_nameiop = LOOKUP; ndp->ni_cnd.cn_flags = LOCKLEAF | FOLLOW | SAVENAME; ndp->ni_cnd.cn_proc = curproc; ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred; goto interpret; } break; } /* If we made it through all the activators and none matched, exit. */ if (error == -1) { error = ENOEXEC; goto exec_fail_dealloc; } /* * Copy out strings (args and env) and initialize stack base */ stack_base = exec_copyout_strings(iparams); p->p_vmspace->vm_minsaddr = (char *)stack_base; /* * Stuff argument count as first item on stack */ *(--stack_base) = iparams->argc; /* close files on exec */ fdcloseexec(p); /* reset caught signals */ execsigs(p); /* name this process - nameiexec(p, ndp) */ len = min(ndp->ni_cnd.cn_namelen,MAXCOMLEN); bcopy(ndp->ni_cnd.cn_nameptr, p->p_comm, len); p->p_comm[len] = 0; /* * mark as executable, wakeup any process that was vforked and tell * it that it now has it's own resources back */ p->p_flag |= P_EXEC; if (p->p_pptr && (p->p_flag & P_PPWAIT)) { p->p_flag &= ~P_PPWAIT; wakeup((caddr_t)p->p_pptr); } /* implement set userid/groupid */ p->p_flag &= ~P_SUGID; /* * Turn off kernel tracing for set-id programs, except for * root. */ if (p->p_tracep && (attr.va_mode & (VSUID | VSGID)) && suser(p->p_ucred, &p->p_acflag)) { p->p_traceflag = 0; vrele(p->p_tracep); p->p_tracep = 0; } if ((attr.va_mode & VSUID) && (p->p_flag & P_TRACED) == 0) { p->p_ucred = crcopy(p->p_ucred); p->p_ucred->cr_uid = attr.va_uid; p->p_flag |= P_SUGID; } if ((attr.va_mode & VSGID) && (p->p_flag & P_TRACED) == 0) { p->p_ucred = crcopy(p->p_ucred); p->p_ucred->cr_groups[0] = attr.va_gid; p->p_flag |= P_SUGID; } /* * Implement correct POSIX saved uid behavior. */ p->p_cred->p_svuid = p->p_ucred->cr_uid; p->p_cred->p_svgid = p->p_ucred->cr_gid; /* mark vnode pure text */ ndp->ni_vp->v_flag |= VTEXT; /* * If tracing the process, trap to debugger so breakpoints * can be set before the program executes. */ if (p->p_flag & P_TRACED) psignal(p, SIGTRAP); /* clear "fork but no exec" flag, as we _are_ execing */ p->p_acflag &= ~AFORK; /* Set entry address */ setregs(p, iparams->entry_addr, stack_base); /* * free various allocated resources */ if (vm_deallocate(kernel_map, (vm_offset_t)iparams->stringbase, ARG_MAX)) panic("execve: string buffer dealloc failed (1)"); if (vm_deallocate(kernel_map, (vm_offset_t)image_header, PAGE_SIZE)) panic("execve: header dealloc failed (2)"); vput(ndp->ni_vp); FREE(ndp->ni_cnd.cn_pnbuf, M_NAMEI); return (0); exec_fail_dealloc: if (iparams->stringbase && iparams->stringbase != (char *)-1) if (vm_deallocate(kernel_map, (vm_offset_t)iparams->stringbase, ARG_MAX)) panic("execve: string buffer dealloc failed (2)"); if (iparams->image_header && iparams->image_header != (char *)-1) if (vm_deallocate(kernel_map, (vm_offset_t)iparams->image_header, PAGE_SIZE)) panic("execve: header dealloc failed (3)"); vput(ndp->ni_vp); FREE(ndp->ni_cnd.cn_pnbuf, M_NAMEI); exec_fail: if (iparams->vmspace_destroyed) { /* sorry, no more process anymore. exit gracefully */ #if 0 /* XXX */ vm_deallocate(&vs->vm_map, USRSTACK - MAXSSIZ, MAXSSIZ); #endif exit1(p, W_EXITCODE(0, SIGABRT)); /* NOT REACHED */ return(0); } else { return(error); } } /* * Destroy old address space, and allocate a new stack * The new stack is only SGROWSIZ large because it is grown * automatically in trap.c. */ int exec_new_vmspace(iparams) struct image_params *iparams; { int error; struct vmspace *vmspace = iparams->proc->p_vmspace; caddr_t stack_addr = (caddr_t) (USRSTACK - SGROWSIZ); iparams->vmspace_destroyed = 1; /* Blow away entire process VM */ + if (vmspace->vm_shm) + shmexit(iparams->proc); vm_deallocate(&vmspace->vm_map, 0, USRSTACK); /* Allocate a new stack */ error = vm_allocate(&vmspace->vm_map, (vm_offset_t *)&stack_addr, SGROWSIZ, FALSE); if (error) return(error); vmspace->vm_ssize = SGROWSIZ >> PAGE_SHIFT; /* Initialize maximum stack address */ vmspace->vm_maxsaddr = (char *)USRSTACK - MAXSSIZ; return(0); } /* * Copy out argument and environment strings from the old process * address space into the temporary string buffer. */ int exec_extract_strings(iparams) struct image_params *iparams; { char **argv, **envv; char *argp, *envp; int error, length; /* * extract arguments first */ argv = iparams->uap->argv; if (argv) { while (argp = (caddr_t) fuword(argv++)) { if (argp == (caddr_t) -1) return (EFAULT); if (error = copyinstr(argp, iparams->stringp, iparams->stringspace, &length)) { if (error == ENAMETOOLONG) return(E2BIG); return (error); } iparams->stringspace -= length; iparams->stringp += length; iparams->argc++; } } /* * extract environment strings */ envv = iparams->uap->envv; if (envv) { while (envp = (caddr_t) fuword(envv++)) { if (envp == (caddr_t) -1) return (EFAULT); if (error = copyinstr(envp, iparams->stringp, iparams->stringspace, &length)) { if (error == ENAMETOOLONG) return(E2BIG); return (error); } iparams->stringspace -= length; iparams->stringp += length; iparams->envc++; } } return (0); } /* * Copy strings out to the new process address space, constructing * new arg and env vector tables. Return a pointer to the base * so that it can be used as the initial stack pointer. */ int * exec_copyout_strings(iparams) struct image_params *iparams; { int argc, envc; char **vectp; char *stringp, *destp; int *stack_base; int vect_table_size, string_table_size; struct ps_strings *arginfo; /* * Calculate string base and vector table pointers. */ arginfo = PS_STRINGS; destp = (caddr_t)arginfo - roundup((ARG_MAX - iparams->stringspace), sizeof(char *)); /* * The '+ 2' is for the null pointers at the end of each of the * arg and env vector sets */ vectp = (char **) (destp - (iparams->argc + iparams->envc + 2) * sizeof(char *)); /* * vectp also becomes our initial stack base */ stack_base = (int *)vectp; stringp = iparams->stringbase; argc = iparams->argc; envc = iparams->envc; /* * Fill in "ps_strings" struct for ps, w, etc. */ arginfo->ps_argvstr = destp; arginfo->ps_nargvstr = argc; /* * Copy the arg strings and fill in vector table as we go. */ for (; argc > 0; --argc) { *(vectp++) = destp; while (*destp++ = *stringp++); } /* a null vector table pointer seperates the argp's from the envp's */ *(vectp++) = NULL; arginfo->ps_envstr = destp; arginfo->ps_nenvstr = envc; /* * Copy the env strings and fill in vector table as we go. */ for (; envc > 0; --envc) { *(vectp++) = destp; while (*destp++ = *stringp++); } /* end of vector table is a null pointer */ *vectp = NULL; return (stack_base); } /* * Check permissions of file to execute. * Return 0 for success or error code on failure. */ static int exec_check_permissions(iparams) struct image_params *iparams; { struct proc *p = iparams->proc; struct vnode *vnodep = iparams->vnodep; struct vattr *attr = iparams->attr; int error; /* * Check number of open-for-writes on the file and deny execution * if there are any. */ if (vnodep->v_writecount) { return (ETXTBSY); } /* Get file attributes */ error = VOP_GETATTR(vnodep, attr, p->p_ucred, p); if (error) return (error); /* * 1) Check if file execution is disabled for the filesystem that this * file resides on. * 2) Insure that at least one execute bit is on - otherwise root * will always succeed, and we don't want to happen unless the * file really is executable. * 3) Insure that the file is a regular file. */ if ((vnodep->v_mount->mnt_flag & MNT_NOEXEC) || ((attr->va_mode & 0111) == 0) || (attr->va_type != VREG)) { return (EACCES); } /* * Zero length files can't be exec'd */ if (attr->va_size == 0) return (ENOEXEC); /* * Disable setuid/setgid if the filesystem prohibits it or if * the process is being traced. */ if ((vnodep->v_mount->mnt_flag & MNT_NOSUID) || (p->p_flag & P_TRACED)) attr->va_mode &= ~(VSUID | VSGID); /* * Check for execute permission to file based on current credentials. * Then call filesystem specific open routine (which does nothing * in the general case). */ error = VOP_ACCESS(vnodep, VEXEC, p->p_ucred, p); if (error) return (error); error = VOP_OPEN(vnodep, FREAD, p->p_ucred, p); if (error) return (error); return (0); } Index: head/sys/kern/subr_param.c =================================================================== --- head/sys/kern/subr_param.c (revision 2728) +++ head/sys/kern/subr_param.c (revision 2729) @@ -1,147 +1,190 @@ /* * Copyright (c) 1980, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)param.c 8.2 (Berkeley) 1/21/94 - * $Id$ + * $Id: param.c,v 1.3 1994/08/02 07:38:30 davidg Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #ifdef SYSVSHM #include #include #endif +#ifdef SYSVSEM +#include "sys/sem.h" +#endif +#ifdef SYSVMSG +#include "sys/msg.h" +#endif /* * System parameter formulae. * * This file is copied into each directory where we compile * the kernel; it should be modified there to suit local taste * if necessary. * * Compiled with -DHZ=xx -DTIMEZONE=x -DDST=x -DMAXUSERS=xx */ #ifndef HZ #define HZ 100 #endif int hz = HZ; int tick = 1000000 / HZ; int tickadj = 30000 / (60 * HZ); /* can adjust 30ms in 60s */ struct timezone tz = { TIMEZONE, DST }; #define NPROC (20 + 16 * MAXUSERS) int maxproc = NPROC; #define NTEXT NPROC int vm_cache_max = NTEXT/2 + 16; #define NVNODE (NPROC + NTEXT + 100) int desiredvnodes = NVNODE; int maxfiles = 3 * (NPROC + MAXUSERS) + 80; int ncallout = 16 + NPROC; int nclist = 60 + 12 * MAXUSERS; int nmbclusters = NMBCLUSTERS; int fscale = FSCALE; /* kernel uses `FSCALE', user uses `fscale' */ /* * Values in support of System V compatible shared memory. XXX */ #ifdef SYSVSHM #define SHMMAX (SHMMAXPGS*NBPG) #define SHMMIN 1 #define SHMMNI 32 /* <= SHMMMNI in shm.h */ #define SHMSEG 8 #define SHMALL (SHMMAXPGS/CLSIZE) struct shminfo shminfo = { SHMMAX, SHMMIN, SHMMNI, SHMSEG, SHMALL +}; +#endif + +/* + * Values in support of System V compatible semaphores. + */ + +#ifdef SYSVSEM + +struct seminfo seminfo = { + SEMMAP, /* # of entries in semaphore map */ + SEMMNI, /* # of semaphore identifiers */ + SEMMNS, /* # of semaphores in system */ + SEMMNU, /* # of undo structures in system */ + SEMMSL, /* max # of semaphores per id */ + SEMOPM, /* max # of operations per semop call */ + SEMUME, /* max # of undo entries per process */ + SEMUSZ, /* size in bytes of undo structure */ + SEMVMX, /* semaphore maximum value */ + SEMAEM /* adjust on exit max value */ +}; +#endif + +/* + * Values in support of System V compatible messages. + */ + +#ifdef SYSVMSG + +struct msginfo msginfo = { + MSGMAX, /* max chars in a message */ + MSGMNI, /* # of message queue identifiers */ + MSGMNB, /* max chars in a queue */ + MSGTQL, /* max messages in system */ + MSGSSZ, /* size of a message segment */ + /* (must be small power of 2 greater than 4) */ + MSGSEG /* number of message segments */ }; #endif /* * These are initialized at bootstrap time * to values dependent on memory size */ int nbuf, nswbuf; /* * These have to be allocated somewhere; allocating * them here forces loader errors if this file is omitted * (if they've been externed everywhere else; hah!). */ struct callout *callout; struct cblock *cfree; struct buf *buf, *swbuf; char *buffers; /* * Proc/pgrp hashing. * Here so that hash table sizes can depend on MAXUSERS/NPROC. * Hash size must be a power of two. * NOW omission of this file will cause loader errors! */ #if NPROC > 1024 #define PIDHSZ 512 #else #if NPROC > 512 #define PIDHSZ 256 #else #if NPROC > 256 #define PIDHSZ 128 #else #define PIDHSZ 64 #endif #endif #endif struct proc *pidhash[PIDHSZ]; struct pgrp *pgrphash[PIDHSZ]; int pidhashmask = PIDHSZ - 1; Index: head/sys/kern/syscalls.c =================================================================== --- head/sys/kern/syscalls.c (revision 2728) +++ head/sys/kern/syscalls.c (revision 2729) @@ -1,273 +1,281 @@ /* * System call names. * * DO NOT EDIT-- this file is automatically generated. - * created from $Id: syscalls.master,v 1.6 1994/09/01 05:12:42 davidg Exp $ + * created from $Id: syscalls.master,v 1.7 1994/09/13 00:48:19 wollman Exp $ */ char *syscallnames[] = { "syscall", /* 0 = syscall */ "exit", /* 1 = exit */ "fork", /* 2 = fork */ "read", /* 3 = read */ "write", /* 4 = write */ "open", /* 5 = open */ "close", /* 6 = close */ "wait4", /* 7 = wait4 */ "old.creat", /* 8 = old creat */ "link", /* 9 = link */ "unlink", /* 10 = unlink */ "obs_execv", /* 11 = obsolete execv */ "chdir", /* 12 = chdir */ "fchdir", /* 13 = fchdir */ "mknod", /* 14 = mknod */ "chmod", /* 15 = chmod */ "chown", /* 16 = chown */ "break", /* 17 = break */ "getfsstat", /* 18 = getfsstat */ "old.lseek", /* 19 = old lseek */ "getpid", /* 20 = getpid */ "mount", /* 21 = mount */ "unmount", /* 22 = unmount */ "setuid", /* 23 = setuid */ "getuid", /* 24 = getuid */ "geteuid", /* 25 = geteuid */ "ptrace", /* 26 = ptrace */ "recvmsg", /* 27 = recvmsg */ "sendmsg", /* 28 = sendmsg */ "recvfrom", /* 29 = recvfrom */ "accept", /* 30 = accept */ "getpeername", /* 31 = getpeername */ "getsockname", /* 32 = getsockname */ "access", /* 33 = access */ "chflags", /* 34 = chflags */ "fchflags", /* 35 = fchflags */ "sync", /* 36 = sync */ "kill", /* 37 = kill */ "old.stat", /* 38 = old stat */ "getppid", /* 39 = getppid */ "old.lstat", /* 40 = old lstat */ "dup", /* 41 = dup */ "pipe", /* 42 = pipe */ "getegid", /* 43 = getegid */ "profil", /* 44 = profil */ #ifdef KTRACE "ktrace", /* 45 = ktrace */ #else "#45", /* 45 = ktrace */ #endif "sigaction", /* 46 = sigaction */ "getgid", /* 47 = getgid */ "sigprocmask", /* 48 = sigprocmask */ "getlogin", /* 49 = getlogin */ "setlogin", /* 50 = setlogin */ "acct", /* 51 = acct */ "sigpending", /* 52 = sigpending */ "sigaltstack", /* 53 = sigaltstack */ "ioctl", /* 54 = ioctl */ "reboot", /* 55 = reboot */ "revoke", /* 56 = revoke */ "symlink", /* 57 = symlink */ "readlink", /* 58 = readlink */ "execve", /* 59 = execve */ "umask", /* 60 = umask */ "chroot", /* 61 = chroot */ "old.fstat", /* 62 = old fstat */ "old.getkerninfo", /* 63 = old getkerninfo */ "old.getpagesize", /* 64 = old getpagesize */ "msync", /* 65 = msync */ "vfork", /* 66 = vfork */ "obs_vread", /* 67 = obsolete vread */ "obs_vwrite", /* 68 = obsolete vwrite */ "sbrk", /* 69 = sbrk */ "sstk", /* 70 = sstk */ "old.mmap", /* 71 = old mmap */ "vadvise", /* 72 = vadvise */ "munmap", /* 73 = munmap */ "mprotect", /* 74 = mprotect */ "madvise", /* 75 = madvise */ "obs_vhangup", /* 76 = obsolete vhangup */ "obs_vlimit", /* 77 = obsolete vlimit */ "mincore", /* 78 = mincore */ "getgroups", /* 79 = getgroups */ "setgroups", /* 80 = setgroups */ "getpgrp", /* 81 = getpgrp */ "setpgid", /* 82 = setpgid */ "setitimer", /* 83 = setitimer */ "old.wait", /* 84 = old wait */ "swapon", /* 85 = swapon */ "getitimer", /* 86 = getitimer */ "old.gethostname", /* 87 = old gethostname */ "old.sethostname", /* 88 = old sethostname */ "getdtablesize", /* 89 = getdtablesize */ "dup2", /* 90 = dup2 */ "#91", /* 91 = getdopt */ "fcntl", /* 92 = fcntl */ "select", /* 93 = select */ "#94", /* 94 = setdopt */ "fsync", /* 95 = fsync */ "setpriority", /* 96 = setpriority */ "socket", /* 97 = socket */ "connect", /* 98 = connect */ "old.accept", /* 99 = old accept */ "getpriority", /* 100 = getpriority */ "old.send", /* 101 = old send */ "old.recv", /* 102 = old recv */ "sigreturn", /* 103 = sigreturn */ "bind", /* 104 = bind */ "setsockopt", /* 105 = setsockopt */ "listen", /* 106 = listen */ "obs_vtimes", /* 107 = obsolete vtimes */ "old.sigvec", /* 108 = old sigvec */ "old.sigblock", /* 109 = old sigblock */ "old.sigsetmask", /* 110 = old sigsetmask */ "sigsuspend", /* 111 = sigsuspend */ "old.sigstack", /* 112 = old sigstack */ "old.recvmsg", /* 113 = old recvmsg */ "old.sendmsg", /* 114 = old sendmsg */ #ifdef TRACE "vtrace", /* 115 = vtrace */ #else "obs_vtrace", /* 115 = obsolete vtrace */ #endif "gettimeofday", /* 116 = gettimeofday */ "getrusage", /* 117 = getrusage */ "getsockopt", /* 118 = getsockopt */ #ifdef vax "resuba", /* 119 = resuba */ #else "#119", /* 119 = nosys */ #endif "readv", /* 120 = readv */ "writev", /* 121 = writev */ "settimeofday", /* 122 = settimeofday */ "fchown", /* 123 = fchown */ "fchmod", /* 124 = fchmod */ "old.recvfrom", /* 125 = old recvfrom */ "old.setreuid", /* 126 = old setreuid */ "old.setregid", /* 127 = old setregid */ "rename", /* 128 = rename */ "old.truncate", /* 129 = old truncate */ "old.ftruncate", /* 130 = old ftruncate */ "flock", /* 131 = flock */ "mkfifo", /* 132 = mkfifo */ "sendto", /* 133 = sendto */ "shutdown", /* 134 = shutdown */ "socketpair", /* 135 = socketpair */ "mkdir", /* 136 = mkdir */ "rmdir", /* 137 = rmdir */ "utimes", /* 138 = utimes */ "obs_4.2", /* 139 = obsolete 4.2 sigreturn */ "adjtime", /* 140 = adjtime */ "old.getpeername", /* 141 = old getpeername */ "old.gethostid", /* 142 = old gethostid */ "old.sethostid", /* 143 = old sethostid */ "old.getrlimit", /* 144 = old getrlimit */ "old.setrlimit", /* 145 = old setrlimit */ "old.killpg", /* 146 = old killpg */ "setsid", /* 147 = setsid */ "quotactl", /* 148 = quotactl */ "old.quota", /* 149 = old quota */ "old.getsockname", /* 150 = old getsockname */ "#151", /* 151 = nosys */ "#152", /* 152 = nosys */ "#153", /* 153 = nosys */ "#154", /* 154 = nosys */ #ifdef NFS "nfssvc", /* 155 = nfssvc */ #else "#155", /* 155 = nosys */ #endif "old.getdirentries", /* 156 = old getdirentries */ "statfs", /* 157 = statfs */ "fstatfs", /* 158 = fstatfs */ "#159", /* 159 = nosys */ "#160", /* 160 = nosys */ #ifdef NFS "getfh", /* 161 = getfh */ #else "#161", /* 161 = nosys */ #endif "getdomainname", /* 162 = getdomainname */ "setdomainname", /* 163 = setdomainname */ "uname", /* 164 = uname */ "sysarch", /* 165 = sysarch */ "rtprio", /* 166 = rtprio */ "#167", /* 167 = nosys */ "#168", /* 168 = nosys */ +#ifdef SYSVSEM + "semsys", /* 169 = semsys */ +#else "#169", /* 169 = nosys */ +#endif +#ifdef SYSVMSG + "msgsys", /* 170 = msgsys */ +#else "#170", /* 170 = nosys */ +#endif #ifdef SYSVSHM "shmsys", /* 171 = shmsys */ #else "#171", /* 171 = nosys */ #endif "#172", /* 172 = nosys */ "#173", /* 173 = nosys */ "#174", /* 174 = nosys */ "ntp_gettime", /* 175 = ntp_gettime */ "ntp_adjtime", /* 176 = ntp_adjtime */ "#177", /* 177 = nosys */ "#178", /* 178 = nosys */ "#179", /* 179 = nosys */ "#180", /* 180 = nosys */ "setgid", /* 181 = setgid */ "setegid", /* 182 = setegid */ "seteuid", /* 183 = seteuid */ #ifdef LFS "lfs_bmapv", /* 184 = lfs_bmapv */ "lfs_markv", /* 185 = lfs_markv */ "lfs_segclean", /* 186 = lfs_segclean */ "lfs_segwait", /* 187 = lfs_segwait */ #else "#184", /* 184 = nosys */ "#185", /* 185 = nosys */ "#186", /* 186 = nosys */ "#187", /* 187 = nosys */ #endif "stat", /* 188 = stat */ "fstat", /* 189 = fstat */ "lstat", /* 190 = lstat */ "pathconf", /* 191 = pathconf */ "fpathconf", /* 192 = fpathconf */ "#193", /* 193 = nosys */ "getrlimit", /* 194 = getrlimit */ "setrlimit", /* 195 = setrlimit */ "getdirentries", /* 196 = getdirentries */ "mmap", /* 197 = mmap */ "__syscall", /* 198 = __syscall */ "lseek", /* 199 = lseek */ "truncate", /* 200 = truncate */ "ftruncate", /* 201 = ftruncate */ "__sysctl", /* 202 = __sysctl */ "mlock", /* 203 = mlock */ "munlock", /* 204 = munlock */ "#205", /* 205 = nosys */ "#206", /* 206 = nosys */ "#207", /* 207 = nosys */ "#208", /* 208 = nosys */ "#209", /* 209 = nosys */ #ifdef LKM "lkmnosys", /* 210 = lkmnosys */ "lkmnosys", /* 211 = lkmnosys */ "lkmnosys", /* 212 = lkmnosys */ "lkmnosys", /* 213 = lkmnosys */ "lkmnosys", /* 214 = lkmnosys */ "lkmnosys", /* 215 = lkmnosys */ "lkmnosys", /* 216 = lkmnosys */ "lkmnosys", /* 217 = lkmnosys */ "lkmnosys", /* 218 = lkmnosys */ "lkmnosys", /* 219 = lkmnosys */ #else "#210", /* 210 = nosys */ "#211", /* 211 = nosys */ "#212", /* 212 = nosys */ "#213", /* 213 = nosys */ "#214", /* 214 = nosys */ "#215", /* 215 = nosys */ "#216", /* 216 = nosys */ "#217", /* 217 = nosys */ "#218", /* 218 = nosys */ "#219", /* 219 = nosys */ #endif }; Index: head/sys/kern/syscalls.master =================================================================== --- head/sys/kern/syscalls.master (revision 2728) +++ head/sys/kern/syscalls.master (revision 2729) @@ -1,307 +1,315 @@ - $Id: syscalls.master,v 1.6 1994/09/01 05:12:42 davidg Exp $ + $Id: syscalls.master,v 1.7 1994/09/13 00:48:19 wollman Exp $ ; from: @(#)syscalls.master 8.2 (Berkeley) 1/13/94 ; ; System call name/number master file. ; Processed to created init_sysent.c, syscalls.c and syscall.h. ; Columns: number type nargs namespc name altname/comments ; number system call number, must be in order ; type one of STD, OBSOL, UNIMPL, COMPAT ; nargs number of arguments ; namespc one of POSIX, BSD, NOHIDE ; name name of syscall routine ; altname name of system call if different ; for UNIMPL/OBSOL, name continues with comments ; types: ; STD always included ; COMPAT included on COMPAT #ifdef ; LIBCOMPAT included on COMPAT #ifdef, and placed in syscall.h ; OBSOL obsolete, not included in system, only specifies name ; UNIMPL not implemented, placeholder only ; #ifdef's, etc. may be included, and are copied to the output files. ; Reserved/unimplemented system calls in the range 0-150 inclusive ; are reserved for use in future Berkeley releases. ; Additional system calls implemented in vendor and other ; redistributions should be placed in the reserved range at the end ; of the current calls. 0 STD 0 NOHIDE nosys syscall 1 STD 1 NOHIDE exit 2 STD 0 POSIX fork 3 STD 3 POSIX read 4 STD 3 POSIX write 5 STD 3 POSIX open 6 STD 1 POSIX close 7 STD 4 BSD wait4 8 COMPAT 2 BSD creat 9 STD 2 POSIX link 10 STD 1 POSIX unlink 11 OBSOL 2 NOHIDE execv 12 STD 1 POSIX chdir 13 STD 1 BSD fchdir 14 STD 3 POSIX mknod 15 STD 2 POSIX chmod 16 STD 3 POSIX chown 17 STD 1 BSD obreak break 18 STD 3 BSD getfsstat 19 COMPAT 3 POSIX lseek 20 STD 0 POSIX getpid 21 STD 4 BSD mount 22 STD 2 BSD unmount 23 STD 1 POSIX setuid 24 STD 0 POSIX getuid 25 STD 0 POSIX geteuid 26 STD 4 BSD ptrace 27 STD 3 BSD recvmsg 28 STD 3 BSD sendmsg 29 STD 6 BSD recvfrom 30 STD 3 BSD accept 31 STD 3 BSD getpeername 32 STD 3 BSD getsockname 33 STD 2 POSIX access 34 STD 2 BSD chflags 35 STD 2 BSD fchflags 36 STD 0 BSD sync 37 STD 2 POSIX kill 38 COMPAT 2 POSIX stat 39 STD 0 POSIX getppid 40 COMPAT 2 POSIX lstat 41 STD 2 POSIX dup 42 STD 0 POSIX pipe 43 STD 0 POSIX getegid 44 STD 4 BSD profil #ifdef KTRACE 45 STD 4 BSD ktrace #else 45 UNIMPL 0 BSD ktrace #endif 46 STD 3 POSIX sigaction 47 STD 0 POSIX getgid 48 STD 2 POSIX sigprocmask 49 STD 2 BSD getlogin 50 STD 1 BSD setlogin 51 STD 1 BSD acct 52 STD 0 POSIX sigpending 53 STD 2 BSD sigaltstack 54 STD 3 POSIX ioctl 55 STD 1 BSD reboot 56 STD 1 POSIX revoke 57 STD 2 POSIX symlink 58 STD 3 POSIX readlink 59 STD 3 POSIX execve 60 STD 1 POSIX umask 61 STD 1 BSD chroot 62 COMPAT 2 POSIX fstat 63 COMPAT 4 BSD getkerninfo 64 COMPAT 0 BSD getpagesize 65 STD 2 BSD msync 66 STD 0 BSD vfork 67 OBSOL 0 NOHIDE vread 68 OBSOL 0 NOHIDE vwrite 69 STD 1 BSD sbrk 70 STD 1 BSD sstk 71 COMPAT 6 BSD mmap 72 STD 1 BSD ovadvise vadvise 73 STD 2 BSD munmap 74 STD 3 BSD mprotect 75 STD 3 BSD madvise 76 OBSOL 0 NOHIDE vhangup 77 OBSOL 0 NOHIDE vlimit 78 STD 3 BSD mincore 79 STD 2 POSIX getgroups 80 STD 2 POSIX setgroups 81 STD 0 POSIX getpgrp 82 STD 2 POSIX setpgid 83 STD 3 BSD setitimer 84 COMPAT 0 BSD wait 85 STD 1 BSD swapon 86 STD 2 BSD getitimer 87 COMPAT 2 BSD gethostname 88 COMPAT 2 BSD sethostname 89 STD 0 BSD getdtablesize 90 STD 2 POSIX dup2 91 UNIMPL 2 BSD getdopt 92 STD 3 POSIX fcntl 93 STD 5 BSD select 94 UNIMPL 2 BSD setdopt 95 STD 1 POSIX fsync 96 STD 3 BSD setpriority 97 STD 3 BSD socket 98 STD 3 BSD connect 99 COMPAT 3 BSD accept 100 STD 2 BSD getpriority 101 COMPAT 4 BSD send 102 COMPAT 4 BSD recv 103 STD 1 BSD sigreturn 104 STD 3 BSD bind 105 STD 5 BSD setsockopt 106 STD 2 BSD listen 107 OBSOL 0 NOHIDE vtimes 108 COMPAT 3 BSD sigvec 109 COMPAT 1 BSD sigblock 110 COMPAT 1 BSD sigsetmask 111 STD 1 POSIX sigsuspend 112 COMPAT 2 BSD sigstack 113 COMPAT 3 BSD recvmsg 114 COMPAT 3 BSD sendmsg #ifdef TRACE 115 STD 2 BSD vtrace #else 115 OBSOL 2 NOHIDE vtrace #endif 116 STD 2 BSD gettimeofday 117 STD 2 BSD getrusage 118 STD 5 BSD getsockopt #ifdef vax 119 STD 1 BSD resuba #else 119 UNIMPL 0 NOHIDE nosys #endif 120 STD 3 BSD readv 121 STD 3 BSD writev 122 STD 2 BSD settimeofday 123 STD 3 BSD fchown 124 STD 2 BSD fchmod 125 COMPAT 6 BSD recvfrom 126 COMPAT 2 BSD setreuid 127 COMPAT 2 BSD setregid 128 STD 2 POSIX rename 129 COMPAT 2 BSD truncate 130 COMPAT 2 BSD ftruncate 131 STD 2 BSD flock 132 STD 2 POSIX mkfifo 133 STD 6 BSD sendto 134 STD 2 BSD shutdown 135 STD 5 BSD socketpair 136 STD 2 POSIX mkdir 137 STD 1 POSIX rmdir 138 STD 2 BSD utimes 139 OBSOL 0 NOHIDE 4.2 sigreturn 140 STD 2 BSD adjtime 141 COMPAT 3 BSD getpeername 142 COMPAT 0 BSD gethostid 143 COMPAT 1 BSD sethostid 144 COMPAT 2 BSD getrlimit 145 COMPAT 2 BSD setrlimit 146 COMPAT 2 BSD killpg 147 STD 0 POSIX setsid 148 STD 4 BSD quotactl 149 COMPAT 4 BSD quota 150 COMPAT 3 BSD getsockname ; Syscalls 151-180 inclusive are reserved for vendor-specific ; system calls. (This includes various calls added for compatibity ; with other Unix variants.) ; Some of these calls are now supported by BSD... 151 UNIMPL 0 NOHIDE nosys 152 UNIMPL 0 NOHIDE nosys 153 UNIMPL 0 NOHIDE nosys 154 UNIMPL 0 NOHIDE nosys #ifdef NFS 155 STD 2 BSD nfssvc #else 155 UNIMPL 0 BSD nosys #endif 156 COMPAT 4 BSD getdirentries 157 STD 2 BSD statfs 158 STD 2 BSD fstatfs 159 UNIMPL 0 NOHIDE nosys 160 UNIMPL 0 NOHIDE nosys #ifdef NFS 161 STD 2 BSD getfh #else 161 UNIMPL 0 BSD nosys #endif 162 STD 2 BSD getdomainname 163 STD 2 BSD setdomainname 164 STD 1 BSD uname 165 STD 2 BSD sysarch 166 STD 2 BSD rtprio 167 UNIMPL 0 NOHIDE nosys 168 UNIMPL 0 NOHIDE nosys +#ifdef SYSVSEM +169 STD 5 BSD semsys +#else 169 UNIMPL 0 NOHIDE nosys +#endif +#ifdef SYSVMSG +170 STD 6 BSD msgsys +#else 170 UNIMPL 0 NOHIDE nosys +#endif #ifdef SYSVSHM 171 STD 4 BSD shmsys #else 171 UNIMPL 0 BSD nosys #endif 172 UNIMPL 0 NOHIDE nosys 173 UNIMPL 0 NOHIDE nosys 174 UNIMPL 0 NOHIDE nosys 175 STD 1 BSD nosys ntp_gettime 176 STD 1 BSD nosys ntp_adjtime 177 UNIMPL 0 NOHIDE nosys 178 UNIMPL 0 NOHIDE nosys 179 UNIMPL 0 NOHIDE nosys 180 UNIMPL 0 NOHIDE nosys ; Syscalls 180-199 are used by/reserved for BSD 181 STD 1 POSIX setgid 182 STD 1 BSD setegid 183 STD 1 BSD seteuid #ifdef LFS 184 STD 3 BSD lfs_bmapv 185 STD 3 BSD lfs_markv 186 STD 2 BSD lfs_segclean 187 STD 2 BSD lfs_segwait #else 184 UNIMPL 0 BSD nosys 185 UNIMPL 0 BSD nosys 186 UNIMPL 0 BSD nosys 187 UNIMPL 0 BSD nosys #endif 188 STD 2 POSIX stat 189 STD 2 POSIX fstat 190 STD 2 POSIX lstat 191 STD 2 POSIX pathconf 192 STD 2 POSIX fpathconf 193 UNIMPL 0 NOHIDE nosys 194 STD 2 BSD getrlimit 195 STD 2 BSD setrlimit 196 STD 4 BSD getdirentries 197 STD 8 BSD mmap 198 STD 0 NOHIDE nosys __syscall 199 STD 5 POSIX lseek 200 STD 4 BSD truncate 201 STD 4 BSD ftruncate 202 STD 6 BSD __sysctl ; properly, __sysctl should be a NOHIDE, but making an exception ; here allows to avoid one in libc/sys/Makefile.inc. 203 STD 2 BSD mlock 204 STD 2 BSD munlock 205 UNIMPL 0 NOHIDE nosys 206 UNIMPL 0 NOHIDE nosys 207 UNIMPL 0 NOHIDE nosys 208 UNIMPL 0 NOHIDE nosys 209 UNIMPL 0 NOHIDE nosys ; ; The following are reserved for loadable syscalls ; #ifdef LKM 210 NODEF 0 NOHIDE lkmnosys 211 NODEF 0 NOHIDE lkmnosys 212 NODEF 0 NOHIDE lkmnosys 213 NODEF 0 NOHIDE lkmnosys 214 NODEF 0 NOHIDE lkmnosys 215 NODEF 0 NOHIDE lkmnosys 216 NODEF 0 NOHIDE lkmnosys 217 NODEF 0 NOHIDE lkmnosys 218 NODEF 0 NOHIDE lkmnosys 219 NODEF 0 NOHIDE lkmnosys #else 210 UNIMPL 0 NOHIDE nosys 211 UNIMPL 0 NOHIDE nosys 212 UNIMPL 0 NOHIDE nosys 213 UNIMPL 0 NOHIDE nosys 214 UNIMPL 0 NOHIDE nosys 215 UNIMPL 0 NOHIDE nosys 216 UNIMPL 0 NOHIDE nosys 217 UNIMPL 0 NOHIDE nosys 218 UNIMPL 0 NOHIDE nosys 219 UNIMPL 0 NOHIDE nosys #endif Index: head/sys/kern/sysv_ipc.c =================================================================== --- head/sys/kern/sysv_ipc.c (nonexistent) +++ head/sys/kern/sysv_ipc.c (revision 2729) @@ -0,0 +1,69 @@ +/* $Id$ */ +/* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */ + +/* + * Copyright (c) 1994 Herb Peyerl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Herb Peyerl. + * 4. The name of Herb Peyerl may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +/* + * Check for ipc permission + */ + +int +ipcperm(cred, perm, mode) + struct ucred *cred; + struct ipc_perm *perm; + int mode; +{ + + if (cred->cr_uid == 0) + return (0); + + /* Check for user match. */ + if (cred->cr_uid != perm->cuid && cred->cr_uid != perm->uid) { + if (mode & IPC_M) + return (EPERM); + /* Check for group match. */ + mode >>= 3; + if (!groupmember(perm->gid, cred) && + !groupmember(perm->cgid, cred)) + /* Check for `other' match. */ + mode >>= 3; + } + + if (mode & IPC_M) + return (0); + return ((mode & perm->mode) == mode ? 0 : EACCES); +} Property changes on: head/sys/kern/sysv_ipc.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/kern/sysv_msg.c =================================================================== --- head/sys/kern/sysv_msg.c (nonexistent) +++ head/sys/kern/sysv_msg.c (revision 2729) @@ -0,0 +1,1006 @@ +/* $Id$ */ + +/* + * Implementation of SVID messages + * + * Author: Daniel Boulet + * + * Copyright 1993 Daniel Boulet and RTMX Inc. + * + * This system call was implemented by Daniel Boulet under contract from RTMX. + * + * Redistribution and use in source forms, with and without modification, + * are permitted provided that this entire comment appears intact. + * + * Redistribution in binary form may occur without any restrictions. + * Obviously, it would be nice if you gave credit where credit is due + * but requiring it would be too onerous. + * + * This software is provided ``AS IS'' without any warranties of any kind. + */ + +#include +#include +#include +#include +#include +#include + +#define MSG_DEBUG +#undef MSG_DEBUG_OK + +static int msgctl(), msgget(), msgsnd(), msgrcv(); + +int (*msgcalls[])() = { msgctl, msgget, msgsnd, msgrcv }; + +int nfree_msgmaps; /* # of free map entries */ +short free_msgmaps; /* head of linked list of free map entries */ +struct msg *free_msghdrs; /* list of free msg headers */ + +int +msginit() +{ + register int i; + vm_offset_t whocares1, whocares2; + + /* + * msginfo.msgssz should be a power of two for efficiency reasons. + * It is also pretty silly if msginfo.msgssz is less than 8 + * or greater than about 256 so ... + */ + + i = 8; + while (i < 1024 && i != msginfo.msgssz) + i <<= 1; + if (i != msginfo.msgssz) { + printf("msginfo.msgssz=%d (0x%x)\n", msginfo.msgssz, + msginfo.msgssz); + panic("msginfo.msgssz not a small power of 2"); + } + + if (msginfo.msgseg > 32767) { + printf("msginfo.msgseg=%d\n", msginfo.msgseg); + panic("msginfo.msgseg > 32767"); + } + + if (msgmaps == NULL) + panic("msgmaps is NULL"); + + for (i = 0; i < msginfo.msgseg; i++) { + if (i > 0) + msgmaps[i-1].next = i; + msgmaps[i].next = -1; /* implies entry is available */ + } + free_msgmaps = 0; + nfree_msgmaps = msginfo.msgseg; + + if (msghdrs == NULL) + panic("msghdrs is NULL"); + + for (i = 0; i < msginfo.msgtql; i++) { + msghdrs[i].msg_type = 0; + if (i > 0) + msghdrs[i-1].msg_next = &msghdrs[i]; + msghdrs[i].msg_next = NULL; + } + free_msghdrs = &msghdrs[0]; + + if (msqids == NULL) + panic("msqids is NULL"); + + for (i = 0; i < msginfo.msgmni; i++) { + msqids[i].msg_qbytes = 0; /* implies entry is available */ + msqids[i].msg_perm.seq = 0; /* reset to a known value */ + } +} + +/* + * Entry point for all MSG calls + */ + +struct msgsys_args { + u_int which; +}; + +int +msgsys(p, uap, retval) + struct caller *p; + struct msgsys_args *uap; + int *retval; +{ + + if (uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0])) + return (EINVAL); + return ((*msgcalls[uap->which])(p, &uap[1], retval)); +} + +static void +msg_freehdr(msghdr) + struct msg *msghdr; +{ + while (msghdr->msg_ts > 0) { + short next; + if (msghdr->msg_spot < 0 || msghdr->msg_spot >= msginfo.msgseg) + panic("msghdr->msg_spot out of range"); + next = msgmaps[msghdr->msg_spot].next; + msgmaps[msghdr->msg_spot].next = free_msgmaps; + free_msgmaps = msghdr->msg_spot; + nfree_msgmaps++; + msghdr->msg_spot = next; + if (msghdr->msg_ts >= msginfo.msgssz) + msghdr->msg_ts -= msginfo.msgssz; + else + msghdr->msg_ts = 0; + } + if (msghdr->msg_spot != -1) + panic("msghdr->msg_spot != -1"); + msghdr->msg_next = free_msghdrs; + free_msghdrs = msghdr; +} + +struct msgctl_args { + int msqid; + int cmd; + struct msqid_ds *user_msqptr; +}; + +int +msgctl(p, uap, retval) + struct proc *p; + register struct msgctl_args *uap; + int *retval; +{ + int msqid = uap->msqid; + int cmd = uap->cmd; + struct msqid_ds *user_msqptr = uap->user_msqptr; + struct ucred *cred = p->p_ucred; + int i, rval, eval; + struct msqid_ds msqbuf; + register struct msqid_ds *msqptr; + +#ifdef MSG_DEBUG_OK + printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr); +#endif + + msqid = IPCID_TO_IX(msqid); + + if (msqid < 0 || msqid >= msginfo.msgmni) { +#ifdef MSG_DEBUG_OK + printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, + msginfo.msgmni); +#endif + return(EINVAL); + } + + msqptr = &msqids[msqid]; + + if (msqptr->msg_qbytes == 0) { +#ifdef MSG_DEBUG_OK + printf("no such msqid\n"); +#endif + return(EINVAL); + } + if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { +#ifdef MSG_DEBUG_OK + printf("wrong sequence number\n"); +#endif + return(EINVAL); + } + + eval = 0; + rval = 0; + + switch (cmd) { + + case IPC_RMID: + { + struct msg *msghdr; + if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_M))) + return(eval); + /* Free the message headers */ + msghdr = msqptr->msg_first; + while (msghdr != NULL) { + struct msg *msghdr_tmp; + + /* Free the segments of each message */ + msqptr->msg_cbytes -= msghdr->msg_ts; + msqptr->msg_qnum--; + msghdr_tmp = msghdr; + msghdr = msghdr->msg_next; + msg_freehdr(msghdr_tmp); + } + + if (msqptr->msg_cbytes != 0) + panic("msg_cbytes is screwed up"); + if (msqptr->msg_qnum != 0) + panic("msg_qnum is screwed up"); + + msqptr->msg_qbytes = 0; /* Mark it as free */ + + wakeup((caddr_t)msqptr); + } + + break; + + case IPC_SET: + if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_M))) + return(eval); + if ((eval = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0) + return(eval); + if (msqbuf.msg_qbytes > msqptr->msg_qbytes && cred->cr_uid != 0) + return(EPERM); + if (msqbuf.msg_qbytes > msginfo.msgmnb) { +#ifdef MSG_DEBUG_OK + printf("can't increase msg_qbytes beyond %d (truncating)\n", + msginfo.msgmnb); +#endif + msqbuf.msg_qbytes = msginfo.msgmnb; /* silently restrict qbytes to system limit */ + } + if (msqbuf.msg_qbytes == 0) { +#ifdef MSG_DEBUG_OK + printf("can't reduce msg_qbytes to 0\n"); +#endif + return(EINVAL); /* non-standard errno! */ + } + msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */ + msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */ + msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) | + (msqbuf.msg_perm.mode & 0777); + msqptr->msg_qbytes = msqbuf.msg_qbytes; + msqptr->msg_ctime = time.tv_sec; + break; + + case IPC_STAT: + if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_R))) { +#ifdef MSG_DEBUG_OK + printf("requester doesn't have read access\n"); +#endif + return(eval); + } + eval = copyout((caddr_t)msqptr, user_msqptr, + sizeof(struct msqid_ds)); + break; + + default: +#ifdef MSG_DEBUG_OK + printf("invalid command %d\n", cmd); +#endif + return(EINVAL); + } + + if (eval == 0) + *retval = rval; + return(eval); +} + +struct msgget_args { + key_t key; + int msgflg; +}; + +int +msgget(p, uap, retval) + struct proc *p; + register struct msgget_args *uap; + int *retval; +{ + int msqid, eval; + int key = uap->key; + int msgflg = uap->msgflg; + struct ucred *cred = p->p_ucred; + register struct msqid_ds *msqptr; + +#ifdef MSG_DEBUG_OK + printf("msgget(0x%x, 0%o)\n", key, msgflg); +#endif + + if (key != IPC_PRIVATE) { + for (msqid = 0; msqid < msginfo.msgmni; msqid++) { + msqptr = &msqids[msqid]; + if (msqptr->msg_qbytes != 0 && + msqptr->msg_perm.key == key) + break; + } + if (msqid < msginfo.msgmni) { +#ifdef MSG_DEBUG_OK + printf("found public key\n"); +#endif + if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) { +#ifdef MSG_DEBUG_OK + printf("not exclusive\n"); +#endif + return(EEXIST); + } + if ((eval = ipcperm(cred, &msqptr->msg_perm, msgflg & 0700 ))) { +#ifdef MSG_DEBUG_OK + printf("requester doesn't have 0%o access\n", + msgflg & 0700); +#endif + return(eval); + } + goto found; + } + } + +#ifdef MSG_DEBUG_OK + printf("need to allocate the msqid_ds\n"); +#endif + if (key == IPC_PRIVATE || (msgflg & IPC_CREAT)) { + for (msqid = 0; msqid < msginfo.msgmni; msqid++) { + /* + * Look for an unallocated and unlocked msqid_ds. + * msqid_ds's can be locked by msgsnd or msgrcv while + * they are copying the message in/out. We can't + * re-use the entry until they release it. + */ + msqptr = &msqids[msqid]; + if (msqptr->msg_qbytes == 0 && + (msqptr->msg_perm.mode & MSG_LOCKED) == 0) + break; + } + if (msqid == msginfo.msgmni) { +#ifdef MSG_DEBUG_OK + printf("no more msqid_ds's available\n"); +#endif + return(ENOSPC); + } +#ifdef MSG_DEBUG_OK + printf("msqid %d is available\n", msqid); +#endif + msqptr->msg_perm.key = key; + msqptr->msg_perm.cuid = cred->cr_uid; + msqptr->msg_perm.uid = cred->cr_uid; + msqptr->msg_perm.cgid = cred->cr_gid; + msqptr->msg_perm.gid = cred->cr_gid; + msqptr->msg_perm.mode = (msgflg & 0777); + /* Make sure that the returned msqid is unique */ + msqptr->msg_perm.seq++; + msqptr->msg_first = NULL; + msqptr->msg_last = NULL; + msqptr->msg_cbytes = 0; + msqptr->msg_qnum = 0; + msqptr->msg_qbytes = msginfo.msgmnb; + msqptr->msg_lspid = 0; + msqptr->msg_lrpid = 0; + msqptr->msg_stime = 0; + msqptr->msg_rtime = 0; + msqptr->msg_ctime = time.tv_sec; + } else { +#ifdef MSG_DEBUG_OK + printf("didn't find it and wasn't asked to create it\n"); +#endif + return(ENOENT); + } + +found: + /* Construct the unique msqid */ + *retval = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm); + return(0); +} + +struct msgsnd_args { + int msqid; + void *user_msgp; + size_t msgsz; + int msgflg; +}; + +int +msgsnd(p, uap, retval) + struct proc *p; + register struct msgsnd_args *uap; + int *retval; +{ + int msqid = uap->msqid; + void *user_msgp = uap->user_msgp; + size_t msgsz = uap->msgsz; + int msgflg = uap->msgflg; + int segs_needed, eval; + struct ucred *cred = p->p_ucred; + register struct msqid_ds *msqptr; + register struct msg *msghdr; + short next; + +#ifdef MSG_DEBUG_OK + printf("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz, + msgflg); +#endif + + msqid = IPCID_TO_IX(msqid); + + if (msqid < 0 || msqid >= msginfo.msgmni) { +#ifdef MSG_DEBUG_OK + printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, + msginfo.msgmni); +#endif + return(EINVAL); + } + + msqptr = &msqids[msqid]; + if (msqptr->msg_qbytes == 0) { +#ifdef MSG_DEBUG_OK + printf("no such message queue id\n"); +#endif + return(EINVAL); + } + if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { +#ifdef MSG_DEBUG_OK + printf("wrong sequence number\n"); +#endif + return(EINVAL); + } + + if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_W))) { +#ifdef MSG_DEBUG_OK + printf("requester doesn't have write access\n"); +#endif + return(eval); + } + + segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz; +#ifdef MSG_DEBUG_OK + printf("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz, + segs_needed); +#endif + for (;;) { + int need_more_resources = 0; + + /* + * check msgsz + * (inside this loop in case msg_qbytes changes while we sleep) + */ + + if (msgsz < 0 || msgsz > msqptr->msg_qbytes) { +#ifdef MSG_DEBUG_OK + printf("msgsz > msqptr->msg_qbytes\n"); +#endif + return(EINVAL); + } + + if (msqptr->msg_perm.mode & MSG_LOCKED) { +#ifdef MSG_DEBUG_OK + printf("msqid is locked\n"); +#endif + need_more_resources = 1; + } + if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes) { +#ifdef MSG_DEBUG_OK + printf("msgsz + msg_cbytes > msg_qbytes\n"); +#endif + need_more_resources = 1; + } + if (segs_needed > nfree_msgmaps) { +#ifdef MSG_DEBUG_OK + printf("segs_needed > nfree_msgmaps\n"); +#endif + need_more_resources = 1; + } + if (free_msghdrs == NULL) { +#ifdef MSG_DEBUG_OK + printf("no more msghdrs\n"); +#endif + need_more_resources = 1; + } + + if (need_more_resources) { + int we_own_it; + + if ((msgflg & IPC_NOWAIT) != 0) { +#ifdef MSG_DEBUG_OK + printf("need more resources but caller doesn't want to wait\n"); +#endif + return(EAGAIN); + } + + if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) { +#ifdef MSG_DEBUG_OK + printf("we don't own the msqid_ds\n"); +#endif + we_own_it = 0; + } else { + /* Force later arrivals to wait for our + request */ +#ifdef MSG_DEBUG_OK + printf("we own the msqid_ds\n"); +#endif + msqptr->msg_perm.mode |= MSG_LOCKED; + we_own_it = 1; + } +#ifdef MSG_DEBUG_OK + printf("goodnight\n"); +#endif + eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH, + "msgwait", 0); +#ifdef MSG_DEBUG_OK + printf("good morning, eval=%d\n", eval); +#endif + if (we_own_it) + msqptr->msg_perm.mode &= ~MSG_LOCKED; + if (eval != 0) { +#ifdef MSG_DEBUG_OK + printf("msgsnd: interrupted system call\n"); +#endif + return(EINTR); + } + + /* + * Make sure that the msq queue still exists + */ + + if (msqptr->msg_qbytes == 0) { +#ifdef MSG_DEBUG_OK + printf("msqid deleted\n"); +#endif + /* The SVID says to return EIDRM. */ +#ifdef EIDRM + return(EIDRM); +#else + /* Unfortunately, BSD doesn't define that code + yet! */ + return(EINVAL); +#endif + } + + } else { +#ifdef MSG_DEBUG_OK + printf("got all the resources that we need\n"); +#endif + break; + } + } + + /* + * We have the resources that we need. + * Make sure! + */ + + if (msqptr->msg_perm.mode & MSG_LOCKED) + panic("msg_perm.mode & MSG_LOCKED"); + if (segs_needed > nfree_msgmaps) + panic("segs_needed > nfree_msgmaps"); + if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes) + panic("msgsz + msg_cbytes > msg_qbytes"); + if (free_msghdrs == NULL) + panic("no more msghdrs"); + + /* + * Re-lock the msqid_ds in case we page-fault when copying in the + * message + */ + + if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) + panic("msqid_ds is already locked"); + msqptr->msg_perm.mode |= MSG_LOCKED; + + /* + * Allocate a message header + */ + + msghdr = free_msghdrs; + free_msghdrs = msghdr->msg_next; + msghdr->msg_spot = -1; + msghdr->msg_ts = msgsz; + + /* + * Allocate space for the message + */ + + while (segs_needed > 0) { + if (nfree_msgmaps <= 0) + panic("not enough msgmaps"); + if (free_msgmaps == -1) + panic("nil free_msgmaps"); + next = free_msgmaps; + if (next <= -1) + panic("next too low #1"); + if (next >= msginfo.msgseg) + panic("next out of range #1"); +#ifdef MSG_DEBUG_OK + printf("allocating segment %d to message\n", next); +#endif + free_msgmaps = msgmaps[next].next; + nfree_msgmaps--; + msgmaps[next].next = msghdr->msg_spot; + msghdr->msg_spot = next; + segs_needed--; + } + + /* + * Copy in the message type + */ + + if ((eval = copyin(user_msgp, &msghdr->msg_type, + sizeof(msghdr->msg_type))) != 0) { +#ifdef MSG_DEBUG_OK + printf("error %d copying the message type\n", eval); +#endif + msg_freehdr(msghdr); + msqptr->msg_perm.mode &= ~MSG_LOCKED; + wakeup((caddr_t)msqptr); + return(eval); + } + user_msgp += sizeof(msghdr->msg_type); + + /* + * Validate the message type + */ + + if (msghdr->msg_type < 1) { + msg_freehdr(msghdr); + msqptr->msg_perm.mode &= ~MSG_LOCKED; + wakeup((caddr_t)msqptr); +#ifdef MSG_DEBUG_OK + printf("mtype (%d) < 1\n", msghdr->msg_type); +#endif + return(EINVAL); + } + + /* + * Copy in the message body + */ + + next = msghdr->msg_spot; + while (msgsz > 0) { + size_t tlen; + if (msgsz > msginfo.msgssz) + tlen = msginfo.msgssz; + else + tlen = msgsz; + if (next <= -1) + panic("next too low #2"); + if (next >= msginfo.msgseg) + panic("next out of range #2"); + if ((eval = copyin(user_msgp, &msgpool[next * msginfo.msgssz], + tlen)) != 0) { +#ifdef MSG_DEBUG_OK + printf("error %d copying in message segment\n", eval); +#endif + msg_freehdr(msghdr); + msqptr->msg_perm.mode &= ~MSG_LOCKED; + wakeup((caddr_t)msqptr); + return(eval); + } + msgsz -= tlen; + user_msgp += tlen; + next = msgmaps[next].next; + } + if (next != -1) + panic("didn't use all the msg segments"); + + /* + * We've got the message. Unlock the msqid_ds. + */ + + msqptr->msg_perm.mode &= ~MSG_LOCKED; + + /* + * Make sure that the msqid_ds is still allocated. + */ + + if (msqptr->msg_qbytes == 0) { + msg_freehdr(msghdr); + wakeup((caddr_t)msqptr); + /* The SVID says to return EIDRM. */ +#ifdef EIDRM + return(EIDRM); +#else + /* Unfortunately, BSD doesn't define that code yet! */ + return(EINVAL); +#endif + } + + /* + * Put the message into the queue + */ + + if (msqptr->msg_first == NULL) { + msqptr->msg_first = msghdr; + msqptr->msg_last = msghdr; + } else { + msqptr->msg_last->msg_next = msghdr; + msqptr->msg_last = msghdr; + } + msqptr->msg_last->msg_next = NULL; + + msqptr->msg_cbytes += msghdr->msg_ts; + msqptr->msg_qnum++; + msqptr->msg_lspid = p->p_pid; + msqptr->msg_stime = time.tv_sec; + + wakeup((caddr_t)msqptr); + *retval = 0; + return(0); +} + +struct msgrcv_args { + int msqid; + void *msgp; + size_t msgsz; + long msgtyp; + int msgflg; +}; + +int +msgrcv(p, uap, retval) + struct proc *p; + register struct msgrcv_args *uap; + int *retval; +{ + int msqid = uap->msqid; + void *user_msgp = uap->msgp; + size_t msgsz = uap->msgsz; + long msgtyp = uap->msgtyp; + int msgflg = uap->msgflg; + size_t len; + struct ucred *cred = p->p_ucred; + register struct msqid_ds *msqptr; + register struct msg *msghdr; + int eval; + short next; + +#ifdef MSG_DEBUG_OK + printf("call to msgrcv(%d, 0x%x, %d, %ld, %d)\n", msqid, user_msgp, + msgsz, msgtyp, msgflg); +#endif + + msqid = IPCID_TO_IX(msqid); + + if (msqid < 0 || msqid >= msginfo.msgmni) { +#ifdef MSG_DEBUG_OK + printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid, + msginfo.msgmni); +#endif + return(EINVAL); + } + + msqptr = &msqids[msqid]; + if (msqptr->msg_qbytes == 0) { +#ifdef MSG_DEBUG_OK + printf("no such message queue id\n"); +#endif + return(EINVAL); + } + if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { +#ifdef MSG_DEBUG_OK + printf("wrong sequence number\n"); +#endif + return(EINVAL); + } + + if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_R))) { +#ifdef MSG_DEBUG_OK + printf("requester doesn't have read access\n"); +#endif + return(eval); + } + + if (msgsz < 0) { +#ifdef MSG_DEBUG_OK + printf("msgsz < 0\n"); +#endif + return(EINVAL); + } + + msghdr = NULL; + while (msghdr == NULL) { + if (msgtyp == 0) { + msghdr = msqptr->msg_first; + if (msghdr != NULL) { + if (msgsz < msghdr->msg_ts && + (msgflg & MSG_NOERROR) == 0) { +#ifdef MSG_DEBUG_OK + printf("first message on the queue is too big (want %d, got %d)\n", + msgsz, msghdr->msg_ts); +#endif + return(E2BIG); + } + if (msqptr->msg_first == msqptr->msg_last) { + msqptr->msg_first = NULL; + msqptr->msg_last = NULL; + } else { + msqptr->msg_first = msghdr->msg_next; + if (msqptr->msg_first == NULL) + panic("msg_first/last screwed up #1"); + } + } + } else { + struct msg *previous; + struct msg **prev; + + previous = NULL; + prev = &(msqptr->msg_first); + while ((msghdr = *prev) != NULL) { + /* + * Is this message's type an exact match or is + * this message's type less than or equal to + * the absolute value of a negative msgtyp? + * Note that the second half of this test can + * NEVER be true if msgtyp is positive since + * msg_type is always positive! + */ + + if (msgtyp == msghdr->msg_type || + msghdr->msg_type <= -msgtyp) { +#ifdef MSG_DEBUG_OK + printf("found message type %d, requested %d\n", + msghdr->msg_type, msgtyp); +#endif + if (msgsz < msghdr->msg_ts && + (msgflg & MSG_NOERROR) == 0) { +#ifdef MSG_DEBUG_OK + printf("requested message on the queue is too big (want %d, got %d)\n", + msgsz, msghdr->msg_ts); +#endif + return(E2BIG); + } + *prev = msghdr->msg_next; + if (msghdr == msqptr->msg_last) { + if (previous == NULL) { + if (prev != + &msqptr->msg_first) + panic("msg_first/last screwed up #2"); + msqptr->msg_first = + NULL; + msqptr->msg_last = + NULL; + } else { + if (prev == + &msqptr->msg_first) + panic("msg_first/last screwed up #3"); + msqptr->msg_last = + previous; + } + } + break; + } + previous = msghdr; + prev = &(msghdr->msg_next); + } + } + + /* + * We've either extracted the msghdr for the appropriate + * message or there isn't one. + * If there is one then bail out of this loop. + */ + + if (msghdr != NULL) + break; + + /* + * Hmph! No message found. Does the user want to wait? + */ + + if ((msgflg & IPC_NOWAIT) != 0) { +#ifdef MSG_DEBUG_OK + printf("no appropriate message found (msgtyp=%d)\n", + msgtyp); +#endif + /* The SVID says to return ENOMSG. */ +#ifdef ENOMSG + return(ENOMSG); +#else + /* Unfortunately, BSD doesn't define that code yet! */ + return(EAGAIN); +#endif + } + + /* + * Wait for something to happen + */ + +#ifdef MSG_DEBUG_OK + printf("msgrcv: goodnight\n"); +#endif + eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH, "msgwait", + 0); +#ifdef MSG_DEBUG_OK + printf("msgrcv: good morning (eval=%d)\n", eval); +#endif + + if (eval != 0) { +#ifdef MSG_DEBUG_OK + printf("msgsnd: interrupted system call\n"); +#endif + return(EINTR); + } + + /* + * Make sure that the msq queue still exists + */ + + if (msqptr->msg_qbytes == 0 || + msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) { +#ifdef MSG_DEBUG_OK + printf("msqid deleted\n"); +#endif + /* The SVID says to return EIDRM. */ +#ifdef EIDRM + return(EIDRM); +#else + /* Unfortunately, BSD doesn't define that code yet! */ + return(EINVAL); +#endif + } + } + + /* + * Return the message to the user. + * + * First, do the bookkeeping (before we risk being interrupted). + */ + + msqptr->msg_cbytes -= msghdr->msg_ts; + msqptr->msg_qnum--; + msqptr->msg_lrpid = p->p_pid; + msqptr->msg_rtime = time.tv_sec; + + /* + * Make msgsz the actual amount that we'll be returning. + * Note that this effectively truncates the message if it is too long + * (since msgsz is never increased). + */ + +#ifdef MSG_DEBUG_OK + printf("found a message, msgsz=%d, msg_ts=%d\n", msgsz, + msghdr->msg_ts); +#endif + if (msgsz > msghdr->msg_ts) + msgsz = msghdr->msg_ts; + + /* + * Return the type to the user. + */ + + eval = copyout((caddr_t)&(msghdr->msg_type), user_msgp, + sizeof(msghdr->msg_type)); + if (eval != 0) { +#ifdef MSG_DEBUG_OK + printf("error (%d) copying out message type\n", eval); +#endif + msg_freehdr(msghdr); + wakeup((caddr_t)msqptr); + return(eval); + } + user_msgp += sizeof(msghdr->msg_type); + + /* + * Return the segments to the user + */ + + next = msghdr->msg_spot; + for (len = 0; len < msgsz; len += msginfo.msgssz) { + size_t tlen; + + if (msgsz > msginfo.msgssz) + tlen = msginfo.msgssz; + else + tlen = msgsz; + if (next <= -1) + panic("next too low #3"); + if (next >= msginfo.msgseg) + panic("next out of range #3"); + eval = copyout((caddr_t)&msgpool[next * msginfo.msgssz], + user_msgp, tlen); + if (eval != 0) { +#ifdef MSG_DEBUG_OK + printf("error (%d) copying out message segment\n", + eval); +#endif + msg_freehdr(msghdr); + wakeup((caddr_t)msqptr); + return(eval); + } + user_msgp += tlen; + next = msgmaps[next].next; + } + + /* + * Done, return the actual number of bytes copied out. + */ + + msg_freehdr(msghdr); + wakeup((caddr_t)msqptr); + *retval = msgsz; + return(0); +} Property changes on: head/sys/kern/sysv_msg.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/kern/sysv_sem.c =================================================================== --- head/sys/kern/sysv_sem.c (nonexistent) +++ head/sys/kern/sysv_sem.c (revision 2729) @@ -0,0 +1,939 @@ +/* $Id$ */ + +/* + * Implementation of SVID semaphores + * + * Author: Daniel Boulet + * + * This software is provided ``AS IS'' without any warranties of any kind. + */ + +#include +#include +#include +#include +#include +#include + +static int semctl(), semget(), semop(), semconfig(); +int (*semcalls[])() = { semctl, semget, semop, semconfig }; +int semtot = 0; + +static struct proc *semlock_holder = NULL; + +int +seminit() +{ + register int i; + vm_offset_t whocares1, whocares2; + + if (sema == NULL) + panic("sema is NULL"); + if (semu == NULL) + panic("semu is NULL"); + + for (i = 0; i < seminfo.semmni; i++) { + sema[i].sem_base = 0; + sema[i].sem_perm.mode = 0; + } + for (i = 0; i < seminfo.semmnu; i++) { + register struct sem_undo *suptr = SEMU(i); + suptr->un_proc = NULL; + } + semu_list = NULL; +} + +/* + * Entry point for all SEM calls + */ + +struct semsys_args { + u_int which; +}; + +int +semsys(p, uap, retval) + struct proc *p; + struct semsys_args *uap; + int *retval; +{ + + while (semlock_holder != NULL && semlock_holder != p) + sleep((caddr_t)&semlock_holder, (PZERO - 4)); + + if (uap->which >= sizeof(semcalls)/sizeof(semcalls[0])) + return (EINVAL); + return ((*semcalls[uap->which])(p, &uap[1], retval)); +} + +/* + * Lock or unlock the entire semaphore facility. + * + * This will probably eventually evolve into a general purpose semaphore + * facility status enquiry mechanism (I don't like the "read /dev/kmem" + * approach currently taken by ipcs and the amount of info that we want + * to be able to extract for ipcs is probably beyond what the capability + * of the getkerninfo facility. + * + * At the time that the current version of semconfig was written, ipcs is + * the only user of the semconfig facility. It uses it to ensure that the + * semaphore facility data structures remain static while it fishes around + * in /dev/kmem. + */ + +struct semconfig_args { + semconfig_ctl_t flag; +}; + +int +semconfig(p, uap, retval) + struct proc *p; + struct semconfig_args *uap; + int *retval; +{ + int eval = 0; + + switch (uap->flag) { + case SEM_CONFIG_FREEZE: + semlock_holder = p; + break; + + case SEM_CONFIG_THAW: + semlock_holder = NULL; + wakeup((caddr_t)&semlock_holder); + break; + + default: + printf("semconfig: unknown flag parameter value (%d) - ignored\n", + uap->flag); + eval = EINVAL; + break; + } + + *retval = 0; + return(eval); +} + +/* + * Allocate a new sem_undo structure for a process + * (returns ptr to structure or NULL if no more room) + */ + +struct sem_undo * +semu_alloc(p) + struct proc *p; +{ + register int i; + register struct sem_undo *suptr; + register struct sem_undo **supptr; + int attempt; + + /* + * Try twice to allocate something. + * (we'll purge any empty structures after the first pass so + * two passes are always enough) + */ + + for (attempt = 0; attempt < 2; attempt++) { + /* + * Look for a free structure. + * Fill it in and return it if we find one. + */ + + for (i = 0; i < seminfo.semmnu; i++) { + suptr = SEMU(i); + if (suptr->un_proc == NULL) { + suptr->un_next = semu_list; + semu_list = suptr; + suptr->un_cnt = 0; + suptr->un_proc = p; + return(suptr); + } + } + + /* + * We didn't find a free one, if this is the first attempt + * then try to free some structures. + */ + + if (attempt == 0) { + /* All the structures are in use - try to free some */ + int did_something = 0; + + supptr = &semu_list; + while ((suptr = *supptr) != NULL) { + if (suptr->un_cnt == 0) { + suptr->un_proc = NULL; + *supptr = suptr->un_next; + did_something = 1; + } else + supptr = &(suptr->un_next); + } + + /* If we didn't free anything then just give-up */ + if (!did_something) + return(NULL); + } else { + /* + * The second pass failed even though we freed + * something after the first pass! + * This is IMPOSSIBLE! + */ + panic("semu_alloc - second attempt failed"); + } + } +} + +/* + * Adjust a particular entry for a particular proc + */ + +int +semundo_adjust(p, supptr, semid, semnum, adjval) + register struct proc *p; + struct sem_undo **supptr; + int semid, semnum; + int adjval; +{ + register struct sem_undo *suptr; + register struct undo *sunptr; + int i; + + /* Look for and remember the sem_undo if the caller doesn't provide + it */ + + suptr = *supptr; + if (suptr == NULL) { + for (suptr = semu_list; suptr != NULL; + suptr = suptr->un_next) { + if (suptr->un_proc == p) { + *supptr = suptr; + break; + } + } + if (suptr == NULL) { + if (adjval == 0) + return(0); + suptr = semu_alloc(p); + if (suptr == NULL) + return(ENOSPC); + *supptr = suptr; + } + } + + /* + * Look for the requested entry and adjust it (delete if adjval becomes + * 0). + */ + sunptr = &suptr->un_ent[0]; + for (i = 0; i < suptr->un_cnt; i++, sunptr++) { + if (sunptr->un_id != semid || sunptr->un_num != semnum) + continue; + if (adjval == 0) + sunptr->un_adjval = 0; + else + sunptr->un_adjval += adjval; + if (sunptr->un_adjval == 0) { + suptr->un_cnt--; + if (i < suptr->un_cnt) + suptr->un_ent[i] = + suptr->un_ent[suptr->un_cnt]; + } + return(0); + } + + /* Didn't find the right entry - create it */ + if (adjval == 0) + return(0); + if (suptr->un_cnt != SEMUME) { + sunptr = &suptr->un_ent[suptr->un_cnt]; + suptr->un_cnt++; + sunptr->un_adjval = adjval; + sunptr->un_id = semid; sunptr->un_num = semnum; + } else + return(EINVAL); + return(0); +} + +void +semundo_clear(semid, semnum) + int semid, semnum; +{ + register struct sem_undo *suptr; + + for (suptr = semu_list; suptr != NULL; suptr = suptr->un_next) { + register struct undo *sunptr = &suptr->un_ent[0]; + register int i = 0; + + while (i < suptr->un_cnt) { + if (sunptr->un_id == semid) { + if (semnum == -1 || sunptr->un_num == semnum) { + suptr->un_cnt--; + if (i < suptr->un_cnt) { + suptr->un_ent[i] = + suptr->un_ent[suptr->un_cnt]; + continue; + } + } + if (semnum != -1) + break; + } + i++, sunptr++; + } + } +} + +struct semctl_args { + int semid; + int semnum; + int cmd; + union semun *arg; +}; + +int +semctl(p, uap, retval) + struct proc *p; + register struct semctl_args *uap; + int *retval; +{ + int semid = uap->semid; + int semnum = uap->semnum; + int cmd = uap->cmd; + union semun *arg = uap->arg; + union semun real_arg; + struct ucred *cred = p->p_ucred; + int i, rval, eval; + struct semid_ds sbuf; + register struct semid_ds *semaptr; + +#ifdef SEM_DEBUG + printf("call to semctl(%d, %d, %d, 0x%x)\n", semid, semnum, cmd, arg); +#endif + + semid = IPCID_TO_IX(semid); + if (semid < 0 || semid >= seminfo.semmsl) + return(EINVAL); + + semaptr = &sema[semid]; + if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || + semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) + return(EINVAL); + + eval = 0; + rval = 0; + + switch (cmd) { + case IPC_RMID: + if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M))) + return(eval); + semaptr->sem_perm.cuid = cred->cr_uid; + semaptr->sem_perm.uid = cred->cr_uid; + semtot -= semaptr->sem_nsems; + for (i = semaptr->sem_base - sem; i < semtot; i++) + sem[i] = sem[i + semaptr->sem_nsems]; + for (i = 0; i < seminfo.semmni; i++) { + if ((sema[i].sem_perm.mode & SEM_ALLOC) && + sema[i].sem_base > semaptr->sem_base) + sema[i].sem_base -= semaptr->sem_nsems; + } + semaptr->sem_perm.mode = 0; + semundo_clear(semid, -1); + wakeup((caddr_t)semaptr); + break; + + case IPC_SET: + if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M))) + return(eval); + if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return(eval); + if ((eval = copyin(real_arg.buf, (caddr_t)&sbuf, + sizeof(sbuf))) != 0) + return(eval); + semaptr->sem_perm.uid = sbuf.sem_perm.uid; + semaptr->sem_perm.gid = sbuf.sem_perm.gid; + semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) | + (sbuf.sem_perm.mode & 0777); + semaptr->sem_ctime = time.tv_sec; + break; + + case IPC_STAT: + if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(eval); + if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return(eval); + eval = copyout((caddr_t)semaptr, real_arg.buf, + sizeof(struct semid_ds)); + break; + + case GETNCNT: + if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(eval); + if (semnum < 0 || semnum >= semaptr->sem_nsems) + return(EINVAL); + rval = semaptr->sem_base[semnum].semncnt; + break; + + case GETPID: + if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(eval); + if (semnum < 0 || semnum >= semaptr->sem_nsems) + return(EINVAL); + rval = semaptr->sem_base[semnum].sempid; + break; + + case GETVAL: + if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(eval); + if (semnum < 0 || semnum >= semaptr->sem_nsems) + return(EINVAL); + rval = semaptr->sem_base[semnum].semval; + break; + + case GETALL: + if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(eval); + if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return(eval); + for (i = 0; i < semaptr->sem_nsems; i++) { + eval = copyout((caddr_t)&semaptr->sem_base[i].semval, + &real_arg.array[i], sizeof(real_arg.array[0])); + if (eval != 0) + break; + } + break; + + case GETZCNT: + if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R))) + return(eval); + if (semnum < 0 || semnum >= semaptr->sem_nsems) + return(EINVAL); + rval = semaptr->sem_base[semnum].semzcnt; + break; + + case SETVAL: + if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) + return(eval); + if (semnum < 0 || semnum >= semaptr->sem_nsems) + return(EINVAL); + if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return(eval); + semaptr->sem_base[semnum].semval = real_arg.val; + semundo_clear(semid, semnum); + wakeup((caddr_t)semaptr); + break; + + case SETALL: + if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) + return(eval); + if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0) + return(eval); + for (i = 0; i < semaptr->sem_nsems; i++) { + eval = copyin(&real_arg.array[i], + (caddr_t)&semaptr->sem_base[i].semval, + sizeof(real_arg.array[0])); + if (eval != 0) + break; + } + semundo_clear(semid, -1); + wakeup((caddr_t)semaptr); + break; + + default: + return(EINVAL); + } + + if (eval == 0) + *retval = rval; + return(eval); +} + +struct semget_args { + key_t key; + int nsems; + int semflg; +}; + +int +semget(p, uap, retval) + struct proc *p; + register struct semget_args *uap; + int *retval; +{ + int semid, eval; + int key = uap->key; + int nsems = uap->nsems; + int semflg = uap->semflg; + struct ucred *cred = p->p_ucred; + +#ifdef SEM_DEBUG + printf("semget(0x%x, %d, 0%o)\n", key, nsems, semflg); +#endif + + if (key != IPC_PRIVATE) { + for (semid = 0; semid < seminfo.semmni; semid++) { + if ((sema[semid].sem_perm.mode & SEM_ALLOC) && + sema[semid].sem_perm.key == key) + break; + } + if (semid < seminfo.semmni) { +#ifdef SEM_DEBUG + printf("found public key\n"); +#endif + if ((eval = ipcperm(cred, &sema[semid].sem_perm, + semflg & 0700))) + return(eval); + if (nsems > 0 && sema[semid].sem_nsems < nsems) { +#ifdef SEM_DEBUG + printf("too small\n"); +#endif + return(EINVAL); + } + if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) { +#ifdef SEM_DEBUG + printf("not exclusive\n"); +#endif + return(EEXIST); + } + goto found; + } + } + +#ifdef SEM_DEBUG + printf("need to allocate the semid_ds\n"); +#endif + if (key == IPC_PRIVATE || (semflg & IPC_CREAT)) { + if (nsems <= 0 || nsems > seminfo.semmsl) { +#ifdef SEM_DEBUG + printf("nsems out of range (0<%d<=%d)\n", nsems, + seminfo.semmsl); +#endif + return(EINVAL); + } + if (nsems > seminfo.semmns - semtot) { +#ifdef SEM_DEBUG + printf("not enough semaphores left (need %d, got %d)\n", + nsems, seminfo.semmns - semtot); +#endif + return(ENOSPC); + } + for (semid = 0; semid < seminfo.semmni; semid++) { + if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0) + break; + } + if (semid == seminfo.semmni) { +#ifdef SEM_DEBUG + printf("no more semid_ds's available\n"); +#endif + return(ENOSPC); + } +#ifdef SEM_DEBUG + printf("semid %d is available\n", semid); +#endif + sema[semid].sem_perm.key = key; + sema[semid].sem_perm.cuid = cred->cr_uid; + sema[semid].sem_perm.uid = cred->cr_uid; + sema[semid].sem_perm.cgid = cred->cr_gid; + sema[semid].sem_perm.gid = cred->cr_gid; + sema[semid].sem_perm.mode = (semflg & 0777) | SEM_ALLOC; + sema[semid].sem_perm.seq = + (sema[semid].sem_perm.seq + 1) & 0x7fff; + sema[semid].sem_nsems = nsems; + sema[semid].sem_otime = 0; + sema[semid].sem_ctime = time.tv_sec; + sema[semid].sem_base = &sem[semtot]; + semtot += nsems; + bzero(sema[semid].sem_base, + sizeof(sema[semid].sem_base[0])*nsems); +#ifdef SEM_DEBUG + printf("sembase = 0x%x, next = 0x%x\n", sema[semid].sem_base, + &sem[semtot]); +#endif + } else { +#ifdef SEM_DEBUG + printf("didn't find it and wasn't asked to create it\n"); +#endif + return(ENOENT); + } + +found: + *retval = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm); + return(0); +} + +struct semop_args { + int semid; + struct sembuf *sops; + int nsops; +}; + +int +semop(p, uap, retval) + struct proc *p; + register struct semop_args *uap; + int *retval; +{ + int semid = uap->semid; + int nsops = uap->nsops; + struct sembuf sops[MAX_SOPS]; + register struct semid_ds *semaptr; + register struct sembuf *sopptr; + register struct sem *semptr; + struct sem_undo *suptr = NULL; + struct ucred *cred = p->p_ucred; + int i, j, eval; + int all_ok, do_wakeup, do_undos; + +#ifdef SEM_DEBUG + printf("call to semop(%d, 0x%x, %d)\n", semid, sops, nsops); +#endif + + semid = IPCID_TO_IX(semid); /* Convert back to zero origin */ + + if (semid < 0 || semid >= seminfo.semmsl) + return(EINVAL); + + semaptr = &sema[semid]; + if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) + return(EINVAL); + if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) + return(EINVAL); + + if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) { +#ifdef SEM_DEBUG + printf("eval = %d from ipaccess\n", eval); +#endif + return(eval); + } + + if (nsops > MAX_SOPS) { +#ifdef SEM_DEBUG + printf("too many sops (max=%d, nsops=%d)\n", MAX_SOPS, nsops); +#endif + return(E2BIG); + } + + if ((eval = copyin(uap->sops, &sops, nsops * sizeof(sops[0]))) != 0) { +#ifdef SEM_DEBUG + printf("eval = %d from copyin(%08x, %08x, %d)\n", eval, + uap->sops, &sops, nsops * sizeof(sops[0])); +#endif + return(eval); + } + + /* + * Loop trying to satisfy the vector of requests. + * If we reach a point where we must wait, any requests already + * performed are rolled back and we go to sleep until some other + * process wakes us up. At this point, we start all over again. + * + * This ensures that from the perspective of other tasks, a set + * of requests is atomic (never partially satisfied). + */ + do_undos = 0; + + for (;;) { + do_wakeup = 0; + + for (i = 0; i < nsops; i++) { + sopptr = &sops[i]; + + if (sopptr->sem_num >= semaptr->sem_nsems) + return(EFBIG); + + semptr = &semaptr->sem_base[sopptr->sem_num]; + +#ifdef SEM_DEBUG + printf("semop: semaptr=%x, sem_base=%x, semptr=%x, sem[%d]=%d : op=%d, flag=%s\n", + semaptr, semaptr->sem_base, semptr, + sopptr->sem_num, semptr->semval, sopptr->sem_op, + (sopptr->sem_flg & IPC_NOWAIT) ? "nowait" : "wait"); +#endif + + if (sopptr->sem_op < 0) { + if (semptr->semval + sopptr->sem_op < 0) { +#ifdef SEM_DEBUG + printf("semop: can't do it now\n"); +#endif + break; + } else { + semptr->semval += sopptr->sem_op; + if (semptr->semval == 0 && + semptr->semzcnt > 0) + do_wakeup = 1; + } + if (sopptr->sem_flg & SEM_UNDO) + do_undos = 1; + } else if (sopptr->sem_op == 0) { + if (semptr->semval > 0) { +#ifdef SEM_DEBUG + printf("semop: not zero now\n"); +#endif + break; + } + } else { + if (semptr->semncnt > 0) + do_wakeup = 1; + semptr->semval += sopptr->sem_op; + if (sopptr->sem_flg & SEM_UNDO) + do_undos = 1; + } + } + + /* + * Did we get through the entire vector? + */ + if (i >= nsops) + goto done; + + /* + * No ... rollback anything that we've already done + */ +#ifdef SEM_DEBUG + printf("semop: rollback 0 through %d\n", i-1); +#endif + for (j = 0; j < i; j++) + semaptr->sem_base[sops[j].sem_num].semval -= + sops[j].sem_op; + + /* + * If the request that we couldn't satisfy has the + * NOWAIT flag set then return with EAGAIN. + */ + if (sopptr->sem_flg & IPC_NOWAIT) + return(EAGAIN); + + if (sopptr->sem_op == 0) + semptr->semzcnt++; + else + semptr->semncnt++; + +#ifdef SEM_DEBUG + printf("semop: good night!\n"); +#endif + eval = tsleep((caddr_t)semaptr, (PZERO - 4) | PCATCH, + "semwait", 0); +#ifdef SEM_DEBUG + printf("semop: good morning (eval=%d)!\n", eval); +#endif + + suptr = NULL; /* sem_undo may have been reallocated */ + + if (eval != 0) + return(EINTR); +#ifdef SEM_DEBUG + printf("semop: good morning!\n"); +#endif + + /* + * Make sure that the semaphore still exists + */ + if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || + semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { + /* The man page says to return EIDRM. */ + /* Unfortunately, BSD doesn't define that code! */ +#ifdef EIDRM + return(EIDRM); +#else + return(EINVAL); +#endif + } + + /* + * The semaphore is still alive. Readjust the count of + * waiting processes. + */ + if (sopptr->sem_op == 0) + semptr->semzcnt--; + else + semptr->semncnt--; + } + +done: + /* + * Process any SEM_UNDO requests. + */ + if (do_undos) { + for (i = 0; i < nsops; i++) { + /* + * We only need to deal with SEM_UNDO's for non-zero + * op's. + */ + int adjval; + + if ((sops[i].sem_flg & SEM_UNDO) == 0) + continue; + adjval = sops[i].sem_op; + if (adjval == 0) + continue; + eval = semundo_adjust(p, &suptr, semid, + sops[i].sem_num, -adjval); + if (eval == 0) + continue; + + /* + * Oh-Oh! We ran out of either sem_undo's or undo's. + * Rollback the adjustments to this point and then + * rollback the semaphore ups and down so we can return + * with an error with all structures restored. We + * rollback the undo's in the exact reverse order that + * we applied them. This guarantees that we won't run + * out of space as we roll things back out. + */ + for (j = i - 1; j >= 0; j--) { + if ((sops[j].sem_flg & SEM_UNDO) == 0) + continue; + adjval = sops[j].sem_op; + if (adjval == 0) + continue; + if (semundo_adjust(p, &suptr, semid, + sops[j].sem_num, adjval) != 0) + panic("semop - can't undo undos"); + } + + for (j = 0; j < nsops; j++) + semaptr->sem_base[sops[j].sem_num].semval -= + sops[j].sem_op; + +#ifdef SEM_DEBUG + printf("eval = %d from semundo_adjust\n", eval); +#endif + return(eval); + } /* loop through the sops */ + } /* if (do_undos) */ + + /* We're definitely done - set the sempid's */ + for (i = 0; i < nsops; i++) { + sopptr = &sops[i]; + semptr = &semaptr->sem_base[sopptr->sem_num]; + semptr->sempid = p->p_pid; + } + + /* Do a wakeup if any semaphore was up'd. */ + if (do_wakeup) { +#ifdef SEM_DEBUG + printf("semop: doing wakeup\n"); +#ifdef SEM_WAKEUP + sem_wakeup((caddr_t)semaptr); +#else + wakeup((caddr_t)semaptr); +#endif + printf("semop: back from wakeup\n"); +#else + wakeup((caddr_t)semaptr); +#endif + } +#ifdef SEM_DEBUG + printf("semop: done\n"); +#endif + *retval = 0; + return(0); +} + +/* + * Go through the undo structures for this process and apply the adjustments to + * semaphores. + */ +semexit(p) + struct proc *p; +{ + register struct sem_undo *suptr; + register struct sem_undo **supptr; + int did_something; + + /* + * If somebody else is holding the global semaphore facility lock + * then sleep until it is released. + */ + while (semlock_holder != NULL && semlock_holder != p) { +#ifdef SEM_DEBUG + printf("semaphore facility locked - sleeping ...\n"); +#endif + sleep((caddr_t)&semlock_holder, (PZERO - 4)); + } + + did_something = 0; + + /* + * Go through the chain of undo vectors looking for one + * associated with this process. + */ + + for (supptr = &semu_list; (suptr = *supptr) != NULL; + supptr = &suptr->un_next) { + if (suptr->un_proc == p) + break; + } + + if (suptr == NULL) + goto unlock; + +#ifdef SEM_DEBUG + printf("proc @%08x has undo structure with %d entries\n", p, + suptr->un_cnt); +#endif + + /* + * If there are any active undo elements then process them. + */ + if (suptr->un_cnt > 0) { + int ix; + + for (ix = 0; ix < suptr->un_cnt; ix++) { + int semid = suptr->un_ent[ix].un_id; + int semnum = suptr->un_ent[ix].un_num; + int adjval = suptr->un_ent[ix].un_adjval; + struct semid_ds *semaptr; + + semaptr = &sema[semid]; + if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) + panic("semexit - semid not allocated"); + if (semnum >= semaptr->sem_nsems) + panic("semexit - semnum out of range"); + +#ifdef SEM_DEBUG + printf("semexit: %08x id=%d num=%d(adj=%d) ; sem=%d\n", + suptr->un_proc, suptr->un_ent[ix].un_id, + suptr->un_ent[ix].un_num, + suptr->un_ent[ix].un_adjval, + semaptr->sem_base[semnum].semval); +#endif + + if (adjval < 0) { + if (semaptr->sem_base[semnum].semval < -adjval) + semaptr->sem_base[semnum].semval = 0; + else + semaptr->sem_base[semnum].semval += + adjval; + } else + semaptr->sem_base[semnum].semval += adjval; + +#ifdef SEM_WAKEUP + sem_wakeup((caddr_t)semaptr); +#else + wakeup((caddr_t)semaptr); +#endif +#ifdef SEM_DEBUG + printf("semexit: back from wakeup\n"); +#endif + } + } + + /* + * Deallocate the undo vector. + */ +#ifdef SEM_DEBUG + printf("removing vector\n"); +#endif + suptr->un_proc = NULL; + *supptr = suptr->un_next; + +unlock: + /* + * If the exiting process is holding the global semaphore facility + * lock then release it. + */ + if (semlock_holder == p) { + semlock_holder = NULL; + wakeup((caddr_t)&semlock_holder); + } +} Property changes on: head/sys/kern/sysv_sem.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/kern/sysv_shm.c =================================================================== --- head/sys/kern/sysv_shm.c (nonexistent) +++ head/sys/kern/sysv_shm.c (revision 2729) @@ -0,0 +1,517 @@ +/* $Id$ */ +/* $NetBSD: sysv_shm.c,v 1.23 1994/07/04 23:25:12 glass Exp $ */ + +/* + * Copyright (c) 1994 Adam Glass and Charles Hannum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Glass and Charles + * Hannum. + * 4. The names of the authors may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * Provides the following externally accessible functions: + * + * shminit(void); initialization + * shmexit(struct proc *) cleanup + * shmfork(struct proc *, struct proc *, int) fork handling + * shmsys(arg1, arg2, arg3, arg4); shm{at,ctl,dt,get}(arg2, arg3, arg4) + * + * Structures: + * shmsegs (an array of 'struct shmid_ds') + * per proc array of 'struct shmmap_state' + */ + +int shmat(), shmctl(), shmdt(), shmget(); +int (*shmcalls[])() = { shmat, shmctl, shmdt, shmget }; + +#define SHMSEG_FREE 0x0200 +#define SHMSEG_REMOVED 0x0400 +#define SHMSEG_ALLOCATED 0x0800 +#define SHMSEG_WANTED 0x1000 + +vm_map_t sysvshm_map; +int shm_last_free, shm_nused, shm_committed; + +struct shm_handle { + vm_offset_t kva; +}; + +struct shmmap_state { + vm_offset_t va; + int shmid; +}; + +static void shm_deallocate_segment __P((struct shmid_ds *)); +static int shm_find_segment_by_key __P((key_t)); +static struct shmid_ds *shm_find_segment_by_shmid __P((int)); +static int shm_delete_mapping __P((struct proc *, struct shmmap_state *)); + +static int +shm_find_segment_by_key(key) + key_t key; +{ + int i; + + for (i = 0; i < shminfo.shmmni; i++) + if ((shmsegs[i].shm_perm.mode & SHMSEG_ALLOCATED) && + shmsegs[i].shm_perm.key == key) + return i; + return -1; +} + +static struct shmid_ds * +shm_find_segment_by_shmid(shmid) + int shmid; +{ + int segnum; + struct shmid_ds *shmseg; + + segnum = IPCID_TO_IX(shmid); + if (segnum < 0 || segnum >= shminfo.shmmni) + return NULL; + shmseg = &shmsegs[segnum]; + if ((shmseg->shm_perm.mode & (SHMSEG_ALLOCATED | SHMSEG_REMOVED)) + != SHMSEG_ALLOCATED || + shmseg->shm_perm.seq != IPCID_TO_SEQ(shmid)) + return NULL; + return shmseg; +} + +static void +shm_deallocate_segment(shmseg) + struct shmid_ds *shmseg; +{ + struct shm_handle *shm_handle; + size_t size; + + shm_handle = shmseg->shm_internal; + size = (shmseg->shm_segsz + CLOFSET) & ~CLOFSET; + vm_deallocate(sysvshm_map, shm_handle->kva, size); + free((caddr_t)shm_handle, M_SHM); + shmseg->shm_internal = NULL; + shm_committed -= btoc(size); + shm_nused--; + shmseg->shm_perm.mode = SHMSEG_FREE; +} + +static int +shm_delete_mapping(p, shmmap_s) + struct proc *p; + struct shmmap_state *shmmap_s; +{ + struct shmid_ds *shmseg; + int segnum, result; + size_t size; + + segnum = IPCID_TO_IX(shmmap_s->shmid); + shmseg = &shmsegs[segnum]; + size = (shmseg->shm_segsz + CLOFSET) & ~CLOFSET; + result = vm_deallocate(&p->p_vmspace->vm_map, shmmap_s->va, size); + if (result != KERN_SUCCESS) + return EINVAL; + shmmap_s->shmid = -1; + shmseg->shm_dtime = time.tv_sec; + if ((--shmseg->shm_nattch <= 0) && + (shmseg->shm_perm.mode & SHMSEG_REMOVED)) { + shm_deallocate_segment(shmseg); + shm_last_free = segnum; + } + return 0; +} + +struct shmdt_args { + void *shmaddr; +}; +int +shmdt(p, uap, retval) + struct proc *p; + struct shmdt_args *uap; + int *retval; +{ + struct shmmap_state *shmmap_s; + int i; + + shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; + for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) + if (shmmap_s->shmid != -1 && + shmmap_s->va == (vm_offset_t)uap->shmaddr) + break; + if (i == shminfo.shmseg) + return EINVAL; + return shm_delete_mapping(p, shmmap_s); +} + +struct shmat_args { + int shmid; + void *shmaddr; + int shmflg; +}; +int +shmat(p, uap, retval) + struct proc *p; + struct shmat_args *uap; + int *retval; +{ + int error, i, flags; + struct ucred *cred = p->p_ucred; + struct shmid_ds *shmseg; + struct shmmap_state *shmmap_s = NULL; + vm_offset_t attach_va; + vm_prot_t prot; + vm_size_t size; + + shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; + if (shmmap_s == NULL) { + size = shminfo.shmseg * sizeof(struct shmmap_state); + shmmap_s = malloc(size, M_SHM, M_WAITOK); + for (i = 0; i < shminfo.shmseg; i++) + shmmap_s[i].shmid = -1; + p->p_vmspace->vm_shm = (caddr_t)shmmap_s; + } + shmseg = shm_find_segment_by_shmid(uap->shmid); + if (shmseg == NULL) + return EINVAL; + if (error = ipcperm(cred, &shmseg->shm_perm, + (uap->shmflg & SHM_RDONLY) ? IPC_R : IPC_R|IPC_W)) + return error; + for (i = 0; i < shminfo.shmseg; i++) { + if (shmmap_s->shmid == -1) + break; + shmmap_s++; + } + if (i >= shminfo.shmseg) + return EMFILE; + size = (shmseg->shm_segsz + CLOFSET) & ~CLOFSET; + prot = VM_PROT_READ; + if ((uap->shmflg & SHM_RDONLY) == 0) + prot |= VM_PROT_WRITE; + flags = MAP_ANON | MAP_SHARED; + if (uap->shmaddr) { + flags |= MAP_FIXED; + if (uap->shmflg & SHM_RND) + attach_va = (vm_offset_t)uap->shmaddr & ~(SHMLBA-1); + else if (((vm_offset_t)uap->shmaddr & (SHMLBA-1)) == 0) + attach_va = (vm_offset_t)uap->shmaddr; + else + return EINVAL; + } else { + /* This is just a hint to vm_mmap() about where to put it. */ + attach_va = round_page(p->p_vmspace->vm_daddr + MAXDSIZ); + } + error = vm_mmap(&p->p_vmspace->vm_map, &attach_va, size, prot, + VM_PROT_DEFAULT, flags, (caddr_t) uap->shmid, 0); + if (error) + return error; + shmmap_s->va = attach_va; + shmmap_s->shmid = uap->shmid; + shmseg->shm_lpid = p->p_pid; + shmseg->shm_atime = time.tv_sec; + shmseg->shm_nattch++; + *retval = attach_va; + return 0; +} + +struct shmctl_args { + int shmid; + int cmd; + struct shmat_ds *ubuf; +}; +int +shmctl(p, uap, retval) + struct proc *p; + struct shmctl_args *uap; + int *retval; +{ + int error, segnum; + struct ucred *cred = p->p_ucred; + struct shmid_ds inbuf; + struct shmid_ds *shmseg; + + shmseg = shm_find_segment_by_shmid(uap->shmid); + if (shmseg == NULL) + return EINVAL; + switch (uap->cmd) { + case IPC_STAT: + if (error = ipcperm(cred, &shmseg->shm_perm, IPC_R)) + return error; + if (error = copyout((caddr_t)shmseg, uap->ubuf, sizeof(inbuf))) + return error; + break; + case IPC_SET: + if (error = ipcperm(cred, &shmseg->shm_perm, IPC_M)) + return error; + if (error = copyin(uap->ubuf, (caddr_t)&inbuf, sizeof(inbuf))) + return error; + shmseg->shm_perm.uid = inbuf.shm_perm.uid; + shmseg->shm_perm.gid = inbuf.shm_perm.gid; + shmseg->shm_perm.mode = + (shmseg->shm_perm.mode & ~ACCESSPERMS) | + (inbuf.shm_perm.mode & ACCESSPERMS); + shmseg->shm_ctime = time.tv_sec; + break; + case IPC_RMID: + if (error = ipcperm(cred, &shmseg->shm_perm, IPC_M)) + return error; + shmseg->shm_perm.key = IPC_PRIVATE; + shmseg->shm_perm.mode |= SHMSEG_REMOVED; + if (shmseg->shm_nattch <= 0) { + shm_deallocate_segment(shmseg); + shm_last_free = IPCID_TO_IX(uap->shmid); + } + break; +#if 0 + case SHM_LOCK: + case SHM_UNLOCK: +#endif + default: + return EINVAL; + } + return 0; +} + +struct shmget_args { + key_t key; + size_t size; + int shmflg; +}; +static int +shmget_existing(p, uap, mode, segnum, retval) + struct proc *p; + struct shmget_args *uap; + int mode; + int segnum; + int *retval; +{ + struct shmid_ds *shmseg; + struct ucred *cred = p->p_ucred; + int error; + + shmseg = &shmsegs[segnum]; + if (shmseg->shm_perm.mode & SHMSEG_REMOVED) { + /* + * This segment is in the process of being allocated. Wait + * until it's done, and look the key up again (in case the + * allocation failed or it was freed). + */ + shmseg->shm_perm.mode |= SHMSEG_WANTED; + if (error = + tsleep((caddr_t)shmseg, PLOCK | PCATCH, "shmget", 0)) + return error; + return EAGAIN; + } + if (error = ipcperm(cred, &shmseg->shm_perm, mode)) + return error; + if (uap->size && uap->size > shmseg->shm_segsz) + return EINVAL; + if (uap->shmflg & (IPC_CREAT | IPC_EXCL) == (IPC_CREAT | IPC_EXCL)) + return EEXIST; + *retval = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm); + return 0; +} + +static int +shmget_allocate_segment(p, uap, mode, retval) + struct proc *p; + struct shmget_args *uap; + int mode; + int *retval; +{ + int i, segnum, result, shmid, size; + struct ucred *cred = p->p_ucred; + struct shmid_ds *shmseg; + struct shm_handle *shm_handle; + + if (uap->size < shminfo.shmmin || uap->size > shminfo.shmmax) + return EINVAL; + if (shm_nused >= shminfo.shmmni) /* any shmids left? */ + return ENOSPC; + size = (uap->size + CLOFSET) & ~CLOFSET; + if (shm_committed + btoc(size) > shminfo.shmall) + return ENOMEM; + if (shm_last_free < 0) { + for (i = 0; i < shminfo.shmmni; i++) + if (shmsegs[i].shm_perm.mode & SHMSEG_FREE) + break; + if (i == shminfo.shmmni) + panic("shmseg free count inconsistent"); + segnum = i; + } else { + segnum = shm_last_free; + shm_last_free = -1; + } + shmseg = &shmsegs[segnum]; + /* + * In case we sleep in malloc(), mark the segment present but deleted + * so that noone else tries to create the same key. + */ + shmseg->shm_perm.mode = SHMSEG_ALLOCATED | SHMSEG_REMOVED; + shmseg->shm_perm.key = uap->key; + shmseg->shm_perm.seq = (shmseg->shm_perm.seq + 1) & 0x7fff; + shm_handle = (struct shm_handle *) + malloc(sizeof(struct shm_handle), M_SHM, M_WAITOK); + shmid = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm); + result = vm_mmap(sysvshm_map, &shm_handle->kva, size, VM_PROT_ALL, + VM_PROT_DEFAULT, MAP_ANON, (caddr_t) shmid, 0); + if (result != KERN_SUCCESS) { + shmseg->shm_perm.mode = SHMSEG_FREE; + shm_last_free = segnum; + free((caddr_t)shm_handle, M_SHM); + /* Just in case. */ + wakeup((caddr_t)shmseg); + return ENOMEM; + } + shmseg->shm_internal = shm_handle; + shmseg->shm_perm.cuid = shmseg->shm_perm.uid = cred->cr_uid; + shmseg->shm_perm.cgid = shmseg->shm_perm.gid = cred->cr_gid; + shmseg->shm_perm.mode = (shmseg->shm_perm.mode & SHMSEG_WANTED) | + (mode & ACCESSPERMS) | SHMSEG_ALLOCATED; + shmseg->shm_segsz = uap->size; + shmseg->shm_cpid = p->p_pid; + shmseg->shm_lpid = shmseg->shm_nattch = 0; + shmseg->shm_atime = shmseg->shm_dtime = 0; + shmseg->shm_ctime = time.tv_sec; + shm_committed += btoc(size); + shm_nused++; + if (shmseg->shm_perm.mode & SHMSEG_WANTED) { + /* + * Somebody else wanted this key while we were asleep. Wake + * them up now. + */ + shmseg->shm_perm.mode &= ~SHMSEG_WANTED; + wakeup((caddr_t)shmseg); + } + *retval = shmid; + return 0; +} + +int +shmget(p, uap, retval) + struct proc *p; + struct shmget_args *uap; + int *retval; +{ + int segnum, mode, error; + struct shmid_ds *shmseg; + + mode = uap->shmflg & ACCESSPERMS; + if (uap->key != IPC_PRIVATE) { + again: + segnum = shm_find_segment_by_key(uap->key); + if (segnum >= 0) { + error = shmget_existing(p, uap, mode, segnum, retval); + if (error == EAGAIN) + goto again; + return error; + } + if ((uap->shmflg & IPC_CREAT) == 0) + return ENOENT; + } + return shmget_allocate_segment(p, uap, mode, retval); +} + +struct shmsys_args { + u_int which; +}; +int +shmsys(p, uap, retval) + struct proc *p; + struct shmsys_args *uap; + int *retval; +{ + + if (uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0])) + return EINVAL; + return ((*shmcalls[uap->which])(p, &uap[1], retval)); +} + +void +shmfork(p1, p2, isvfork) + struct proc *p1, *p2; + int isvfork; +{ + struct shmmap_state *shmmap_s; + size_t size; + int i; + + size = shminfo.shmseg * sizeof(struct shmmap_state); + shmmap_s = malloc(size, M_SHM, M_WAITOK); + bcopy((caddr_t)p1->p_vmspace->vm_shm, (caddr_t)shmmap_s, size); + p2->p_vmspace->vm_shm = (caddr_t)shmmap_s; + for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) + if (shmmap_s->shmid != -1) + shmsegs[IPCID_TO_IX(shmmap_s->shmid)].shm_nattch++; +} + +void +shmexit(p) + struct proc *p; +{ + struct shmmap_state *shmmap_s; + struct shmid_ds *shmseg; + int i; + + shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; + for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) + if (shmmap_s->shmid != -1) + shm_delete_mapping(p, shmmap_s); + free((caddr_t)p->p_vmspace->vm_shm, M_SHM); + p->p_vmspace->vm_shm = NULL; +} + +void +shminit() +{ + int i; + vm_offset_t garbage1, garbage2; + + /* actually this *should* be pageable. SHM_{LOCK,UNLOCK} */ + sysvshm_map = kmem_suballoc(kernel_map, &garbage1, &garbage2, + shminfo.shmall * NBPG, TRUE); + for (i = 0; i < shminfo.shmmni; i++) { + shmsegs[i].shm_perm.mode = SHMSEG_FREE; + shmsegs[i].shm_perm.seq = 0; + } + shm_last_free = 0; + shm_nused = 0; + shm_committed = 0; +} Property changes on: head/sys/kern/sysv_shm.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/sys/ipc.h =================================================================== --- head/sys/sys/ipc.h (revision 2728) +++ head/sys/sys/ipc.h (revision 2729) @@ -1,80 +1,88 @@ /* * Copyright (c) 1988 University of Utah. * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)ipc.h 8.3 (Berkeley) 1/21/94 - * $Id$ + * $Id: ipc.h,v 1.2 1994/08/02 07:53:06 davidg Exp $ */ /* * SVID compatible ipc.h file */ #ifndef _SYS_IPC_H_ #define _SYS_IPC_H_ typedef long key_t; /* XXX should be in types.h */ struct ipc_perm { ushort cuid; /* creator user id */ ushort cgid; /* creator group id */ ushort uid; /* user id */ ushort gid; /* group id */ ushort mode; /* r/w permission */ ushort seq; /* sequence # (to generate unique msg/sem/shm id) */ key_t key; /* user specified msg/sem/shm key */ }; /* common mode bits */ #define IPC_R 00400 /* read permission */ #define IPC_W 00200 /* write/alter permission */ +#define IPC_M 10000 /* permission to change control info */ /* SVID required constants (same values as system 5) */ #define IPC_CREAT 01000 /* create entry if key does not exist */ #define IPC_EXCL 02000 /* fail if key exists */ #define IPC_NOWAIT 04000 /* error if request must wait */ #define IPC_PRIVATE (key_t)0 /* private key */ #define IPC_RMID 0 /* remove identifier */ #define IPC_SET 1 /* set options */ #define IPC_STAT 2 /* get options */ + +#ifdef KERNEL +/* Macros to convert between ipc ids and array indices or sequence ids */ +#define IPCID_TO_IX(id) ((id) & 0xffff) +#define IPCID_TO_SEQ(id) (((id) >> 16) & 0xffff) +#define IXSEQ_TO_IPCID(ix,perm) (((perm.seq) << 16) | (ix & 0xffff)) +#endif /* KERNEL */ #endif /* !_SYS_IPC_H_ */ Index: head/sys/sys/msg.h =================================================================== --- head/sys/sys/msg.h (nonexistent) +++ head/sys/sys/msg.h (revision 2729) @@ -0,0 +1,161 @@ +/* $Id$ */ +/* $NetBSD: msg.h,v 1.4 1994/06/29 06:44:43 cgd Exp $ */ + +/* + * SVID compatible msg.h file + * + * Author: Daniel Boulet + * + * Copyright 1993 Daniel Boulet and RTMX Inc. + * + * This system call was implemented by Daniel Boulet under contract from RTMX. + * + * Redistribution and use in source forms, with and without modification, + * are permitted provided that this entire comment appears intact. + * + * Redistribution in binary form may occur without any restrictions. + * Obviously, it would be nice if you gave credit where credit is due + * but requiring it would be too onerous. + * + * This software is provided ``AS IS'' without any warranties of any kind. + */ + +#ifndef _SYS_MSG_H_ +#define _SYS_MSG_H_ + +#include + +/* + * The MSG_NOERROR identifier value, the msqid_ds struct and the msg struct + * are as defined by the SV API Intel 386 Processor Supplement. + */ + +#define MSG_NOERROR 010000 /* don't complain about too long msgs */ + +struct msqid_ds { + struct ipc_perm msg_perm; /* msg queue permission bits */ + struct msg *msg_first; /* first message in the queue */ + struct msg *msg_last; /* last message in the queue */ + u_long msg_cbytes; /* number of bytes in use on the queue */ + u_long msg_qnum; /* number of msgs in the queue */ + u_long msg_qbytes; /* max # of bytes on the queue */ + pid_t msg_lspid; /* pid of last msgsnd() */ + pid_t msg_lrpid; /* pid of last msgrcv() */ + time_t msg_stime; /* time of last msgsnd() */ + long msg_pad1; + time_t msg_rtime; /* time of last msgrcv() */ + long msg_pad2; + time_t msg_ctime; /* time of last msgctl() */ + long msg_pad3; + long msg_pad4[4]; +}; + +struct msg { + struct msg *msg_next; /* next msg in the chain */ + long msg_type; /* type of this message */ + /* >0 -> type of this message */ + /* 0 -> free header */ + u_short msg_ts; /* size of this message */ + short msg_spot; /* location of start of msg in buffer */ +}; + +/* + * Structure describing a message. The SVID doesn't suggest any + * particular name for this structure. There is a reference in the + * msgop man page that reads "The structure mymsg is an example of what + * this user defined buffer might look like, and includes the following + * members:". This sentence is followed by two lines equivalent + * to the mtype and mtext field declarations below. It isn't clear + * if "mymsg" refers to the naem of the structure type or the name of an + * instance of the structure... + */ +struct mymsg { + long mtype; /* message type (+ve integer) */ + char mtext[1]; /* message body */ +}; + +/* + * Based on the configuration parameters described in an SVR2 (yes, two) + * config(1m) man page. + * + * Each message is broken up and stored in segments that are msgssz bytes + * long. For efficiency reasons, this should be a power of two. Also, + * it doesn't make sense if it is less than 8 or greater than about 256. + * Consequently, msginit in kern/sysv_msg.c checks that msgssz is a power of + * two between 8 and 1024 inclusive (and panic's if it isn't). + */ +struct msginfo { + int msgmax, /* max chars in a message */ + msgmni, /* max message queue identifiers */ + msgmnb, /* max chars in a queue */ + msgtql, /* max messages in system */ + msgssz, /* size of a message segment (see notes above) */ + msgseg; /* number of message segments */ +}; +struct msginfo msginfo; + +#ifdef KERNEL +#ifndef MSGSSZ +#define MSGSSZ 8 /* Each segment must be 2^N long */ +#endif +#ifndef MSGSEG +#define MSGSEG 2048 /* must be less than 32767 */ +#endif +#undef MSGMAX /* ALWAYS compute MGSMAX! */ +#define MSGMAX (MSGSSZ*MSGSEG) +#ifndef MSGMNB +#define MSGMNB 2048 /* max # of bytes in a queue */ +#endif +#ifndef MSGMNI +#define MSGMNI 40 +#endif +#ifndef MSGTQL +#define MSGTQL 40 +#endif + +/* + * macros to convert between msqid_ds's and msqid's. + * (specific to this implementation) + */ +#define MSQID(ix,ds) ((ix) & 0xffff | (((ds).msg_perm.seq << 16) & 0xffff0000)) +#define MSQID_IX(id) ((id) & 0xffff) +#define MSQID_SEQ(id) (((id) >> 16) & 0xffff) +#endif + +/* + * The rest of this file is specific to this particular implementation. + */ + +#ifdef KERNEL + +/* + * Stuff allocated in machdep.h + */ +struct msgmap { + short next; /* next segment in buffer */ + /* -1 -> available */ + /* 0..(MSGSEG-1) -> index of next segment */ +}; + +char *msgpool; /* MSGMAX byte long msg buffer pool */ +struct msgmap *msgmaps; /* MSGSEG msgmap structures */ +struct msg *msghdrs; /* MSGTQL msg headers */ +struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */ + +#define MSG_LOCKED 01000 /* Is this msqid_ds locked? */ + +#endif + +#ifndef KERNEL +#include + +__BEGIN_DECLS +int msgsys __P((int, ...)); +int msgctl __P((int, int, struct msqid_ds *)); +int msgget __P((key_t, int)); +int msgsnd __P((int, void *, size_t, int)); +int msgrcv __P((int, void*, size_t, long, int)); +__END_DECLS +#endif /* !KERNEL */ + +#endif /* !_SYS_MSG_H_ */ Property changes on: head/sys/sys/msg.h ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/sys/sem.h =================================================================== --- head/sys/sys/sem.h (nonexistent) +++ head/sys/sys/sem.h (revision 2729) @@ -0,0 +1,179 @@ +/* $Id$ */ +/* $NetBSD: sem.h,v 1.5 1994/06/29 06:45:15 cgd Exp $ */ + +/* + * SVID compatible sem.h file + * + * Author: Daniel Boulet + */ + +#ifndef _SYS_SEM_H_ +#define _SYS_SEM_H_ + +#include + +struct sem { + u_short semval; /* semaphore value */ + pid_t sempid; /* pid of last operation */ + u_short semncnt; /* # awaiting semval > cval */ + u_short semzcnt; /* # awaiting semval = 0 */ +}; + +struct semid_ds { + struct ipc_perm sem_perm; /* operation permission struct */ + struct sem *sem_base; /* pointer to first semaphore in set */ + u_short sem_nsems; /* number of sems in set */ + time_t sem_otime; /* last operation time */ + long sem_pad1; /* SVABI/386 says I need this here */ + time_t sem_ctime; /* last change time */ + /* Times measured in secs since */ + /* 00:00:00 GMT, Jan. 1, 1970 */ + long sem_pad2; /* SVABI/386 says I need this here */ + long sem_pad3[4]; /* SVABI/386 says I need this here */ +}; + +/* + * semop's sops parameter structure + */ +struct sembuf { + u_short sem_num; /* semaphore # */ + short sem_op; /* semaphore operation */ + short sem_flg; /* operation flags */ +}; +#define SEM_UNDO 010000 + +#define MAX_SOPS 5 /* maximum # of sembuf's per semop call */ + +/* + * semctl's arg parameter structure + */ +union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ + u_short *array; /* array for GETALL & SETALL */ +}; + +/* + * commands for semctl + */ +#define GETNCNT 3 /* Return the value of semncnt {READ} */ +#define GETPID 4 /* Return the value of sempid {READ} */ +#define GETVAL 5 /* Return the value of semval {READ} */ +#define GETALL 6 /* Return semvals into arg.array {READ} */ +#define GETZCNT 7 /* Return the value of semzcnt {READ} */ +#define SETVAL 8 /* Set the value of semval to arg.val {ALTER} */ +#define SETALL 9 /* Set semvals from arg.array {ALTER} */ + +#ifdef KERNEL +/* + * Kernel implementation stuff + */ +#define SEMVMX 32767 /* semaphore maximum value */ +#define SEMAEM 16384 /* adjust on exit max value */ + +/* + * Permissions + */ +#define SEM_A 0200 /* alter permission */ +#define SEM_R 0400 /* read permission */ + +/* + * Undo structure (one per process) + */ +struct sem_undo { + struct sem_undo *un_next; /* ptr to next active undo structure */ + struct proc *un_proc; /* owner of this structure */ + short un_cnt; /* # of active entries */ + struct undo { + short un_adjval; /* adjust on exit values */ + short un_num; /* semaphore # */ + int un_id; /* semid */ + } un_ent[1]; /* undo entries */ +}; + +/* + * semaphore info struct + */ +struct seminfo { + int semmap, /* # of entries in semaphore map */ + semmni, /* # of semaphore identifiers */ + semmns, /* # of semaphores in system */ + semmnu, /* # of undo structures in system */ + semmsl, /* max # of semaphores per id */ + semopm, /* max # of operations per semop call */ + semume, /* max # of undo entries per process */ + semusz, /* size in bytes of undo structure */ + semvmx, /* semaphore maximum value */ + semaem; /* adjust on exit max value */ +}; +struct seminfo seminfo; + +/* internal "mode" bits */ +#define SEM_ALLOC 01000 /* semaphore is allocated */ +#define SEM_DEST 02000 /* semaphore will be destroyed on last detach */ + +/* + * Configuration parameters + */ +#ifndef SEMMNI +#define SEMMNI 10 /* # of semaphore identifiers */ +#endif +#ifndef SEMMNS +#define SEMMNS 60 /* # of semaphores in system */ +#endif +#ifndef SEMUME +#define SEMUME 10 /* max # of undo entries per process */ +#endif +#ifndef SEMMNU +#define SEMMNU 30 /* # of undo structures in system */ +#endif + +/* shouldn't need tuning */ +#ifndef SEMMAP +#define SEMMAP 30 /* # of entries in semaphore map */ +#endif +#ifndef SEMMSL +#define SEMMSL SEMMNS /* max # of semaphores per id */ +#endif +#ifndef SEMOPM +#define SEMOPM 100 /* max # of operations per semop call */ +#endif + +/* actual size of an undo structure */ +#define SEMUSZ (sizeof(struct sem_undo)+sizeof(struct undo)*SEMUME) + +/* + * Structures allocated in machdep.c + */ +struct semid_ds *sema; /* semaphore id pool */ +struct sem *sem; /* semaphore pool */ +struct map *semmap; /* semaphore allocation map */ +struct sem_undo *semu_list; /* list of active undo structures */ +int *semu; /* undo structure pool */ + +/* + * Macro to find a particular sem_undo vector + */ +#define SEMU(ix) ((struct sem_undo *)(((long)semu)+ix * SEMUSZ)) + +/* + * Parameters to the semconfig system call + */ +typedef enum { + SEM_CONFIG_FREEZE, /* Freeze the semaphore facility. */ + SEM_CONFIG_THAW /* Thaw the semaphore facility. */ +} semconfig_ctl_t; +#endif /* KERNEL */ + +#ifndef KERNEL +#include + +__BEGIN_DECLS +int semsys __P((int, ...)); +int semctl __P((int, int, int, union semun)); +int semget __P((key_t, int, int)); +int semop __P((int, struct sembuf *,unsigned)); +__END_DECLS +#endif /* !KERNEL */ + +#endif /* !_SEM_H_ */ Property changes on: head/sys/sys/sem.h ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/sys/shm.h =================================================================== --- head/sys/sys/shm.h (nonexistent) +++ head/sys/sys/shm.h (revision 2729) @@ -0,0 +1,90 @@ +/* $Id$ */ +/* $NetBSD: shm.h,v 1.15 1994/06/29 06:45:17 cgd Exp $ */ + +/* + * Copyright (c) 1994 Adam Glass + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Glass. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * As defined+described in "X/Open System Interfaces and Headers" + * Issue 4, p. XXX + */ + +#ifndef _SYS_SHM_H_ +#define _SYS_SHM_H_ + +#include + +#define SHM_RDONLY 010000 /* Attach read-only (else read-write) */ +#define SHM_RND 020000 /* Round attach address to SHMLBA */ +#define SHMLBA CLBYTES /* Segment low boundry address multiple */ + +struct shmid_ds { + struct ipc_perm shm_perm; /* operation permission structure */ + int shm_segsz; /* size of segment in bytes */ + pid_t shm_lpid; /* process ID of last shared memory op */ + pid_t shm_cpid; /* process ID of creator */ + short shm_nattch; /* number of current attaches */ + time_t shm_atime; /* time of last shmat() */ + time_t shm_dtime; /* time of last shmdt() */ + time_t shm_ctime; /* time of last change by shmctl() */ + void *shm_internal; /* sysv stupidity */ +}; + +#ifdef KERNEL + +/* + * System 5 style catch-all structure for shared memory constants that + * might be of interest to user programs. Do we really want/need this? + */ +struct shminfo { + int shmmax, /* max shared memory segment size (bytes) */ + shmmin, /* min shared memory segment size (bytes) */ + shmmni, /* max number of shared memory identifiers */ + shmseg, /* max shared memory segments per process */ + shmall; /* max amount of shared memory (pages) */ +}; +struct shminfo shminfo; +struct shmid_ds *shmsegs; + +#else /* !KERNEL */ + +#include + +__BEGIN_DECLS +int shmsys __P((int, ...)); +void *shmat __P((int, void *, int)); +int shmget __P((key_t, int, int)); +int shmctl __P((int, int, struct shmid_ds *)); +int shmdt __P((void *)); +__END_DECLS + +#endif /* !KERNEL */ + +#endif /* !_SYS_SHM_H_ */ Property changes on: head/sys/sys/shm.h ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/sys/sys/syscall-hide.h =================================================================== --- head/sys/sys/syscall-hide.h (revision 2728) +++ head/sys/sys/syscall-hide.h (revision 2729) @@ -1,216 +1,224 @@ /* * System call hiders. * * DO NOT EDIT-- this file is automatically generated. - * created from $Id: syscalls.master,v 1.6 1994/09/01 05:12:42 davidg Exp $ + * created from $Id: syscalls.master,v 1.7 1994/09/13 00:48:19 wollman Exp $ */ HIDE_POSIX(fork) HIDE_POSIX(read) HIDE_POSIX(write) HIDE_POSIX(open) HIDE_POSIX(close) HIDE_BSD(wait4) HIDE_BSD(creat) HIDE_POSIX(link) HIDE_POSIX(unlink) HIDE_POSIX(chdir) HIDE_BSD(fchdir) HIDE_POSIX(mknod) HIDE_POSIX(chmod) HIDE_POSIX(chown) HIDE_BSD(obreak) HIDE_BSD(getfsstat) HIDE_POSIX(lseek) HIDE_POSIX(getpid) HIDE_BSD(mount) HIDE_BSD(unmount) HIDE_POSIX(setuid) HIDE_POSIX(getuid) HIDE_POSIX(geteuid) HIDE_BSD(ptrace) HIDE_BSD(recvmsg) HIDE_BSD(sendmsg) HIDE_BSD(recvfrom) HIDE_BSD(accept) HIDE_BSD(getpeername) HIDE_BSD(getsockname) HIDE_POSIX(access) HIDE_BSD(chflags) HIDE_BSD(fchflags) HIDE_BSD(sync) HIDE_POSIX(kill) HIDE_POSIX(stat) HIDE_POSIX(getppid) HIDE_POSIX(lstat) HIDE_POSIX(dup) HIDE_POSIX(pipe) HIDE_POSIX(getegid) HIDE_BSD(profil) #ifdef KTRACE HIDE_BSD(ktrace) #else HIDE_BSD(ktrace) #endif HIDE_POSIX(sigaction) HIDE_POSIX(getgid) HIDE_POSIX(sigprocmask) HIDE_BSD(getlogin) HIDE_BSD(setlogin) HIDE_BSD(acct) HIDE_POSIX(sigpending) HIDE_BSD(sigaltstack) HIDE_POSIX(ioctl) HIDE_BSD(reboot) HIDE_POSIX(revoke) HIDE_POSIX(symlink) HIDE_POSIX(readlink) HIDE_POSIX(execve) HIDE_POSIX(umask) HIDE_BSD(chroot) HIDE_POSIX(fstat) HIDE_BSD(getkerninfo) HIDE_BSD(getpagesize) HIDE_BSD(msync) HIDE_BSD(vfork) HIDE_BSD(sbrk) HIDE_BSD(sstk) HIDE_BSD(mmap) HIDE_BSD(ovadvise) HIDE_BSD(munmap) HIDE_BSD(mprotect) HIDE_BSD(madvise) HIDE_BSD(mincore) HIDE_POSIX(getgroups) HIDE_POSIX(setgroups) HIDE_POSIX(getpgrp) HIDE_POSIX(setpgid) HIDE_BSD(setitimer) HIDE_BSD(wait) HIDE_BSD(swapon) HIDE_BSD(getitimer) HIDE_BSD(gethostname) HIDE_BSD(sethostname) HIDE_BSD(getdtablesize) HIDE_POSIX(dup2) HIDE_BSD(getdopt) HIDE_POSIX(fcntl) HIDE_BSD(select) HIDE_BSD(setdopt) HIDE_POSIX(fsync) HIDE_BSD(setpriority) HIDE_BSD(socket) HIDE_BSD(connect) HIDE_BSD(accept) HIDE_BSD(getpriority) HIDE_BSD(send) HIDE_BSD(recv) HIDE_BSD(sigreturn) HIDE_BSD(bind) HIDE_BSD(setsockopt) HIDE_BSD(listen) HIDE_BSD(sigvec) HIDE_BSD(sigblock) HIDE_BSD(sigsetmask) HIDE_POSIX(sigsuspend) HIDE_BSD(sigstack) HIDE_BSD(recvmsg) HIDE_BSD(sendmsg) #ifdef TRACE HIDE_BSD(vtrace) #else #endif HIDE_BSD(gettimeofday) HIDE_BSD(getrusage) HIDE_BSD(getsockopt) #ifdef vax HIDE_BSD(resuba) #else #endif HIDE_BSD(readv) HIDE_BSD(writev) HIDE_BSD(settimeofday) HIDE_BSD(fchown) HIDE_BSD(fchmod) HIDE_BSD(recvfrom) HIDE_BSD(setreuid) HIDE_BSD(setregid) HIDE_POSIX(rename) HIDE_BSD(truncate) HIDE_BSD(ftruncate) HIDE_BSD(flock) HIDE_POSIX(mkfifo) HIDE_BSD(sendto) HIDE_BSD(shutdown) HIDE_BSD(socketpair) HIDE_POSIX(mkdir) HIDE_POSIX(rmdir) HIDE_BSD(utimes) HIDE_BSD(adjtime) HIDE_BSD(getpeername) HIDE_BSD(gethostid) HIDE_BSD(sethostid) HIDE_BSD(getrlimit) HIDE_BSD(setrlimit) HIDE_BSD(killpg) HIDE_POSIX(setsid) HIDE_BSD(quotactl) HIDE_BSD(quota) HIDE_BSD(getsockname) #ifdef NFS HIDE_BSD(nfssvc) #else HIDE_BSD(nosys) #endif HIDE_BSD(getdirentries) HIDE_BSD(statfs) HIDE_BSD(fstatfs) #ifdef NFS HIDE_BSD(getfh) #else HIDE_BSD(nosys) #endif HIDE_BSD(getdomainname) HIDE_BSD(setdomainname) HIDE_BSD(uname) HIDE_BSD(sysarch) HIDE_BSD(rtprio) +#ifdef SYSVSEM +HIDE_BSD(semsys) +#else +#endif +#ifdef SYSVMSG +HIDE_BSD(msgsys) +#else +#endif #ifdef SYSVSHM HIDE_BSD(shmsys) #else HIDE_BSD(nosys) #endif HIDE_BSD(nosys) HIDE_BSD(nosys) HIDE_POSIX(setgid) HIDE_BSD(setegid) HIDE_BSD(seteuid) #ifdef LFS HIDE_BSD(lfs_bmapv) HIDE_BSD(lfs_markv) HIDE_BSD(lfs_segclean) HIDE_BSD(lfs_segwait) #else HIDE_BSD(nosys) HIDE_BSD(nosys) HIDE_BSD(nosys) HIDE_BSD(nosys) #endif HIDE_POSIX(stat) HIDE_POSIX(fstat) HIDE_POSIX(lstat) HIDE_POSIX(pathconf) HIDE_POSIX(fpathconf) HIDE_BSD(getrlimit) HIDE_BSD(setrlimit) HIDE_BSD(getdirentries) HIDE_BSD(mmap) HIDE_POSIX(lseek) HIDE_BSD(truncate) HIDE_BSD(ftruncate) HIDE_BSD(__sysctl) HIDE_BSD(mlock) HIDE_BSD(munlock) #ifdef LKM #else #endif Index: head/sys/sys/syscall.h =================================================================== --- head/sys/sys/syscall.h (revision 2728) +++ head/sys/sys/syscall.h (revision 2729) @@ -1,193 +1,195 @@ /* * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * created from $Id: syscalls.master,v 1.6 1994/09/01 05:12:42 davidg Exp $ + * created from $Id: syscalls.master,v 1.7 1994/09/13 00:48:19 wollman Exp $ */ #define SYS_syscall 0 #define SYS_exit 1 #define SYS_fork 2 #define SYS_read 3 #define SYS_write 4 #define SYS_open 5 #define SYS_close 6 #define SYS_wait4 7 /* 8 is old creat */ #define SYS_link 9 #define SYS_unlink 10 /* 11 is obsolete execv */ #define SYS_chdir 12 #define SYS_fchdir 13 #define SYS_mknod 14 #define SYS_chmod 15 #define SYS_chown 16 #define SYS_break 17 #define SYS_getfsstat 18 /* 19 is old lseek */ #define SYS_getpid 20 #define SYS_mount 21 #define SYS_unmount 22 #define SYS_setuid 23 #define SYS_getuid 24 #define SYS_geteuid 25 #define SYS_ptrace 26 #define SYS_recvmsg 27 #define SYS_sendmsg 28 #define SYS_recvfrom 29 #define SYS_accept 30 #define SYS_getpeername 31 #define SYS_getsockname 32 #define SYS_access 33 #define SYS_chflags 34 #define SYS_fchflags 35 #define SYS_sync 36 #define SYS_kill 37 /* 38 is old stat */ #define SYS_getppid 39 /* 40 is old lstat */ #define SYS_dup 41 #define SYS_pipe 42 #define SYS_getegid 43 #define SYS_profil 44 #define SYS_ktrace 45 #define SYS_sigaction 46 #define SYS_getgid 47 #define SYS_sigprocmask 48 #define SYS_getlogin 49 #define SYS_setlogin 50 #define SYS_acct 51 #define SYS_sigpending 52 #define SYS_sigaltstack 53 #define SYS_ioctl 54 #define SYS_reboot 55 #define SYS_revoke 56 #define SYS_symlink 57 #define SYS_readlink 58 #define SYS_execve 59 #define SYS_umask 60 #define SYS_chroot 61 /* 62 is old fstat */ /* 63 is old getkerninfo */ /* 64 is old getpagesize */ #define SYS_msync 65 #define SYS_vfork 66 /* 67 is obsolete vread */ /* 68 is obsolete vwrite */ #define SYS_sbrk 69 #define SYS_sstk 70 /* 71 is old mmap */ #define SYS_vadvise 72 #define SYS_munmap 73 #define SYS_mprotect 74 #define SYS_madvise 75 /* 76 is obsolete vhangup */ /* 77 is obsolete vlimit */ #define SYS_mincore 78 #define SYS_getgroups 79 #define SYS_setgroups 80 #define SYS_getpgrp 81 #define SYS_setpgid 82 #define SYS_setitimer 83 /* 84 is old wait */ #define SYS_swapon 85 #define SYS_getitimer 86 /* 87 is old gethostname */ /* 88 is old sethostname */ #define SYS_getdtablesize 89 #define SYS_dup2 90 #define SYS_fcntl 92 #define SYS_select 93 #define SYS_fsync 95 #define SYS_setpriority 96 #define SYS_socket 97 #define SYS_connect 98 /* 99 is old accept */ #define SYS_getpriority 100 /* 101 is old send */ /* 102 is old recv */ #define SYS_sigreturn 103 #define SYS_bind 104 #define SYS_setsockopt 105 #define SYS_listen 106 /* 107 is obsolete vtimes */ /* 108 is old sigvec */ /* 109 is old sigblock */ /* 110 is old sigsetmask */ #define SYS_sigsuspend 111 /* 112 is old sigstack */ /* 113 is old recvmsg */ /* 114 is old sendmsg */ #define SYS_vtrace 115 /* 115 is obsolete vtrace */ #define SYS_gettimeofday 116 #define SYS_getrusage 117 #define SYS_getsockopt 118 #define SYS_resuba 119 #define SYS_readv 120 #define SYS_writev 121 #define SYS_settimeofday 122 #define SYS_fchown 123 #define SYS_fchmod 124 /* 125 is old recvfrom */ /* 126 is old setreuid */ /* 127 is old setregid */ #define SYS_rename 128 /* 129 is old truncate */ /* 130 is old ftruncate */ #define SYS_flock 131 #define SYS_mkfifo 132 #define SYS_sendto 133 #define SYS_shutdown 134 #define SYS_socketpair 135 #define SYS_mkdir 136 #define SYS_rmdir 137 #define SYS_utimes 138 /* 139 is obsolete 4.2 sigreturn */ #define SYS_adjtime 140 /* 141 is old getpeername */ /* 142 is old gethostid */ /* 143 is old sethostid */ /* 144 is old getrlimit */ /* 145 is old setrlimit */ /* 146 is old killpg */ #define SYS_setsid 147 #define SYS_quotactl 148 /* 149 is old quota */ /* 150 is old getsockname */ #define SYS_nfssvc 155 /* 156 is old getdirentries */ #define SYS_statfs 157 #define SYS_fstatfs 158 #define SYS_getfh 161 #define SYS_getdomainname 162 #define SYS_setdomainname 163 #define SYS_uname 164 #define SYS_sysarch 165 #define SYS_rtprio 166 +#define SYS_semsys 169 +#define SYS_msgsys 170 #define SYS_shmsys 171 #define SYS_ntp_gettime 175 #define SYS_ntp_adjtime 176 #define SYS_setgid 181 #define SYS_setegid 182 #define SYS_seteuid 183 #define SYS_lfs_bmapv 184 #define SYS_lfs_markv 185 #define SYS_lfs_segclean 186 #define SYS_lfs_segwait 187 #define SYS_stat 188 #define SYS_fstat 189 #define SYS_lstat 190 #define SYS_pathconf 191 #define SYS_fpathconf 192 #define SYS_getrlimit 194 #define SYS_setrlimit 195 #define SYS_getdirentries 196 #define SYS_mmap 197 #define SYS___syscall 198 #define SYS_lseek 199 #define SYS_truncate 200 #define SYS_ftruncate 201 #define SYS___sysctl 202 #define SYS_mlock 203 #define SYS_munlock 204