summaryrefslogtreecommitdiff
path: root/share/doc/psd
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /share/doc/psd
initial import of NetBSD tree
Diffstat (limited to 'share/doc/psd')
-rw-r--r--share/doc/psd/00.contents191
-rw-r--r--share/doc/psd/05.sysman/0.t292
-rw-r--r--share/doc/psd/05.sysman/1.0.t56
-rw-r--r--share/doc/psd/05.sysman/1.1.t215
-rw-r--r--share/doc/psd/05.sysman/1.2.t272
-rw-r--r--share/doc/psd/05.sysman/1.3.t254
-rw-r--r--share/doc/psd/05.sysman/1.4.t137
-rw-r--r--share/doc/psd/05.sysman/1.5.t225
-rw-r--r--share/doc/psd/05.sysman/1.6.t135
-rw-r--r--share/doc/psd/05.sysman/1.7.t100
-rw-r--r--share/doc/psd/05.sysman/2.0.t83
-rw-r--r--share/doc/psd/05.sysman/2.1.t138
-rw-r--r--share/doc/psd/05.sysman/2.2.t470
-rw-r--r--share/doc/psd/05.sysman/2.3.t412
-rw-r--r--share/doc/psd/05.sysman/2.4.t174
-rw-r--r--share/doc/psd/05.sysman/2.5.t39
-rw-r--r--share/doc/psd/05.sysman/Makefile11
-rw-r--r--share/doc/psd/05.sysman/a.t235
-rw-r--r--share/doc/psd/05.sysman/spell.ok332
-rw-r--r--share/doc/psd/20.ipctut/Makefile13
-rw-r--r--share/doc/psd/20.ipctut/dgramread.c83
-rw-r--r--share/doc/psd/20.ipctut/dgramsend.c80
-rw-r--r--share/doc/psd/20.ipctut/fig2.pic77
-rw-r--r--share/doc/psd/20.ipctut/fig2.xfig100
-rw-r--r--share/doc/psd/20.ipctut/fig3.pic69
-rw-r--r--share/doc/psd/20.ipctut/fig3.xfig100
-rw-r--r--share/doc/psd/20.ipctut/fig8.pic79
-rw-r--r--share/doc/psd/20.ipctut/fig8.xfig116
-rw-r--r--share/doc/psd/20.ipctut/pipe.c74
-rw-r--r--share/doc/psd/20.ipctut/socketpair.c77
-rw-r--r--share/doc/psd/20.ipctut/strchkread.c106
-rw-r--r--share/doc/psd/20.ipctut/streamread.c102
-rw-r--r--share/doc/psd/20.ipctut/streamwrite.c81
-rw-r--r--share/doc/psd/20.ipctut/tutor.me939
-rw-r--r--share/doc/psd/20.ipctut/udgramread.c80
-rw-r--r--share/doc/psd/20.ipctut/udgramsend.c68
-rw-r--r--share/doc/psd/20.ipctut/ustreamread.c96
-rw-r--r--share/doc/psd/20.ipctut/ustreamwrite.c71
-rw-r--r--share/doc/psd/21.ipc/0.t93
-rw-r--r--share/doc/psd/21.ipc/1.t106
-rw-r--r--share/doc/psd/21.ipc/2.t714
-rw-r--r--share/doc/psd/21.ipc/3.t409
-rw-r--r--share/doc/psd/21.ipc/4.t514
-rw-r--r--share/doc/psd/21.ipc/5.t1667
-rw-r--r--share/doc/psd/21.ipc/Makefile10
-rw-r--r--share/doc/psd/21.ipc/spell.ok347
-rw-r--r--share/doc/psd/Makefile36
-rw-r--r--share/doc/psd/Title131
48 files changed, 10209 insertions, 0 deletions
diff --git a/share/doc/psd/00.contents b/share/doc/psd/00.contents
new file mode 100644
index 00000000000..3866526be5a
--- /dev/null
+++ b/share/doc/psd/00.contents
@@ -0,0 +1,191 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)00.contents 8.1 (Berkeley) 6/8/93
+.\"
+.OH '''PSD Contents'
+.EH 'PSD Contents'''
+.TL
+UNIX Programmer's Supplementary Documents (PSD)
+.sp
+\s-24.4 Berkeley Software Distribution\s+2
+.sp
+\fRJune, 1993\fR
+.PP
+This volume contains documents which supplement the manual pages in
+.I
+The
+.UX
+Programmer's Reference Manual
+.R
+for the 4.4BSD system as distributed by U.C. Berkeley.
+.SH
+Documents of Historical Interest
+.IP
+.tl 'The Unix Time\-Sharing System''PSD:1'
+.QP
+Dennis Ritchie and Ken Thompson's original paper about UNIX, reprinted
+from Communications of the ACM.
+
+.IP
+.tl 'Unix Implementation''PSD:2'
+.QP
+Ken Thompson's description of the implementation of the Version 7
+kernel and file system.
+
+.IP
+.tl 'The Unix I/O System''PSD:3'
+.QP
+Dennis Ritchie's overview of the I/O System of Version 7; still helpful for
+those writing device drivers.
+
+.IP
+.tl 'Unix Programming \- Second Edition ''PSD:4'
+.QP
+Describes the programming interface to the UNIX version 7 operating
+system and the standard I/O library. Should be supplemented by
+Kernighan and Pike, ``The UNIX Programming Environment'',
+Prentice-Hall, 1984 and especially by the Programmer Reference Manual
+section 2 (system calls) and 3 (library routines).
+
+.IP
+.tl 'Berkeley Software Architecture Manual (4.4 Edition)''PSD:5'
+.QP
+A concise and terse description of the system call interface
+provided in Berkeley Unix, as revised for 4.4BSD.
+This will never be a best seller.
+
+.SH
+Languages in common use
+.IP
+.tl 'The C Programming Language \- Reference Manual''PSD:6'
+.QP
+Official statement of the syntax of C.
+Should be supplemented by ``The C Programming Language,''
+B.W. Kernighan and D.M. Ritchie, Prentice-Hall, 1978, that
+contains a tutorial introduction and many examples.
+
+.IP
+.tl 'Berkeley Pascal User\'s Manual''PSD:7'
+.QP
+An implementation of this language popular for learning to program.
+
+.IP
+.tl 'A Portable Fortran 77 Compiler''PSD:8'
+.QP
+A revised version of the document which originally appeared in
+Volume 2b of the Bell Labs documentation;
+this version reflects the work done at Berkeley.
+
+.IP
+.tl 'Introduction to the f77 I/O Library''PSD:9'
+.QP
+A description of the revised input/output library for Fortran 77,
+reflecting work carried out at Berkeley.
+
+.SH
+Programming Tools
+.IP
+.tl 'Debugging with GDB: The GNU Source-Level Debugger''PSD:10'
+.QP
+How to debug programs using the source level \fIgdb\fP debugger
+(or how to debug programs without having to know much about machine language).
+
+.IP
+.tl 'A Tutorial Introduction to ADB''PSD:11'
+.QP
+How to debug programs using the assembly-language level \fIadb\fP debugger.
+
+.IP
+.tl 'Make \- A Program for Maintaining Computer Programs''PSD:12'
+.QP
+Indispensable tool for making sure large programs are properly
+compiled with minimal effort.
+
+.IP
+.tl 'An Introduction to the Revision Control System''PSD:13'
+.QP
+RCS is a user-contributed tool for working together with other people
+without stepping on each other's toes.
+An alternative to \fIsccs\fR for controlling software changes.
+
+.IP
+.tl 'An Introduction to the Source Code Control System''PSD:14'
+.QP
+A useful introductory article for those users with
+installations licensed for SCCS.
+
+.IP
+.tl 'YACC: Yet Another Compiler-Compiler''PSD:15'
+.QP
+Converts a BNF specification of a language and semantic actions
+written in C into a compiler for that language.
+
+.IP
+.tl 'LEX \- A Lexical Analyzer Generator''PSD:16'
+.QP
+Creates a recognizer for a set of regular expressions:
+each regular expression can be followed by arbitrary C code
+to be executed upon finding the regular expression.
+
+.IP
+.tl 'The M4 Macro Processor''PSD:17'
+.QP
+M4 is a macro processor useful in its own right and as a
+front-end for C, Ratfor, and Cobol.
+
+.IP
+.tl 'gprof: a Call Graph Execution Profiler''PSD:18'
+.QP
+A program to show the call graph and execution time of a program.
+Indispensable aid for improving the running time of almost everything.
+
+.SH
+Programming Libraries
+.IP
+.tl 'Screen Updating and Cursor Movement Optimization''PSD:19'
+.QP
+Describes the \fIcurses\fP package, an aid for writing screen-oriented,
+terminal-independent programs.
+
+.SH
+General Reference
+.IP
+.tl 'An Introductory 4.4BSD Interprocess Communication Tutorial''PSD:20'
+.QP
+How to write programs that use the Interprocess Communication Facilities
+of 4.4BSD.
+
+.IP
+.tl 'An Advanced 4.4BSD Interprocess Communication Tutorial''PSD:21'
+.QP
+The reference document (with some examples) for the Interprocess Communication
+Facilities of 4.4BSD.
diff --git a/share/doc/psd/05.sysman/0.t b/share/doc/psd/05.sysman/0.t
new file mode 100644
index 00000000000..865e8ff521e
--- /dev/null
+++ b/share/doc/psd/05.sysman/0.t
@@ -0,0 +1,292 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)0.t 8.1 (Berkeley) 6/8/93
+.\"
+.if n .ND
+.TL
+Berkeley Software Architecture Manual
+.br
+4.4BSD Edition
+.AU
+William Joy, Robert Fabry,
+.AU
+Samuel Leffler, M. Kirk McKusick,
+.AU
+Michael Karels
+.AI
+Computer Systems Research Group
+Computer Science Division
+Department of Electrical Engineering and Computer Science
+University of California, Berkeley
+Berkeley, CA 94720
+.EH 'PSD:5-%''4.4BSD Architecture Manual'
+.OH '4.4BSD Architecture Manual''PSD:5-%'
+.AB
+.FS
+* UNIX is a trademark of Bell Laboratories.
+.FE
+This document summarizes the facilities
+provided by the 4.4BSD version of the UNIX\|* operating system.
+It does not attempt to act as a tutorial for use of the system
+nor does it attempt to explain or justify the design of the
+system facilities.
+It gives neither motivation nor implementation details,
+in favor of brevity.
+.PP
+The first section describes the basic kernel functions
+provided to a UNIX process: process naming and protection,
+memory management, software interrupts,
+object references (descriptors), time and statistics functions,
+and resource controls.
+These facilities, as well as facilities for
+bootstrap, shutdown and process accounting,
+are provided solely by the kernel.
+.PP
+The second section describes the standard system
+abstractions for
+files and file systems,
+communication,
+terminal handling,
+and process control and debugging.
+These facilities are implemented by the operating system or by
+network server processes.
+.AE
+.LP
+.bp
+.ft B
+.br
+.sv 2
+.ce
+TABLE OF CONTENTS
+.ft R
+.LP
+.sp 1
+.nf
+.B "Introduction."
+.LP
+.if t .sp .5v
+.nf
+.B "0. Notation and types"
+.LP
+.if t .sp .5v
+.nf
+.B "1. Kernel primitives"
+.LP
+.if t .sp .5v
+.nf
+.nf
+\fB1.1. Processes and protection\fP
+1.1.1. Host and process identifiers
+1.1.2. Process creation and termination
+1.1.3. User and group ids
+1.1.4. Process groups
+.LP
+.nf
+\fB1.2. Memory management\fP
+1.2.1. Text, data and stack
+1.2.2. Mapping pages
+1.2.3. Page protection control
+1.2.4. Giving and getting advice
+1.2.5. Protection primitives
+.LP
+.if t .sp .5v
+.nf
+\fB1.3. Signals\fP
+1.3.1. Overview
+1.3.2. Signal types
+1.3.3. Signal handlers
+1.3.4. Sending signals
+1.3.5. Protecting critical sections
+1.3.6. Signal stacks
+.LP
+.if t .sp .5v
+.nf
+\fB1.4. Timing and statistics\fP
+1.4.1. Real time
+1.4.2. Interval time
+.LP
+.if t .sp .5v
+.nf
+\fB1.5. Descriptors\fP
+1.5.1. The reference table
+1.5.2. Descriptor properties
+1.5.3. Managing descriptor references
+1.5.4. Multiplexing requests
+1.5.5. Descriptor wrapping
+.LP
+.if t .sp .5v
+.nf
+\fB1.6. Resource controls\fP
+1.6.1. Process priorities
+1.6.2. Resource utilization
+1.6.3. Resource limits
+.LP
+.if t .sp .5v
+.nf
+\fB1.7. System operation support\fP
+1.7.1. Bootstrap operations
+1.7.2. Shutdown operations
+1.7.3. Accounting
+.bp
+.LP
+.if t .sp .5v
+.sp 1
+.nf
+\fB2. System facilities\fP
+.LP
+.if t .sp .5v
+.nf
+\fB2.1. Generic operations\fP
+2.1.1. Read and write
+2.1.2. Input/output control
+2.1.3. Non-blocking and asynchronous operations
+.LP
+.if t .sp .5v
+.nf
+\fB2.2. File system\fP
+2.2.1 Overview
+2.2.2. Naming
+2.2.3. Creation and removal
+2.2.3.1. Directory creation and removal
+2.2.3.2. File creation
+2.2.3.3. Creating references to devices
+2.2.3.4. Portal creation
+2.2.3.6. File, device, and portal removal
+2.2.4. Reading and modifying file attributes
+2.2.5. Links and renaming
+2.2.6. Extension and truncation
+2.2.7. Checking accessibility
+2.2.8. Locking
+2.2.9. Disc quotas
+.LP
+.if t .sp .5v
+.nf
+\fB2.3. Interprocess communication\fP
+2.3.1. Interprocess communication primitives
+2.3.1.1.\0 Communication domains
+2.3.1.2.\0 Socket types and protocols
+2.3.1.3.\0 Socket creation, naming and service establishment
+2.3.1.4.\0 Accepting connections
+2.3.1.5.\0 Making connections
+2.3.1.6.\0 Sending and receiving data
+2.3.1.7.\0 Scatter/gather and exchanging access rights
+2.3.1.8.\0 Using read and write with sockets
+2.3.1.9.\0 Shutting down halves of full-duplex connections
+2.3.1.10.\0 Socket and protocol options
+2.3.2. UNIX domain
+2.3.2.1. Types of sockets
+2.3.2.2. Naming
+2.3.2.3. Access rights transmission
+2.3.3. INTERNET domain
+2.3.3.1. Socket types and protocols
+2.3.3.2. Socket naming
+2.3.3.3. Access rights transmission
+2.3.3.4. Raw access
+.LP
+.if t .sp .5v
+.nf
+\fB2.4. Terminals and devices\fP
+2.4.1. Terminals
+2.4.1.1. Terminal input
+2.4.1.1.1 Input modes
+2.4.1.1.2 Interrupt characters
+2.4.1.1.3 Line editing
+2.4.1.2. Terminal output
+2.4.1.3. Terminal control operations
+2.4.1.4. Terminal hardware support
+2.4.2. Structured devices
+2.4.3. Unstructured devices
+.LP
+.if t .sp .5v
+.nf
+\fB2.5. Process control and debugging\fP
+.LP
+.if t .sp .5v
+.nf
+\fBI. Summary of facilities\fP
+.LP
+.de sh
+.ds RH \\$1
+.bp
+.NH \\*(ss
+\s+2\\$1\s0
+.PP
+.PP
+..
+.bp
+.ds ss 1
+.de _d
+.if t .ta .6i 2.1i 2.6i
+.\" 2.94 went to 2.6, 3.64 to 3.30
+.if n .ta .84i 2.6i 3.30i
+..
+.de _f
+.if t .ta .5i 1.25i 2.5i 3.5i
+.\" 3.5i went to 3.8i
+.if n .ta .7i 1.75i 3.8i 4.8i
+..
+.nr H1 -1
+.sh "Notation and types
+.PP
+The notation used to describe system calls is a variant of a
+C language call, consisting of a prototype call followed by
+declaration of parameters and results.
+An additional keyword \fBresult\fP, not part of the normal C language,
+is used to indicate which of the declared entities receive results.
+As an example, consider the \fIread\fP call, as described in
+section 2.1:
+.DS
+cc = read(fd, buf, nbytes);
+result int cc; int fd; result char *buf; int nbytes;
+.DE
+The first line shows how the \fIread\fP routine is called, with
+three parameters.
+As shown on the second line \fIcc\fP is an integer and \fIread\fP also
+returns information in the parameter \fIbuf\fP.
+.PP
+Description of all error conditions arising from each system call
+is not provided here; they appear in the programmer's manual.
+In particular, when accessed from the C language,
+many calls return a characteristic \-1 value
+when an error occurs, returning the error code in the global variable
+\fIerrno\fP.
+Other languages may present errors in different ways.
+.PP
+A number of system standard types are defined in the include file
+.I <sys/types.h>
+and used in the specifications here and in many C programs.
+These include \fBcaddr_t\fP giving a memory address (typically as
+a character pointer),
+\fBoff_t\fP giving a file offset (typically as a long integer),
+and a set of unsigned types \fBu_char\fP, \fBu_short\fP, \fBu_int\fP
+and \fBu_long\fP, shorthand names for \fBunsigned char\fP, \fBunsigned
+short\fP, etc.
diff --git a/share/doc/psd/05.sysman/1.0.t b/share/doc/psd/05.sysman/1.0.t
new file mode 100644
index 00000000000..5a465a7281c
--- /dev/null
+++ b/share/doc/psd/05.sysman/1.0.t
@@ -0,0 +1,56 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)1.0.t 8.1 (Berkeley) 6/8/93
+.\"
+.ds ss 1
+.sh "Kernel primitives
+.PP
+The facilities available to a UNIX user process are logically
+divided into two parts: kernel facilities directly implemented by
+UNIX code running in the operating system, and system facilities
+implemented either by the system, or in cooperation with a
+\fIserver process\fP. These kernel facilities are described in
+this section 1.
+.PP
+The facilities implemented in the kernel are those which define the
+\fIUNIX virtual machine\fP in which each process runs.
+Like many real machines, this virtual machine has memory management hardware,
+an interrupt facility, timers and counters. The UNIX
+virtual machine also allows access to files and other objects through a set of
+\fIdescriptors\fP. Each descriptor resembles a device controller,
+and supports a set of operations. Like devices on real machines, some
+of which are internal to the machine and some of which are external,
+parts of the descriptor machinery are built-in to the operating system, while
+other parts are often implemented in server processes on other machines.
+The facilities provided through the descriptor machinery are described in
+section 2.
+.ds ss 2
diff --git a/share/doc/psd/05.sysman/1.1.t b/share/doc/psd/05.sysman/1.1.t
new file mode 100644
index 00000000000..099a450e91e
--- /dev/null
+++ b/share/doc/psd/05.sysman/1.1.t
@@ -0,0 +1,215 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)1.1.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh "Processes and protection
+.NH 3
+Host and process identifiers
+.PP
+Each UNIX host has associated with it a 32-bit host id, and a host
+name of up to 64 characters (as defined by MAXHOSTNAMELEN in
+\fI<sys/param.h>\fP).
+These are set (by a privileged user)
+and returned by the calls:
+.DS
+sethostid(hostid)
+long hostid;
+
+hostid = gethostid();
+result long hostid;
+
+sethostname(name, len)
+char *name; int len;
+
+len = gethostname(buf, buflen)
+result int len; result char *buf; int buflen;
+.DE
+On each host runs a set of \fIprocesses\fP.
+Each process is largely independent of other processes,
+having its own protection domain, address space, timers, and
+an independent set of references to system or user implemented objects.
+.PP
+Each process in a host is named by an integer
+called the \fIprocess id\fP. This number is
+in the range 1-30000
+and is returned by
+the \fIgetpid\fP routine:
+.DS
+pid = getpid();
+result int pid;
+.DE
+On each UNIX host this identifier is guaranteed to be unique;
+in a multi-host environment, the (hostid, process id) pairs are
+guaranteed unique.
+.NH 3
+Process creation and termination
+.PP
+A new process is created by making a logical duplicate of an
+existing process:
+.DS
+pid = fork();
+result int pid;
+.DE
+The \fIfork\fP call returns twice, once in the parent process, where
+\fIpid\fP is the process identifier of the child,
+and once in the child process where \fIpid\fP is 0.
+The parent-child relationship induces a hierarchical structure on
+the set of processes in the system.
+.PP
+A process may terminate by executing an \fIexit\fP call:
+.DS
+exit(status)
+int status;
+.DE
+returning 8 bits of exit status to its parent.
+.PP
+When a child process exits or
+terminates abnormally, the parent process receives
+information about any
+event which caused termination of the child process. A
+second call provides a non-blocking interface and may also be used
+to retrieve information about resources consumed by the process during its
+lifetime.
+.DS
+#include <sys/wait.h>
+
+pid = wait(astatus);
+result int pid; result union wait *astatus;
+
+pid = wait3(astatus, options, arusage);
+result int pid; result union waitstatus *astatus;
+int options; result struct rusage *arusage;
+.DE
+.PP
+A process can overlay itself with the memory image of another process,
+passing the newly created process a set of parameters, using the call:
+.DS
+execve(name, argv, envp)
+char *name, **argv, **envp;
+.DE
+The specified \fIname\fP must be a file which is in a format recognized
+by the system, either a binary executable file or a file which causes
+the execution of a specified interpreter program to process its contents.
+.NH 3
+User and group ids
+.PP
+Each process in the system has associated with it two user-id's:
+a \fIreal user id\fP and a \fIeffective user id\fP, both 16 bit
+unsigned integers (type \fBuid_t\fP).
+Each process has an \fIreal accounting group id\fP and an \fIeffective
+accounting group id\fP and a set of
+\fIaccess group id's\fP. The group id's are 16 bit unsigned integers
+(type \fBgid_t\fP).
+Each process may be in several different access groups, with the maximum
+concurrent number of access groups a system compilation parameter,
+the constant NGROUPS in the file \fI<sys/param.h>\fP,
+guaranteed to be at least 8.
+.PP
+The real and effective user ids associated with a process are returned by:
+.DS
+ruid = getuid();
+result uid_t ruid;
+
+euid = geteuid();
+result uid_t euid;
+.DE
+the real and effective accounting group ids by:
+.DS
+rgid = getgid();
+result gid_t rgid;
+
+egid = getegid();
+result gid_t egid;
+.DE
+The access group id set is returned by a \fIgetgroups\fP call*:
+.DS
+ngroups = getgroups(gidsetsize, gidset);
+result int ngroups; int gidsetsize; result int gidset[gidsetsize];
+.DE
+.FS
+* The type of the gidset array in getgroups and setgroups
+remains integer for compatibility with 4.2BSD.
+It may change to \fBgid_t\fP in future releases.
+.FE
+.PP
+The user and group id's
+are assigned at login time using the \fIsetreuid\fP, \fIsetregid\fP,
+and \fIsetgroups\fP calls:
+.DS
+setreuid(ruid, euid);
+int ruid, euid;
+
+setregid(rgid, egid);
+int rgid, egid;
+
+setgroups(gidsetsize, gidset)
+int gidsetsize; int gidset[gidsetsize];
+.DE
+The \fIsetreuid\fP call sets both the real and effective user-id's,
+while the \fIsetregid\fP call sets both the real
+and effective accounting group id's.
+Unless the caller is the super-user, \fIruid\fP
+must be equal to either the current real or effective user-id,
+and \fIrgid\fP equal to either the current real or effective
+accounting group id. The \fIsetgroups\fP call is restricted
+to the super-user.
+.NH 3
+Process groups
+.PP
+Each process in the system is also normally associated with a \fIprocess
+group\fP. The group of processes in a process group is sometimes
+referred to as a \fIjob\fP and manipulated by high-level system
+software (such as the shell).
+The current process group of a process is returned by the
+\fIgetpgrp\fP call:
+.DS
+pgrp = getpgrp(pid);
+result int pgrp; int pid;
+.DE
+When a process is in a specific process group it may receive
+software interrupts affecting the group, causing the group to
+suspend or resume execution or to be interrupted or terminated.
+In particular, a system terminal has a process group and only processes
+which are in the process group of the terminal may read from the
+terminal, allowing arbitration of terminals among several different jobs.
+.PP
+The process group associated with a process may be changed by
+the \fIsetpgrp\fP call:
+.DS
+setpgrp(pid, pgrp);
+int pid, pgrp;
+.DE
+Newly created processes are assigned process id's distinct from all
+processes and process groups, and the same process group as their
+parent. A normal (unprivileged) process may set its process group equal
+to its process id. A privileged process may set the process group of any
+process to any value.
diff --git a/share/doc/psd/05.sysman/1.2.t b/share/doc/psd/05.sysman/1.2.t
new file mode 100644
index 00000000000..c0a3b177ed6
--- /dev/null
+++ b/share/doc/psd/05.sysman/1.2.t
@@ -0,0 +1,272 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)1.2.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh "Memory management\(dg
+.NH 3
+Text, data and stack
+.PP
+.FS
+\(dg This section represents the interface planned for later
+releases of the system. Of the calls described in this section,
+only \fIsbrk\fP and \fIgetpagesize\fP are included in 4.3BSD.
+.FE
+Each process begins execution with three logical areas of memory
+called text, data and stack.
+The text area is read-only and shared, while the data and stack
+areas are private to the process. Both the data and stack areas may
+be extended and contracted on program request. The call
+.DS
+addr = sbrk(incr);
+result caddr_t addr; int incr;
+.DE
+changes the size of the data area by \fIincr\fP bytes and
+returns the new end of the data area, while
+.DS
+addr = sstk(incr);
+result caddr_t addr; int incr;
+.DE
+changes the size of the stack area.
+The stack area is also automatically extended as needed.
+On the VAX the text and data areas are adjacent in the P0 region,
+while the stack section is in the P1 region, and grows downward.
+.NH 3
+Mapping pages
+.PP
+The system supports sharing of data between processes
+by allowing pages to be mapped into memory. These mapped
+pages may be \fIshared\fP with other processes or \fIprivate\fP
+to the process.
+Protection and sharing options are defined in \fI<sys/mman.h>\fP as:
+.DS
+.ta \w'#define\ \ 'u +\w'MAP_HASSEMAPHORE\ \ 'u +\w'0x0080\ \ 'u
+/* protections are chosen from these bits, or-ed together */
+#define PROT_READ 0x04 /* pages can be read */
+#define PROT_WRITE 0x02 /* pages can be written */
+#define PROT_EXEC 0x01 /* pages can be executed */
+.DE
+.DS
+.ta \w'#define\ \ 'u +\w'MAP_HASSEMAPHORE\ \ 'u +\w'0x0080\ \ 'u
+/* flags contain mapping type, sharing type and options */
+/* mapping type; choose one */
+#define MAP_FILE 0x0001 /* mapped from a file or device */
+#define MAP_ANON 0x0002 /* allocated from memory, swap space */
+#define MAP_TYPE 0x000f /* mask for type field */
+.DE
+.DS
+.ta \w'#define\ \ 'u +\w'MAP_HASSEMAPHORE\ \ 'u +\w'0x0080\ \ 'u
+/* sharing types; choose one */
+#define MAP_SHARED 0x0010 /* share changes */
+#define MAP_PRIVATE 0x0000 /* changes are private */
+.DE
+.DS
+.ta \w'#define\ \ 'u +\w'MAP_HASSEMAPHORE\ \ 'u +\w'0x0080\ \ 'u
+/* other flags */
+#define MAP_FIXED 0x0020 /* map addr must be exactly as requested */
+#define MAP_INHERIT 0x0040 /* region is retained after exec */
+#define MAP_HASSEMAPHORE 0x0080 /* region may contain semaphores */
+#define MAP_NOPREALLOC 0x0100 /* do not preallocate space */
+.DE
+The cpu-dependent size of a page is returned by the
+\fIgetpagesize\fP system call:
+.DS
+pagesize = getpagesize();
+result int pagesize;
+.DE
+.LP
+The call:
+.DS
+maddr = mmap(addr, len, prot, flags, fd, pos);
+result caddr_t maddr; caddr_t addr; int *len, prot, flags, fd; off_t pos;
+.DE
+causes the pages starting at \fIaddr\fP and continuing
+for at most \fIlen\fP bytes to be mapped from the object represented by
+descriptor \fIfd\fP, starting at byte offset \fIpos\fP.
+The starting address of the region is returned;
+for the convenience of the system,
+it may differ from that supplied
+unless the MAP_FIXED flag is given,
+in which case the exact address will be used or the call will fail.
+The actual amount mapped is returned in \fIlen\fP.
+The \fIaddr\fP, \fIlen\fP, and \fIpos\fP parameters
+must all be multiples of the pagesize.
+A successful \fImmap\fP will delete any previous mapping
+in the allocated address range.
+The parameter \fIprot\fP specifies the accessibility
+of the mapped pages.
+The parameter \fIflags\fP specifies
+the type of object to be mapped,
+mapping options, and
+whether modifications made to
+this mapped copy of the page
+are to be kept \fIprivate\fP, or are to be \fIshared\fP with
+other references.
+Possible types include MAP_FILE,
+mapping a regular file or character-special device memory,
+and MAP_ANON, which maps memory not associated with any specific file.
+The file descriptor used for creating MAP_ANON regions is used only
+for naming, and may be given as \-1 if no name
+is associated with the region.\(dd
+.FS
+\(dd The current design does not allow a process
+to specify the location of swap space.
+In the future we may define an additional mapping type, MAP_SWAP,
+in which the file descriptor argument specifies a file
+or device to which swapping should be done.
+.FE
+The MAP_INHERIT flag allows a region to be inherited after an \fIexec\fP.
+The MAP_HASSEMAPHORE flag allows special handling for
+regions that may contain semaphores.
+The MAP_NOPREALLOC flag allows processes to allocate regions whose
+virtual address space, if fully allocated,
+would exceed the available memory plus swap resources.
+Such regions may get a SIGSEGV signal if they page fault and resources
+are not available to service their request;
+typically they would free up some resources via \fIunmap\fP so that
+when they return from the signal the page
+fault could be successfully completed.
+.PP
+A facility is provided to synchronize a mapped region with the file
+it maps; the call
+.DS
+msync(addr, len);
+caddr_t addr; int len;
+.DE
+writes any modified pages back to the filesystem and updates
+the file modification time.
+If \fIlen\fP is 0, all modified pages within the region containing \fIaddr\fP
+will be flushed;
+if \fIlen\fP is non-zero, only the pages containing \fIaddr\fP and \fIlen\fP
+succeeding locations will be examined.
+Any required synchronization of memory caches
+will also take place at this time.
+Filesystem operations on a file that is mapped for shared modifications
+are unpredictable except after an \fImsync\fP.
+.PP
+A mapping can be removed by the call
+.DS
+munmap(addr, len);
+caddr_t addr; int len;
+.DE
+This call deletes the mappings for the specified address range,
+and causes further references to addresses within the range
+to generate invalid memory references.
+.NH 3
+Page protection control
+.PP
+A process can control the protection of pages using the call
+.DS
+mprotect(addr, len, prot);
+caddr_t addr; int len, prot;
+.DE
+This call changes the specified pages to have protection \fIprot\fP\|.
+Not all implementations will guarantee protection on a page basis;
+the granularity of protection changes may be as large as an entire region.
+.NH 3
+Giving and getting advice
+.PP
+A process that has knowledge of its memory behavior may
+use the \fImadvise\fP call:
+.DS
+madvise(addr, len, behav);
+caddr_t addr; int len, behav;
+.DE
+\fIBehav\fP describes expected behavior, as given
+in \fI<sys/mman.h>\fP:
+.DS
+.ta \w'#define\ \ 'u +\w'MADV_SEQUENTIAL\ \ 'u +\w'00\ \ \ \ 'u
+#define MADV_NORMAL 0 /* no further special treatment */
+#define MADV_RANDOM 1 /* expect random page references */
+#define MADV_SEQUENTIAL 2 /* expect sequential references */
+#define MADV_WILLNEED 3 /* will need these pages */
+#define MADV_DONTNEED 4 /* don't need these pages */
+#define MADV_SPACEAVAIL 5 /* insure that resources are reserved */
+.DE
+Finally, a process may obtain information about whether pages are
+core resident by using the call
+.DS
+mincore(addr, len, vec)
+caddr_t addr; int len; result char *vec;
+.DE
+Here the current core residency of the pages is returned
+in the character array \fIvec\fP, with a value of 1 meaning
+that the page is in-core.
+.NH 3
+Synchronization primitives
+.PP
+Primitives are provided for synchronization using semaphores in shared memory.
+Semaphores must lie within a MAP_SHARED region with at least modes
+PROT_READ and PROT_WRITE.
+The MAP_HASSEMAPHORE flag must have been specified when the region was created.
+To acquire a lock a process calls:
+.DS
+value = mset(sem, wait)
+result int value; semaphore *sem; int wait;
+.DE
+\fIMset\fP indivisibly tests and sets the semaphore \fIsem\fP.
+If the the previous value is zero, the process has acquired the lock
+and \fImset\fP returns true immediately.
+Otherwise, if the \fIwait\fP flag is zero,
+failure is returned.
+If \fIwait\fP is true and the previous value is non-zero,
+\fImset\fP relinquishes the processor until notified that it should retry.
+.LP
+To release a lock a process calls:
+.DS
+mclear(sem)
+semaphore *sem;
+.DE
+\fIMclear\fP indivisibly tests and clears the semaphore \fIsem\fP.
+If the ``WANT'' flag is zero in the previous value,
+\fImclear\fP returns immediately.
+If the ``WANT'' flag is non-zero in the previous value,
+\fImclear\fP arranges for waiting processes to retry before returning.
+.PP
+Two routines provide services analogous to the kernel
+\fIsleep\fP and \fIwakeup\fP functions interpreted in the domain of
+shared memory.
+A process may relinquish the processor by calling \fImsleep\fP
+with a set semaphore:
+.DS
+msleep(sem)
+semaphore *sem;
+.DE
+If the semaphore is still set when it is checked by the kernel,
+the process will be put in a sleeping state
+until some other process issues an \fImwakeup\fP for the same semaphore
+within the region using the call:
+.DS
+mwakeup(sem)
+semaphore *sem;
+.DE
+An \fImwakeup\fP may awaken all sleepers on the semaphore,
+or may awaken only the next sleeper on a queue.
diff --git a/share/doc/psd/05.sysman/1.3.t b/share/doc/psd/05.sysman/1.3.t
new file mode 100644
index 00000000000..f81a1850117
--- /dev/null
+++ b/share/doc/psd/05.sysman/1.3.t
@@ -0,0 +1,254 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)1.3.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh "Signals
+.PP
+.NH 3
+Overview
+.PP
+The system defines a set of \fIsignals\fP that may be delivered
+to a process. Signal delivery resembles the occurrence of a hardware
+interrupt: the signal is blocked from further occurrence,
+the current process context is saved, and a new one
+is built. A process may specify
+the \fIhandler\fP to which a signal is delivered, or specify that
+the signal is to be \fIblocked\fP or \fIignored\fP. A process may
+also specify that a
+\fIdefault\fP action is to be taken when signals occur.
+.PP
+Some signals
+will cause a process to exit when they are not caught. This
+may be accompanied by creation of a \fIcore\fP image file, containing
+the current memory image of the process for use in post-mortem debugging.
+A process may choose to have signals delivered on a special
+stack, so that sophisticated software stack manipulations are possible.
+.PP
+All signals have the same \fIpriority\fP. If multiple signals
+are pending simultaneously, the order in which they are delivered
+to a process is implementation specific. Signal routines execute
+with the signal that caused their invocation \fIblocked\fP, but other
+signals may yet occur. Mechanisms are provided whereby critical sections
+of code may protect themselves against the occurrence of specified signals.
+.NH 3
+Signal types
+.PP
+The signals defined by the system fall into one of
+five classes: hardware conditions,
+software conditions, input/output notification, process control, or
+resource control.
+The set of signals is defined in the file \fI<signal.h>\fP.
+.PP
+Hardware signals are derived from exceptional conditions which
+may occur during
+execution. Such signals include SIGFPE representing floating
+point and other arithmetic exceptions, SIGILL for illegal instruction
+execution, SIGSEGV for addresses outside the currently assigned
+area of memory, and SIGBUS for accesses that violate memory
+protection constraints.
+Other, more cpu-specific hardware signals exist,
+such as those for the various customer-reserved instructions on
+the VAX (SIGIOT, SIGEMT, and SIGTRAP).
+.PP
+Software signals reflect interrupts generated by user request:
+SIGINT for the normal interrupt signal; SIGQUIT for the more
+powerful \fIquit\fP signal, that normally causes a core image
+to be generated; SIGHUP and SIGTERM that cause graceful
+process termination, either because a user has ``hung up'', or
+by user or program request; and SIGKILL, a more powerful termination
+signal which a process cannot catch or ignore.
+Programs may define their own asynchronous events using SIGUSR1
+and SIGUSR2.
+Other software signals (SIGALRM, SIGVTALRM, SIGPROF)
+indicate the expiration of interval timers.
+.PP
+A process can request notification via a SIGIO signal
+when input or output is possible
+on a descriptor, or when a \fInon-blocking\fP operation completes.
+A process may request to receive a SIGURG signal when an
+urgent condition arises.
+.PP
+A process may be \fIstopped\fP by a signal sent to it or the members
+of its process group. The SIGSTOP signal is a powerful stop
+signal, because it cannot be caught. Other stop signals
+SIGTSTP, SIGTTIN, and SIGTTOU are used when a user request, input
+request, or output request respectively is the reason for stopping the process.
+A SIGCONT signal is sent to a process when it is
+continued from a stopped state.
+Processes may receive notification with a SIGCHLD signal when
+a child process changes state, either by stopping or by terminating.
+.PP
+Exceeding resource limits may cause signals to be generated.
+SIGXCPU occurs when a process nears its CPU time limit and SIGXFSZ
+warns that the limit on file size creation has been reached.
+.NH 3
+Signal handlers
+.PP
+A process has a handler associated with each signal.
+The handler controls the way the signal is delivered.
+The call
+.DS
+#include <signal.h>
+
+._f
+struct sigvec {
+ int (*sv_handler)();
+ int sv_mask;
+ int sv_flags;
+};
+
+sigvec(signo, sv, osv)
+int signo; struct sigvec *sv; result struct sigvec *osv;
+.DE
+assigns interrupt handler address \fIsv_handler\fP to signal \fIsigno\fP.
+Each handler address
+specifies either an interrupt routine for the signal, that the
+signal is to be ignored,
+or that a default action (usually process termination) is to occur
+if the signal occurs.
+The constants
+SIG_IGN and SIG_DEF used as values for \fIsv_handler\fP
+cause ignoring or defaulting of a condition.
+The \fIsv_mask\fP value specifies the
+signal mask to be used when the handler is invoked; it implicitly includes
+the signal which invoked the handler.
+Signal masks include one bit for each signal;
+the mask for a signal \fIsigno\fP is provided by the macro
+\fIsigmask\fP(\fIsigno\fP), from \fI<signal.h>\fP.
+\fISv_flags\fP specifies whether system calls should be
+restarted if the signal handler returns and
+whether the handler should operate on the normal run-time
+stack or a special signal stack (see below). If \fIosv\fP
+is non-zero, the previous signal vector is returned.
+.PP
+When a signal condition arises for a process, the signal
+is added to a set of signals pending for the process.
+If the signal is not currently \fIblocked\fP by the process
+then it will be delivered. The process of signal delivery
+adds the signal to be delivered and those signals
+specified in the associated signal
+handler's \fIsv_mask\fP to a set of those \fImasked\fP
+for the process, saves the current process context,
+and places the process in the context of the signal
+handling routine. The call is arranged so that if the signal
+handling routine exits normally the signal mask will be restored
+and the process will resume execution in the original context.
+If the process wishes to resume in a different context, then
+it must arrange to restore the signal mask itself.
+.PP
+The mask of \fIblocked\fP signals is independent of handlers for
+signals. It delays signals from being delivered much as a
+raised hardware interrupt priority level delays hardware interrupts.
+Preventing an interrupt from occurring by changing the handler is analogous to
+disabling a device from further interrupts.
+.PP
+The signal handling routine \fIsv_handler\fP is called by a C call
+of the form
+.DS
+(*sv_handler)(signo, code, scp);
+int signo; long code; struct sigcontext *scp;
+.DE
+The \fIsigno\fP gives the number of the signal that occurred, and
+the \fIcode\fP, a word of information supplied by the hardware.
+The \fIscp\fP parameter is a pointer to a machine-dependent
+structure containing the information for restoring the
+context before the signal.
+.NH 3
+Sending signals
+.PP
+A process can send a signal to another process or group of processes
+with the calls:
+.DS
+kill(pid, signo)
+int pid, signo;
+
+killpgrp(pgrp, signo)
+int pgrp, signo;
+.DE
+Unless the process sending the signal is privileged,
+it must have the same effective user id as the process receiving the signal.
+.PP
+Signals are also sent implicitly from a terminal device to the
+process group associated with the terminal when certain input characters
+are typed.
+.NH 3
+Protecting critical sections
+.PP
+To block a section of code against one or more signals, a \fIsigblock\fP
+call may be used to add a set of signals to the existing mask, returning
+the old mask:
+.DS
+oldmask = sigblock(mask);
+result long oldmask; long mask;
+.DE
+The old mask can then be restored later with \fIsigsetmask\fP\|,
+.DS
+oldmask = sigsetmask(mask);
+result long oldmask; long mask;
+.DE
+The \fIsigblock\fP call can be used to read the current mask
+by specifying an empty \fImask\fP\|.
+.PP
+It is possible to check conditions with some signals blocked,
+and then to pause waiting for a signal and restoring the mask, by using:
+.DS
+sigpause(mask);
+long mask;
+.DE
+.NH 3
+Signal stacks
+.PP
+Applications that maintain complex or fixed size stacks can use
+the call
+.DS
+._f
+struct sigstack {
+ caddr_t ss_sp;
+ int ss_onstack;
+};
+
+sigstack(ss, oss)
+struct sigstack *ss; result struct sigstack *oss;
+.DE
+to provide the system with a stack based at \fIss_sp\fP for delivery
+of signals. The value \fIss_onstack\fP indicates whether the
+process is currently on the signal stack,
+a notion maintained in software by the system.
+.PP
+When a signal is to be delivered, the system checks whether
+the process is on a signal stack. If not, then the process is switched
+to the signal stack for delivery, with the return from the signal
+arranged to restore the previous stack.
+.PP
+If the process wishes to take a non-local exit from the signal routine,
+or run code from the signal stack that uses a different stack,
+a \fIsigstack\fP call should be used to reset the signal stack.
diff --git a/share/doc/psd/05.sysman/1.4.t b/share/doc/psd/05.sysman/1.4.t
new file mode 100644
index 00000000000..a67a5cedcfa
--- /dev/null
+++ b/share/doc/psd/05.sysman/1.4.t
@@ -0,0 +1,137 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)1.4.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh "Timers
+.NH 3
+Real time
+.PP
+The system's notion of the current Greenwich time and the current time
+zone is set and returned by the call by the calls:
+.DS
+#include <sys/time.h>
+
+settimeofday(tvp, tzp);
+struct timeval *tp;
+struct timezone *tzp;
+
+gettimeofday(tp, tzp);
+result struct timeval *tp;
+result struct timezone *tzp;
+.DE
+where the structures are defined in \fI<sys/time.h>\fP as:
+.DS
+._f
+struct timeval {
+ long tv_sec; /* seconds since Jan 1, 1970 */
+ long tv_usec; /* and microseconds */
+};
+
+struct timezone {
+ int tz_minuteswest; /* of Greenwich */
+ int tz_dsttime; /* type of dst correction to apply */
+};
+.DE
+The precision of the system clock is hardware dependent.
+Earlier versions of UNIX contained only a 1-second resolution version
+of this call, which remains as a library routine:
+.DS
+time(tvsec)
+result long *tvsec;
+.DE
+returning only the tv_sec field from the \fIgettimeofday\fP call.
+.NH 3
+Interval time
+.PP
+The system provides each process with three interval timers,
+defined in \fI<sys/time.h>\fP:
+.DS
+._d
+#define ITIMER_REAL 0 /* real time intervals */
+#define ITIMER_VIRTUAL 1 /* virtual time intervals */
+#define ITIMER_PROF 2 /* user and system virtual time */
+.DE
+The ITIMER_REAL timer decrements
+in real time. It could be used by a library routine to
+maintain a wakeup service queue. A SIGALRM signal is delivered
+when this timer expires.
+.PP
+The ITIMER_VIRTUAL timer decrements in process virtual time.
+It runs only when the process is executing. A SIGVTALRM signal
+is delivered when it expires.
+.PP
+The ITIMER_PROF timer decrements both in process virtual time and when
+the system is running on behalf of the process.
+It is designed to be used by processes to statistically profile
+their execution.
+A SIGPROF signal is delivered when it expires.
+.PP
+A timer value is defined by the \fIitimerval\fP structure:
+.DS
+._f
+struct itimerval {
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+.DE
+and a timer is set or read by the call:
+.DS
+getitimer(which, value);
+int which; result struct itimerval *value;
+
+setitimer(which, value, ovalue);
+int which; struct itimerval *value; result struct itimerval *ovalue;
+.DE
+The third argument to \fIsetitimer\fP specifies an optional structure
+to receive the previous contents of the interval timer.
+A timer can be disabled by specifying a timer value of 0.
+.PP
+The system rounds argument timer intervals to be not less than the
+resolution of its clock. This clock resolution can be determined
+by loading a very small value into a timer and reading the timer back to
+see what value resulted.
+.PP
+The \fIalarm\fP system call of earlier versions of UNIX is provided
+as a library routine using the ITIMER_REAL timer. The process
+profiling facilities of earlier versions of UNIX
+remain because
+it is not always possible to guarantee
+the automatic restart of system calls after
+receipt of a signal.
+The \fIprofil\fP call arranges for the kernel to begin gathering
+execution statistics for a process:
+.DS
+profil(buf, bufsize, offset, scale);
+result char *buf; int bufsize, offset, scale;
+.DE
+This begins sampling of the program counter, with statistics maintained
+in the user-provided buffer.
diff --git a/share/doc/psd/05.sysman/1.5.t b/share/doc/psd/05.sysman/1.5.t
new file mode 100644
index 00000000000..e642e2dfa2b
--- /dev/null
+++ b/share/doc/psd/05.sysman/1.5.t
@@ -0,0 +1,225 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)1.5.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh Descriptors
+.PP
+.NH 3
+The reference table
+.PP
+Each process has access to resources through
+\fIdescriptors\fP. Each descriptor is a handle allowing
+the process to reference objects such as files, devices
+and communications links.
+.PP
+Rather than allowing processes direct access to descriptors, the system
+introduces a level of indirection, so that descriptors may be shared
+between processes. Each process has a \fIdescriptor reference table\fP,
+containing pointers to the actual descriptors. The descriptors
+themselves thus have multiple references, and are reference counted by the
+system.
+.PP
+Each process has a fixed size descriptor reference table, where
+the size is returned by the \fIgetdtablesize\fP call:
+.DS
+nds = getdtablesize();
+result int nds;
+.DE
+and guaranteed to be at least 20. The entries in the descriptor reference
+table are referred to by small integers; for example if there
+are 20 slots they are numbered 0 to 19.
+.NH 3
+Descriptor properties
+.PP
+Each descriptor has a logical set of properties maintained
+by the system and defined by its \fItype\fP.
+Each type supports a set of operations;
+some operations, such as reading and writing, are common to several
+abstractions, while others are unique.
+The generic operations applying to many of these types are described
+in section 2.1. Naming contexts, files and directories are described in
+section 2.2. Section 2.3 describes communications domains and sockets.
+Terminals and (structured and unstructured) devices are described
+in section 2.4.
+.NH 3
+Managing descriptor references
+.PP
+A duplicate of a descriptor reference may be made by doing
+.DS
+new = dup(old);
+result int new; int old;
+.DE
+returning a copy of descriptor reference \fIold\fP indistinguishable from
+the original. The \fInew\fP chosen by the system will be the
+smallest unused descriptor reference slot.
+A copy of a descriptor reference may be made in a specific slot
+by doing
+.DS
+dup2(old, new);
+int old, new;
+.DE
+The \fIdup2\fP call causes the system to deallocate the descriptor reference
+current occupying slot \fInew\fP, if any, replacing it with a reference
+to the same descriptor as old.
+This deallocation is also performed by:
+.DS
+close(old);
+int old;
+.DE
+.NH 3
+Multiplexing requests
+.PP
+The system provides a
+standard way to do
+synchronous and asynchronous multiplexing of operations.
+.PP
+Synchronous multiplexing is performed by using the \fIselect\fP call
+to examine the state of multiple descriptors simultaneously,
+and to wait for state changes on those descriptors.
+Sets of descriptors of interest are specified as bit masks,
+as follows:
+.DS
+#include <sys/types.h>
+
+nds = select(nd, in, out, except, tvp);
+result int nds; int nd; result fd_set *in, *out, *except;
+struct timeval *tvp;
+
+FD_ZERO(&fdset);
+FD_SET(fd, &fdset);
+FD_CLR(fd, &fdset);
+FD_ISSET(fd, &fdset);
+int fs; fs_set fdset;
+.DE
+The \fIselect\fP call examines the descriptors
+specified by the
+sets \fIin\fP, \fIout\fP and \fIexcept\fP, replacing
+the specified bit masks by the subsets that select true for input,
+output, and exceptional conditions respectively (\fInd\fP
+indicates the number of file descriptors specified by the bit masks).
+If any descriptors meet the following criteria,
+then the number of such descriptors is returned in \fInds\fP and the
+bit masks are updated.
+.if n .ds bu *
+.if t .ds bu \(bu
+.IP \*(bu
+A descriptor selects for input if an input oriented operation
+such as \fIread\fP or \fIreceive\fP is possible, or if a
+connection request may be accepted (see section 2.3.1.4).
+.IP \*(bu
+A descriptor selects for output if an output oriented operation
+such as \fIwrite\fP or \fIsend\fP is possible, or if an operation
+that was ``in progress'', such as connection establishment,
+has completed (see section 2.1.3).
+.IP \*(bu
+A descriptor selects for an exceptional condition if a condition
+that would cause a SIGURG signal to be generated exists (see section 1.3.2),
+or other device-specific events have occurred.
+.LP
+If none of the specified conditions is true, the operation
+waits for one of the conditions to arise,
+blocking at most the amount of time specified by \fItvp\fP.
+If \fItvp\fP is given as 0, the \fIselect\fP waits indefinitely.
+.PP
+Options affecting I/O on a descriptor
+may be read and set by the call:
+.DS
+._d
+dopt = fcntl(d, cmd, arg)
+result int dopt; int d, cmd, arg;
+
+/* interesting values for cmd */
+#define F_SETFL 3 /* set descriptor options */
+#define F_GETFL 4 /* get descriptor options */
+#define F_SETOWN 5 /* set descriptor owner (pid/pgrp) */
+#define F_GETOWN 6 /* get descriptor owner (pid/pgrp) */
+.DE
+The F_SETFL \fIcmd\fP may be used to set a descriptor in
+non-blocking I/O mode and/or enable signaling when I/O is
+possible. F_SETOWN may be used to specify a process or process
+group to be signaled when using the latter mode of operation
+or when urgent indications arise.
+.PP
+Operations on non-blocking descriptors will
+either complete immediately,
+note an error EWOULDBLOCK,
+partially complete an input or output operation returning a partial count,
+or return an error EINPROGRESS noting that the requested operation is
+in progress.
+A descriptor which has signalling enabled will cause the specified process
+and/or process group
+be signaled, with a SIGIO for input, output, or in-progress
+operation complete, or
+a SIGURG for exceptional conditions.
+.PP
+For example, when writing to a terminal
+using non-blocking output,
+the system will accept only as much data as there is buffer space for
+and return; when making a connection on a \fIsocket\fP, the operation may
+return indicating that the connection establishment is ``in progress''.
+The \fIselect\fP facility can be used to determine when further
+output is possible on the terminal, or when the connection establishment
+attempt is complete.
+.NH 3
+Descriptor wrapping.\(dg
+.PP
+.FS
+\(dg The facilities described in this section are not included
+in 4.3BSD.
+.FE
+A user process may build descriptors of a specified type by
+\fIwrapping\fP a communications channel with a system supplied protocol
+translator:
+.DS
+new = wrap(old, proto)
+result int new; int old; struct dprop *proto;
+.DE
+Operations on the descriptor \fIold\fP are then translated by the
+system provided protocol translator into requests on the underlying
+object \fIold\fP in a way defined by the protocol.
+The protocols supported by the kernel may vary from system to system
+and are described in the programmers manual.
+.PP
+Protocols may be based on communications multiplexing or a rights-passing
+style of handling multiple requests made on the same object. For instance,
+a protocol for implementing a file abstraction may or may not include
+locally generated ``read-ahead'' requests. A protocol that provides for
+read-ahead may provide higher performance but have a more difficult
+implementation.
+.PP
+Another example is the terminal driving facilities. Normally a terminal
+is associated with a communications line, and the terminal type
+and standard terminal access protocol are wrapped around a synchronous
+communications line and given to the user. If a virtual terminal
+is required, the terminal driver can be wrapped around a communications
+link, the other end of which is held by a virtual terminal protocol
+interpreter.
diff --git a/share/doc/psd/05.sysman/1.6.t b/share/doc/psd/05.sysman/1.6.t
new file mode 100644
index 00000000000..109d2714f54
--- /dev/null
+++ b/share/doc/psd/05.sysman/1.6.t
@@ -0,0 +1,135 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)1.6.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh "Resource controls
+.NH 3
+Process priorities
+.PP
+The system gives CPU scheduling priority to processes that have not used
+CPU time recently. This tends to favor interactive processes and
+processes that execute only for short periods.
+It is possible to determine the priority currently
+assigned to a process, process group, or the processes of a specified user,
+or to alter this priority using the calls:
+.DS
+._d
+#define PRIO_PROCESS 0 /* process */
+#define PRIO_PGRP 1 /* process group */
+#define PRIO_USER 2 /* user id */
+
+prio = getpriority(which, who);
+result int prio; int which, who;
+
+setpriority(which, who, prio);
+int which, who, prio;
+.DE
+The value \fIprio\fP is in the range \-20 to 20.
+The default priority is 0; lower priorities cause more
+favorable execution.
+The \fIgetpriority\fP call returns the highest priority (lowest numerical value)
+enjoyed by any of the specified processes.
+The \fIsetpriority\fP call sets the priorities of all of the
+specified processes to the specified value.
+Only the super-user may lower priorities.
+.NH 3
+Resource utilization
+.PP
+The resources used by a process are returned by a \fIgetrusage\fP call,
+returning information in a structure defined in \fI<sys/resource.h>\fP:
+.DS
+._d
+#define RUSAGE_SELF 0 /* usage by this process */
+#define RUSAGE_CHILDREN -1 /* usage by all children */
+
+getrusage(who, rusage)
+int who; result struct rusage *rusage;
+
+._f
+struct rusage {
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
+ int ru_maxrss; /* maximum core resident set size: kbytes */
+ int ru_ixrss; /* integral shared memory size (kbytes*sec) */
+ int ru_idrss; /* unshared data memory size */
+ int ru_isrss; /* unshared stack memory size */
+ int ru_minflt; /* page-reclaims */
+ int ru_majflt; /* page faults */
+ int ru_nswap; /* swaps */
+ int ru_inblock; /* block input operations */
+ int ru_oublock; /* block output operations */
+ int ru_msgsnd; /* messages sent */
+ int ru_msgrcv; /* messages received */
+ int ru_nsignals; /* signals received */
+ int ru_nvcsw; /* voluntary context switches */
+ int ru_nivcsw; /* involuntary context switches */
+};
+.DE
+The \fIwho\fP parameter specifies whose resource usage is to be returned.
+The resources used by the current process, or by all
+the terminated children of the current process may be requested.
+.NH 3
+Resource limits
+.PP
+The resources of a process for which limits are controlled by the
+kernel are defined in \fI<sys/resource.h>\fP, and controlled by the
+\fIgetrlimit\fP and \fIsetrlimit\fP calls:
+.DS
+._d
+#define RLIMIT_CPU 0 /* cpu time in milliseconds */
+#define RLIMIT_FSIZE 1 /* maximum file size */
+#define RLIMIT_DATA 2 /* maximum data segment size */
+#define RLIMIT_STACK 3 /* maximum stack segment size */
+#define RLIMIT_CORE 4 /* maximum core file size */
+#define RLIMIT_RSS 5 /* maximum resident set size */
+
+#define RLIM_NLIMITS 6
+
+#define RLIM_INFINITY 0x7f\&f\&f\&f\&f\&f\&f
+
+._f
+struct rlimit {
+ int rlim_cur; /* current (soft) limit */
+ int rlim_max; /* hard limit */
+};
+
+getrlimit(resource, rlp)
+int resource; result struct rlimit *rlp;
+
+setrlimit(resource, rlp)
+int resource; struct rlimit *rlp;
+.DE
+.PP
+Only the super-user can raise the maximum limits.
+Other users may only
+alter \fIrlim_cur\fP within the range from 0 to \fIrlim_max\fP
+or (irreversibly) lower \fIrlim_max\fP.
diff --git a/share/doc/psd/05.sysman/1.7.t b/share/doc/psd/05.sysman/1.7.t
new file mode 100644
index 00000000000..09e1a027930
--- /dev/null
+++ b/share/doc/psd/05.sysman/1.7.t
@@ -0,0 +1,100 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)1.7.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh "System operation support
+.PP
+Unless noted otherwise,
+the calls in this section are permitted only to a privileged user.
+.NH 3
+Bootstrap operations
+.PP
+The call
+.DS
+mount(blkdev, dir, ronly);
+char *blkdev, *dir; int ronly;
+.DE
+extends the UNIX name space. The \fImount\fP call specifies
+a block device \fIblkdev\fP containing a UNIX file system
+to be made available starting at \fIdir\fP. If \fIronly\fP is
+set then the file system is read-only; writes to the file system
+will not be permitted and access times will not be updated
+when files are referenced.
+\fIDir\fP is normally a name in the root directory.
+.PP
+The call
+.DS
+swapon(blkdev, size);
+char *blkdev; int size;
+.DE
+specifies a device to be made available for paging and swapping.
+.PP
+.NH 3
+Shutdown operations
+.PP
+The call
+.DS
+unmount(dir);
+char *dir;
+.DE
+unmounts the file system mounted on \fIdir\fP.
+This call will succeed only if the file system is
+not currently being used.
+.PP
+The call
+.DS
+sync();
+.DE
+schedules input/output to clean all system buffer caches.
+(This call does not require privileged status.)
+.PP
+The call
+.DS
+reboot(how)
+int how;
+.DE
+causes a machine halt or reboot. The call may request a reboot
+by specifying \fIhow\fP as RB_AUTOBOOT, or that the machine be halted
+with RB_HALT. These constants are defined in \fI<sys/reboot.h>\fP.
+.NH 3
+Accounting
+.PP
+The system optionally keeps an accounting record in a file
+for each process that exits on the system.
+The format of this record is beyond the scope of this document.
+The accounting may be enabled to a file \fIname\fP by doing
+.DS
+acct(path);
+char *path;
+.DE
+If \fIpath\fP is null, then accounting is disabled. Otherwise,
+the named file becomes the accounting file.
diff --git a/share/doc/psd/05.sysman/2.0.t b/share/doc/psd/05.sysman/2.0.t
new file mode 100644
index 00000000000..ca44bc2a869
--- /dev/null
+++ b/share/doc/psd/05.sysman/2.0.t
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)2.0.t 8.1 (Berkeley) 6/8/93
+.\"
+.ds ss 1
+.sh "System facilities
+This section discusses the system facilities that
+are not considered part of the kernel.
+.PP
+The system abstractions described are:
+.IP "Directory contexts
+.br
+A directory context is a position in the UNIX file system name
+space. Operations on files and other named objects in a file system are
+always specified relative to such a context.
+.IP "Files
+.br
+Files are used to store uninterpreted sequence of bytes on which
+random access \fIreads\fP and \fIwrites\fP may occur.
+Pages from files may also be mapped into process address space.\(dg
+A directory may be read as a file.
+.FS
+\(dg Support for mapping files is not included in the 4.3 release.
+.FE
+.IP "Communications domains
+.br
+A communications domain represents
+an interprocess communications environment, such as the communications
+facilities of the UNIX system,
+communications in the INTERNET, or the resource sharing protocols
+and access rights of a resource sharing system on a local network.
+.IP "Sockets
+.br
+A socket is an endpoint of communication and the focal
+point for IPC in a communications domain. Sockets may be created in pairs,
+or given names and used to rendezvous with other sockets
+in a communications domain, accepting connections from these
+sockets or exchanging messages with them. These operations model
+a labeled or unlabeled communications graph, and can be used in a
+wide variety of communications domains. Sockets can have different
+\fItypes\fP\| to provide different semantics of communication,
+increasing the flexibility of the model.
+.IP "Terminals and other devices
+.br
+Devices include
+terminals, providing input editing and interrupt generation
+and output flow control and editing, magnetic tapes,
+disks and other peripherals. They often support the generic
+\fIread\fP and \fIwrite\fP operations as well as a number of \fIioctl\fP\|s.
+.IP "Processes
+.br
+Process descriptors provide facilities for control and debugging of
+other processes.
+.ds ss 2
diff --git a/share/doc/psd/05.sysman/2.1.t b/share/doc/psd/05.sysman/2.1.t
new file mode 100644
index 00000000000..ef25887ee18
--- /dev/null
+++ b/share/doc/psd/05.sysman/2.1.t
@@ -0,0 +1,138 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)2.1.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh "Generic operations
+.PP
+.PP
+Many system abstractions support the
+operations \fIread\fP, \fIwrite\fP and \fIioctl\fP. We describe
+the basics of these common primitives here.
+Similarly, the mechanisms whereby normally synchronous operations
+may occur in a non-blocking or asynchronous fashion are
+common to all system-defined abstractions and are described here.
+.NH 3
+Read and write
+.PP
+The \fIread\fP and \fIwrite\fP system calls can be applied
+to communications channels, files, terminals and devices.
+They have the form:
+.DS
+cc = read(fd, buf, nbytes);
+result int cc; int fd; result caddr_t buf; int nbytes;
+
+cc = write(fd, buf, nbytes);
+result int cc; int fd; caddr_t buf; int nbytes;
+.DE
+The \fIread\fP call transfers as much data as possible from the
+object defined by \fIfd\fP to the buffer at address \fIbuf\fP of
+size \fInbytes\fP. The number of bytes transferred is
+returned in \fIcc\fP, which is \-1 if a return occurred before
+any data was transferred because of an error or use of non-blocking
+operations.
+.PP
+The \fIwrite\fP call transfers data from the buffer to the
+object defined by \fIfd\fP. Depending on the type of \fIfd\fP,
+it is possible that the \fIwrite\fP call will accept some portion
+of the provided bytes; the user should resubmit the other bytes
+in a later request in this case.
+Error returns because of interrupted or otherwise incomplete operations
+are possible.
+.PP
+Scattering of data on input or gathering of data for output
+is also possible using an array of input/output vector descriptors.
+The type for the descriptors is defined in \fI<sys/uio.h>\fP as:
+.DS
+._f
+struct iovec {
+ caddr_t iov_msg; /* base of a component */
+ int iov_len; /* length of a component */
+};
+.DE
+The calls using an array of descriptors are:
+.DS
+cc = readv(fd, iov, iovlen);
+result int cc; int fd; struct iovec *iov; int iovlen;
+
+cc = writev(fd, iov, iovlen);
+result int cc; int fd; struct iovec *iov; int iovlen;
+.DE
+Here \fIiovlen\fP is the count of elements in the \fIiov\fP array.
+.NH 3
+Input/output control
+.PP
+Control operations on an object are performed by the \fIioctl\fP
+operation:
+.DS
+ioctl(fd, request, buffer);
+int fd, request; caddr_t buffer;
+.DE
+This operation causes the specified \fIrequest\fP to be performed
+on the object \fIfd\fP. The \fIrequest\fP parameter specifies
+whether the argument buffer is to be read, written, read and written,
+or is not needed, and also the size of the buffer, as well as the
+request.
+Different descriptor types and subtypes within descriptor types
+may use distinct \fIioctl\fP requests. For example,
+operations on terminals control flushing of input and output
+queues and setting of terminal parameters; operations on
+disks cause formatting operations to occur; operations on tapes
+control tape positioning.
+.PP
+The names for basic control operations are defined in \fI<sys/ioctl.h>\fP.
+.NH 3
+Non-blocking and asynchronous operations
+.PP
+A process that wishes to do non-blocking operations on one of
+its descriptors sets the descriptor in non-blocking mode as
+described in section 1.5.4. Thereafter the \fIread\fP call will
+return a specific EWOULDBLOCK error indication if there is no data to be
+\fIread\fP. The process may
+\fIselect\fP the associated descriptor to determine when a read is
+possible.
+.PP
+Output attempted when a descriptor can accept less than is requested
+will either accept some of the provided data, returning a shorter than normal
+length, or return an error indicating that the operation would block.
+More output can be performed as soon as a \fIselect\fP call indicates
+the object is writeable.
+.PP
+Operations other than data input or output
+may be performed on a descriptor in a non-blocking fashion.
+These operations will return with a characteristic error indicating
+that they are in progress
+if they cannot complete immediately. The descriptor
+may then be \fIselect\fPed for \fIwrite\fP to find out
+when the operation has been completed. When \fIselect\fP indicates
+the descriptor is writeable, the operation has completed.
+Depending on the nature of the descriptor and the operation,
+additional activity may be started or the new state may be tested.
diff --git a/share/doc/psd/05.sysman/2.2.t b/share/doc/psd/05.sysman/2.2.t
new file mode 100644
index 00000000000..996e9b5953b
--- /dev/null
+++ b/share/doc/psd/05.sysman/2.2.t
@@ -0,0 +1,470 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)2.2.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh "File system
+.NH 3
+Overview
+.PP
+The file system abstraction provides access to a hierarchical
+file system structure.
+The file system contains directories (each of which may contain
+other sub-directories) as well as files and references to other
+objects such as devices and inter-process communications sockets.
+.PP
+Each file is organized as a linear array of bytes. No record
+boundaries or system related information is present in
+a file.
+Files may be read and written in a random-access fashion.
+The user may read the data in a directory as though
+it were an ordinary file to determine the names of the contained files,
+but only the system may write into the directories.
+The file system stores only a small amount of ownership, protection and usage
+information with a file.
+.NH 3
+Naming
+.PP
+The file system calls take \fIpath name\fP arguments.
+These consist of a zero or more component \fIfile names\fP
+separated by ``/\^'' characters, where each file name
+is up to 255 ASCII characters excluding null and ``/\^''.
+.PP
+Each process always has two naming contexts: one for the
+root directory of the file system and one for the
+current working directory. These are used
+by the system in the filename translation process.
+If a path name begins with a ``/\^'', it is called
+a full path name and interpreted relative to the root directory context.
+If the path name does not begin with a ``/\^'' it is called
+a relative path name and interpreted relative to the current directory
+context.
+.PP
+The system limits
+the total length of a path name to 1024 characters.
+.PP
+The file name ``..'' in each directory refers to
+the parent directory of that directory.
+The parent directory of the root of the file system is always that directory.
+.PP
+The calls
+.DS
+chdir(path);
+char *path;
+
+chroot(path)
+char *path;
+.DE
+change the current working directory and root directory context of a process.
+Only the super-user can change the root directory context of a process.
+.NH 3
+Creation and removal
+.PP
+The file system allows directories, files, special devices,
+and ``portals'' to be created and removed from the file system.
+.NH 4
+Directory creation and removal
+.PP
+A directory is created with the \fImkdir\fP system call:
+.DS
+mkdir(path, mode);
+char *path; int mode;
+.DE
+where the mode is defined as for files (see below).
+Directories are removed with the \fIrmdir\fP system call:
+.DS
+rmdir(path);
+char *path;
+.DE
+A directory must be empty if it is to be deleted.
+.NH 4
+File creation
+.PP
+Files are created with the \fIopen\fP system call,
+.DS
+fd = open(path, oflag, mode);
+result int fd; char *path; int oflag, mode;
+.DE
+The \fIpath\fP parameter specifies the name of the
+file to be created. The \fIoflag\fP parameter must
+include O_CREAT from below to cause the file to be created.
+Bits for \fIoflag\fP are
+defined in \fI<sys/file.h>\fP:
+.DS
+._d
+#define O_RDONLY 000 /* open for reading */
+#define O_WRONLY 001 /* open for writing */
+#define O_RDWR 002 /* open for read & write */
+#define O_NDELAY 004 /* non-blocking open */
+#define O_APPEND 010 /* append on each write */
+#define O_CREAT 01000 /* open with file create */
+#define O_TRUNC 02000 /* open with truncation */
+#define O_EXCL 04000 /* error on create if file exists */
+.DE
+.PP
+One of O_RDONLY, O_WRONLY and O_RDWR should be specified,
+indicating what types of operations are desired to be performed
+on the open file. The operations will be checked against the user's
+access rights to the file before allowing the \fIopen\fP to succeed.
+Specifying O_APPEND causes writes to automatically append to the
+file.
+The flag O_CREAT causes the file to be created if it does not
+exist, owned by the current user
+and the group of the containing directory.
+The protection for the new file is specified in \fImode\fP.
+The file mode is used as a three digit octal number.
+Each digit encodes read access as 4, write access as 2 and execute
+access as 1, or'ed together. The 0700 bits describe owner
+access, the 070 bits describe the access rights for processes in the same
+group as the file, and the 07 bits describe the access rights
+for other processes.
+.PP
+If the open specifies to create the file with O_EXCL
+and the file already exists, then the \fIopen\fP will fail
+without affecting the file in any way. This provides a
+simple exclusive access facility.
+If the file exists but is a symbolic link, the open will fail
+regardless of the existence of the file specified by the link.
+.NH 4
+Creating references to devices
+.PP
+The file system allows entries which reference peripheral devices.
+Peripherals are distinguished as \fIblock\fP or \fIcharacter\fP
+devices according by their ability to support block-oriented
+operations.
+Devices are identified by their ``major'' and ``minor''
+device numbers. The major device number determines the kind
+of peripheral it is, while the minor device number indicates
+one of possibly many peripherals of that kind.
+Structured devices have all operations performed internally
+in ``block'' quantities while
+unstructured devices often have a number of
+special \fIioctl\fP operations, and may have input and output
+performed in varying units.
+The \fImknod\fP call creates special entries:
+.DS
+mknod(path, mode, dev);
+char *path; int mode, dev;
+.DE
+where \fImode\fP is formed from the object type
+and access permissions. The parameter \fIdev\fP is a configuration
+dependent parameter used to identify specific character or
+block I/O devices.
+.NH 4
+Portal creation\(dg
+.PP
+.FS
+\(dg The \fIportal\fP call is not implemented in 4.3BSD.
+.FE
+The call
+.DS
+fd = portal(name, server, param, dtype, protocol, domain, socktype)
+result int fd; char *name, *server, *param; int dtype, protocol;
+int domain, socktype;
+.DE
+places a \fIname\fP in the file system name space that causes connection to a
+server process when the name is used.
+The portal call returns an active portal in \fIfd\fP as though an
+access had occurred to activate an inactive portal, as now described.
+.PP
+When an inactive portal is accessed, the system sets up a socket
+of the specified \fIsocktype\fP in the specified communications
+\fIdomain\fP (see section 2.3), and creates the \fIserver\fP process,
+giving it the specified \fIparam\fP as argument to help it identify
+the portal, and also giving it the newly created socket as descriptor
+number 0. The accessor of the portal will create a socket in the same
+\fIdomain\fP and \fIconnect\fP to the server. The user will then
+\fIwrap\fP the socket in the specified \fIprotocol\fP to create an object of
+the required descriptor type \fIdtype\fP and proceed with the
+operation which was in progress before the portal was encountered.
+.PP
+While the server process holds the socket (which it received as \fIfd\fP
+from the \fIportal\fP call on descriptor 0 at activation) further references
+will result in connections being made to the same socket.
+.NH 4
+File, device, and portal removal
+.PP
+A reference to a file, special device or portal may be removed with the
+\fIunlink\fP call,
+.DS
+unlink(path);
+char *path;
+.DE
+The caller must have write access to the directory in which
+the file is located for this call to be successful.
+.NH 3
+Reading and modifying file attributes
+.PP
+Detailed information about the attributes of a file
+may be obtained with the calls:
+.DS
+#include <sys/stat.h>
+
+stat(path, stb);
+char *path; result struct stat *stb;
+
+fstat(fd, stb);
+int fd; result struct stat *stb;
+.DE
+The \fIstat\fP structure includes the file
+type, protection, ownership, access times,
+size, and a count of hard links.
+If the file is a symbolic link, then the status of the link
+itself (rather than the file the link references)
+may be found using the \fIlstat\fP call:
+.DS
+lstat(path, stb);
+char *path; result struct stat *stb;
+.DE
+.PP
+Newly created files are assigned the user id of the
+process that created it and the group id of the directory
+in which it was created. The ownership of a file may
+be changed by either of the calls
+.DS
+chown(path, owner, group);
+char *path; int owner, group;
+
+fchown(fd, owner, group);
+int fd, owner, group;
+.DE
+.PP
+In addition to ownership, each file has three levels of access
+protection associated with it. These levels are owner relative,
+group relative, and global (all users and groups). Each level
+of access has separate indicators for read permission, write
+permission, and execute permission.
+The protection bits associated with a file may be set by either
+of the calls:
+.DS
+chmod(path, mode);
+char *path; int mode;
+
+fchmod(fd, mode);
+int fd, mode;
+.DE
+where \fImode\fP is a value indicating the new protection
+of the file, as listed in section 2.2.3.2.
+.PP
+Finally, the access and modify times on a file may be set by the call:
+.DS
+utimes(path, tvp)
+char *path; struct timeval *tvp[2];
+.DE
+This is particularly useful when moving files between media, to
+preserve relationships between the times the file was modified.
+.NH 3
+Links and renaming
+.PP
+Links allow multiple names for a file
+to exist. Links exist independently of the file linked to.
+.PP
+Two types of links exist, \fIhard\fP links and \fIsymbolic\fP
+links. A hard link is a reference counting mechanism that
+allows a file to have multiple names within the same file
+system. Symbolic links cause string substitution
+during the pathname interpretation process.
+.PP
+Hard links and symbolic links have different
+properties. A hard link insures the target
+file will always be accessible, even after its original
+directory entry is removed; no such guarantee exists for a symbolic link.
+Symbolic links can span file systems boundaries.
+.PP
+The following calls create a new link, named \fIpath2\fP,
+to \fIpath1\fP:
+.DS
+link(path1, path2);
+char *path1, *path2;
+
+symlink(path1, path2);
+char *path1, *path2;
+.DE
+The \fIunlink\fP primitive may be used to remove
+either type of link.
+.PP
+If a file is a symbolic link, the ``value'' of the
+link may be read with the \fIreadlink\fP call,
+.DS
+len = readlink(path, buf, bufsize);
+result int len; result char *path, *buf; int bufsize;
+.DE
+This call returns, in \fIbuf\fP, the null-terminated string
+substituted into pathnames passing through \fIpath\fP\|.
+.PP
+Atomic renaming of file system resident objects is possible
+with the \fIrename\fP call:
+.DS
+rename(oldname, newname);
+char *oldname, *newname;
+.DE
+where both \fIoldname\fP and \fInewname\fP must be
+in the same file system.
+If \fInewname\fP exists and is a directory, then it must be empty.
+.NH 3
+Extension and truncation
+.PP
+Files are created with zero length and may be extended
+simply by writing or appending to them. While a file is
+open the system maintains a pointer into the file
+indicating the current location in the file associated with
+the descriptor. This pointer may be moved about in the
+file in a random access fashion.
+To set the current offset into a file, the \fIlseek\fP
+call may be used,
+.DS
+oldoffset = lseek(fd, offset, type);
+result off_t oldoffset; int fd; off_t offset; int type;
+.DE
+where \fItype\fP is given in \fI<sys/file.h>\fP as one of:
+.DS
+._d
+#define L_SET 0 /* set absolute file offset */
+#define L_INCR 1 /* set file offset relative to current position */
+#define L_XTND 2 /* set offset relative to end-of-file */
+.DE
+The call ``lseek(fd, 0, L_INCR)''
+returns the current offset into the file.
+.PP
+Files may have ``holes'' in them. Holes are void areas in the
+linear extent of the file where data has never been
+written. These may be created by seeking to
+a location in a file past the current end-of-file and writing.
+Holes are treated by the system as zero valued bytes.
+.PP
+A file may be truncated with either of the calls:
+.DS
+truncate(path, length);
+char *path; int length;
+
+ftruncate(fd, length);
+int fd, length;
+.DE
+reducing the size of the specified file to \fIlength\fP bytes.
+.NH 3
+Checking accessibility
+.PP
+A process running with
+different real and effective user ids
+may interrogate the accessibility of a file to the
+real user by using
+the \fIaccess\fP call:
+.DS
+accessible = access(path, how);
+result int accessible; char *path; int how;
+.DE
+Here \fIhow\fP is constructed by or'ing the following bits, defined
+in \fI<sys/file.h>\fP:
+.DS
+._d
+#define F_OK 0 /* file exists */
+#define X_OK 1 /* file is executable */
+#define W_OK 2 /* file is writable */
+#define R_OK 4 /* file is readable */
+.DE
+The presence or absence of advisory locks does not affect the
+result of \fIaccess\fP\|.
+.NH 3
+Locking
+.PP
+The file system provides basic facilities that allow cooperating processes
+to synchronize their access to shared files. A process may
+place an advisory \fIread\fP or \fIwrite\fP lock on a file,
+so that other cooperating processes may avoid interfering
+with the process' access. This simple mechanism
+provides locking with file granularity. More granular
+locking can be built using the IPC facilities to provide a lock
+manager.
+The system does not force processes to obey the locks;
+they are of an advisory nature only.
+.PP
+Locking is performed after an \fIopen\fP call by applying the
+\fIflock\fP primitive,
+.DS
+flock(fd, how);
+int fd, how;
+.DE
+where the \fIhow\fP parameter is formed from bits defined in \fI<sys/file.h>\fP:
+.DS
+._d
+#define LOCK_SH 1 /* shared lock */
+#define LOCK_EX 2 /* exclusive lock */
+#define LOCK_NB 4 /* don't block when locking */
+#define LOCK_UN 8 /* unlock */
+.DE
+Successive lock calls may be used to increase or
+decrease the level of locking. If an object is currently
+locked by another process when a \fIflock\fP call is made,
+the caller will be blocked until the current lock owner
+releases the lock; this may be avoided by including LOCK_NB
+in the \fIhow\fP parameter.
+Specifying LOCK_UN removes all locks associated with the descriptor.
+Advisory locks held by a process are automatically deleted when
+the process terminates.
+.NH 3
+Disk quotas
+.PP
+As an optional facility, each file system may be requested to
+impose limits on a user's disk usage.
+Two quantities are limited: the total amount of disk space which
+a user may allocate in a file system and the total number of files
+a user may create in a file system. Quotas are expressed as
+\fIhard\fP limits and \fIsoft\fP limits. A hard limit is
+always imposed; if a user would exceed a hard limit, the operation
+which caused the resource request will fail. A soft limit results
+in the user receiving a warning message, but with allocation succeeding.
+Facilities are provided to turn soft limits into hard limits if a
+user has exceeded a soft limit for an unreasonable period of time.
+.PP
+To enable disk quotas on a file system the \fIsetquota\fP call
+is used:
+.DS
+setquota(special, file)
+char *special, *file;
+.DE
+where \fIspecial\fP refers to a structured device file where
+a mounted file system exists, and
+\fIfile\fP refers to a disk quota file (residing on the file
+system associated with \fIspecial\fP) from which user quotas
+should be obtained. The format of the disk quota file is
+implementation dependent.
+.PP
+To manipulate disk quotas the \fIquota\fP call is provided:
+.DS
+#include <sys/quota.h>
+
+quota(cmd, uid, arg, addr)
+int cmd, uid, arg; caddr_t addr;
+.DE
+The indicated \fIcmd\fP is applied to the user ID \fIuid\fP.
+The parameters \fIarg\fP and \fIaddr\fP are command specific.
+The file \fI<sys/quota.h>\fP contains definitions pertinent to the
+use of this call.
diff --git a/share/doc/psd/05.sysman/2.3.t b/share/doc/psd/05.sysman/2.3.t
new file mode 100644
index 00000000000..509c7f31589
--- /dev/null
+++ b/share/doc/psd/05.sysman/2.3.t
@@ -0,0 +1,412 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)2.3.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh "Interprocess communications
+.NH 3
+Interprocess communication primitives
+.NH 4
+Communication domains
+.PP
+The system provides access to an extensible set of
+communication \fIdomains\fP. A communication domain
+is identified by a manifest constant defined in the
+file \fI<sys/socket.h>\fP.
+Important standard domains supported by the system are the ``unix''
+domain, AF_UNIX, for communication within the system, the ``Internet''
+domain for communication in the DARPA Internet, AF_INET,
+and the ``NS'' domain, AF_NS, for communication
+using the Xerox Network Systems protocols.
+Other domains can be added to the system.
+.NH 4
+Socket types and protocols
+.PP
+Within a domain, communication takes place between communication endpoints
+known as \fIsockets\fP. Each socket has the potential to exchange
+information with other sockets of an appropriate type within the domain.
+.PP
+Each socket has an associated
+abstract type, which describes the semantics of communication using that
+socket. Properties such as reliability, ordering, and prevention
+of duplication of messages are determined by the type.
+The basic set of socket types is defined in \fI<sys/socket.h>\fP:
+.DS
+/* Standard socket types */
+._d
+#define SOCK_DGRAM 1 /* datagram */
+#define SOCK_STREAM 2 /* virtual circuit */
+#define SOCK_RAW 3 /* raw socket */
+#define SOCK_RDM 4 /* reliably-delivered message */
+#define SOCK_SEQPACKET 5 /* sequenced packets */
+.DE
+The SOCK_DGRAM type models the semantics of datagrams in network communication:
+messages may be lost or duplicated and may arrive out-of-order.
+A datagram socket may send messages to and receive messages from multiple
+peers.
+The SOCK_RDM type models the semantics of reliable datagrams: messages
+arrive unduplicated and in-order, the sender is notified if
+messages are lost.
+The \fIsend\fP and \fIreceive\fP operations (described below)
+generate reliable/unreliable datagrams.
+The SOCK_STREAM type models connection-based virtual circuits: two-way
+byte streams with no record boundaries.
+Connection setup is required before data communication may begin.
+The SOCK_SEQPACKET type models a connection-based,
+full-duplex, reliable, sequenced packet exchange;
+the sender is notified if messages are lost, and messages are never
+duplicated or presented out-of-order.
+Users of the last two abstractions may use the facilities for
+out-of-band transmission to send out-of-band data.
+.PP
+SOCK_RAW is used for unprocessed access to internal network layers
+and interfaces; it has no specific semantics.
+.PP
+Other socket types can be defined.
+.PP
+Each socket may have a specific \fIprotocol\fP associated with it.
+This protocol is used within the domain to provide the semantics
+required by the socket type.
+Not all socket types are supported by each domain;
+support depends on the existence and the implementation
+of a suitable protocol within the domain.
+For example, within the ``Internet'' domain, the SOCK_DGRAM type may be
+implemented by the UDP user datagram protocol, and the SOCK_STREAM
+type may be implemented by the TCP transmission control protocol, while
+no standard protocols to provide SOCK_RDM or SOCK_SEQPACKET sockets exist.
+.NH 4
+Socket creation, naming and service establishment
+.PP
+Sockets may be \fIconnected\fP or \fIunconnected\fP. An unconnected
+socket descriptor is obtained by the \fIsocket\fP call:
+.DS
+s = socket(domain, type, protocol);
+result int s; int domain, type, protocol;
+.DE
+The socket domain and type are as described above,
+and are specified using the definitions from \fI<sys/socket.h>\fP.
+The protocol may be given as 0, meaning any suitable protocol.
+One of several possible protocols may be selected using identifiers
+obtained from a library routine, \fIgetprotobyname\fP.
+.PP
+An unconnected socket descriptor of a connection-oriented type
+may yield a connected socket descriptor
+in one of two ways: either by actively connecting to another socket,
+or by becoming associated with a name in the communications domain and
+\fIaccepting\fP a connection from another socket.
+Datagram sockets need not establish connections before use.
+.PP
+To accept connections or to receive datagrams,
+a socket must first have a binding
+to a name (or address) within the communications domain.
+Such a binding may be established by a \fIbind\fP call:
+.DS
+bind(s, name, namelen);
+int s; struct sockaddr *name; int namelen;
+.DE
+Datagram sockets may have default bindings established when first
+sending data if not explicitly bound earlier.
+In either case,
+a socket's bound name may be retrieved with a \fIgetsockname\fP call:
+.DS
+getsockname(s, name, namelen);
+int s; result struct sockaddr *name; result int *namelen;
+.DE
+while the peer's name can be retrieved with \fIgetpeername\fP:
+.DS
+getpeername(s, name, namelen);
+int s; result struct sockaddr *name; result int *namelen;
+.DE
+Domains may support sockets with several names.
+.NH 4
+Accepting connections
+.PP
+Once a binding is made to a connection-oriented socket,
+it is possible to \fIlisten\fP for connections:
+.DS
+listen(s, backlog);
+int s, backlog;
+.DE
+The \fIbacklog\fP specifies the maximum count of connections
+that can be simultaneously queued awaiting acceptance.
+.PP
+An \fIaccept\fP call:
+.DS
+t = accept(s, name, anamelen);
+result int t; int s; result struct sockaddr *name; result int *anamelen;
+.DE
+returns a descriptor for a new, connected, socket
+from the queue of pending connections on \fIs\fP.
+If no new connections are queued for acceptance,
+the call will wait for a connection unless non-blocking I/O has been enabled.
+.NH 4
+Making connections
+.PP
+An active connection to a named socket is made by the \fIconnect\fP call:
+.DS
+connect(s, name, namelen);
+int s; struct sockaddr *name; int namelen;
+.DE
+Although datagram sockets do not establish connections,
+the \fIconnect\fP call may be used with such sockets
+to create an \fIassociation\fP with the foreign address.
+The address is recorded for use in future \fIsend\fP calls,
+which then need not supply destination addresses.
+Datagrams will be received only from that peer,
+and asynchronous error reports may be received.
+.PP
+It is also possible to create connected pairs of sockets without
+using the domain's name space to rendezvous; this is done with the
+\fIsocketpair\fP call\(dg:
+.FS
+\(dg 4.3BSD supports \fIsocketpair\fP creation only in the ``unix''
+communication domain.
+.FE
+.DS
+socketpair(domain, type, protocol, sv);
+int domain, type, protocol; result int sv[2];
+.DE
+Here the returned \fIsv\fP descriptors correspond to those obtained with
+\fIaccept\fP and \fIconnect\fP.
+.PP
+The call
+.DS
+pipe(pv)
+result int pv[2];
+.DE
+creates a pair of SOCK_STREAM sockets in the UNIX domain,
+with pv[0] only writable and pv[1] only readable.
+.NH 4
+Sending and receiving data
+.PP
+Messages may be sent from a socket by:
+.DS
+cc = sendto(s, buf, len, flags, to, tolen);
+result int cc; int s; caddr_t buf; int len, flags; caddr_t to; int tolen;
+.DE
+if the socket is not connected or:
+.DS
+cc = send(s, buf, len, flags);
+result int cc; int s; caddr_t buf; int len, flags;
+.DE
+if the socket is connected.
+The corresponding receive primitives are:
+.DS
+msglen = recvfrom(s, buf, len, flags, from, fromlenaddr);
+result int msglen; int s; result caddr_t buf; int len, flags;
+result caddr_t from; result int *fromlenaddr;
+.DE
+and
+.DS
+msglen = recv(s, buf, len, flags);
+result int msglen; int s; result caddr_t buf; int len, flags;
+.DE
+.PP
+In the unconnected case,
+the parameters \fIto\fP and \fItolen\fP
+specify the destination or source of the message, while
+the \fIfrom\fP parameter stores the source of the message,
+and \fI*fromlenaddr\fP initially gives the size of the \fIfrom\fP
+buffer and is updated to reflect the true length of the \fIfrom\fP
+address.
+.PP
+All calls cause the message to be received in or sent from
+the message buffer of length \fIlen\fP bytes, starting at address \fIbuf\fP.
+The \fIflags\fP specify
+peeking at a message without reading it or sending or receiving
+high-priority out-of-band messages, as follows:
+.DS
+._d
+#define MSG_PEEK 0x1 /* peek at incoming message */
+#define MSG_OOB 0x2 /* process out-of-band data */
+.DE
+.NH 4
+Scatter/gather and exchanging access rights
+.PP
+It is possible scatter and gather data and to exchange access rights
+with messages. When either of these operations is involved,
+the number of parameters to the call becomes large.
+Thus the system defines a message header structure, in \fI<sys/socket.h>\fP,
+which can be
+used to conveniently contain the parameters to the calls:
+.DS
+.if t .ta .5i 1.25i 2i 2.7i
+.if n ._f
+struct msghdr {
+ caddr_t msg_name; /* optional address */
+ int msg_namelen; /* size of address */
+ struct iov *msg_iov; /* scatter/gather array */
+ int msg_iovlen; /* # elements in msg_iov */
+ caddr_t msg_accrights; /* access rights sent/received */
+ int msg_accrightslen; /* size of msg_accrights */
+};
+.DE
+Here \fImsg_name\fP and \fImsg_namelen\fP specify the source or destination
+address if the socket is unconnected; \fImsg_name\fP may be given as
+a null pointer if no names are desired or required.
+The \fImsg_iov\fP and \fImsg_iovlen\fP describe the scatter/gather
+locations, as described in section 2.1.3.
+Access rights to be sent along with the message are specified
+in \fImsg_accrights\fP, which has length \fImsg_accrightslen\fP.
+In the ``unix'' domain these are an array of integer descriptors,
+taken from the sending process and duplicated in the receiver.
+.PP
+This structure is used in the operations \fIsendmsg\fP and \fIrecvmsg\fP:
+.DS
+sendmsg(s, msg, flags);
+int s; struct msghdr *msg; int flags;
+
+msglen = recvmsg(s, msg, flags);
+result int msglen; int s; result struct msghdr *msg; int flags;
+.DE
+.NH 4
+Using read and write with sockets
+.PP
+The normal UNIX \fIread\fP and \fIwrite\fP calls may be
+applied to connected sockets and translated into \fIsend\fP and \fIreceive\fP
+calls from or to a single area of memory and discarding any rights
+received. A process may operate on a virtual circuit socket, a terminal
+or a file with blocking or non-blocking input/output
+operations without distinguishing the descriptor type.
+.NH 4
+Shutting down halves of full-duplex connections
+.PP
+A process that has a full-duplex socket such as a virtual circuit
+and no longer wishes to read from or write to this socket can
+give the call:
+.DS
+shutdown(s, direction);
+int s, direction;
+.DE
+where \fIdirection\fP is 0 to not read further, 1 to not
+write further, or 2 to completely shut the connection down.
+If the underlying protocol supports unidirectional or bidirectional shutdown,
+this indication will be passed to the peer.
+For example, a shutdown for writing might produce an end-of-file
+condition at the remote end.
+.NH 4
+Socket and protocol options
+.PP
+Sockets, and their underlying communication protocols, may
+support \fIoptions\fP. These options may be used to manipulate
+implementation- or protocol-specific facilities.
+The \fIgetsockopt\fP
+and \fIsetsockopt\fP calls are used to control options:
+.DS
+getsockopt(s, level, optname, optval, optlen)
+int s, level, optname; result caddr_t optval; result int *optlen;
+
+setsockopt(s, level, optname, optval, optlen)
+int s, level, optname; caddr_t optval; int optlen;
+.DE
+The option \fIoptname\fP is interpreted at the indicated
+protocol \fIlevel\fP for socket \fIs\fP. If a value is specified
+with \fIoptval\fP and \fIoptlen\fP, it is interpreted by
+the software operating at the specified \fIlevel\fP. The \fIlevel\fP
+SOL_SOCKET is reserved to indicate options maintained
+by the socket facilities. Other \fIlevel\fP values indicate
+a particular protocol which is to act on the option request;
+these values are normally interpreted as a ``protocol number''.
+.NH 3
+UNIX domain
+.PP
+This section describes briefly the properties of the UNIX communications
+domain.
+.NH 4
+Types of sockets
+.PP
+In the UNIX domain,
+the SOCK_STREAM abstraction provides pipe-like
+facilities, while SOCK_DGRAM provides (usually)
+reliable message-style communications.
+.NH 4
+Naming
+.PP
+Socket names are strings and may appear in the UNIX file
+system name space through portals\(dg.
+.FS
+\(dg The 4.3BSD implementation of the UNIX domain embeds
+bound sockets in the UNIX file system name space;
+this may change in future releases.
+.FE
+.NH 4
+Access rights transmission
+.PP
+The ability to pass UNIX descriptors with messages in this domain
+allows migration of service within the system and allows
+user processes to be used in building system facilities.
+.NH 3
+INTERNET domain
+.PP
+This section describes briefly how the Internet domain is
+mapped to the model described in this section. More
+information will be found in the document describing the
+network implementation in 4.3BSD.
+.NH 4
+Socket types and protocols
+.PP
+SOCK_STREAM is supported by the Internet TCP protocol;
+SOCK_DGRAM by the UDP protocol.
+Each is layered atop the transport-level Internet Protocol (IP).
+The Internet Control Message Protocol is implemented atop/beside IP
+and is accessible via a raw socket.
+The SOCK_SEQPACKET
+has no direct Internet family analogue; a protocol
+based on one from the XEROX NS family and layered on
+top of IP could be implemented to fill this gap.
+.NH 4
+Socket naming
+.PP
+Sockets in the Internet domain have names composed of the 32 bit
+Internet address, and a 16 bit port number.
+Options may be used to
+provide IP source routing or security options.
+The 32-bit address is composed of network and host parts;
+the network part is variable in size and is frequency encoded.
+The host part may optionally be interpreted as a subnet field
+plus the host on subnet; this is is enabled by setting a network address
+mask at boot time.
+.NH 4
+Access rights transmission
+.PP
+No access rights transmission facilities are provided in the Internet domain.
+.NH 4
+Raw access
+.PP
+The Internet domain allows the super-user access to the raw facilities
+of IP.
+These interfaces are modeled as SOCK_RAW sockets.
+Each raw socket is associated with one IP protocol number,
+and receives all traffic received for that protocol.
+This allows administrative and debugging
+functions to occur,
+and enables user-level implementations of special-purpose protocols
+such as inter-gateway routing protocols.
diff --git a/share/doc/psd/05.sysman/2.4.t b/share/doc/psd/05.sysman/2.4.t
new file mode 100644
index 00000000000..cd7dcb98790
--- /dev/null
+++ b/share/doc/psd/05.sysman/2.4.t
@@ -0,0 +1,174 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)2.4.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh "Terminals and Devices
+.NH 3
+Terminals
+.PP
+Terminals support \fIread\fP and \fIwrite\fP I/O operations,
+as well as a collection of terminal specific \fIioctl\fP operations,
+to control input character interpretation and editing,
+and output format and delays.
+.NH 4
+Terminal input
+.PP
+Terminals are handled according to the underlying communication
+characteristics such as baud rate and required delays,
+and a set of software parameters.
+.NH 5
+Input modes
+.PP
+A terminal is in one of three possible modes: \fIraw\fP, \fIcbreak\fP,
+or \fIcooked\fP.
+In raw mode all input is passed through to the
+reading process immediately and without interpretation.
+In cbreak mode, the handler interprets input only by looking
+for characters that cause interrupts or output flow control;
+all other characters are made available as in raw mode.
+In cooked mode, input
+is processed to provide standard line-oriented local editing functions,
+and input is presented on a line-by-line basis.
+.NH 5
+Interrupt characters
+.PP
+Interrupt characters are interpreted by the terminal handler only in
+cbreak and cooked modes, and
+cause a software interrupt to be sent to all processes in the process
+group associated with the terminal. Interrupt characters exist
+to send SIGINT
+and SIGQUIT signals,
+and to stop a process group
+with the SIGTSTP signal either immediately, or when
+all input up to the stop character has been read.
+.NH 5
+Line editing
+.PP
+When the terminal is in cooked mode, editing of an input line
+is performed. Editing facilities allow deletion of the previous
+character or word, or deletion of the current input line.
+In addition, a special character may be used to reprint the current
+input line after some number of editing operations have been applied.
+.PP
+Certain other characters are interpreted specially when a process is
+in cooked mode. The \fIend of line\fP character determines
+the end of an input record. The \fIend of file\fP character simulates
+an end of file occurrence on terminal input. Flow control is provided
+by \fIstop output\fP and \fIstart output\fP control characters. Output
+may be flushed with the \fIflush output\fP character; and a \fIliteral
+character\fP may be used to force literal input of the immediately
+following character in the input line.
+.PP
+Input characters may be echoed to the terminal as they are received.
+Non-graphic ASCII input characters may be echoed as a two-character
+printable representation, ``^character.''
+.NH 4
+Terminal output
+.PP
+On output, the terminal handler provides some simple formatting services.
+These include converting the carriage return character to the
+two character return-linefeed sequence,
+inserting delays after certain standard control characters,
+expanding tabs, and providing translations
+for upper-case only terminals.
+.NH 4
+Terminal control operations
+.PP
+When a terminal is first opened it is initialized to a standard
+state and configured with a set of standard control, editing,
+and interrupt characters. A process
+may alter this configuration with certain
+control operations, specifying parameters in a standard structure:\(dg
+.FS
+\(dg The control interface described here is an internal interface only
+in 4.3BSD. Future releases will probably use a modified interface
+based on currently-proposed standards.
+.FE
+.DS
+._f
+struct ttymode {
+ short tt_ispeed; /* input speed */
+ int tt_iflags; /* input flags */
+ short tt_ospeed; /* output speed */
+ int tt_oflags; /* output flags */
+};
+.DE
+and ``special characters'' are specified with the
+\fIttychars\fP structure,
+.DS
+._f
+struct ttychars {
+ char tc_erasec; /* erase char */
+ char tc_killc; /* erase line */
+ char tc_intrc; /* interrupt */
+ char tc_quitc; /* quit */
+ char tc_startc; /* start output */
+ char tc_stopc; /* stop output */
+ char tc_eofc; /* end-of-file */
+ char tc_brkc; /* input delimiter (like nl) */
+ char tc_suspc; /* stop process signal */
+ char tc_dsuspc; /* delayed stop process signal */
+ char tc_rprntc; /* reprint line */
+ char tc_flushc; /* flush output (toggles) */
+ char tc_werasc; /* word erase */
+ char tc_lnextc; /* literal next character */
+};
+.DE
+.NH 4
+Terminal hardware support
+.PP
+The terminal handler allows a user to access basic
+hardware related functions; e.g. line speed,
+modem control, parity, and stop bits. A special signal,
+SIGHUP, is automatically
+sent to processes in a terminal's process
+group when a carrier transition is detected. This is
+normally associated with a user hanging up on a modem
+controlled terminal line.
+.NH 3
+Structured devices
+.PP
+Structures devices are typified by disks and magnetic
+tapes, but may represent any random-access device.
+The system performs read-modify-write type buffering actions on block
+devices to allow them to be read and written in a totally random
+access fashion like ordinary files.
+File systems are normally created in block devices.
+.NH 3
+Unstructured devices
+.PP
+Unstructured devices are those devices which
+do not support block structure. Familiar unstructured devices
+are raw communications lines (with
+no terminal handler), raster plotters, magnetic tape and disks unfettered
+by buffering and permitting large block input/output and positioning
+and formatting commands.
diff --git a/share/doc/psd/05.sysman/2.5.t b/share/doc/psd/05.sysman/2.5.t
new file mode 100644
index 00000000000..109eb6a46ef
--- /dev/null
+++ b/share/doc/psd/05.sysman/2.5.t
@@ -0,0 +1,39 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)2.5.t 8.1 (Berkeley) 6/8/93
+.\"
+.sh "Process and kernel descriptors
+.PP
+The status of the facilities in this section is still under discussion.
+The \fIptrace\fP facility of earlier UNIX systems
+remains in 4.3BSD.
+Planned enhancements would allow a descriptor-based process control facility.
diff --git a/share/doc/psd/05.sysman/Makefile b/share/doc/psd/05.sysman/Makefile
new file mode 100644
index 00000000000..3e63a479f4f
--- /dev/null
+++ b/share/doc/psd/05.sysman/Makefile
@@ -0,0 +1,11 @@
+# @(#)Makefile 8.1 (Berkeley) 6/8/93
+
+DIR= psd/05.sysman
+SRCS= 0.t 1.0.t 1.1.t 1.2.t 1.3.t 1.4.t 1.5.t 1.6.t 1.7.t \
+ 2.0.t 2.1.t 2.2.t 2.3.t 2.4.t 2.5.t a.t
+MACROS= -ms
+
+paper.ps: ${SRCS}
+ ${TBL} ${SRCS} | ${ROFF} > ${.TARGET}
+
+.include <bsd.doc.mk>
diff --git a/share/doc/psd/05.sysman/a.t b/share/doc/psd/05.sysman/a.t
new file mode 100644
index 00000000000..3acefb1482d
--- /dev/null
+++ b/share/doc/psd/05.sysman/a.t
@@ -0,0 +1,235 @@
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)a.t 8.1 (Berkeley) 6/8/93
+.\"
+.ds RH Summary of facilities
+.bp
+.SH
+\s+2I. Summary of facilities\s0
+.PP
+.de h
+.br
+.if n .ne 8
+\fB\\$1 \\$2\fP
+.br
+..
+.nr H1 0
+.NH
+Kernel primitives
+.LP
+.h 1.1. "Process naming and protection
+.in +5
+.TS
+lw(1.6i) aw(3i).
+sethostid set UNIX host id
+gethostid get UNIX host id
+sethostname set UNIX host name
+gethostname get UNIX host name
+getpid get process id
+fork create new process
+exit terminate a process
+execve execute a different process
+getuid get user id
+geteuid get effective user id
+setreuid set real and effective user id's
+getgid get accounting group id
+getegid get effective accounting group id
+getgroups get access group set
+setregid set real and effective group id's
+setgroups set access group set
+getpgrp get process group
+setpgrp set process group
+.TE
+.in -5
+.h 1.2 "Memory management
+.in +5
+.TS
+lw(1.6i) aw(3i).
+<sys/mman.h> memory management definitions
+sbrk change data section size
+sstk\(dg change stack section size
+.FS
+\(dg Not supported in 4.3BSD.
+.FE
+getpagesize get memory page size
+mmap\(dg map pages of memory
+msync\(dg flush modified mapped pages to filesystem
+munmap\(dg unmap memory
+mprotect\(dg change protection of pages
+madvise\(dg give memory management advice
+mincore\(dg determine core residency of pages
+msleep\(dg sleep on a lock
+mwakeup\(dg wakeup process sleeping on a lock
+.TE
+.in -5
+.h 1.3 "Signals
+.in +5
+.TS
+lw(1.6i) aw(3i).
+<signal.h> signal definitions
+sigvec set handler for signal
+kill send signal to process
+killpgrp send signal to process group
+sigblock block set of signals
+sigsetmask restore set of blocked signals
+sigpause wait for signals
+sigstack set software stack for signals
+.TE
+.in -5
+.h 1.4 "Timing and statistics
+.in +5
+.TS
+lw(1.6i) aw(3i).
+<sys/time.h> time-related definitions
+gettimeofday get current time and timezone
+settimeofday set current time and timezone
+getitimer read an interval timer
+setitimer get and set an interval timer
+profil profile process
+.TE
+.in -5
+.h 1.5 "Descriptors
+.in +5
+.TS
+lw(1.6i) aw(3i).
+getdtablesize descriptor reference table size
+dup duplicate descriptor
+dup2 duplicate to specified index
+close close descriptor
+select multiplex input/output
+fcntl control descriptor options
+wrap\(dg wrap descriptor with protocol
+.FS
+\(dg Not supported in 4.3BSD.
+.FE
+.TE
+.in -5
+.h 1.6 "Resource controls
+.in +5
+.TS
+lw(1.6i) aw(3i).
+<sys/resource.h> resource-related definitions
+getpriority get process priority
+setpriority set process priority
+getrusage get resource usage
+getrlimit get resource limitations
+setrlimit set resource limitations
+.TE
+.in -5
+.h 1.7 "System operation support
+.in +5
+.TS
+lw(1.6i) aw(3i).
+mount mount a device file system
+swapon add a swap device
+umount umount a file system
+sync flush system caches
+reboot reboot a machine
+acct specify accounting file
+.TE
+.in -5
+.NH
+System facilities
+.LP
+.h 2.1 "Generic operations
+.in +5
+.TS
+lw(1.6i) aw(3i).
+read read data
+write write data
+<sys/uio.h> scatter-gather related definitions
+readv scattered data input
+writev gathered data output
+<sys/ioctl.h> standard control operations
+ioctl device control operation
+.TE
+.in -5
+.h 2.2 "File system
+.PP
+Operations marked with a * exist in two forms: as shown,
+operating on a file name, and operating on a file descriptor,
+when the name is preceded with a ``f''.
+.in +5
+.TS
+lw(1.6i) aw(3i).
+<sys/file.h> file system definitions
+chdir change directory
+chroot change root directory
+mkdir make a directory
+rmdir remove a directory
+open open a new or existing file
+mknod make a special file
+portal\(dg make a portal entry
+unlink remove a link
+stat* return status for a file
+lstat returned status of link
+chown* change owner
+chmod* change mode
+utimes change access/modify times
+link make a hard link
+symlink make a symbolic link
+readlink read contents of symbolic link
+rename change name of file
+lseek reposition within file
+truncate* truncate file
+access determine accessibility
+flock lock a file
+.TE
+.in -5
+.h 2.3 "Communications
+.in +5
+.TS
+lw(1.6i) aw(3i).
+<sys/socket.h> standard definitions
+socket create socket
+bind bind socket to name
+getsockname get socket name
+listen allow queuing of connections
+accept accept a connection
+connect connect to peer socket
+socketpair create pair of connected sockets
+sendto send data to named socket
+send send data to connected socket
+recvfrom receive data on unconnected socket
+recv receive data on connected socket
+sendmsg send gathered data and/or rights
+recvmsg receive scattered data and/or rights
+shutdown partially close full-duplex connection
+getsockopt get socket option
+setsockopt set socket option
+.TE
+.in -5
+.h 2.4 "Terminals, block and character devices
+.in +5
+.in -5
+.h 2.5 "Processes and kernel hooks
+.in -5
diff --git a/share/doc/psd/05.sysman/spell.ok b/share/doc/psd/05.sysman/spell.ok
new file mode 100644
index 00000000000..b0cbd9ce9cf
--- /dev/null
+++ b/share/doc/psd/05.sysman/spell.ok
@@ -0,0 +1,332 @@
+AF
+ANON
+AUTOBOOT
+Behav
+CLR
+DEF
+DGRAM
+DONTNEED
+Datagram
+Datagrams
+EINPROGRESS
+EWOULDBLOCK
+EXCL
+FD
+FSIZE
+Fabry
+GETFL
+GETOWN
+HASSEMAPHORE
+HASSEMPHORE
+IGN
+INCR
+INET
+IP
+IPC
+ISSET
+ITIMER
+Karels
+Leffler
+MADV
+MAXHOSTNAMELEN
+MSG
+Manual''PS1:6
+McKusick
+Mclear
+Mset
+NB
+NDELAY
+NGROUPS
+NLIMITS
+NOEXTEND
+NS
+OOB
+PGRP
+PRIO
+PROT
+PS1:6
+RB
+RDM
+RDONLY
+RDWR
+RH
+RLIM
+RLIMIT
+RSS
+RUSAGE
+SEQPACKET
+SETFL
+SETOWN
+SIG
+SIGALRM
+SIGBUS
+SIGCHLD
+SIGCONT
+SIGEMT
+SIGFPE
+SIGHUP
+SIGILL
+SIGINT
+SIGIO
+SIGIOT
+SIGKILL
+SIGPROF
+SIGQUIT
+SIGSEGV
+SIGSTOP
+SIGTERM
+SIGTRAP
+SIGTSTP
+SIGTTIN
+SIGTTOU
+SIGURG
+SIGUSR1
+SIGUSR2
+SIGVTALRM
+SIGXCPU
+SIGXFSZ
+Sem
+Sv
+TCP
+TRUNC
+UDP
+VAX
+WILLNEED
+WRONLY
+XTND
+accessor
+accrights
+accrightslen
+addr
+anamelen
+arg
+argv
+arusage
+astatus
+behav
+blkdev
+brkc
+bu
+buf
+buflen
+bufsize
+caddr
+cbreak
+chroot
+cmd
+datagram
+datagrams
+dev
+dopt
+dprop
+ds
+dst
+dsttime
+dsuspc
+dtype
+dup2
+egid
+envp
+eofc
+erasec
+errno
+euid
+fchmod
+fchown
+fcntl
+fd
+fdset
+file.h
+filename
+filesystem
+flushc
+fromlenaddr
+fs
+fstat
+ftruncate
+getdtablesize
+getegid
+geteuid
+getgid
+getgroups
+gethostid
+gethostname
+getitimer
+getpagesize
+getpeername
+getpriority
+getprotobyname
+getrlimit
+getrusage
+getsockname
+getsockopt
+gettimeofday
+gid
+gidset
+gidsetsize
+hostid
+idrss
+iflags
+inblock
+incr
+intrc
+ioctl.h
+iov
+iovec
+iovlen
+ispeed
+isrss
+itimerval
+ixrss
+kbytes
+killc
+killpgrp
+len
+linefeed
+lnextc
+lstat
+maddr
+madvise
+majflt
+maxrss
+mclear
+mincore
+minflt
+minuteswest
+mman.h
+mmap
+mprotect
+mremap
+mset
+msg
+msghdr
+msglen
+msgrcv
+msgsnd
+msleep
+msync
+munmap
+mwakeup
+namelen
+nbytes
+nd
+nds
+newname
+ngroups
+nivcsw
+nl
+nsignals
+nswap
+nvcsw
+oflag
+oflags
+oldmask
+oldname
+oldoffset
+onstack
+optlen
+optname
+optval
+or'ed
+or'ing
+ospeed
+oss
+osv
+oublock
+ovalue
+pagesize
+param
+param.h
+path1
+path2
+pathname
+pathnames
+pgrp
+pid
+pos
+prio
+prot
+proto
+pv
+quitc
+quota.h
+readlink
+readv
+reboot.h
+recv
+recvfrom
+recvmsg
+resource.h
+rgid
+rlim
+rlimit
+rlp
+ronly
+rprntc
+ru
+ruid
+rusage
+sbrk
+scp
+sem
+sendmsg
+sendto
+setgroups
+sethostid
+sethostname
+setitimer
+setpriority
+setquota
+setregid
+setreuid
+setrlimit
+setsockopt
+settimeofday
+sigblock
+sigcontext
+sigmask
+signal.h
+signo
+sigpause
+sigsetmask
+sigstack
+sigvec
+sockaddr
+socket.h
+socketpair
+socktype
+sp
+ss
+sstk
+startc
+stat.h
+stb
+stopc
+suspc
+sv
+sw
+symlink
+ta
+time.h
+timeval
+timezone
+tolen
+tt
+ttychars
+ttymode
+tv
+tvp
+tvsec
+types.h
+tz
+tzp
+uid
+uio.h
+umount
+usec
+vec
+wait.h
+waitstatus
+werasc
+writeable
+writev
diff --git a/share/doc/psd/20.ipctut/Makefile b/share/doc/psd/20.ipctut/Makefile
new file mode 100644
index 00000000000..9fe861d1d81
--- /dev/null
+++ b/share/doc/psd/20.ipctut/Makefile
@@ -0,0 +1,13 @@
+# @(#)Makefile 8.1 (Berkeley) 8/14/93
+
+DIR= psd/20.ipctut
+SRCS= tutor.me
+MACROS= -me
+EXTRA= dgramread.c dgramsend.c fig2.pic fig3.pic fig8.pic pipe.c \
+ socketpair.c strchkread.c streamread.c streamwrite.c \
+ udgramread.c udgramsend.c ustreamread.c ustreamwrite.c
+
+paper.ps: ${SRCS} ${EXTRA}
+ ${SOELIM} ${SRCS} | ${PIC} | ${TBL} | ${ROFF} > ${.TARGET}
+
+.include <bsd.doc.mk>
diff --git a/share/doc/psd/20.ipctut/dgramread.c b/share/doc/psd/20.ipctut/dgramread.c
new file mode 100644
index 00000000000..cd0f147111f
--- /dev/null
+++ b/share/doc/psd/20.ipctut/dgramread.c
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)dgramread.c 8.1 (Berkeley) 6/8/93
+.\"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <stdio.h>
+
+/*
+ * In the included file <netinet/in.h> a sockaddr_in is defined as follows:
+ * struct sockaddr_in {
+ * short sin_family;
+ * u_short sin_port;
+ * struct in_addr sin_addr;
+ * char sin_zero[8];
+ * };
+ *
+ * This program creates a datagram socket, binds a name to it, then reads
+ * from the socket.
+ */
+main()
+{
+ int sock, length;
+ struct sockaddr_in name;
+ char buf[1024];
+
+ /* Create socket from which to read. */
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ perror("opening datagram socket");
+ exit(1);
+ }
+ /* Create name with wildcards. */
+ name.sin_family = AF_INET;
+ name.sin_addr.s_addr = INADDR_ANY;
+ name.sin_port = 0;
+ if (bind(sock, &name, sizeof(name))) {
+ perror("binding datagram socket");
+ exit(1);
+ }
+ /* Find assigned port value and print it out. */
+ length = sizeof(name);
+ if (getsockname(sock, &name, &length)) {
+ perror("getting socket name");
+ exit(1);
+ }
+ printf("Socket has port #%d\en", ntohs(name.sin_port));
+ /* Read from the socket */
+ if (read(sock, buf, 1024) < 0)
+ perror("receiving datagram packet");
+ printf("-->%s\en", buf);
+ close(sock);
+}
diff --git a/share/doc/psd/20.ipctut/dgramsend.c b/share/doc/psd/20.ipctut/dgramsend.c
new file mode 100644
index 00000000000..831fbf1575a
--- /dev/null
+++ b/share/doc/psd/20.ipctut/dgramsend.c
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)dgramsend.c 8.1 (Berkeley) 6/8/93
+.\"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+
+#define DATA "The sea is calm tonight, the tide is full . . ."
+
+/*
+ * Here I send a datagram to a receiver whose name I get from the command
+ * line arguments. The form of the command line is dgramsend hostname
+ * portnumber
+ */
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int sock;
+ struct sockaddr_in name;
+ struct hostent *hp, *gethostbyname();
+
+ /* Create socket on which to send. */
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ perror("opening datagram socket");
+ exit(1);
+ }
+ /*
+ * Construct name, with no wildcards, of the socket to send to.
+ * Getnostbyname() returns a structure including the network address
+ * of the specified host. The port number is taken from the command
+ * line.
+ */
+ hp = gethostbyname(argv[1]);
+ if (hp == 0) {
+ fprintf(stderr, "%s: unknown host\n", argv[1]);
+ exit(2);
+ }
+ bcopy(hp->h_addr, &name.sin_addr, hp->h_length);
+ name.sin_family = AF_INET;
+ name.sin_port = htons(atoi(argv[2]));
+ /* Send message. */
+ if (sendto(sock, DATA, sizeof(DATA), 0, &name, sizeof(name)) < 0)
+ perror("sending datagram message");
+ close(sock);
+}
diff --git a/share/doc/psd/20.ipctut/fig2.pic b/share/doc/psd/20.ipctut/fig2.pic
new file mode 100644
index 00000000000..ffbc193f733
--- /dev/null
+++ b/share/doc/psd/20.ipctut/fig2.pic
@@ -0,0 +1,77 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" @(#)fig2.pic 8.1 (Berkeley) 8/14/93
+.PS
+.ps
+.ps 10
+arc at 5.407,4.723 from 5.375,4.838 to 5.362,4.612 cw
+arc at 5.907,7.973 from 5.875,8.088 to 5.862,7.862 cw
+line from 5.963,5.513 to 6.925,5.513
+line from 5.963,5.650 to 6.925,5.650
+line from 5.963,5.787 to 6.925,5.787
+line from 5.963,5.912 to 6.925,5.912
+line from 5.963,6.050 to 6.925,6.050
+line from 5.963,6.200 to 6.925,6.200 to 6.925,5.375 to 5.963,5.375 to 5.963,6.200
+ellipse at 6.388,6.713 wid 0.475 ht 0.475
+line from 6.388,6.463 to 6.388,6.200
+line from 3.150,6.200 to 4.112,6.200 to 4.112,5.375 to 3.150,5.375 to 3.150,6.200
+line from 3.150,6.050 to 4.112,6.050
+line from 3.150,5.912 to 4.112,5.912
+line from 3.150,5.787 to 4.112,5.787
+line from 3.150,5.650 to 4.112,5.650
+line from 3.150,5.513 to 4.112,5.513
+ellipse at 3.575,6.713 wid 0.475 ht 0.475
+line from 3.575,6.463 to 3.575,6.200
+line from 3.650,8.762 to 4.612,8.762
+line from 3.650,8.900 to 4.612,8.900
+line from 3.650,9.037 to 4.612,9.037
+line from 3.650,9.162 to 4.612,9.162
+line from 3.650,9.300 to 4.612,9.300
+line from 3.650,9.450 to 4.612,9.450 to 4.612,8.625 to 3.650,8.625 to 3.650,9.450
+ellipse at 4.075,9.963 wid 0.475 ht 0.475
+ellipse at 3.950,4.725 wid 0.225 ht 0.225
+ellipse at 4.450,7.975 wid 0.225 ht 0.225
+dashwid = 0.037i
+line dotted from 1.925,7.513 to 8.238,7.513
+line from 6.050,6.138 to 5.737,6.138 to 5.737,4.700 to 5.550,4.700
+line from 5.650,4.725 to 5.550,4.700 to 5.650,4.675
+line from 6.050,6.013 to 4.050,4.888
+line from 4.125,4.958 to 4.050,4.888 to 4.149,4.915
+line from 3.975,6.000 to 4.525,5.987 to 3.925,4.875
+line from 3.950,4.975 to 3.925,4.875 to 3.994,4.951
+line from 3.975,6.112 to 5.650,6.112 to 5.650,4.750 to 5.550,4.763
+line from 5.652,4.775 to 5.550,4.763 to 5.646,4.725
+line from 4.075,9.713 to 4.075,9.450
+line from 4.475,9.363 to 6.150,9.363 to 6.150,8.000 to 6.050,8.012
+line from 6.152,8.025 to 6.050,8.012 to 6.146,7.975
+line from 4.475,9.250 to 5.025,9.238 to 4.425,8.125
+line from 4.450,8.225 to 4.425,8.125 to 4.494,8.201
+.ps
+.ps 20
+line from 4.362,4.775 to 4.162,4.725 to 4.362,4.675
+line from 4.162,4.725 to 4.838,4.725
+.ps
+.ps 10
+line from 3.962,4.600 to 5.375,4.600
+line from 3.950,4.838 to 5.375,4.838
+line from 4.450,8.088 to 5.875,8.088
+line from 4.463,7.850 to 5.875,7.850
+.ps
+.ps 20
+line from 4.862,8.025 to 4.662,7.975 to 4.862,7.925
+line from 4.662,7.975 to 5.338,7.975
+.ps
+.ps 11
+.ft
+.ft R
+"Child" at 6.362,7.106
+.ps
+.ps 12
+"Parent" at 3.362,7.096 ljust
+"Parent" at 3.862,10.346 ljust
+"PIPE" at 4.987,4.671 ljust
+"PIPE" at 5.425,7.921 ljust
+.ps
+.ft
+.PE
diff --git a/share/doc/psd/20.ipctut/fig2.xfig b/share/doc/psd/20.ipctut/fig2.xfig
new file mode 100644
index 00000000000..59b46be37b8
--- /dev/null
+++ b/share/doc/psd/20.ipctut/fig2.xfig
@@ -0,0 +1,100 @@
+#FIG 2.0
+80 2
+5 1 0 1 0 0 0 0 0.000 0 0 0 432.554 462.170 430 453 442 461 429 471
+5 1 0 1 0 0 0 0 0.000 0 0 0 472.554 202.170 470 193 482 201 469 211
+6 414 279 589 424
+6 473 340 557 414
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 399 554 399 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 388 554 388 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 377 554 377 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 367 554 367 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 356 554 356 9999 9999
+2 2 0 1 0 0 0 0 0.000 0 0
+ 477 344 554 344 554 410 477 410 477 344 9999 9999
+-6
+1 3 0 1 0 0 0 0 0.000 1 0.000 511 303 19 19 511 303 525 317
+2 1 0 1 0 0 0 0 0.000 0 0
+ 511 323 511 344 9999 9999
+-6
+6 189 279 364 424
+6 248 340 332 414
+2 2 0 1 0 0 0 0 0.000 0 0
+ 252 344 329 344 329 410 252 410 252 344 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 356 329 356 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 367 329 367 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 377 329 377 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 388 329 388 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 399 329 399 9999 9999
+-6
+1 3 0 1 0 0 0 0 0.000 1 0.000 286 303 19 19 286 303 300 317
+2 1 0 1 0 0 0 0 0.000 0 0
+ 286 323 286 344 9999 9999
+-6
+6 288 80 372 154
+2 1 0 1 0 0 0 0 0.000 0 0
+ 292 139 369 139 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 292 128 369 128 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 292 117 369 117 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 292 107 369 107 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 292 96 369 96 9999 9999
+2 2 0 1 0 0 0 0 0.000 0 0
+ 292 84 369 84 369 150 292 150 292 84 9999 9999
+-6
+1 3 0 1 0 0 0 0 0.000 1 0.000 326 43 19 19 326 43 340 57
+1 3 0 1 0 0 0 0 0.000 1 0.000 316 462 9 9 316 462 322 469
+1 3 0 1 0 0 0 0 0.000 1 0.000 356 202 9 9 356 202 362 209
+2 1 2 1 0 0 0 0 3.000 0 0
+ 154 239 659 239 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 484 349 459 349 459 464 444 464 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 484 359 324 449 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 318 360 362 361 314 450 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 318 351 452 351 452 460 444 459 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 326 63 326 84 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 358 91 492 91 492 200 484 199 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 358 100 402 101 354 190 9999 9999
+2 1 0 2 0 0 0 0 0.000 0 1
+ 0 0 2.000 8.000 16.000
+ 333 462 387 462 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 317 472 430 472 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 316 453 430 453 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 356 193 470 193 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 357 212 470 212 9999 9999
+2 1 0 2 0 0 0 0 0.000 0 1
+ 0 0 2.000 8.000 16.000
+ 373 202 427 202 9999 9999
+4 1 0 11 0 0 0 0.000 1 7 24 509 274 Child
+4 0 0 12 0 0 0 0.000 1 9 33 269 275 Parent
+4 0 0 12 0 0 0 0.000 1 9 33 309 15 Parent
+4 0 0 12 0 0 0 0.000 1 9 26 399 469 PIPE
+4 0 0 12 0 0 0 0.000 1 9 26 434 209 PIPE
diff --git a/share/doc/psd/20.ipctut/fig3.pic b/share/doc/psd/20.ipctut/fig3.pic
new file mode 100644
index 00000000000..15a4a73bf7d
--- /dev/null
+++ b/share/doc/psd/20.ipctut/fig3.pic
@@ -0,0 +1,69 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" @(#)fig3.pic 8.1 (Berkeley) 8/14/93
+.PS
+.ps
+.ps 10
+ellipse at 5.787,8.012 wid 0.275 ht 0.275
+ellipse at 4.175,8.012 wid 0.275 ht 0.275
+dashwid = 0.037i
+line dotted from 5.550,8.012 to 4.362,8.012
+line from 4.462,8.037 to 4.362,8.012 to 4.462,7.987
+line dotted from 4.362,7.950 to 5.550,7.950
+line from 5.450,7.925 to 5.550,7.950 to 5.450,7.975
+ellipse at 3.737,4.763 wid 0.275 ht 0.275
+ellipse at 5.350,4.763 wid 0.275 ht 0.275
+line dotted from 3.925,4.700 to 5.112,4.700
+line from 5.013,4.675 to 5.112,4.700 to 5.013,4.725
+line dotted from 5.112,4.763 to 3.925,4.763
+line from 4.025,4.788 to 3.925,4.763 to 4.025,4.737
+line from 5.963,5.513 to 6.925,5.513
+line from 5.963,5.650 to 6.925,5.650
+line from 5.963,5.787 to 6.925,5.787
+line from 5.963,5.912 to 6.925,5.912
+line from 5.963,6.050 to 6.925,6.050
+line from 5.963,6.200 to 6.925,6.200 to 6.925,5.375 to 5.963,5.375 to 5.963,6.200
+ellipse at 6.388,6.713 wid 0.475 ht 0.475
+line from 6.388,6.463 to 6.388,6.200
+line from 3.150,6.200 to 4.112,6.200 to 4.112,5.375 to 3.150,5.375 to 3.150,6.200
+line from 3.150,6.050 to 4.112,6.050
+line from 3.150,5.912 to 4.112,5.912
+line from 3.150,5.787 to 4.112,5.787
+line from 3.150,5.650 to 4.112,5.650
+line from 3.150,5.513 to 4.112,5.513
+ellipse at 3.575,6.713 wid 0.475 ht 0.475
+line from 3.575,6.463 to 3.575,6.200
+line from 3.650,8.762 to 4.612,8.762
+line from 3.650,8.900 to 4.612,8.900
+line from 3.650,9.037 to 4.612,9.037
+line from 3.650,9.162 to 4.612,9.162
+line from 3.650,9.300 to 4.612,9.300
+line from 3.650,9.450 to 4.612,9.450 to 4.612,8.625 to 3.650,8.625 to 3.650,9.450
+ellipse at 4.075,9.963 wid 0.475 ht 0.475
+line from 3.975,6.112 to 5.650,6.112 to 5.650,4.750 to 5.550,4.763
+line from 5.652,4.775 to 5.550,4.763 to 5.646,4.725
+line from 6.050,6.138 to 5.737,6.138 to 5.737,4.700 to 5.550,4.700
+line from 5.650,4.725 to 5.550,4.700 to 5.650,4.675
+line dotted from 1.925,7.513 to 8.238,7.513
+line from 6.050,6.013 to 4.050,4.888
+line from 4.125,4.958 to 4.050,4.888 to 4.149,4.915
+line from 3.975,6.000 to 4.525,5.987 to 3.925,4.875
+line from 3.950,4.975 to 3.925,4.875 to 3.994,4.951
+line from 4.075,9.713 to 4.075,9.450
+line from 4.475,9.363 to 6.150,9.363 to 6.150,8.000 to 6.050,8.012
+line from 6.152,8.025 to 6.050,8.012 to 6.146,7.975
+line from 4.475,9.250 to 5.025,9.238 to 4.425,8.125
+line from 4.450,8.225 to 4.425,8.125 to 4.494,8.201
+.ps
+.ps 11
+.ft
+.ft R
+"Child" at 6.362,7.106
+.ps
+.ps 12
+"Parent" at 3.362,7.096 ljust
+"Parent" at 3.862,10.346 ljust
+.ps
+.ft
+.PE
diff --git a/share/doc/psd/20.ipctut/fig3.xfig b/share/doc/psd/20.ipctut/fig3.xfig
new file mode 100644
index 00000000000..ed65b70bd18
--- /dev/null
+++ b/share/doc/psd/20.ipctut/fig3.xfig
@@ -0,0 +1,100 @@
+#FIG 2.0
+80 2
+6 309 184 479 214
+1 3 0 1 0 0 0 0 0.000 1 0.000 463 199 11 11 463 199 468 209
+1 3 0 1 0 0 0 0 0.000 1 0.000 334 199 11 11 334 199 339 209
+2 1 2 1 0 0 0 0 3.000 1 0
+ 0 0 1.000 4.000 8.000
+ 444 199 349 199 9999 9999
+2 1 2 1 0 0 0 0 3.000 1 0
+ 0 0 1.000 4.000 8.000
+ 349 204 444 204 9999 9999
+-6
+6 274 444 444 474
+1 3 0 1 0 0 0 0 0.000 1 0.000 299 459 11 11 299 459 304 469
+1 3 0 1 0 0 0 0 0.000 1 0.000 428 459 11 11 428 459 433 469
+2 1 2 1 0 0 0 0 3.000 1 0
+ 0 0 1.000 4.000 8.000
+ 314 464 409 464 9999 9999
+2 1 2 1 0 0 0 0 3.000 1 0
+ 0 0 1.000 4.000 8.000
+ 409 459 314 459 9999 9999
+-6
+6 414 279 589 424
+6 473 340 557 414
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 399 554 399 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 388 554 388 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 377 554 377 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 367 554 367 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 356 554 356 9999 9999
+2 2 0 1 0 0 0 0 0.000 0 0
+ 477 344 554 344 554 410 477 410 477 344 9999 9999
+-6
+1 3 0 1 0 0 0 0 0.000 1 0.000 511 303 19 19 511 303 525 317
+2 1 0 1 0 0 0 0 0.000 0 0
+ 511 323 511 344 9999 9999
+-6
+6 189 279 364 424
+6 248 340 332 414
+2 2 0 1 0 0 0 0 0.000 0 0
+ 252 344 329 344 329 410 252 410 252 344 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 356 329 356 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 367 329 367 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 377 329 377 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 388 329 388 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 399 329 399 9999 9999
+-6
+1 3 0 1 0 0 0 0 0.000 1 0.000 286 303 19 19 286 303 300 317
+2 1 0 1 0 0 0 0 0.000 0 0
+ 286 323 286 344 9999 9999
+-6
+6 288 80 372 154
+2 1 0 1 0 0 0 0 0.000 0 0
+ 292 139 369 139 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 292 128 369 128 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 292 117 369 117 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 292 107 369 107 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 292 96 369 96 9999 9999
+2 2 0 1 0 0 0 0 0.000 0 0
+ 292 84 369 84 369 150 292 150 292 84 9999 9999
+-6
+1 3 0 1 0 0 0 0 0.000 1 0.000 326 43 19 19 326 43 340 57
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 318 351 452 351 452 460 444 459 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 484 349 459 349 459 464 444 464 9999 9999
+2 1 2 1 0 0 0 0 3.000 0 0
+ 154 239 659 239 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 484 359 324 449 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 318 360 362 361 314 450 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 326 63 326 84 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 358 91 492 91 492 200 484 199 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 358 100 402 101 354 190 9999 9999
+4 1 0 11 0 0 0 0.000 1 7 24 509 274 Child
+4 0 0 12 0 0 0 0.000 1 9 33 269 275 Parent
+4 0 0 12 0 0 0 0.000 1 9 33 309 15 Parent
diff --git a/share/doc/psd/20.ipctut/fig8.pic b/share/doc/psd/20.ipctut/fig8.pic
new file mode 100644
index 00000000000..92b8833760e
--- /dev/null
+++ b/share/doc/psd/20.ipctut/fig8.pic
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" @(#)fig8.pic 8.1 (Berkeley) 8/14/93
+.PS
+.ps
+.ps 11
+.ft
+.ft R
+"Process 1" at 3.800,7.106 rjust
+"Process 2" at 6.612,7.106 rjust
+.ps
+.ps 10
+line from 3.150,6.200 to 4.112,6.200 to 4.112,5.375 to 3.150,5.375 to 3.150,6.200
+line from 3.150,6.050 to 4.112,6.050
+line from 3.150,5.912 to 4.112,5.912
+line from 3.150,5.787 to 4.112,5.787
+line from 3.150,5.650 to 4.112,5.650
+line from 3.150,5.513 to 4.112,5.513
+ellipse at 3.575,6.713 wid 0.475 ht 0.475
+line from 3.575,6.463 to 3.575,6.200
+line from 5.963,5.513 to 6.925,5.513
+line from 5.963,5.650 to 6.925,5.650
+line from 5.963,5.787 to 6.925,5.787
+line from 5.963,5.912 to 6.925,5.912
+line from 5.963,6.050 to 6.925,6.050
+line from 5.963,6.200 to 6.925,6.200 to 6.925,5.375 to 5.963,5.375 to 5.963,6.200
+ellipse at 6.388,6.713 wid 0.475 ht 0.475
+line from 6.388,6.463 to 6.388,6.200
+line from 3.087,8.637 to 4.050,8.637
+line from 3.087,8.775 to 4.050,8.775
+line from 3.087,8.912 to 4.050,8.912
+line from 3.087,9.037 to 4.050,9.037
+line from 3.087,9.175 to 4.050,9.175
+line from 3.087,9.325 to 4.050,9.325 to 4.050,8.500 to 3.087,8.500 to 3.087,9.325
+ellipse at 3.513,9.838 wid 0.475 ht 0.475
+line from 3.513,9.588 to 3.513,9.325
+line from 5.900,9.325 to 6.862,9.325 to 6.862,8.500 to 5.900,8.500 to 5.900,9.325
+line from 5.900,9.175 to 6.862,9.175
+line from 5.900,9.037 to 6.862,9.037
+line from 5.900,8.912 to 6.862,8.912
+line from 5.900,8.775 to 6.862,8.775
+line from 5.900,8.637 to 6.862,8.637
+ellipse at 6.325,9.838 wid 0.475 ht 0.475
+line from 6.325,9.588 to 6.325,9.325
+.ps
+.ps 11
+"Process 2" at 6.550,10.231 rjust
+"Process 1" at 3.737,10.231 rjust
+.ps
+.ps 10
+ellipse at 6.112,4.888 wid 0.275 ht 0.275
+ellipse at 5.350,4.763 wid 0.275 ht 0.275
+ellipse at 3.737,4.763 wid 0.275 ht 0.275
+ellipse at 4.550,7.950 wid 0.275 ht 0.275
+ellipse at 5.487,7.950 wid 0.275 ht 0.275
+line from 6.050,6.013 to 5.175,6.013 to 5.987,5.013
+line from 5.905,5.074 to 5.987,5.013 to 5.944,5.106
+line from 6.050,6.138 to 5.737,6.138 to 5.737,4.700 to 5.550,4.700
+line from 5.650,4.725 to 5.550,4.700 to 5.650,4.675
+dashwid = 0.037i
+line dotted from 1.925,7.513 to 8.238,7.513
+line from 3.975,6.000 to 4.525,5.987 to 3.925,4.875
+line from 3.950,4.975 to 3.925,4.875 to 3.994,4.951
+line dotted from 5.112,4.763 to 3.925,4.763
+line from 4.025,4.788 to 3.925,4.763 to 4.025,4.737
+line dotted from 3.925,4.700 to 5.112,4.700
+line from 5.013,4.675 to 5.112,4.700 to 5.013,4.725
+line from 6.050,9.012 to 5.487,9.012 to 5.487,8.137
+line from 5.462,8.237 to 5.487,8.137 to 5.513,8.237
+line from 3.737,9.137 to 4.550,9.137 to 4.550,8.137
+line from 4.525,8.237 to 4.550,8.137 to 4.575,8.237
+.ps
+.ps 11
+"NAME" at 6.737,4.918 rjust
+"NAME" at 6.112,8.043 rjust
+.ps
+.ft
+.PE
diff --git a/share/doc/psd/20.ipctut/fig8.xfig b/share/doc/psd/20.ipctut/fig8.xfig
new file mode 100644
index 00000000000..f1a52576857
--- /dev/null
+++ b/share/doc/psd/20.ipctut/fig8.xfig
@@ -0,0 +1,116 @@
+#FIG 2.0
+80 2
+6 224 254 589 279
+4 2 0 11 0 0 0 0.000 1 7 38 304 274 Process 1
+4 2 0 11 0 0 0 0.000 1 7 38 529 274 Process 2
+-6
+6 189 279 364 424
+6 248 340 332 414
+2 2 0 1 0 0 0 0 0.000 0 0
+ 252 344 329 344 329 410 252 410 252 344 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 356 329 356 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 367 329 367 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 377 329 377 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 388 329 388 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 252 399 329 399 9999 9999
+-6
+1 3 0 1 0 0 0 0 0.000 1 0.000 286 303 19 19 286 303 300 317
+2 1 0 1 0 0 0 0 0.000 0 0
+ 286 323 286 344 9999 9999
+-6
+6 414 279 589 424
+6 473 340 557 414
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 399 554 399 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 388 554 388 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 377 554 377 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 367 554 367 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 477 356 554 356 9999 9999
+2 2 0 1 0 0 0 0 0.000 0 0
+ 477 344 554 344 554 410 477 410 477 344 9999 9999
+-6
+1 3 0 1 0 0 0 0 0.000 1 0.000 511 303 19 19 511 303 525 317
+2 1 0 1 0 0 0 0 0.000 0 0
+ 511 323 511 344 9999 9999
+-6
+6 184 29 359 174
+6 243 90 327 164
+2 1 0 1 0 0 0 0 0.000 0 0
+ 247 149 324 149 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 247 138 324 138 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 247 127 324 127 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 247 117 324 117 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 247 106 324 106 9999 9999
+2 2 0 1 0 0 0 0 0.000 0 0
+ 247 94 324 94 324 160 247 160 247 94 9999 9999
+-6
+1 3 0 1 0 0 0 0 0.000 1 0.000 281 53 19 19 281 53 295 67
+2 1 0 1 0 0 0 0 0.000 0 0
+ 281 73 281 94 9999 9999
+-6
+6 409 29 584 174
+6 468 90 552 164
+2 2 0 1 0 0 0 0 0.000 0 0
+ 472 94 549 94 549 160 472 160 472 94 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 472 106 549 106 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 472 117 549 117 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 472 127 549 127 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 472 138 549 138 9999 9999
+2 1 0 1 0 0 0 0 0.000 0 0
+ 472 149 549 149 9999 9999
+-6
+1 3 0 1 0 0 0 0 0.000 1 0.000 506 53 19 19 506 53 520 67
+2 1 0 1 0 0 0 0 0.000 0 0
+ 506 73 506 94 9999 9999
+-6
+6 219 4 584 29
+4 2 0 11 0 0 0 0.000 1 7 38 524 24 Process 2
+4 2 0 11 0 0 0 0.000 1 7 38 299 24 Process 1
+-6
+1 3 0 1 0 0 0 0 0.000 1 0.000 489 449 11 11 489 449 494 459
+1 3 0 1 0 0 0 0 0.000 1 0.000 428 459 11 11 428 459 433 469
+1 3 0 1 0 0 0 0 0.000 1 0.000 299 459 11 11 299 459 304 469
+1 3 0 1 0 0 0 0 0.000 1 0.000 364 204 11 11 364 204 369 214
+1 3 0 1 0 0 0 0 0.000 1 0.000 439 204 11 11 439 204 444 214
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 484 359 414 359 479 439 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 484 349 459 349 459 464 444 464 9999 9999
+2 1 2 1 0 0 0 0 3.000 0 0
+ 154 239 659 239 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 318 360 362 361 314 450 9999 9999
+2 1 2 1 0 0 0 0 3.000 1 0
+ 0 0 1.000 4.000 8.000
+ 409 459 314 459 9999 9999
+2 1 2 1 0 0 0 0 3.000 1 0
+ 0 0 1.000 4.000 8.000
+ 314 464 409 464 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 484 119 439 119 439 189 9999 9999
+2 1 0 1 0 0 0 0 0.000 1 0
+ 0 0 1.000 4.000 8.000
+ 299 109 364 109 364 189 9999 9999
+4 2 0 11 0 0 0 0.000 1 7 32 539 449 NAME
+4 2 0 11 0 0 0 0.000 1 7 32 489 199 NAME
diff --git a/share/doc/psd/20.ipctut/pipe.c b/share/doc/psd/20.ipctut/pipe.c
new file mode 100644
index 00000000000..3f482f3084d
--- /dev/null
+++ b/share/doc/psd/20.ipctut/pipe.c
@@ -0,0 +1,74 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)pipe.c 8.1 (Berkeley) 6/8/93
+.\"
+#include <stdio.h>
+
+#define DATA "Bright star, would I were steadfast as thou art . . ."
+
+/*
+ * This program creates a pipe, then forks. The child communicates to the
+ * parent over the pipe. Notice that a pipe is a one-way communications
+ * device. I can write to the output socket (sockets[1], the second socket
+ * of the array returned by pipe()) and read from the input socket
+ * (sockets[0]), but not vice versa.
+ */
+
+main()
+{
+ int sockets[2], child;
+
+ /* Create a pipe */
+ if (pipe(sockets) < 0) {
+ perror("opening stream socket pair");
+ exit(10);
+ }
+
+ if ((child = fork()) == -1)
+ perror("fork");
+ else if (child) {
+ char buf[1024];
+
+ /* This is still the parent. It reads the child's message. */
+ close(sockets[1]);
+ if (read(sockets[0], buf, 1024) < 0)
+ perror("reading message");
+ printf("-->%s\en", buf);
+ close(sockets[0]);
+ } else {
+ /* This is the child. It writes a message to its parent. */
+ close(sockets[0]);
+ if (write(sockets[1], DATA, sizeof(DATA)) < 0)
+ perror("writing message");
+ close(sockets[1]);
+ }
+}
diff --git a/share/doc/psd/20.ipctut/socketpair.c b/share/doc/psd/20.ipctut/socketpair.c
new file mode 100644
index 00000000000..afc5c90cab4
--- /dev/null
+++ b/share/doc/psd/20.ipctut/socketpair.c
@@ -0,0 +1,77 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)socketpair.c 8.1 (Berkeley) 6/8/93
+.\"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+
+#define DATA1 "In Xanadu, did Kublai Khan . . ."
+#define DATA2 "A stately pleasure dome decree . . ."
+
+/*
+ * This program creates a pair of connected sockets then forks and
+ * communicates over them. This is very similar to communication with pipes,
+ * however, socketpairs are two-way communications objects. Therefore I can
+ * send messages in both directions.
+ */
+
+main()
+{
+ int sockets[2], child;
+ char buf[1024];
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
+ perror("opening stream socket pair");
+ exit(1);
+ }
+
+ if ((child = fork()) == -1)
+ perror("fork");
+ else if (child) { /* This is the parent. */
+ close(sockets[0]);
+ if (read(sockets[1], buf, 1024, 0) < 0)
+ perror("reading stream message");
+ printf("-->%s\en", buf);
+ if (write(sockets[1], DATA2, sizeof(DATA2)) < 0)
+ perror("writing stream message");
+ close(sockets[1]);
+ } else { /* This is the child. */
+ close(sockets[1]);
+ if (write(sockets[0], DATA1, sizeof(DATA1)) < 0)
+ perror("writing stream message");
+ if (read(sockets[0], buf, 1024, 0) < 0)
+ perror("reading stream message");
+ printf("-->%s\en", buf);
+ close(sockets[0]);
+ }
+}
diff --git a/share/doc/psd/20.ipctut/strchkread.c b/share/doc/psd/20.ipctut/strchkread.c
new file mode 100644
index 00000000000..dcab1fce828
--- /dev/null
+++ b/share/doc/psd/20.ipctut/strchkread.c
@@ -0,0 +1,106 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)strchkread.c 8.1 (Berkeley) 6/8/93
+.\"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#define TRUE 1
+
+/*
+ * This program uses select() to check that someone is trying to connect
+ * before calling accept().
+ */
+
+main()
+{
+ int sock, length;
+ struct sockaddr_in server;
+ int msgsock;
+ char buf[1024];
+ int rval;
+ fd_set ready;
+ struct timeval to;
+
+ /* Create socket */
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ perror("opening stream socket");
+ exit(1);
+ }
+ /* Name socket using wildcards */
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+ server.sin_port = 0;
+ if (bind(sock, &server, sizeof(server))) {
+ perror("binding stream socket");
+ exit(1);
+ }
+ /* Find out assigned port number and print it out */
+ length = sizeof(server);
+ if (getsockname(sock, &server, &length)) {
+ perror("getting socket name");
+ exit(1);
+ }
+ printf("Socket has port #%d\en", ntohs(server.sin_port));
+
+ /* Start accepting connections */
+ listen(sock, 5);
+ do {
+ FD_ZERO(&ready);
+ FD_SET(sock, &ready);
+ to.tv_sec = 5;
+ if (select(sock + 1, &ready, 0, 0, &to) < 0) {
+ perror("select");
+ continue;
+ }
+ if (FD_ISSET(sock, &ready)) {
+ msgsock = accept(sock, (struct sockaddr *)0, (int *)0);
+ if (msgsock == -1)
+ perror("accept");
+ else do {
+ bzero(buf, sizeof(buf));
+ if ((rval = read(msgsock, buf, 1024)) < 0)
+ perror("reading stream message");
+ else if (rval == 0)
+ printf("Ending connection\en");
+ else
+ printf("-->%s\en", buf);
+ } while (rval > 0);
+ close(msgsock);
+ } else
+ printf("Do something else\en");
+ } while (TRUE);
+}
diff --git a/share/doc/psd/20.ipctut/streamread.c b/share/doc/psd/20.ipctut/streamread.c
new file mode 100644
index 00000000000..139a2698dad
--- /dev/null
+++ b/share/doc/psd/20.ipctut/streamread.c
@@ -0,0 +1,102 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)streamread.c 8.1 (Berkeley) 6/8/93
+.\"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#define TRUE 1
+
+/*
+ * This program creates a socket and then begins an infinite loop. Each time
+ * through the loop it accepts a connection and prints out messages from it.
+ * When the connection breaks, or a termination message comes through, the
+ * program accepts a new connection.
+ */
+
+main()
+{
+ int sock, length;
+ struct sockaddr_in server;
+ int msgsock;
+ char buf[1024];
+ int rval;
+ int i;
+
+ /* Create socket */
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ perror("opening stream socket");
+ exit(1);
+ }
+ /* Name socket using wildcards */
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+ server.sin_port = 0;
+ if (bind(sock, &server, sizeof(server))) {
+ perror("binding stream socket");
+ exit(1);
+ }
+ /* Find out assigned port number and print it out */
+ length = sizeof(server);
+ if (getsockname(sock, &server, &length)) {
+ perror("getting socket name");
+ exit(1);
+ }
+ printf("Socket has port #%d\en", ntohs(server.sin_port));
+
+ /* Start accepting connections */
+ listen(sock, 5);
+ do {
+ msgsock = accept(sock, 0, 0);
+ if (msgsock == -1)
+ perror("accept");
+ else do {
+ bzero(buf, sizeof(buf));
+ if ((rval = read(msgsock, buf, 1024)) < 0)
+ perror("reading stream message");
+ i = 0;
+ if (rval == 0)
+ printf("Ending connection\en");
+ else
+ printf("-->%s\en", buf);
+ } while (rval != 0);
+ close(msgsock);
+ } while (TRUE);
+ /*
+ * Since this program has an infinite loop, the socket "sock" is
+ * never explicitly closed. However, all sockets will be closed
+ * automatically when a process is killed or terminates normally.
+ */
+}
diff --git a/share/doc/psd/20.ipctut/streamwrite.c b/share/doc/psd/20.ipctut/streamwrite.c
new file mode 100644
index 00000000000..db4daafe5a7
--- /dev/null
+++ b/share/doc/psd/20.ipctut/streamwrite.c
@@ -0,0 +1,81 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)streamwrite.c 8.1 (Berkeley) 6/8/93
+.\"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+
+#define DATA "Half a league, half a league . . ."
+
+/*
+ * This program creates a socket and initiates a connection with the socket
+ * given in the command line. One message is sent over the connection and
+ * then the socket is closed, ending the connection. The form of the command
+ * line is streamwrite hostname portnumber
+ */
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int sock;
+ struct sockaddr_in server;
+ struct hostent *hp, *gethostbyname();
+ char buf[1024];
+
+ /* Create socket */
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ perror("opening stream socket");
+ exit(1);
+ }
+ /* Connect socket using name specified by command line. */
+ server.sin_family = AF_INET;
+ hp = gethostbyname(argv[1]);
+ if (hp == 0) {
+ fprintf(stderr, "%s: unknown host\n", argv[1]);
+ exit(2);
+ }
+ bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
+ server.sin_port = htons(atoi(argv[2]));
+
+ if (connect(sock, &server, sizeof(server)) < 0) {
+ perror("connecting stream socket");
+ exit(1);
+ }
+ if (write(sock, DATA, sizeof(DATA)) < 0)
+ perror("writing on stream socket");
+ close(sock);
+}
diff --git a/share/doc/psd/20.ipctut/tutor.me b/share/doc/psd/20.ipctut/tutor.me
new file mode 100644
index 00000000000..fba4583f139
--- /dev/null
+++ b/share/doc/psd/20.ipctut/tutor.me
@@ -0,0 +1,939 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)tutor.me 8.1 (Berkeley) 8/14/93
+.\"
+.oh 'Introductory 4.4BSD IPC''PSD:20-%'
+.eh 'PSD:20-%''Introductory 4.4BSD IPC'
+.rs
+.sp 2
+.sz 14
+.ft B
+.ce 2
+An Introductory 4.4BSD
+Interprocess Communication Tutorial
+.sz 10
+.sp 2
+.ce
+.i "Stuart Sechrest"
+.ft
+.sp
+.ce 4
+Computer Science Research Group
+Computer Science Division
+Department of Electrical Engineering and Computer Science
+University of California, Berkeley
+.sp 2
+.ce
+.i ABSTRACT
+.sp
+.(c
+.pp
+Berkeley UNIX\(dg 4.4BSD offers several choices for interprocess communication.
+To aid the programmer in developing programs which are comprised of
+cooperating
+processes, the different choices are discussed and a series of example
+programs are presented. These programs
+demonstrate in a simple way the use of pipes, socketpairs, sockets
+and the use of datagram and stream communication. The intent of this
+document is to present a few simple example programs, not to describe the
+networking system in full.
+.)c
+.sp 2
+.(f
+\(dg\|UNIX is a trademark of AT&T Bell Laboratories.
+.)f
+.b
+.sh 1 "Goals"
+.r
+.pp
+Facilities for interprocess communication (IPC) and networking
+were a major addition to UNIX in the Berkeley UNIX 4.2BSD release.
+These facilities required major additions and some changes
+to the system interface.
+The basic idea of this interface is to make IPC similar to file I/O.
+In UNIX a process has a set of I/O descriptors, from which one reads
+and to which one writes.
+Descriptors may refer to normal files, to devices (including terminals),
+or to communication channels.
+The use of a descriptor has three phases: its creation,
+its use for reading and writing, and its destruction. By using descriptors
+to write files, rather than simply naming the target file in the write
+call, one gains a surprising amount of flexibility. Often, the program that
+creates a descriptor will be different from the program that uses the
+descriptor. For example the shell can create a descriptor for the output
+of the `ls'
+command that will cause the listing to appear in a file rather than
+on a terminal.
+Pipes are another form of descriptor that have been used in UNIX
+for some time.
+Pipes allow one-way data transmission from one process
+to another; the two processes and the pipe must be set up by a common
+ancestor.
+.pp
+The use of descriptors is not the only communication interface
+provided by UNIX.
+The signal mechanism sends a tiny amount of information from one
+process to another.
+The signaled process receives only the signal type,
+not the identity of the sender,
+and the number of possible signals is small.
+The signal semantics limit the flexibility of the signaling mechanism
+as a means of interprocess communication.
+.pp
+The identification of IPC with I/O is quite longstanding in UNIX and
+has proved quite successful. At first, however, IPC was limited to
+processes communicating within a single machine. With Berkeley UNIX
+4.2BSD this expanded to include IPC between machines. This expansion
+has necessitated some change in the way that descriptors are created.
+Additionally, new possibilities for the meaning of read and write have
+been admitted. Originally the meanings, or semantics, of these terms
+were fairly simple. When you wrote something it was delivered. When
+you read something, you were blocked until the data arrived.
+Other possibilities exist,
+however. One can write without full assurance of delivery if one can
+check later to catch occasional failures. Messages can be kept as
+discrete units or merged into a stream.
+One can ask to read, but insist on not waiting if nothing is immediately
+available. These new possibilities are allowed in the Berkeley UNIX IPC
+interface.
+.pp
+Thus Berkeley UNIX 4.4BSD offers several choices for IPC.
+This paper presents simple examples that illustrate some of
+the choices.
+The reader is presumed to be familiar with the C programming language
+[Kernighan & Ritchie 1978],
+but not necessarily with the system calls of the UNIX system or with
+processes and interprocess communication.
+The paper reviews the notion of a process and the types of
+communication that are supported by Berkeley UNIX 4.4BSD.
+A series of examples are presented that create processes that communicate
+with one another. The programs show different ways of establishing
+channels of communication.
+Finally, the calls that actually transfer data are reviewed.
+To clearly present how communication can take place,
+the example programs have been cleared of anything that
+might be construed as useful work.
+They can, therefore, serve as models
+for the programmer trying to construct programs which are comprised of
+cooperating processes.
+.b
+.sh 1 "Processes"
+.pp
+A \fIprogram\fP is both a sequence of statements and a rough way of referring
+to the computation that occurs when the compiled statements are run.
+A \fIprocess\fP can be thought of as a single line of control in a program.
+Most programs execute some statements, go through a few loops, branch in
+various directions and then end. These are single process programs.
+Programs can also have a point where control splits into two independent lines,
+an action called \fIforking.\fP
+In UNIX these lines can never join again. A call to the system routine
+\fIfork()\fP, causes a process to split in this way.
+The result of this call is that two independent processes will be
+running, executing exactly the same code.
+Memory values will be the same for all values set before the fork, but,
+subsequently, each version will be able to change only the
+value of its own copy of each variable.
+Initially, the only difference between the two will be the value returned by
+\fIfork().\fP The parent will receive a process id for the child,
+the child will receive a zero.
+Calls to \fIfork(),\fP
+therefore, typically precede, or are included in, an if-statement.
+.pp
+A process views the rest of the system through a private table of descriptors.
+The descriptors can represent open files or sockets (sockets are communication
+objects that will be discussed below). Descriptors are referred to
+by their index numbers in the table. The first three descriptors are often
+known by special names, \fI stdin, stdout\fP and \fIstderr\fP.
+These are the standard input, output and error.
+When a process forks, its descriptor table is copied to the child.
+Thus, if the parent's standard input is being taken from a terminal
+(devices are also treated as files in UNIX), the child's input will
+be taken from the
+same terminal. Whoever reads first will get the input. If, before forking,
+the parent changes its standard input so that it is reading from a
+new file, the child will take its input from the new file. It is
+also possible to take input from a socket, rather than from a file.
+.b
+.sh 1 "Pipes"
+.r
+.pp
+Most users of UNIX know that they can pipe the output of a
+program ``prog1'' to the input of another, ``prog2,'' by typing the command
+\fI``prog1 | prog2.''\fP
+This is called ``piping'' the output of one program
+to another because the mechanism used to transfer the output is called a
+pipe.
+When the user types a command, the command is read by the shell, which
+decides how to execute it. If the command is simple, for example,
+.i "``prog1,''"
+the shell forks a process, which executes the program, prog1, and then dies.
+The shell waits for this termination and then prompts for the next
+command.
+If the command is a compound command,
+.i "``prog1 | prog2,''"
+the shell creates two processes connected by a pipe. One process
+runs the program, prog1, the other runs prog2. The pipe is an I/O
+mechanism with two ends, or sockets. Data that is written into one socket
+can be read from the other.
+.(z
+.ft CW
+.so pipe.c
+.ft
+.ce 1
+Figure 1\ \ Use of a pipe
+.)z
+.pp
+Since a program specifies its input and output only by the descriptor table
+indices, which appear as variables or constants,
+the input source and output destination can be changed without
+changing the text of the program.
+It is in this way that the shell is able to set up pipes. Before executing
+prog1, the process can close whatever is at \fIstdout\fP
+and replace it with one
+end of a pipe. Similarly, the process that will execute prog2 can substitute
+the opposite end of the pipe for
+\fIstdin.\fP
+.pp
+Let us now examine a program that creates a pipe for communication between
+its child and itself (Figure 1).
+A pipe is created by a parent process, which then forks.
+When a process forks, the parent's descriptor table is copied into
+the child's.
+.pp
+In Figure 1, the parent process makes a call to the system routine
+\fIpipe().\fP
+This routine creates a pipe and places descriptors for the sockets
+for the two ends of the pipe in the process's descriptor table.
+\fIPipe()\fP
+is passed an array into which it places the index numbers of the
+sockets it created.
+The two ends are not equivalent. The socket whose index is
+returned in the low word of the array is opened for reading only,
+while the socket in the high end is opened only for writing.
+This corresponds to the fact that the standard input is the first
+descriptor of a process's descriptor table and the standard output
+is the second. After creating the pipe, the parent creates the child
+with which it will share the pipe by calling \fIfork().\fP
+Figure 2 illustrates the effect of a fork.
+The parent process's descriptor table points to both ends of the pipe.
+After the fork, both parent's and child's descriptor tables point to
+the pipe.
+The child can then use the pipe to send a message to the parent.
+.(z
+.so fig2.pic
+.ce 2
+Figure 2\ \ Sharing a pipe between parent and child
+.ce 0
+.)z
+.pp
+Just what is a pipe?
+It is a one-way communication mechanism, with one end opened
+for reading and the other end for writing.
+Therefore, parent and child need to agree on which way to turn
+the pipe, from parent to child or the other way around.
+Using the same pipe for communication both from parent to child and
+from child to parent would be possible (since both processes have
+references to both ends), but very complicated.
+If the parent and child are to have a two-way conversation,
+the parent creates two pipes, one for use in each direction.
+(In accordance with their plans, both parent and child in the example above
+close the socket that they will not use. It is not required that unused
+descriptors be closed, but it is good practice.)
+A pipe is also a \fIstream\fP communication mechanism; that
+is, all messages sent through the pipe are placed in order
+and reliably delivered. When the reader asks for a certain
+number of bytes from this
+stream, he is given as many bytes as are available, up
+to the amount of the request. Note that these bytes may have come from
+the same call to \fIwrite()\fR or from several calls to \fIwrite()\fR
+which were concatenated.
+.b
+.sh 1 "Socketpairs"
+.r
+.pp
+Berkeley UNIX 4.4BSD provides a slight generalization of pipes. A pipe is a
+pair of connected sockets for one-way stream communication. One may
+obtain a pair of connected sockets for two-way stream communication
+by calling the routine \fIsocketpair().\fP
+The program in Figure 3 calls \fIsocketpair()\fP
+to create such a connection. The program uses the link for
+communication in both directions. Since socketpairs are
+an extension of pipes, their use resembles that of pipes.
+Figure 4 illustrates the result of a fork following a call to
+\fIsocketpair().\fP
+.pp
+\fISocketpair()\fP
+takes as
+arguments a specification of a domain, a style of communication, and a
+protocol.
+These are the parameters shown in the example.
+Domains and protocols will be discussed in the next section.
+Briefly,
+a domain is a space of names that may be bound
+to sockets and implies certain other conventions.
+Currently, socketpairs have only been implemented for one
+domain, called the UNIX domain.
+The UNIX domain uses UNIX path names for naming sockets.
+It only allows communication
+between sockets on the same machine.
+.pp
+Note that the header files
+.i "<sys/socket.h>"
+and
+.i "<sys/types.h>."
+are required in this program.
+The constants AF_UNIX and SOCK_STREAM are defined in
+.i "<sys/socket.h>,"
+which in turn requires the file
+.i "<sys/types.h>"
+for some of its definitions.
+.(z
+.ft CW
+.so socketpair.c
+.ft
+.ce 1
+Figure 3\ \ Use of a socketpair
+.)z
+.(z
+.so fig3.pic
+.ce 1
+Figure 4\ \ Sharing a socketpair between parent and child
+.)z
+.b
+.sh 1 "Domains and Protocols"
+.r
+.pp
+Pipes and socketpairs are a simple solution for communicating between
+a parent and child or between child processes.
+What if we wanted to have processes that have no common ancestor
+with whom to set up communication?
+Neither standard UNIX pipes nor socketpairs are
+the answer here, since both mechanisms require a common ancestor to
+set up the communication.
+We would like to have two processes separately create sockets
+and then have messages sent between them. This is often the
+case when providing or using a service in the system. This is
+also the case when the communicating processes are on separate machines.
+In Berkeley UNIX 4.4BSD one can create individual sockets, give them names and
+send messages between them.
+.pp
+Sockets created by different programs use names to refer to one another;
+names generally must be translated into addresses for use.
+The space from which an address is drawn is referred to as a
+.i domain.
+There are several domains for sockets.
+Two that will be used in the examples here are the UNIX domain (or AF_UNIX,
+for Address Format UNIX) and the Internet domain (or AF_INET).
+UNIX domain IPC is an experimental facility in 4.2BSD and 4.3BSD.
+In the UNIX domain, a socket is given a path name within the file system
+name space.
+A file system node is created for the socket and other processes may
+then refer to the socket by giving the proper pathname.
+UNIX domain names, therefore, allow communication between any two processes
+that work in the same file system.
+The Internet domain is the UNIX implementation of the DARPA Internet
+standard protocols IP/TCP/UDP.
+Addresses in the Internet domain consist of a machine network address
+and an identifying number, called a port.
+Internet domain names allow communication between machines.
+.pp
+Communication follows some particular ``style.''
+Currently, communication is either through a \fIstream\fP
+or by \fIdatagram.\fP
+Stream communication implies several things. Communication takes
+place across a connection between two sockets. The communication
+is reliable, error-free, and, as in pipes, no message boundaries are
+kept. Reading from a stream may result in reading the data sent from
+one or several calls to \fIwrite()\fP
+or only part of the data from a single call, if there is not enough room
+for the entire message, or if not all the data from a large message
+has been transferred.
+The protocol implementing such a style will retransmit messages
+received with errors. It will also return error messages if one tries to
+send a message after the connection has been broken.
+Datagram communication does not use connections. Each message is
+addressed individually. If the address is correct, it will generally
+be received, although this is not guaranteed. Often datagrams are
+used for requests that require a response from the
+recipient. If no response
+arrives in a reasonable amount of time, the request is repeated.
+The individual datagrams will be kept separate when they are read, that
+is, message boundaries are preserved.
+.pp
+The difference in performance between the two styles of communication is
+generally less important than the difference in semantics. The
+performance gain that one might find in using datagrams must be weighed
+against the increased complexity of the program, which must now concern
+itself with lost or out of order messages. If lost messages may simply be
+ignored, the quantity of traffic may be a consideration. The expense
+of setting up a connection is best justified by frequent use of the connection.
+Since the performance of a protocol changes as it is tuned for different
+situations, it is best to seek the most up-to-date information when
+making choices for a program in which performance is crucial.
+.pp
+A protocol is a set of rules, data formats and conventions that regulate the
+transfer of data between participants in the communication.
+In general, there is one protocol for each socket type (stream,
+datagram, etc.) within each domain.
+The code that implements a protocol
+keeps track of the names that are bound to sockets,
+sets up connections and transfers data between sockets,
+perhaps sending the data across a network.
+This code also keeps track of the names that are bound to sockets.
+It is possible for several protocols, differing only in low level
+details, to implement the same style of communication within
+a particular domain. Although it is possible to select
+which protocol should be used, for nearly all uses it is sufficient to
+request the default protocol. This has been done in all of the example
+programs.
+.pp
+One specifies the domain, style and protocol of a socket when
+it is created. For example, in Figure 5a the call to \fIsocket()\fP
+causes the creation of a datagram socket with the default protocol
+in the UNIX domain.
+.b
+.sh 1 "Datagrams in the UNIX Domain"
+.r
+.(z
+.ft CW
+.so udgramread.c
+.ft
+.ce 1
+Figure 5a\ \ Reading UNIX domain datagrams
+.)z
+.pp
+Let us now look at two programs that create sockets separately.
+The programs in Figures 5a and 5b use datagram communication
+rather than a stream.
+The structure used to name UNIX domain sockets is defined
+in the file \fI<sys/un.h>.\fP
+The definition has also been included in the example for clarity.
+.pp
+Each program creates a socket with a call to \fIsocket().\fP
+These sockets are in the UNIX domain.
+Once a name has been decided upon it is attached to a socket by the
+system call \fIbind().\fP
+The program in Figure 5a uses the name ``socket'',
+which it binds to its socket.
+This name will appear in the working directory of the program.
+The routines in Figure 5b use its
+socket only for sending messages. It does not create a name for
+the socket because no other process has to refer to it.
+.(z
+.ft CW
+.so udgramsend.c
+.ft
+.ce 1
+Figure 5b\ \ Sending a UNIX domain datagrams
+.)z
+.pp
+Names in the UNIX domain are path names. Like file path names they may
+be either absolute (e.g. ``/dev/imaginary'') or relative (e.g. ``socket'').
+Because these names are used to allow processes to rendezvous, relative
+path names can pose difficulties and should be used with care.
+When a name is bound into the name space, a file (inode) is allocated in the
+file system. If
+the inode is not deallocated, the name will continue to exist even after
+the bound socket is closed. This can cause subsequent runs of a program
+to find that a name is unavailable, and can cause
+directories to fill up with these
+objects. The names are removed by calling \fIunlink()\fP or using
+the \fIrm\fP\|(1) command.
+Names in the UNIX domain are only used for rendezvous. They are not used
+for message delivery once a connection is established. Therefore, in
+contrast with the Internet domain, unbound sockets need not be (and are
+not) automatically given addresses when they are connected.
+.pp
+There is no established means of communicating names to interested
+parties. In the example, the program in Figure 5b gets the
+name of the socket to which it will send its message through its
+command line arguments. Once a line of communication has been created,
+one can send the names of additional, perhaps new, sockets over the link.
+Facilities will have to be built that will make the distribution of
+names less of a problem than it now is.
+.b
+.sh 1 "Datagrams in the Internet Domain"
+.r
+.(z
+.ft CW
+.so dgramread.c
+.ft
+.ce 1
+Figure 6a\ \ Reading Internet domain datagrams
+.)z
+.pp
+The examples in Figure 6a and 6b are very close to the previous example
+except that the socket is in the Internet domain.
+The structure of Internet domain addresses is defined in the file
+\fI<netinet/in.h>\fP.
+Internet addresses specify a host address (a 32-bit number)
+and a delivery slot, or port, on that
+machine. These ports are managed by the system routines that implement
+a particular protocol.
+Unlike UNIX domain names, Internet socket names are not entered into
+the file system and, therefore,
+they do not have to be unlinked after the socket has been closed.
+When a message must be sent between machines it is sent to
+the protocol routine on the destination machine, which interprets the
+address to determine to which socket the message should be delivered.
+Several different protocols may be active on
+the same machine, but, in general, they will not communicate with one another.
+As a result, different protocols are allowed to use the same port numbers.
+Thus, implicitly, an Internet address is a triple including a protocol as
+well as the port and machine address.
+An \fIassociation\fP is a temporary or permanent specification
+of a pair of communicating sockets.
+An association is thus identified by the tuple
+<\fIprotocol, local machine address, local port,
+remote machine address, remote port\fP>.
+An association may be transient when using datagram sockets;
+the association actually exists during a \fIsend\fP operation.
+.(z
+.ft CW
+.so dgramsend.c
+.ft
+.ce 1
+Figure 6b\ \ Sending an Internet domain datagram
+.)z
+.pp
+The protocol for a socket is chosen when the socket is created. The
+local machine address for a socket can be any valid network address of the
+machine, if it has more than one, or it can be the wildcard value
+INADDR_ANY.
+The wildcard value is used in the program in Figure 6a.
+If a machine has several network addresses, it is likely
+that messages sent to any of the addresses should be deliverable to
+a socket. This will be the case if the wildcard value has been chosen.
+Note that even if the wildcard value is chosen, a program sending messages
+to the named socket must specify a valid network address. One can be willing
+to receive from ``anywhere,'' but one cannot send a message ``anywhere.''
+The program in Figure 6b is given the destination host name as a command
+line argument.
+To determine a network address to which it can send the message, it looks
+up
+the host address by the call to \fIgethostbyname()\fP.
+The returned structure includes the host's network address,
+which is copied into the structure specifying the
+destination of the message.
+.pp
+The port number can be thought of as the number of a mailbox, into
+which the protocol places one's messages. Certain daemons, offering
+certain advertised services, have reserved
+or ``well-known'' port numbers. These fall in the range
+from 1 to 1023. Higher numbers are available to general users.
+Only servers need to ask for a particular number.
+The system will assign an unused port number when an address
+is bound to a socket.
+This may happen when an explicit \fIbind\fP
+call is made with a port number of 0, or
+when a \fIconnect\fP or \fIsend\fP
+is performed on an unbound socket.
+Note that port numbers are not automatically reported back to the user.
+After calling \fIbind(),\fP asking for port 0, one may call
+\fIgetsockname()\fP to discover what port was actually assigned.
+The routine \fIgetsockname()\fP
+will not work for names in the UNIX domain.
+.pp
+The format of the socket address is specified in part by standards within the
+Internet domain. The specification includes the order of the bytes in
+the address. Because machines differ in the internal representation
+they ordinarily use
+to represent integers, printing out the port number as returned by
+\fIgetsockname()\fP may result in a misinterpretation. To
+print out the number, it is necessary to use the routine \fIntohs()\fP
+(for \fInetwork to host: short\fP) to convert the number from the
+network representation to the host's representation. On some machines,
+such as 68000-based machines, this is a null operation. On others,
+such as VAXes, this results in a swapping of bytes. Another routine
+exists to convert a short integer from the host format to the network format,
+called \fIhtons()\fP; similar routines exist for long integers.
+For further information, refer to the
+entry for \fIbyteorder\fP in section 3 of the manual.
+.b
+.sh 1 "Connections"
+.r
+.pp
+To send data between stream sockets (having communication style SOCK_STREAM),
+the sockets must be connected.
+Figures 7a and 7b show two programs that create such a connection.
+The program in 7a is relatively simple.
+To initiate a connection, this program simply creates
+a stream socket, then calls \fIconnect()\fP,
+specifying the address of the socket to which
+it wishes its socket connected. Provided that the target socket exists and
+is prepared to handle a connection, connection will be complete,
+and the program can begin to send
+messages. Messages will be delivered in order without message
+boundaries, as with pipes. The connection is destroyed when either
+socket is closed (or soon thereafter). If a process persists
+in sending messages after the connection is closed, a SIGPIPE signal
+is sent to the process by the operating system. Unless explicit action
+is taken to handle the signal (see the manual page for \fIsignal\fP
+or \fIsigvec\fP),
+the process will terminate and the shell
+will print the message ``broken pipe.''
+.(z
+.ft CW
+.so streamwrite.c
+.ft
+.ce 1
+Figure 7a\ \ Initiating an Internet domain stream connection
+.)z
+.(z
+.ft CW
+.so streamread.c
+.ft
+.ce 1
+Figure 7b\ \ Accepting an Internet domain stream connection
+.sp 2
+.ft CW
+.so strchkread.c
+.ft
+.ce 1
+Figure 7c\ \ Using select() to check for pending connections
+.)z
+.(z
+.so fig8.pic
+.sp
+.ce 1
+Figure 8\ \ Establishing a stream connection
+.)z
+.pp
+Forming a connection is asymmetrical; one process, such as the
+program in Figure 7a, requests a connection with a particular socket,
+the other process accepts connection requests.
+Before a connection can be accepted a socket must be created and an address
+bound to it. This
+situation is illustrated in the top half of Figure 8. Process 2
+has created a socket and bound a port number to it. Process 1 has created an
+unnamed socket.
+The address bound to process 2's socket is then made known to process 1 and,
+perhaps to several other potential communicants as well.
+If there are several possible communicants,
+this one socket might receive several requests for connections.
+As a result, a new socket is created for each connection. This new socket
+is the endpoint for communication within this process for this connection.
+A connection may be destroyed by closing the corresponding socket.
+.pp
+The program in Figure 7b is a rather trivial example of a server. It
+creates a socket to which it binds a name, which it then advertises.
+(In this case it prints out the socket number.) The program then calls
+\fIlisten()\fP for this socket.
+Since several clients may attempt to connect more or less
+simultaneously, a queue of pending connections is maintained in the system
+address space. \fIListen()\fP
+marks the socket as willing to accept connections and initializes the queue.
+When a connection is requested, it is listed in the queue. If the
+queue is full, an error status may be returned to the requester.
+The maximum length of this queue is specified by the second argument of
+\fIlisten()\fP; the maximum length is limited by the system.
+Once the listen call has been completed, the program enters
+an infinite loop. On each pass through the loop, a new connection is
+accepted and removed from the queue, and, hence, a new socket for the
+connection is created. The bottom half of Figure 8 shows the result of
+Process 1 connecting with the named socket of Process 2, and Process 2
+accepting the connection. After the connection is created, the
+service, in this case printing out the messages, is performed and the
+connection socket closed. The \fIaccept()\fP
+call will take a pending connection
+request from the queue if one is available, or block waiting for a request.
+Messages are read from the connection socket.
+Reads from an active connection will normally block until data is available.
+The number of bytes read is returned. When a connection is destroyed,
+the read call returns immediately. The number of bytes returned will
+be zero.
+.pp
+The program in Figure 7c is a slight variation on the server in Figure 7b.
+It avoids blocking when there are no pending connection requests by
+calling \fIselect()\fP
+to check for pending requests before calling \fIaccept().\fP
+This strategy is useful when connections may be received
+on more than one socket, or when data may arrive on other connected
+sockets before another connection request.
+.pp
+The programs in Figures 9a and 9b show a program using stream communication
+in the UNIX domain. Streams in the UNIX domain can be used for this sort
+of program in exactly the same way as Internet domain streams, except for
+the form of the names and the restriction of the connections to a single
+file system. There are some differences, however, in the functionality of
+streams in the two domains, notably in the handling of
+\fIout-of-band\fP data (discussed briefly below). These differences
+are beyond the scope of this paper.
+.(z
+.ft CW
+.so ustreamwrite.c
+.ft
+.ce 1
+Figure 9a\ \ Initiating a UNIX domain stream connection
+.sp 2
+.ft CW
+.so ustreamread.c
+.ft
+.ce 1
+Figure 9b\ \ Accepting a UNIX domain stream connection
+.)z
+.b
+.sh 1 "Reads, Writes, Recvs, etc."
+.r
+.pp
+UNIX 4.4BSD has several system calls for reading and writing information.
+The simplest calls are \fIread() \fP and \fIwrite().\fP \fIWrite()\fP
+takes as arguments the index of a descriptor, a pointer to a buffer
+containing the data and the size of the data.
+The descriptor may indicate either a file or a connected socket.
+``Connected'' can mean either a connected stream socket (as described
+in Section 8) or a datagram socket for which a \fIconnect()\fP
+call has provided a default destination (see the \fIconnect()\fP manual page).
+\fIRead()\fP also takes a descriptor that indicates either a file or a socket.
+\fIWrite()\fP requires a connected socket since no destination is
+specified in the parameters of the system call.
+\fIRead()\fP can be used for either a connected or an unconnected socket.
+These calls are, therefore, quite flexible and may be used to
+write applications that require no assumptions about the source of
+their input or the destination of their output.
+There are variations on \fIread() \fP and \fIwrite()\fP
+that allow the source and destination of the input and output to use
+several separate buffers, while retaining the flexibility to handle
+both files and sockets. These are \fIreadv()\fP and \fI writev(),\fP
+for read and write \fIvector.\fP
+.pp
+It is sometimes necessary to send high priority data over a
+connection that may have unread low priority data at the
+other end. For example, a user interface process may be interpreting
+commands and sending them on to another process through a stream connection.
+The user interface may have filled the stream with as yet unprocessed
+requests when the user types
+a command to cancel all outstanding requests.
+Rather than have the high priority data wait
+to be processed after the low priority data, it is possible to
+send it as \fIout-of-band\fP
+(OOB) data. The notification of pending OOB data results in the generation of
+a SIGURG signal, if this signal has been enabled (see the manual
+page for \fIsignal\fP or \fIsigvec\fP).
+See [Leffler 1986] for a more complete description of the OOB mechanism.
+There are a pair of calls similar to \fIread\fP and \fIwrite\fP
+that allow options, including sending
+and receiving OOB information; these are \fI send()\fP
+and \fIrecv().\fP
+These calls are used only with sockets; specifying a descriptor for a file will
+result in the return of an error status. These calls also allow
+\fIpeeking\fP at data in a stream.
+That is, they allow a process to read data without removing the data from
+the stream. One use of this facility is to read ahead in a stream
+to determine the size of the next item to be read.
+When not using these options, these calls have the same functions as
+\fIread()\fP and \fIwrite().\fP
+.pp
+To send datagrams, one must be allowed to specify the destination.
+The call \fIsendto()\fP
+takes a destination address as an argument and is therefore used for
+sending datagrams. The call \fIrecvfrom()\fP
+is often used to read datagrams, since this call returns the address
+of the sender, if it is available, along with the data.
+If the identity of the sender does not matter, one may use \fIread()\fP
+or \fIrecv().\fP
+.pp
+Finally, there are a pair of calls that allow the sending and
+receiving of messages from multiple buffers, when the address of the
+recipient must be specified. These are \fIsendmsg()\fP and
+\fIrecvmsg().\fP
+These calls are actually quite general and have other uses,
+including, in the UNIX domain, the transmission of a file descriptor from one
+process to another.
+.pp
+The various options for reading and writing are shown in Figure 10,
+together with their parameters. The parameters for each system call
+reflect the differences in function of the different calls.
+In the examples given in this paper, the calls \fIread()\fP and
+\fIwrite()\fP have been used whenever possible.
+.(z
+.ft CW
+ /*
+ * The variable descriptor may be the descriptor of either a file
+ * or of a socket.
+ */
+ cc = read(descriptor, buf, nbytes)
+ int cc, descriptor; char *buf; int nbytes;
+
+ /*
+ * An iovec can include several source buffers.
+ */
+ cc = readv(descriptor, iov, iovcnt)
+ int cc, descriptor; struct iovec *iov; int iovcnt;
+
+ cc = write(descriptor, buf, nbytes)
+ int cc, descriptor; char *buf; int nbytes;
+
+ cc = writev(descriptor, iovec, ioveclen)
+ int cc, descriptor; struct iovec *iovec; int ioveclen;
+
+ /*
+ * The variable ``sock'' must be the descriptor of a socket.
+ * Flags may include MSG_OOB and MSG_PEEK.
+ */
+ cc = send(sock, msg, len, flags)
+ int cc, sock; char *msg; int len, flags;
+
+ cc = sendto(sock, msg, len, flags, to, tolen)
+ int cc, sock; char *msg; int len, flags;
+ struct sockaddr *to; int tolen;
+
+ cc = sendmsg(sock, msg, flags)
+ int cc, sock; struct msghdr msg[]; int flags;
+
+ cc = recv(sock, buf, len, flags)
+ int cc, sock; char *buf; int len, flags;
+
+ cc = recvfrom(sock, buf, len, flags, from, fromlen)
+ int cc, sock; char *buf; int len, flags;
+ struct sockaddr *from; int *fromlen;
+
+ cc = recvmsg(sock, msg, flags)
+ int cc, socket; struct msghdr msg[]; int flags;
+.ft
+.sp 1
+.ce 1
+Figure 10\ \ Varieties of read and write commands
+.)z
+.b
+.sh 1 "Choices"
+.r
+.pp
+This paper has presented examples of some of the forms
+of communication supported by
+Berkeley UNIX 4.4BSD. These have been presented in an order chosen for
+ease of presentation. It is useful to review these options emphasizing the
+factors that make each attractive.
+.pp
+Pipes have the advantage of portability, in that they are supported in all
+UNIX systems. They also are relatively
+simple to use. Socketpairs share this simplicity and have the additional
+advantage of allowing bidirectional communication. The major shortcoming
+of these mechanisms is that they require communicating processes to be
+descendants of a common process. They do not allow intermachine communication.
+.pp
+The two communication domains, UNIX and Internet, allow processes with no common
+ancestor to communicate.
+Of the two, only the Internet domain allows
+communication between machines.
+This makes the Internet domain a necessary
+choice for processes running on separate machines.
+.pp
+The choice between datagrams and stream communication is best made by
+carefully considering the semantic and performance
+requirements of the application.
+Streams can be both advantageous and disadvantageous. One disadvantage
+is that a process is only allowed a limited number of open streams,
+as there are usually only 64 entries available in the open descriptor
+table. This can cause problems if a single server must talk with a large
+number of clients.
+Another is that for delivering a short message the stream setup and
+teardown time can be unnecessarily long. Weighed against this are
+the reliability built into the streams. This will often be the
+deciding factor in favor of streams.
+.b
+.sh 1 "What to do Next"
+.r
+.pp
+Many of the examples presented here can serve as models for multiprocess
+programs and for programs distributed across several machines.
+In developing a new multiprocess program, it is often easiest to
+first write the code to create the processes and communication paths.
+After this code is debugged, the code specific to the application can
+be added.
+.pp
+An introduction to the UNIX system and programming using UNIX system calls
+can be found in [Kernighan and Pike 1984].
+Further documentation of the Berkeley UNIX 4.4BSD IPC mechanisms can be
+found in [Leffler et al. 1986].
+More detailed information about particular calls and protocols
+is provided in sections
+2, 3 and 4 of the
+UNIX Programmer's Manual [CSRG 1986].
+In particular the following manual pages are relevant:
+.(b
+.TS
+l l.
+creating and naming sockets socket(2), bind(2)
+establishing connections listen(2), accept(2), connect(2)
+transferring data read(2), write(2), send(2), recv(2)
+addresses inet(4F)
+protocols tcp(4P), udp(4P).
+.TE
+.)b
+.(b
+.sp
+.b
+Acknowledgements
+.pp
+I would like to thank Sam Leffler and Mike Karels for their help in
+understanding the IPC mechanisms and all the people whose comments
+have helped in writing and improving this report.
+.pp
+This work was sponsored by the Defense Advanced Research Projects Agency
+(DoD), ARPA Order No. 4031, monitored by the Naval Electronics Systems
+Command under contract No. N00039-C-0235.
+The views and conclusions contained in this document are those of the
+author and should not be interpreted as representing official policies,
+either expressed or implied, of the Defense Research Projects Agency
+or of the US Government.
+.)b
+.(b
+.sp
+.b
+References
+.r
+.sp
+.ls 1
+B.W. Kernighan & R. Pike, 1984,
+.i "The UNIX Programming Environment."
+Englewood Cliffs, N.J.: Prentice-Hall.
+.sp
+.ls 1
+B.W. Kernighan & D.M. Ritchie, 1978,
+.i "The C Programming Language,"
+Englewood Cliffs, N.J.: Prentice-Hall.
+.sp
+.ls 1
+S.J. Leffler, R.S. Fabry, W.N. Joy, P. Lapsley, S. Miller & C. Torek, 1986,
+.i "An Advanced 4.4BSD Interprocess Communication Tutorial."
+Computer Systems Research Group,
+Department of Electrical Engineering and Computer Science,
+University of California, Berkeley.
+.sp
+.ls 1
+Computer Systems Research Group, 1986,
+.i "UNIX Programmer's Manual, 4.4 Berkeley Software Distribution."
+Computer Systems Research Group,
+Department of Electrical Engineering and Computer Science,
+University of California, Berkeley.
+.)b
diff --git a/share/doc/psd/20.ipctut/udgramread.c b/share/doc/psd/20.ipctut/udgramread.c
new file mode 100644
index 00000000000..1b6aa3b20de
--- /dev/null
+++ b/share/doc/psd/20.ipctut/udgramread.c
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)udgramread.c 8.1 (Berkeley) 6/8/93
+.\"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+/*
+ * In the included file <sys/un.h> a sockaddr_un is defined as follows
+ * struct sockaddr_un {
+ * short sun_family;
+ * char sun_path[108];
+ * };
+ */
+
+#include <stdio.h>
+
+#define NAME "socket"
+
+/*
+ * This program creates a UNIX domain datagram socket, binds a name to it,
+ * then reads from the socket.
+ */
+main()
+{
+ int sock, length;
+ struct sockaddr_un name;
+ char buf[1024];
+
+ /* Create socket from which to read. */
+ sock = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ perror("opening datagram socket");
+ exit(1);
+ }
+ /* Create name. */
+ name.sun_family = AF_UNIX;
+ strcpy(name.sun_path, NAME);
+ if (bind(sock, &name, sizeof(struct sockaddr_un))) {
+ perror("binding name to datagram socket");
+ exit(1);
+ }
+ printf("socket -->%s\en", NAME);
+ /* Read from the socket */
+ if (read(sock, buf, 1024) < 0)
+ perror("receiving datagram packet");
+ printf("-->%s\en", buf);
+ close(sock);
+ unlink(NAME);
+}
diff --git a/share/doc/psd/20.ipctut/udgramsend.c b/share/doc/psd/20.ipctut/udgramsend.c
new file mode 100644
index 00000000000..5e2b1475daa
--- /dev/null
+++ b/share/doc/psd/20.ipctut/udgramsend.c
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)udgramsend.c 8.1 (Berkeley) 6/8/93
+.\"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
+
+#define DATA "The sea is calm tonight, the tide is full . . ."
+
+/*
+ * Here I send a datagram to a receiver whose name I get from the command
+ * line arguments. The form of the command line is udgramsend pathname
+ */
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int sock;
+ struct sockaddr_un name;
+
+ /* Create socket on which to send. */
+ sock = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ perror("opening datagram socket");
+ exit(1);
+ }
+ /* Construct name of socket to send to. */
+ name.sun_family = AF_UNIX;
+ strcpy(name.sun_path, argv[1]);
+ /* Send message. */
+ if (sendto(sock, DATA, sizeof(DATA), 0,
+ &name, sizeof(struct sockaddr_un)) < 0) {
+ perror("sending datagram message");
+ }
+ close(sock);
+}
diff --git a/share/doc/psd/20.ipctut/ustreamread.c b/share/doc/psd/20.ipctut/ustreamread.c
new file mode 100644
index 00000000000..9faf5aa6aaf
--- /dev/null
+++ b/share/doc/psd/20.ipctut/ustreamread.c
@@ -0,0 +1,96 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)ustreamread.c 8.1 (Berkeley) 6/8/93
+.\"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
+
+#define NAME "socket"
+
+/*
+ * This program creates a socket in the UNIX domain and binds a name to it.
+ * After printing the socket's name it begins a loop. Each time through the
+ * loop it accepts a connection and prints out messages from it. When the
+ * connection breaks, or a termination message comes through, the program
+ * accepts a new connection.
+ */
+main()
+{
+ int sock, msgsock, rval;
+ struct sockaddr_un server;
+ char buf[1024];
+
+ /* Create socket */
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ perror("opening stream socket");
+ exit(1);
+ }
+ /* Name socket using file system name */
+ server.sun_family = AF_UNIX;
+ strcpy(server.sun_path, NAME);
+ if (bind(sock, &server, sizeof(struct sockaddr_un))) {
+ perror("binding stream socket");
+ exit(1);
+ }
+ printf("Socket has name %s\en", server.sun_path);
+ /* Start accepting connections */
+ listen(sock, 5);
+ for (;;) {
+ msgsock = accept(sock, 0, 0);
+ if (msgsock == -1)
+ perror("accept");
+ else do {
+ bzero(buf, sizeof(buf));
+ if ((rval = read(msgsock, buf, 1024)) < 0)
+ perror("reading stream message");
+ else if (rval == 0)
+ printf("Ending connection\en");
+ else
+ printf("-->%s\en", buf);
+ } while (rval > 0);
+ close(msgsock);
+ }
+ /*
+ * The following statements are not executed, because they follow an
+ * infinite loop. However, most ordinary programs will not run
+ * forever. In the UNIX domain it is necessary to tell the file
+ * system that one is through using NAME. In most programs one uses
+ * the call unlink() as below. Since the user will have to kill this
+ * program, it will be necessary to remove the name by a command from
+ * the shell.
+ */
+ close(sock);
+ unlink(NAME);
+}
diff --git a/share/doc/psd/20.ipctut/ustreamwrite.c b/share/doc/psd/20.ipctut/ustreamwrite.c
new file mode 100644
index 00000000000..e356e50e80d
--- /dev/null
+++ b/share/doc/psd/20.ipctut/ustreamwrite.c
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)ustreamwrite.c 8.1 (Berkeley) 6/8/93
+.\"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
+
+#define DATA "Half a league, half a league . . ."
+
+/*
+ * This program connects to the socket named in the command line and sends a
+ * one line message to that socket. The form of the command line is
+ * ustreamwrite pathname
+ */
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int sock;
+ struct sockaddr_un server;
+ char buf[1024];
+
+ /* Create socket */
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ perror("opening stream socket");
+ exit(1);
+ }
+ /* Connect socket using name specified by command line. */
+ server.sun_family = AF_UNIX;
+ strcpy(server.sun_path, argv[1]);
+
+ if (connect(sock, &server, sizeof(struct sockaddr_un)) < 0) {
+ close(sock);
+ perror("connecting stream socket");
+ exit(1);
+ }
+ if (write(sock, DATA, sizeof(DATA)) < 0)
+ perror("writing on stream socket");
+}
diff --git a/share/doc/psd/21.ipc/0.t b/share/doc/psd/21.ipc/0.t
new file mode 100644
index 00000000000..d28199a1bd3
--- /dev/null
+++ b/share/doc/psd/21.ipc/0.t
@@ -0,0 +1,93 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)0.t 8.1 (Berkeley) 6/8/93
+.\"
+.EH 'PSD:21-%''Advanced 4.4BSD IPC Tutorial'
+.OH 'Advanced 4.4BSD IPC Tutorial''PSD:21-%'
+.ds lq ``
+.ds rq ''
+.de DT
+.if t .ta .5i 1.25i 2.5i 3.75i
+.\" 3.5i went to 3.8i
+.if n .ta .7i 1.75i 3.8i
+..
+.bd S B 3
+.TL
+An Advanced 4.4BSD Interprocess Communication Tutorial
+.AU
+Samuel J. Leffler
+.AU
+Robert S. Fabry
+.AU
+William N. Joy
+.AU
+Phil Lapsley
+.AI
+Computer Systems Research Group
+Department of Electrical Engineering and Computer Science
+University of California, Berkeley
+Berkeley, California 94720
+.sp 2
+.AU
+Steve Miller
+.AU
+Chris Torek
+.AI
+Heterogeneous Systems Laboratory
+Department of Computer Science
+University of Maryland, College Park
+College Park, Maryland 20742
+.de IR
+\fI\\$1\fP\\$2
+..
+.de UX
+UNIX\\$1
+..
+.AB
+.PP
+.FS
+* \s-2UNIX\s0 is a trademark of UNIX System Laboratories, Inc.
+in the US and some other countries.
+.FE
+This document provides an introduction to the interprocess
+communication facilities included in the
+4.4BSD release of the
+.UX *
+system.
+.PP
+It discusses the overall model for interprocess communication
+and introduces the interprocess communication primitives
+which have been added to the system. The majority of the
+document considers the use of these primitives in developing
+applications. The reader is expected to be familiar with
+the C programming language as all examples are written in C.
+.AE
diff --git a/share/doc/psd/21.ipc/1.t b/share/doc/psd/21.ipc/1.t
new file mode 100644
index 00000000000..f4e48ffc23d
--- /dev/null
+++ b/share/doc/psd/21.ipc/1.t
@@ -0,0 +1,106 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)1.t 8.1 (Berkeley) 8/14/93
+.\"
+.\".ds LH "4.4BSD IPC Primer
+.\".ds RH Introduction
+.\".ds RF "Leffler/Fabry/Joy
+.\".ds LF "\*(DY
+.\".ds CF "
+.nr H1 1
+.LP
+.bp
+.LG
+.B
+.ce
+1. INTRODUCTION
+.sp 2
+.R
+.NL
+One of the most important additions to UNIX in 4.2BSD was interprocess
+communication.
+These facilities were the result of
+more than two years of discussion and research. The facilities
+provided in 4.2BSD incorporated many of the ideas from current
+research, while trying to maintain the UNIX philosophy of
+simplicity and conciseness.
+The 4.3BSD release of Berkeley UNIX
+improved upon some of the IPC facilities
+while providing an upward-compatible interface.
+4.4BSD adds support for ISO protocols and IP multicasting.
+The BSD interprocess communication
+facilities have become a defacto standard for UNIX.
+.PP
+UNIX has previously been very weak in the area of interprocess
+communication. Prior to the 4BSD facilities, the only
+standard mechanism which allowed two processes to communicate were
+pipes (the mpx files which were part of Version 7 were
+experimental). Unfortunately, pipes are very restrictive
+in that
+the two communicating processes must be related through a
+common ancestor.
+Further, the semantics of pipes makes them almost impossible
+to maintain in a distributed environment.
+.PP
+Earlier attempts at extending the IPC facilities of UNIX have
+met with mixed reaction. The majority of the problems have
+been related to the fact that these facilities have been tied to
+the UNIX file system, either through naming or implementation.
+Consequently, the IPC facilities provided in 4.2BSD were
+designed as a totally independent subsystem. The BSD IPC
+allows processes to rendezvous in many ways.
+Processes may rendezvous through a UNIX file system-like
+name space (a space where all names are path names)
+as well as through a
+network name space. In fact, new name spaces may
+be added at a future time with only minor changes visible
+to users. Further, the communication facilities
+have been extended to include more than the simple byte stream
+provided by a pipe. These extensions have resulted
+in a completely new part of the system which users will need
+time to familiarize themselves with. It is likely that as
+more use is made of these facilities they will be refined;
+only time will tell.
+.PP
+This document provides a high-level description
+of the IPC facilities in 4.4BSD and their use.
+It is designed to complement the manual pages for the IPC primitives
+by examples of their use.
+The remainder of this document is organized in four sections.
+Section 2 introduces the IPC-related system calls and the basic model
+of communication. Section 3 describes some of the supporting
+library routines users may find useful in constructing distributed
+applications. Section 4 is concerned with the client/server model
+used in developing applications and includes examples of the
+two major types of servers. Section 5 delves into advanced topics
+which sophisticated users are likely to encounter when using
+the IPC facilities.
diff --git a/share/doc/psd/21.ipc/2.t b/share/doc/psd/21.ipc/2.t
new file mode 100644
index 00000000000..6f084543675
--- /dev/null
+++ b/share/doc/psd/21.ipc/2.t
@@ -0,0 +1,714 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)2.t 8.1 (Berkeley) 8/14/93
+.\"
+.\".ds RH "Basics
+.bp
+.nr H1 2
+.nr H2 0
+.\" The next line is a major hack to get around internal changes in the groff
+.\" implementation of .NH.
+.nr nh*hl 1
+.bp
+.LG
+.B
+.ce
+2. BASICS
+.sp 2
+.R
+.NL
+.PP
+The basic building block for communication is the \fIsocket\fP.
+A socket is an endpoint of communication to which a name may
+be \fIbound\fP. Each socket in use has a \fItype\fP
+and one or more associated processes. Sockets exist within
+\fIcommunication domains\fP.
+A communication domain is an
+abstraction introduced to bundle common properties of
+processes communicating through sockets.
+One such property is the scheme used to name sockets. For
+example, in the UNIX communication domain sockets are
+named with UNIX path names; e.g. a
+socket may be named \*(lq/dev/foo\*(rq. Sockets normally
+exchange data only with
+sockets in the same domain (it may be possible to cross domain
+boundaries, but only if some translation process is
+performed). The
+4.4BSD IPC facilities support four separate communication domains:
+the UNIX domain, for on-system communication;
+the Internet domain, which is used by
+processes which communicate
+using the Internet standard communication protocols;
+the NS domain, which is used by processes which
+communicate using the Xerox standard communication
+protocols*;
+.FS
+* See \fIInternet Transport Protocols\fP, Xerox System Integration
+Standard (XSIS)028112 for more information. This document is
+almost a necessity for one trying to write NS applications.
+.FE
+and the ISO OSI protocols, which are not documented in this tutorial.
+The underlying communication
+facilities provided by these domains have a significant influence
+on the internal system implementation as well as the interface to
+socket facilities available to a user. An example of the
+latter is that a socket \*(lqoperating\*(rq in the UNIX domain
+sees a subset of the error conditions which are possible
+when operating in the Internet (or NS) domain.
+.NH 2
+Socket types
+.PP
+Sockets are
+typed according to the communication properties visible to a
+user.
+Processes are presumed to communicate only between sockets of
+the same type, although there is
+nothing that prevents communication between sockets of different
+types should the underlying communication
+protocols support this.
+.PP
+Four types of sockets currently are available to a user.
+A \fIstream\fP socket provides for the bidirectional, reliable,
+sequenced, and unduplicated flow of data without record boundaries.
+Aside from the bidirectionality of data flow, a pair of connected
+stream sockets provides an interface nearly identical to that of pipes\(dg.
+.FS
+\(dg In the UNIX domain, in fact, the semantics are identical and,
+as one might expect, pipes have been implemented internally
+as simply a pair of connected stream sockets.
+.FE
+.PP
+A \fIdatagram\fP socket supports bidirectional flow of data which
+is not promised to be sequenced, reliable, or unduplicated.
+That is, a process
+receiving messages on a datagram socket may find messages duplicated,
+and, possibly,
+in an order different from the order in which it was sent.
+An important characteristic of a datagram
+socket is that record boundaries in data are preserved. Datagram
+sockets closely model the facilities found in many contemporary
+packet switched networks such as the Ethernet.
+.PP
+A \fIraw\fP socket provides users access to
+the underlying communication
+protocols which support socket abstractions.
+These sockets are normally datagram oriented, though their
+exact characteristics are dependent on the interface provided by
+the protocol. Raw sockets are not intended for the general user; they
+have been provided mainly for those interested in developing new
+communication protocols, or for gaining access to some of the more
+esoteric facilities of an existing protocol. The use of raw sockets
+is considered in section 5.
+.PP
+A \fIsequenced packet\fP socket is similar to a stream socket,
+with the exception that record boundaries are preserved. This
+interface is provided only as part of the NS socket abstraction,
+and is very important in most serious NS applications.
+Sequenced-packet sockets allow the user to manipulate the
+SPP or IDP headers on a packet or a group of packets either
+by writing a prototype header along with whatever data is
+to be sent, or by specifying a default header to be used with
+all outgoing data, and allows the user to receive the headers
+on incoming packets. The use of these options is considered in
+section 5.
+.PP
+Another potential socket type which has interesting properties is
+the \fIreliably delivered
+message\fP socket.
+The reliably delivered message socket has
+similar properties to a datagram socket, but with
+reliable delivery. There is currently no support for this
+type of socket, but a reliably delivered message protocol
+similar to Xerox's Packet Exchange Protocol (PEX) may be
+simulated at the user level. More information on this topic
+can be found in section 5.
+.NH 2
+Socket creation
+.PP
+To create a socket the \fIsocket\fP system call is used:
+.DS
+s = socket(domain, type, protocol);
+.DE
+This call requests that the system create a socket in the specified
+\fIdomain\fP and of the specified \fItype\fP. A particular protocol may
+also be requested. If the protocol is left unspecified (a value
+of 0), the system will select an appropriate protocol from those
+protocols which comprise the communication domain and which
+may be used to support the requested socket type. The user is
+returned a descriptor (a small integer number) which may be used
+in later system calls which operate on sockets. The domain is specified as
+one of the manifest constants defined in the file <\fIsys/socket.h\fP>.
+For the UNIX domain the constant is AF_UNIX*; for the Internet
+.FS
+* The manifest constants are named AF_whatever as they indicate
+the ``address format'' to use in interpreting names.
+.FE
+domain AF_INET; and for the NS domain, AF_NS.
+The socket types are also defined in this file
+and one of SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, or SOCK_SEQPACKET
+must be specified.
+To create a stream socket in the Internet domain the following
+call might be used:
+.DS
+s = socket(AF_INET, SOCK_STREAM, 0);
+.DE
+This call would result in a stream socket being created with the TCP
+protocol providing the underlying communication support. To
+create a datagram socket for on-machine use the call might
+be:
+.DS
+s = socket(AF_UNIX, SOCK_DGRAM, 0);
+.DE
+.PP
+The default protocol (used when the \fIprotocol\fP argument to the
+\fIsocket\fP call is 0) should be correct for most every
+situation. However, it is possible to specify a protocol
+other than the default; this will be covered in
+section 5.
+.PP
+There are several reasons a socket call may fail. Aside from
+the rare occurrence of lack of memory (ENOBUFS), a socket
+request may fail due to a request for an unknown protocol
+(EPROTONOSUPPORT), or a request for a type of socket for
+which there is no supporting protocol (EPROTOTYPE).
+.NH 2
+Binding local names
+.PP
+A socket is created without a name. Until a name is bound
+to a socket, processes have no way to reference it and, consequently,
+no messages may be received on it.
+Communicating processes are bound
+by an \fIassociation\fP. In the Internet and NS domains,
+an association
+is composed of local and foreign
+addresses, and local and foreign ports,
+while in the UNIX domain, an association is composed of
+local and foreign path names (the phrase ``foreign pathname''
+means a pathname created by a foreign process, not a pathname
+on a foreign system).
+In most domains, associations must be unique.
+In the Internet domain there
+may never be duplicate <protocol, local address, local port, foreign
+address, foreign port> tuples. UNIX domain sockets need not always
+be bound to a name, but when bound
+there may never be duplicate <protocol, local pathname, foreign
+pathname> tuples.
+The pathnames may not refer to files
+already existing on the system
+in 4.3; the situation may change in future releases.
+.PP
+The \fIbind\fP system call allows a process to specify half of
+an association, <local address, local port>
+(or <local pathname>), while the \fIconnect\fP
+and \fIaccept\fP primitives are used to complete a socket's association.
+.PP
+In the Internet domain,
+binding names to sockets can be fairly complex.
+Fortunately, it is usually not necessary to specifically bind an
+address and port number to a socket, because the
+\fIconnect\fP and \fIsend\fP calls will automatically
+bind an appropriate address if they are used with an
+unbound socket. The process of binding names to NS
+sockets is similar in most ways to that of
+binding names to Internet sockets.
+.PP
+The \fIbind\fP system call is used as follows:
+.DS
+bind(s, name, namelen);
+.DE
+The bound name is a variable length byte string which is interpreted
+by the supporting protocol(s). Its interpretation may vary from
+communication domain to communication domain (this is one of
+the properties which comprise the \*(lqdomain\*(rq).
+As mentioned, in the
+Internet domain names contain an Internet address and port
+number. NS domain names contain an NS address and
+port number. In the UNIX domain, names contain a path name and
+a family, which is always AF_UNIX. If one wanted to bind
+the name \*(lq/tmp/foo\*(rq to a UNIX domain socket, the
+following code would be used*:
+.FS
+* Note that, although the tendency here is to call the \*(lqaddr\*(rq
+structure \*(lqsun\*(rq, doing so would cause problems if the code
+were ever ported to a Sun workstation.
+.FE
+.DS
+#include <sys/un.h>
+ ...
+struct sockaddr_un addr;
+ ...
+strcpy(addr.sun_path, "/tmp/foo");
+addr.sun_family = AF_UNIX;
+bind(s, (struct sockaddr *) &addr, strlen(addr.sun_path) +
+ sizeof (addr.sun_len) + sizeof (addr.sun_family));
+.DE
+Note that in determining the size of a UNIX domain address null
+bytes are not counted, which is why \fIstrlen\fP is used. In
+the current implementation of UNIX domain IPC,
+the file name
+referred to in \fIaddr.sun_path\fP is created as a socket
+in the system file space.
+The caller must, therefore, have
+write permission in the directory where
+\fIaddr.sun_path\fP is to reside, and this file should be deleted by the
+caller when it is no longer needed. Future versions of 4BSD
+may not create this file.
+.PP
+In binding an Internet address things become more
+complicated. The actual call is similar,
+.DS
+#include <sys/types.h>
+#include <netinet/in.h>
+ ...
+struct sockaddr_in sin;
+ ...
+bind(s, (struct sockaddr *) &sin, sizeof (sin));
+.DE
+but the selection of what to place in the address \fIsin\fP
+requires some discussion. We will come back to the problem
+of formulating Internet addresses in section 3 when
+the library routines used in name resolution are discussed.
+.PP
+Binding an NS address to a socket is even more
+difficult,
+especially since the Internet library routines do not
+work with NS hostnames. The actual call is again similar:
+.DS
+#include <sys/types.h>
+#include <netns/ns.h>
+ ...
+struct sockaddr_ns sns;
+ ...
+bind(s, (struct sockaddr *) &sns, sizeof (sns));
+.DE
+Again, discussion of what to place in a \*(lqstruct sockaddr_ns\*(rq
+will be deferred to section 3.
+.NH 2
+Connection establishment
+.PP
+Connection establishment is usually asymmetric,
+with one process a \*(lqclient\*(rq and the other a \*(lqserver\*(rq.
+The server, when willing to offer its advertised services,
+binds a socket to a well-known address associated with the service
+and then passively \*(lqlistens\*(rq on its socket.
+It is then possible for an unrelated process to rendezvous
+with the server.
+The client requests services from the server by initiating a
+\*(lqconnection\*(rq to the server's socket.
+On the client side the \fIconnect\fP call is
+used to initiate a connection. Using the UNIX domain, this
+might appear as,
+.DS
+struct sockaddr_un server;
+ ...
+connect(s, (struct sockaddr *)&server, strlen(server.sun_path) +
+ sizeof (server.sun_family));
+.DE
+while in the Internet domain,
+.DS
+struct sockaddr_in server;
+ ...
+connect(s, (struct sockaddr *)&server, sizeof (server));
+.DE
+and in the NS domain,
+.DS
+struct sockaddr_ns server;
+ ...
+connect(s, (struct sockaddr *)&server, sizeof (server));
+.DE
+where \fIserver\fP in the example above would contain either the UNIX
+pathname, Internet address and port number, or NS address and
+port number of the server to which the
+client process wishes to speak.
+If the client process's socket is unbound at the time of
+the connect call,
+the system will automatically select and bind a name to
+the socket if necessary; c.f. section 5.4.
+This is the usual way that local addresses are bound
+to a socket.
+.PP
+An error is returned if the connection was unsuccessful
+(any name automatically bound by the system, however, remains).
+Otherwise, the socket is associated with the server and
+data transfer may begin. Some of the more common errors returned
+when a connection attempt fails are:
+.IP ETIMEDOUT
+.br
+After failing to establish a connection for a period of time,
+the system decided there was no point in retrying the
+connection attempt any more. This usually occurs because
+the destination host is down, or because problems in
+the network resulted in transmissions being lost.
+.IP ECONNREFUSED
+.br
+The host refused service for some reason.
+This is usually
+due to a server process
+not being present at the requested name.
+.IP "ENETDOWN or EHOSTDOWN"
+.br
+These operational errors are
+returned based on status information delivered to
+the client host by the underlying communication services.
+.IP "ENETUNREACH or EHOSTUNREACH"
+.br
+These operational errors can occur either because the network
+or host is unknown (no route to the network or host is present),
+or because of status information returned by intermediate
+gateways or switching nodes. Many times the status returned
+is not sufficient to distinguish a network being down from a
+host being down, in which case the system
+indicates the entire network is unreachable.
+.PP
+For the server to receive a client's connection it must perform
+two steps after binding its socket.
+The first is to indicate a willingness to listen for
+incoming connection requests:
+.DS
+listen(s, 5);
+.DE
+The second parameter to the \fIlisten\fP call specifies the maximum
+number of outstanding connections which may be queued awaiting
+acceptance by the server process; this number
+may be limited by the system. Should a connection be
+requested while the queue is full, the connection will not be
+refused, but rather the individual messages which comprise the
+request will be ignored. This gives a harried server time to
+make room in its pending connection queue while the client
+retries the connection request. Had the connection been returned
+with the ECONNREFUSED error, the client would be unable to tell
+if the server was up or not. As it is now it is still possible
+to get the ETIMEDOUT error back, though this is unlikely. The
+backlog figure supplied with the listen call is currently limited
+by the system to a maximum of 5 pending connections on any
+one queue. This avoids the problem of processes hogging system
+resources by setting an infinite backlog, then ignoring
+all connection requests.
+.PP
+With a socket marked as listening, a server may \fIaccept\fP
+a connection:
+.DS
+struct sockaddr_in from;
+ ...
+fromlen = sizeof (from);
+newsock = accept(s, (struct sockaddr *)&from, &fromlen);
+.DE
+(For the UNIX domain, \fIfrom\fP would be declared as a
+\fIstruct sockaddr_un\fP, and for the NS domain, \fIfrom\fP
+would be declared as a \fIstruct sockaddr_ns\fP,
+but nothing different would need
+to be done as far as \fIfromlen\fP is concerned. In the examples
+which follow, only Internet routines will be discussed.) A new
+descriptor is returned on receipt of a connection (along with
+a new socket). If the server wishes to find out who its client is,
+it may supply a buffer for the client socket's name. The value-result
+parameter \fIfromlen\fP is initialized by the server to indicate how
+much space is associated with \fIfrom\fP, then modified on return
+to reflect the true size of the name. If the client's name is not
+of interest, the second parameter may be a null pointer.
+.PP
+\fIAccept\fP normally blocks. That is, \fIaccept\fP
+will not return until a connection is available or the system call
+is interrupted by a signal to the process. Further, there is no
+way for a process to indicate it will accept connections from only
+a specific individual, or individuals. It is up to the user process
+to consider who the connection is from and close down the connection
+if it does not wish to speak to the process. If the server process
+wants to accept connections on more than one socket, or wants to avoid blocking
+on the accept call, there are alternatives; they will be considered
+in section 5.
+.NH 2
+Data transfer
+.PP
+With a connection established, data may begin to flow. To send
+and receive data there are a number of possible calls.
+With the peer entity at each end of a connection
+anchored, a user can send or receive a message without specifying
+the peer. As one might expect, in this case, then
+the normal \fIread\fP and \fIwrite\fP system calls are usable,
+.DS
+write(s, buf, sizeof (buf));
+read(s, buf, sizeof (buf));
+.DE
+In addition to \fIread\fP and \fIwrite\fP,
+the new calls \fIsend\fP and \fIrecv\fP
+may be used:
+.DS
+send(s, buf, sizeof (buf), flags);
+recv(s, buf, sizeof (buf), flags);
+.DE
+While \fIsend\fP and \fIrecv\fP are virtually identical to
+\fIread\fP and \fIwrite\fP,
+the extra \fIflags\fP argument is important. The flags,
+defined in \fI<sys/socket.h>\fP, may be
+specified as a non-zero value if one or more
+of the following is required:
+.DS
+.TS
+l l.
+MSG_OOB send/receive out of band data
+MSG_PEEK look at data without reading
+MSG_DONTROUTE send data without routing packets
+.TE
+.DE
+Out of band data is a notion specific to stream sockets, and one
+which we will not immediately consider. The option to have data
+sent without routing applied to the outgoing packets is currently
+used only by the routing table management process, and is
+unlikely to be of interest to the casual user. The ability
+to preview data is, however, of interest. When MSG_PEEK
+is specified with a \fIrecv\fP call, any data present is returned
+to the user, but treated as still \*(lqunread\*(rq. That
+is, the next \fIread\fP or \fIrecv\fP call applied to the socket will
+return the data previously previewed.
+.NH 2
+Discarding sockets
+.PP
+Once a socket is no longer of interest, it may be discarded
+by applying a \fIclose\fP to the descriptor,
+.DS
+close(s);
+.DE
+If data is associated with a socket which promises reliable delivery
+(e.g. a stream socket) when a close takes place, the system will
+continue to attempt to transfer the data.
+However, after a fairly long period of
+time, if the data is still undelivered, it will be discarded.
+Should a user have no use for any pending data, it may
+perform a \fIshutdown\fP on the socket prior to closing it.
+This call is of the form:
+.DS
+shutdown(s, how);
+.DE
+where \fIhow\fP is 0 if the user is no longer interested in reading
+data, 1 if no more data will be sent, or 2 if no data is to
+be sent or received.
+.NH 2
+Connectionless sockets
+.PP
+To this point we have been concerned mostly with sockets which
+follow a connection oriented model. However, there is also
+support for connectionless interactions typical of the datagram
+facilities found in contemporary packet switched networks.
+A datagram socket provides a symmetric interface to data
+exchange. While processes are still likely to be client
+and server, there is no requirement for connection establishment.
+Instead, each message includes the destination address.
+.PP
+Datagram sockets are created as before.
+If a particular local address is needed,
+the \fIbind\fP operation must precede the first data transmission.
+Otherwise, the system will set the local address and/or port
+when data is first sent.
+To send data, the \fIsendto\fP primitive is used,
+.DS
+sendto(s, buf, buflen, flags, (struct sockaddr *)&to, tolen);
+.DE
+The \fIs\fP, \fIbuf\fP, \fIbuflen\fP, and \fIflags\fP
+parameters are used as before.
+The \fIto\fP and \fItolen\fP
+values are used to indicate the address of the intended recipient of the
+message. When
+using an unreliable datagram interface, it is
+unlikely that any errors will be reported to the sender. When
+information is present locally to recognize a message that can
+not be delivered (for instance when a network is unreachable),
+the call will return \-1 and the global value \fIerrno\fP will
+contain an error number.
+.PP
+To receive messages on an unconnected datagram socket, the
+\fIrecvfrom\fP primitive is provided:
+.DS
+recvfrom(s, buf, buflen, flags, (struct sockaddr *)&from, &fromlen);
+.DE
+Once again, the \fIfromlen\fP parameter is handled in
+a value-result fashion, initially containing the size of
+the \fIfrom\fP buffer, and modified on return to indicate
+the actual size of the address from which the datagram was received.
+.PP
+In addition to the two calls mentioned above, datagram
+sockets may also use the \fIconnect\fP call to associate
+a socket with a specific destination address. In this case, any
+data sent on the socket will automatically be addressed
+to the connected peer, and only data received from that
+peer will be delivered to the user. Only one connected
+address is permitted for each socket at one time;
+a second connect will change the destination address,
+and a connect to a null address (family AF_UNSPEC)
+will disconnect.
+Connect requests on datagram sockets return immediately,
+as this simply results in the system recording
+the peer's address (as compared to a stream socket, where a
+connect request initiates establishment of an end to end
+connection). \fIAccept\fP and \fIlisten\fP are not
+used with datagram sockets.
+.PP
+While a datagram socket socket is connected,
+errors from recent \fIsend\fP calls may be returned
+asynchronously.
+These errors may be reported on subsequent operations
+on the socket,
+or a special socket option used with \fIgetsockopt\fP, SO_ERROR,
+may be used to interrogate the error status.
+A \fIselect\fP for reading or writing will return true
+when an error indication has been received.
+The next operation will return the error, and the error status is cleared.
+Other of the less
+important details of datagram sockets are described
+in section 5.
+.NH 2
+Input/Output multiplexing
+.PP
+One last facility often used in developing applications
+is the ability to multiplex i/o requests among multiple
+sockets and/or files. This is done using the \fIselect\fP
+call:
+.DS
+#include <sys/time.h>
+#include <sys/types.h>
+ ...
+
+fd_set readmask, writemask, exceptmask;
+struct timeval timeout;
+ ...
+select(nfds, &readmask, &writemask, &exceptmask, &timeout);
+.DE
+\fISelect\fP takes as arguments pointers to three sets, one for
+the set of file descriptors for which the caller wishes to
+be able to read data on, one for those descriptors to which
+data is to be written, and one for which exceptional conditions
+are pending; out-of-band data is the only
+exceptional condition currently implemented by the socket
+If the user is not interested
+in certain conditions (i.e., read, write, or exceptions),
+the corresponding argument to the \fIselect\fP should
+be a null pointer.
+.PP
+Each set is actually a structure containing an array of
+long integer bit masks; the size of the array is set
+by the definition FD_SETSIZE.
+The array is be
+long enough to hold one bit for each of FD_SETSIZE file descriptors.
+.PP
+The macros FD_SET(\fIfd, &mask\fP) and
+FD_CLR(\fIfd, &mask\fP)
+have been provided for adding and removing file descriptor
+\fIfd\fP in the set \fImask\fP. The
+set should be zeroed before use, and
+the macro FD_ZERO(\fI&mask\fP) has been provided
+to clear the set \fImask\fP.
+The parameter \fInfds\fP in the \fIselect\fP call specifies the range
+of file descriptors (i.e. one plus the value of the largest
+descriptor) to be examined in a set.
+.PP
+A timeout value may be specified if the selection
+is not to last more than a predetermined period of time. If
+the fields in \fItimeout\fP are set to 0, the selection takes
+the form of a
+\fIpoll\fP, returning immediately. If the last parameter is
+a null pointer, the selection will block indefinitely*.
+.FS
+* To be more specific, a return takes place only when a
+descriptor is selectable, or when a signal is received by
+the caller, interrupting the system call.
+.FE
+\fISelect\fP normally returns the number of file descriptors selected;
+if the \fIselect\fP call returns due to the timeout expiring, then
+the value 0 is returned.
+If the \fIselect\fP terminates because of an error or interruption,
+a \-1 is returned with the error number in \fIerrno\fP,
+and with the file descriptor masks unchanged.
+.PP
+Assuming a successful return, the three sets will
+indicate which
+file descriptors are ready to be read from, written to, or
+have exceptional conditions pending.
+The status of a file descriptor in a select mask may be
+tested with the \fIFD_ISSET(fd, &mask)\fP macro, which
+returns a non-zero value if \fIfd\fP is a member of the set
+\fImask\fP, and 0 if it is not.
+.PP
+To determine if there are connections waiting
+on a socket to be used with an \fIaccept\fP call,
+\fIselect\fP can be used, followed by
+a \fIFD_ISSET(fd, &mask)\fP macro to check for read
+readiness on the appropriate socket. If \fIFD_ISSET\fP
+returns a non-zero value, indicating permission to read, then a
+connection is pending on the socket.
+.PP
+As an example, to read data from two sockets, \fIs1\fP and
+\fIs2\fP as it is available from each and with a one-second
+timeout, the following code
+might be used:
+.DS
+#include <sys/time.h>
+#include <sys/types.h>
+ ...
+fd_set read_template;
+struct timeval wait;
+ ...
+for (;;) {
+ wait.tv_sec = 1; /* one second */
+ wait.tv_usec = 0;
+
+ FD_ZERO(&read_template);
+
+ FD_SET(s1, &read_template);
+ FD_SET(s2, &read_template);
+
+ nb = select(FD_SETSIZE, &read_template, (fd_set *) 0, (fd_set *) 0, &wait);
+ if (nb <= 0) {
+ \fIAn error occurred during the \fPselect\fI, or
+ the \fPselect\fI timed out.\fP
+ }
+
+ if (FD_ISSET(s1, &read_template)) {
+ \fISocket #1 is ready to be read from.\fP
+ }
+
+ if (FD_ISSET(s2, &read_template)) {
+ \fISocket #2 is ready to be read from.\fP
+ }
+}
+.DE
+.PP
+In 4.2, the arguments to \fIselect\fP were pointers to integers
+instead of pointers to \fIfd_set\fPs. This type of call
+will still work as long as the number of file descriptors
+being examined is less than the number of bits in an
+integer; however, the methods illustrated above should
+be used in all current programs.
+.PP
+\fISelect\fP provides a synchronous multiplexing scheme.
+Asynchronous notification of output completion, input availability,
+and exceptional conditions is possible through use of the
+SIGIO and SIGURG signals described in section 5.
diff --git a/share/doc/psd/21.ipc/3.t b/share/doc/psd/21.ipc/3.t
new file mode 100644
index 00000000000..0d429cfa6a0
--- /dev/null
+++ b/share/doc/psd/21.ipc/3.t
@@ -0,0 +1,409 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)3.t 8.1 (Berkeley) 6/8/93
+.\"
+.\".ds RH "Network Library Routines
+.bp
+.nr H1 3
+.nr H2 0
+.bp
+.LG
+.B
+.ce
+3. NETWORK LIBRARY ROUTINES
+.sp 2
+.R
+.NL
+.PP
+The discussion in section 2 indicated the possible need to
+locate and construct network addresses when using the
+interprocess communication facilities in a distributed
+environment. To aid in this task a number of routines
+have been added to the standard C run-time library.
+In this section we will consider the new routines provided
+to manipulate network addresses. While the 4.4BSD networking
+facilities support the Internet protocols
+and the Xerox NS protocols,
+most of the routines presented
+in this section do not apply to the NS domain. Unless otherwise
+stated, it should be assumed that the routines presented in this
+section do not apply to the NS domain.
+.PP
+Locating a service on a remote host requires many levels of
+mapping before client and server may
+communicate. A service is assigned a name which is intended
+for human consumption; e.g. \*(lqthe \fIlogin server\fP on host
+monet\*(rq.
+This name, and the name of the peer host, must then be translated
+into network \fIaddresses\fP which are not necessarily suitable
+for human consumption. Finally, the address must then used in locating
+a physical \fIlocation\fP and \fIroute\fP to the service. The
+specifics of these three mappings are likely to vary between
+network architectures. For instance, it is desirable for a network
+to not require hosts to
+be named in such a way that their physical location is known by
+the client host. Instead, underlying services in the network
+may discover the actual location of the host at the time a client
+host wishes to communicate. This ability to have hosts named in
+a location independent manner may induce overhead in connection
+establishment, as a discovery process must take place,
+but allows a host to be physically mobile without requiring it to
+notify its clientele of its current location.
+.PP
+Standard routines are provided for: mapping host names
+to network addresses, network names to network numbers,
+protocol names to protocol numbers, and service names
+to port numbers and the appropriate protocol to
+use in communicating with the server process. The
+file <\fInetdb.h\fP> must be included when using any of these
+routines.
+.NH 2
+Host names
+.PP
+An Internet host name to address mapping is represented by
+the \fIhostent\fP structure:
+.DS
+.if t .ta 0.6i 1.1i 2.6i
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type (e.g., AF_INET) */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses, null terminated */
+};
+
+#define h_addr h_addr_list[0] /* first address, network byte order */
+.DE
+The routine \fIgethostbyname\fP(3N) takes an Internet host name
+and returns a \fIhostent\fP structure,
+while the routine \fIgethostbyaddr\fP(3N)
+maps Internet host addresses into a \fIhostent\fP structure.
+.PP
+The official name of the host and its public aliases are
+returned by these routines,
+along with the address type (family) and a null terminated list of
+variable length address. This list of addresses is
+required because it is possible
+for a host to have many addresses, all having the same name.
+The \fIh_addr\fP definition is provided for backward compatibility,
+and is defined to be the first address in the list of addresses
+in the \fIhostent\fP structure.
+.PP
+The database for these calls is provided either by the
+file \fI/etc/hosts\fP (\fIhosts\fP\|(5)),
+or by use of a nameserver, \fInamed\fP\|(8).
+Because of the differences in these databases and their access protocols,
+the information returned may differ.
+When using the host table version of \fIgethostbyname\fP,
+only one address will be returned, but all listed aliases will be included.
+The nameserver version may return alternate addresses,
+but will not provide any aliases other than one given as argument.
+.PP
+Unlike Internet names, NS names are always mapped into host
+addresses by the use of a standard NS \fIClearinghouse service\fP,
+a distributed name and authentication server. The algorithms
+for mapping NS names to addresses via a Clearinghouse are
+rather complicated, and the routines are not part of the
+standard libraries. The user-contributed Courier (Xerox
+remote procedure call protocol) compiler contains routines
+to accomplish this mapping; see the documentation and
+examples provided therein for more information. It is
+expected that almost all software that has to communicate
+using NS will need to use the facilities of
+the Courier compiler.
+.PP
+An NS host address is represented by the following:
+.DS
+union ns_host {
+ u_char c_host[6];
+ u_short s_host[3];
+};
+
+union ns_net {
+ u_char c_net[4];
+ u_short s_net[2];
+};
+
+struct ns_addr {
+ union ns_net x_net;
+ union ns_host x_host;
+ u_short x_port;
+};
+.DE
+The following code fragment inserts a known NS address into
+a \fIns_addr\fP:
+.DS
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netns/ns.h>
+ ...
+u_long netnum;
+struct sockaddr_ns dst;
+ ...
+bzero((char *)&dst, sizeof(dst));
+
+/*
+ * There is no convenient way to assign a long
+ * integer to a ``union ns_net'' at present; in
+ * the future, something will hopefully be provided,
+ * but this is the portable way to go for now.
+ * The network number below is the one for the NS net
+ * that the desired host (gyre) is on.
+ */
+netnum = htonl(2266);
+dst.sns_addr.x_net = *(union ns_net *) &netnum;
+dst.sns_family = AF_NS;
+
+/*
+ * host 2.7.1.0.2a.18 == "gyre:Computer Science:UofMaryland"
+ */
+dst.sns_addr.x_host.c_host[0] = 0x02;
+dst.sns_addr.x_host.c_host[1] = 0x07;
+dst.sns_addr.x_host.c_host[2] = 0x01;
+dst.sns_addr.x_host.c_host[3] = 0x00;
+dst.sns_addr.x_host.c_host[4] = 0x2a;
+dst.sns_addr.x_host.c_host[5] = 0x18;
+dst.sns_addr.x_port = htons(75);
+.DE
+.NH 2
+Network names
+.PP
+As for host names, routines for mapping network names to numbers,
+and back, are provided. These routines return a \fInetent\fP
+structure:
+.DS
+.DT
+/*
+ * Assumption here is that a network number
+ * fits in 32 bits -- probably a poor one.
+ */
+struct netent {
+ char *n_name; /* official name of net */
+ char **n_aliases; /* alias list */
+ int n_addrtype; /* net address type */
+ int n_net; /* network number, host byte order */
+};
+.DE
+The routines \fIgetnetbyname\fP(3N), \fIgetnetbynumber\fP(3N),
+and \fIgetnetent\fP(3N) are the network counterparts to the
+host routines described above. The routines extract their
+information from \fI/etc/networks\fP.
+.PP
+NS network numbers are determined either by asking your local
+Xerox Network Administrator (and hardcoding the information
+into your code), or by querying the Clearinghouse for addresses.
+The internetwork router is the only process
+that needs to manipulate network numbers on a regular basis; if
+a process wishes to communicate with a machine, it should ask the
+Clearinghouse for that machine's address (which will include
+the net number).
+.NH 2
+Protocol names
+.PP
+For protocols, which are defined in \fI/etc/protocols\fP,
+the \fIprotoent\fP structure defines the
+protocol-name mapping
+used with the routines \fIgetprotobyname\fP(3N),
+\fIgetprotobynumber\fP(3N),
+and \fIgetprotoent\fP(3N):
+.DS
+.DT
+struct protoent {
+ char *p_name; /* official protocol name */
+ char **p_aliases; /* alias list */
+ int p_proto; /* protocol number */
+};
+.DE
+.PP
+In the NS domain, protocols are indicated by the "client type"
+field of a IDP header. No protocol database exists; see section
+5 for more information.
+.NH 2
+Service names
+.PP
+Information regarding services is a bit more complicated. A service
+is expected to reside at a specific \*(lqport\*(rq and employ
+a particular communication protocol. This view is consistent with
+the Internet domain, but inconsistent with other network architectures.
+Further, a service may reside on multiple ports.
+If this occurs, the higher level library routines
+will have to be bypassed or extended.
+Services available are contained in the file \fI/etc/services\fP.
+A service mapping is described by the \fIservent\fP structure,
+.DS
+.DT
+struct servent {
+ char *s_name; /* official service name */
+ char **s_aliases; /* alias list */
+ int s_port; /* port number, network byte order */
+ char *s_proto; /* protocol to use */
+};
+.DE
+The routine \fIgetservbyname\fP(3N) maps service
+names to a servent structure by specifying a service name and,
+optionally, a qualifying protocol. Thus the call
+.DS
+sp = getservbyname("telnet", (char *) 0);
+.DE
+returns the service specification for a telnet server using
+any protocol, while the call
+.DS
+sp = getservbyname("telnet", "tcp");
+.DE
+returns only that telnet server which uses the TCP protocol.
+The routines \fIgetservbyport\fP(3N) and \fIgetservent\fP(3N) are
+also provided. The \fIgetservbyport\fP routine has an interface similar
+to that provided by \fIgetservbyname\fP; an optional protocol name may
+be specified to qualify lookups.
+.PP
+In the NS domain, services are handled by a central dispatcher
+provided as part of the Courier remote procedure call facilities.
+Again, the reader is referred to the Courier compiler documentation
+and to the Xerox standard*
+.FS
+* \fICourier: The Remote Procedure Call Protocol\fP, XSIS 038112.
+.FE
+for further details.
+.NH 2
+Miscellaneous
+.PP
+With the support routines described above, an Internet application program
+should rarely have to deal directly
+with addresses. This allows
+services to be developed as much as possible in a network independent
+fashion. It is clear, however, that purging all network dependencies
+is very difficult. So long as the user is required to supply network
+addresses when naming services and sockets there will always some
+network dependency in a program. For example, the normal
+code included in client programs, such as the remote login program,
+is of the form shown in Figure 1.
+(This example will be considered in more detail in section 4.)
+.PP
+If we wanted to make the remote login program independent of the
+Internet protocols and addressing scheme we would be forced to add
+a layer of routines which masked the network dependent aspects from
+the mainstream login code. For the current facilities available in
+the system this does not appear to be worthwhile.
+.PP
+Aside from the address-related data base routines, there are several
+other routines available in the run-time library which are of interest
+to users. These are intended mostly to simplify manipulation of
+names and addresses. Table 1 summarizes the routines
+for manipulating variable length byte strings and handling byte
+swapping of network addresses and values.
+.KF
+.DS B
+.TS
+box;
+l | l
+l | l.
+Call Synopsis
+_
+bcmp(s1, s2, n) compare byte-strings; 0 if same, not 0 otherwise
+bcopy(s1, s2, n) copy n bytes from s1 to s2
+bzero(base, n) zero-fill n bytes starting at base
+htonl(val) convert 32-bit quantity from host to network byte order
+htons(val) convert 16-bit quantity from host to network byte order
+ntohl(val) convert 32-bit quantity from network to host byte order
+ntohs(val) convert 16-bit quantity from network to host byte order
+.TE
+.DE
+.ce
+Table 1. C run-time routines.
+.KE
+.PP
+The byte swapping routines are provided because the operating
+system expects addresses to be supplied in network order (aka ``big-endian'' order). On
+``little-endian'' architectures, such as Intel x86 and VAX,
+host byte ordering is different than
+network byte ordering. Consequently,
+programs are sometimes required to byte swap quantities. The
+library routines which return network addresses provide them
+in network order so that they may simply be copied into the structures
+provided to the system. This implies users should encounter the
+byte swapping problem only when \fIinterpreting\fP network addresses.
+For example, if an Internet port is to be printed out the following
+code would be required:
+.DS
+printf("port number %d\en", ntohs(sp->s_port));
+.DE
+On machines where unneeded these routines are defined as null
+macros.
+.DS
+.if t .ta .5i 1.0i 1.5i 2.0i
+.if n .ta .7i 1.4i 2.1i 2.8i
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <netdb.h>
+ ...
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ struct sockaddr_in server;
+ struct servent *sp;
+ struct hostent *hp;
+ int s;
+ ...
+ sp = getservbyname("login", "tcp");
+ if (sp == NULL) {
+ fprintf(stderr, "rlogin: tcp/login: unknown service\en");
+ exit(1);
+ }
+ hp = gethostbyname(argv[1]);
+ if (hp == NULL) {
+ fprintf(stderr, "rlogin: %s: unknown host\en", argv[1]);
+ exit(2);
+ }
+ bzero((char *)&server, sizeof (server));
+ bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
+ server.sin_family = hp->h_addrtype;
+ server.sin_port = sp->s_port;
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0) {
+ perror("rlogin: socket");
+ exit(3);
+ }
+ ...
+ /* Connect does the bind() for us */
+
+ if (connect(s, (char *)&server, sizeof (server)) < 0) {
+ perror("rlogin: connect");
+ exit(5);
+ }
+ ...
+}
+.DE
+.ce
+Figure 1. Remote login client code.
diff --git a/share/doc/psd/21.ipc/4.t b/share/doc/psd/21.ipc/4.t
new file mode 100644
index 00000000000..e75af1494ac
--- /dev/null
+++ b/share/doc/psd/21.ipc/4.t
@@ -0,0 +1,514 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)4.t 8.1 (Berkeley) 6/8/93
+.\"
+.\".ds RH "Client/Server Model
+.bp
+.nr H1 4
+.nr H2 0
+.sp 8i
+.bp
+.LG
+.B
+.ce
+4. CLIENT/SERVER MODEL
+.sp 2
+.R
+.NL
+.PP
+The most commonly used paradigm in constructing distributed applications
+is the client/server model. In this scheme client applications request
+services from a server process. This implies an asymmetry in establishing
+communication between the client and server which has been examined
+in section 2. In this section we will look more closely at the interactions
+between client and server, and consider some of the problems in developing
+client and server applications.
+.PP
+The client and server require a well known set of conventions before
+service may be rendered (and accepted). This set of conventions
+comprises a protocol which must be implemented at both ends of a
+connection. Depending on the situation, the protocol may be symmetric
+or asymmetric. In a symmetric protocol, either side may play the
+master or slave roles. In an asymmetric protocol, one side is
+immutably recognized as the master, with the other as the slave.
+An example of a symmetric protocol is the TELNET protocol used in
+the Internet for remote terminal emulation. An example
+of an asymmetric protocol is the Internet file transfer protocol,
+FTP. No matter whether the specific protocol used in obtaining
+a service is symmetric or asymmetric, when accessing a service there
+is a \*(lqclient process\*(rq and a \*(lqserver process\*(rq. We
+will first consider the properties of server processes, then
+client processes.
+.PP
+A server process normally listens at a well known address for
+service requests. That is, the server process remains dormant
+until a connection is requested by a client's connection
+to the server's address. At such a time
+the server process ``wakes up'' and services the client,
+performing whatever appropriate actions the client requests of it.
+.PP
+Alternative schemes which use a service server
+may be used to eliminate a flock of server processes clogging the
+system while remaining dormant most of the time. For Internet
+servers in 4.4BSD,
+this scheme has been implemented via \fIinetd\fP, the so called
+``internet super-server.'' \fIInetd\fP listens at a variety
+of ports, determined at start-up by reading a configuration file.
+When a connection is requested to a port on which \fIinetd\fP is
+listening, \fIinetd\fP executes the appropriate server program to handle the
+client. With this method, clients are unaware that an
+intermediary such as \fIinetd\fP has played any part in the
+connection. \fIInetd\fP will be described in more detail in
+section 5.
+.PP
+A similar alternative scheme is used by most Xerox services. In general,
+the Courier dispatch process (if used) accepts connections from
+processes requesting services of some sort or another. The client
+processes request a particular <program number, version number, procedure
+number> triple. If the dispatcher knows of such a program, it is
+started to handle the request; if not, an error is reported to the
+client. In this way, only one port is required to service a large
+variety of different requests. Again, the Courier facilities are
+not available without the use and installation of the Courier
+compiler. The information presented in this section applies only
+to NS clients and services that do not use Courier.
+.NH 2
+Servers
+.PP
+In 4.4BSD most servers are accessed at well known Internet addresses
+or UNIX domain names. For
+example, the remote login server's main loop is of the form shown
+in Figure 2.
+.KF
+.if t .ta .5i 1.0i 1.5i 2.0i 2.5i 3.0i 3.5i
+.if n .ta .7i 1.4i 2.1i 2.8i 3.5i 4.2i 4.9i
+.sp 0.5i
+.DS
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int f;
+ struct sockaddr_in from;
+ struct servent *sp;
+
+ sp = getservbyname("login", "tcp");
+ if (sp == NULL) {
+ fprintf(stderr, "rlogind: tcp/login: unknown service\en");
+ exit(1);
+ }
+ ...
+#ifndef DEBUG
+ /* Disassociate server from controlling terminal */
+ ...
+#endif
+
+ sin.sin_port = sp->s_port; /* Restricted port -- see section 5 */
+ ...
+ f = socket(AF_INET, SOCK_STREAM, 0);
+ ...
+ if (bind(f, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
+ ...
+ }
+ ...
+ listen(f, 5);
+ for (;;) {
+ int g, len = sizeof (from);
+
+ g = accept(f, (struct sockaddr *) &from, &len);
+ if (g < 0) {
+ if (errno != EINTR)
+ syslog(LOG_ERR, "rlogind: accept: %m");
+ continue;
+ }
+ if (fork() == 0) {
+ close(f);
+ doit(g, &from);
+ }
+ close(g);
+ }
+}
+.DE
+.ce
+Figure 2. Remote login server.
+.sp 0.5i
+.KE
+.PP
+The first step taken by the server is look up its service
+definition:
+.sp 1
+.nf
+.in +5
+.if t .ta .5i 1.0i 1.5i 2.0i
+.if n .ta .7i 1.4i 2.1i 2.8i
+sp = getservbyname("login", "tcp");
+if (sp == NULL) {
+ fprintf(stderr, "rlogind: tcp/login: unknown service\en");
+ exit(1);
+}
+.sp 1
+.in -5
+.fi
+The result of the \fIgetservbyname\fP call
+is used in later portions of the code to
+define the Internet port at which it listens for service
+requests (indicated by a connection).
+.KS
+.PP
+Step two is to disassociate the server from the controlling
+terminal of its invoker:
+.DS
+ for (i = 0; i < 3; ++i)
+ close(i);
+
+ open("/", O_RDONLY);
+ dup2(0, 1);
+ dup2(0, 2);
+
+ i = open("/dev/tty", O_RDWR);
+ if (i >= 0) {
+ ioctl(i, TIOCNOTTY, 0);
+ close(i);
+ }
+.DE
+.KE
+This step is important as the server will
+likely not want to receive signals delivered to the process
+group of the controlling terminal. Note, however, that
+once a server has disassociated itself it can no longer
+send reports of errors to a terminal, and must log errors
+via \fIsyslog\fP.
+.PP
+Once a server has established a pristine environment, it
+creates a socket and begins accepting service requests.
+The \fIbind\fP call is required to insure the server listens
+at its expected location. It should be noted that the
+remote login server listens at a restricted port number, and must
+therefore be run
+with a user-id of root.
+This concept of a ``restricted port number'' is 4BSD
+specific, and is covered in section 5.
+.PP
+The main body of the loop is fairly simple:
+.DS
+.if t .ta .5i 1.0i 1.5i 2.0i
+.if n .ta .7i 1.4i 2.1i 2.8i
+for (;;) {
+ int g, len = sizeof (from);
+
+ g = accept(f, (struct sockaddr *)&from, &len);
+ if (g < 0) {
+ if (errno != EINTR)
+ syslog(LOG_ERR, "rlogind: accept: %m");
+ continue;
+ }
+ if (fork() == 0) { /* Child */
+ close(f);
+ doit(g, &from);
+ }
+ close(g); /* Parent */
+}
+.DE
+An \fIaccept\fP call blocks the server until
+a client requests service. This call could return a
+failure status if the call is interrupted by a signal
+such as SIGCHLD (to be discussed in section 5). Therefore,
+the return value from \fIaccept\fP is checked to insure
+a connection has actually been established, and
+an error report is logged via \fIsyslog\fP if an error
+has occurred.
+.PP
+With a connection
+in hand, the server then forks a child process and invokes
+the main body of the remote login protocol processing. Note
+how the socket used by the parent for queuing connection
+requests is closed in the child, while the socket created as
+a result of the \fIaccept\fP is closed in the parent. The
+address of the client is also handed the \fIdoit\fP routine
+because it requires it in authenticating clients.
+.NH 2
+Clients
+.PP
+The client side of the remote login service was shown
+earlier in Figure 1.
+One can see the separate, asymmetric roles of the client
+and server clearly in the code. The server is a passive entity,
+listening for client connections, while the client process is
+an active entity, initiating a connection when invoked.
+.PP
+Let us consider more closely the steps taken
+by the client remote login process. As in the server process,
+the first step is to locate the service definition for a remote
+login:
+.DS
+sp = getservbyname("login", "tcp");
+if (sp == NULL) {
+ fprintf(stderr, "rlogin: tcp/login: unknown service\en");
+ exit(1);
+}
+.DE
+Next the destination host is looked up with a
+\fIgethostbyname\fP call:
+.DS
+hp = gethostbyname(argv[1]);
+if (hp == NULL) {
+ fprintf(stderr, "rlogin: %s: unknown host\en", argv[1]);
+ exit(2);
+}
+.DE
+With this accomplished, all that is required is to establish a
+connection to the server at the requested host and start up the
+remote login protocol. The address buffer is cleared, then filled
+in with the Internet address of the foreign host and the port
+number at which the login process resides on the foreign host:
+.DS
+bzero((char *)&server, sizeof (server));
+bcopy(hp->h_addr, (char *) &server.sin_addr, hp->h_length);
+server.sin_family = hp->h_addrtype;
+server.sin_port = sp->s_port;
+.DE
+A socket is created, and a connection initiated. Note
+that \fIconnect\fP implicitly performs a \fIbind\fP
+call, since \fIs\fP is unbound.
+.DS
+s = socket(hp->h_addrtype, SOCK_STREAM, 0);
+if (s < 0) {
+ perror("rlogin: socket");
+ exit(3);
+}
+ ...
+if (connect(s, (struct sockaddr *) &server, sizeof (server)) < 0) {
+ perror("rlogin: connect");
+ exit(4);
+}
+.DE
+The details of the remote login protocol will not be considered here.
+.NH 2
+Connectionless servers
+.PP
+While connection-based services are the norm, some services
+are based on the use of datagram sockets. One, in particular,
+is the \*(lqrwho\*(rq service which provides users with status
+information for hosts connected to a local area
+network. This service, while predicated on the ability to
+\fIbroadcast\fP information to all hosts connected to a particular
+network, is of interest as an example usage of datagram sockets.
+.PP
+A user on any machine running the rwho server may find out
+the current status of a machine with the \fIruptime\fP(1) program.
+The output generated is illustrated in Figure 3.
+.KF
+.DS B
+.TS
+l r l l l l l.
+arpa up 9:45, 5 users, load 1.15, 1.39, 1.31
+cad up 2+12:04, 8 users, load 4.67, 5.13, 4.59
+calder up 10:10, 0 users, load 0.27, 0.15, 0.14
+dali up 2+06:28, 9 users, load 1.04, 1.20, 1.65
+degas up 25+09:48, 0 users, load 1.49, 1.43, 1.41
+ear up 5+00:05, 0 users, load 1.51, 1.54, 1.56
+ernie down 0:24
+esvax down 17:04
+ingres down 0:26
+kim up 3+09:16, 8 users, load 2.03, 2.46, 3.11
+matisse up 3+06:18, 0 users, load 0.03, 0.03, 0.05
+medea up 3+09:39, 2 users, load 0.35, 0.37, 0.50
+merlin down 19+15:37
+miro up 1+07:20, 7 users, load 4.59, 3.28, 2.12
+monet up 1+00:43, 2 users, load 0.22, 0.09, 0.07
+oz down 16:09
+statvax up 2+15:57, 3 users, load 1.52, 1.81, 1.86
+ucbvax up 9:34, 2 users, load 6.08, 5.16, 3.28
+.TE
+.DE
+.ce
+Figure 3. ruptime output.
+.sp
+.KE
+.PP
+Status information for each host is periodically broadcast
+by rwho server processes on each machine. The same server
+process also receives the status information and uses it
+to update a database. This database is then interpreted
+to generate the status information for each host. Servers
+operate autonomously, coupled only by the local network and
+its broadcast capabilities.
+.PP
+Note that the use of broadcast for such a task is fairly inefficient,
+as all hosts must process each message, whether or not using an rwho server.
+Unless such a service is sufficiently universal and is frequently used,
+the expense of periodic broadcasts outweighs the simplicity.
+.PP
+Multicasting is an alternative to broadcasting.
+Setting up multicast sockets is described in Section 5.10.
+.PP
+The rwho server, in a simplified form, is pictured in Figure
+4. There are two separate tasks performed by the server. The
+first task is to act as a receiver of status information broadcast
+by other hosts on the network. This job is carried out in the
+main loop of the program. Packets received at the rwho port
+are interrogated to insure they've been sent by another rwho
+server process, then are time stamped with their arrival time
+and used to update a file indicating the status of the host.
+When a host has not been heard from for an extended period of
+time, the database interpretation routines assume the host is
+down and indicate such on the status reports. This algorithm
+is prone to error as a server may be down while a host is actually
+up, but serves our current needs.
+.KF
+.DS
+.if t .ta .5i 1.0i 1.5i 2.0i
+.if n .ta .7i 1.4i 2.1i 2.8i
+main()
+{
+ ...
+ sp = getservbyname("who", "udp");
+ net = getnetbyname("localnet");
+ sin.sin_addr = inet_makeaddr(INADDR_ANY, net);
+ sin.sin_port = sp->s_port;
+ ...
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ ...
+ on = 1;
+ if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
+ syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
+ exit(1);
+ }
+ bind(s, (struct sockaddr *) &sin, sizeof (sin));
+ ...
+ signal(SIGALRM, onalrm);
+ onalrm();
+ for (;;) {
+ struct whod wd;
+ int cc, whod, len = sizeof (from);
+
+ cc = recvfrom(s, (char *)&wd, sizeof (struct whod), 0,
+ (struct sockaddr *)&from, &len);
+ if (cc <= 0) {
+ if (cc < 0 && errno != EINTR)
+ syslog(LOG_ERR, "rwhod: recv: %m");
+ continue;
+ }
+ if (from.sin_port != sp->s_port) {
+ syslog(LOG_ERR, "rwhod: %d: bad from port",
+ ntohs(from.sin_port));
+ continue;
+ }
+ ...
+ if (!verify(wd.wd_hostname)) {
+ syslog(LOG_ERR, "rwhod: malformed host name from %x",
+ ntohl(from.sin_addr.s_addr));
+ continue;
+ }
+ (void) sprintf(path, "%s/whod.%s", RWHODIR, wd.wd_hostname);
+ whod = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ ...
+ (void) time(&wd.wd_recvtime);
+ (void) write(whod, (char *)&wd, cc);
+ (void) close(whod);
+ }
+}
+.DE
+.ce
+Figure 4. rwho server.
+.sp
+.KE
+.PP
+The second task performed by the server is to supply information
+regarding the status of its host. This involves periodically
+acquiring system status information, packaging it up in a message
+and broadcasting it on the local network for other rwho servers
+to hear. The supply function is triggered by a timer and
+runs off a signal. Locating the system status
+information is somewhat involved, but uninteresting. Deciding
+where to transmit the resultant packet
+is somewhat problematical, however.
+.PP
+Status information must be broadcast on the local network.
+For networks which do not support the notion of broadcast another
+scheme must be used to simulate or
+replace broadcasting. One possibility is to enumerate the
+known neighbors (based on the status messages received
+from other rwho servers). This, unfortunately,
+requires some bootstrapping information,
+for a server will have no idea what machines are its
+neighbors until it receives status messages from them.
+Therefore, if all machines on a net are freshly booted,
+no machine will have any
+known neighbors and thus never receive, or send, any status information.
+This is the identical problem faced by the routing table management
+process in propagating routing status information. The standard
+solution, unsatisfactory as it may be, is to inform one or more servers
+of known neighbors and request that they always communicate with
+these neighbors. If each server has at least one neighbor supplied
+to it, status information may then propagate through
+a neighbor to hosts which
+are not (possibly) directly neighbors. If the server is able to
+support networks which provide a broadcast capability, as well as
+those which do not, then networks with an
+arbitrary topology may share status information*.
+.FS
+* One must, however, be concerned about \*(lqloops\*(rq.
+That is, if a host is connected to multiple networks, it
+will receive status information from itself. This can lead
+to an endless, wasteful, exchange of information.
+.FE
+.PP
+It is important that software operating in a distributed
+environment not have any site-dependent information compiled into it.
+This would require a separate copy of the server at each host and
+make maintenance a severe headache. 4.4BSD attempts to isolate
+host-specific information from applications by providing system
+calls which return the necessary information*.
+.FS
+* An example of such a system call is the \fIgethostname\fP(2)
+call which returns the host's \*(lqofficial\*(rq name.
+.FE
+A mechanism exists, in the form of an \fIioctl\fP call,
+for finding the collection
+of networks to which a host is directly connected.
+Further, a local network broadcasting mechanism
+has been implemented at the socket level.
+Combining these two features allows a process
+to broadcast on any directly connected local
+network which supports the notion of broadcasting
+in a site independent manner. This allows 4.4BSD
+to solve the problem of deciding how to propagate
+status information in the case of \fIrwho\fP, or
+more generally in broadcasting:
+Such status information is broadcast to connected
+networks at the socket level, where the connected networks
+have been obtained via the appropriate \fIioctl\fP
+calls.
+The specifics of
+such broadcastings are complex, however, and will
+be covered in section 5.
diff --git a/share/doc/psd/21.ipc/5.t b/share/doc/psd/21.ipc/5.t
new file mode 100644
index 00000000000..fe6977ee803
--- /dev/null
+++ b/share/doc/psd/21.ipc/5.t
@@ -0,0 +1,1667 @@
+.\" Copyright (c) 1986, 1993
+.\" The Regents of the University of California. 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 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.
+.\"
+.\" @(#)5.t 8.1 (Berkeley) 8/14/93
+.\"
+.\".ds RH "Advanced Topics
+.bp
+.nr H1 5
+.nr H2 0
+.LG
+.B
+.ce
+5. ADVANCED TOPICS
+.sp 2
+.R
+.NL
+.PP
+A number of facilities have yet to be discussed. For most users
+of the IPC the mechanisms already
+described will suffice in constructing distributed
+applications. However, others will find the need to utilize some
+of the features which we consider in this section.
+.NH 2
+Out of band data
+.PP
+The stream socket abstraction includes the notion of \*(lqout
+of band\*(rq data. Out of band data is a logically independent
+transmission channel associated with each pair of connected
+stream sockets. Out of band data is delivered to the user
+independently of normal data.
+The abstraction defines that the out of band data facilities
+must support the reliable delivery of at least one
+out of band message at a time. This message may contain at least one
+byte of data, and at least one message may be pending delivery
+to the user at any one time. For communications protocols which
+support only in-band signaling (i.e. the urgent data is
+delivered in sequence with the normal data), the system normally extracts
+the data from the normal data stream and stores it separately.
+This allows users to choose between receiving the urgent data
+in order and receiving it out of sequence without having to
+buffer all the intervening data. It is possible
+to ``peek'' (via MSG_PEEK) at out of band data.
+If the socket has a process group, a SIGURG signal is generated
+when the protocol is notified of its existence.
+A process can set the process group
+or process id to be informed by the SIGURG signal via the
+appropriate \fIfcntl\fP call, as described below for
+SIGIO.
+If multiple sockets may have out of band data awaiting
+delivery, a \fIselect\fP call for exceptional conditions
+may be used to determine those sockets with such data pending.
+Neither the signal nor the select indicate the actual arrival
+of the out-of-band data, but only notification that it is pending.
+.PP
+In addition to the information passed, a logical mark is placed in
+the data stream to indicate the point at which the out
+of band data was sent. The remote login and remote shell
+applications use this facility to propagate signals between
+client and server processes. When a signal
+flushs any pending output from the remote process(es), all
+data up to the mark in the data stream is discarded.
+.PP
+To send an out of band message the MSG_OOB flag is supplied to
+a \fIsend\fP or \fIsendto\fP calls,
+while to receive out of band data MSG_OOB should be indicated
+when performing a \fIrecvfrom\fP or \fIrecv\fP call.
+To find out if the read pointer is currently pointing at
+the mark in the data stream, the SIOCATMARK ioctl is provided:
+.DS
+ioctl(s, SIOCATMARK, &yes);
+.DE
+If \fIyes\fP is a 1 on return, the next read will return data
+after the mark. Otherwise (assuming out of band data has arrived),
+the next read will provide data sent by the client prior
+to transmission of the out of band signal. The routine used
+in the remote login process to flush output on receipt of an
+interrupt or quit signal is shown in Figure 5.
+It reads the normal data up to the mark (to discard it),
+then reads the out-of-band byte.
+.KF
+.DS
+#include <sys/ioctl.h>
+#include <sys/file.h>
+ ...
+oob()
+{
+ int out = FWRITE, mark;
+ char waste[BUFSIZ];
+
+ /* flush local terminal output */
+ ioctl(1, TIOCFLUSH, (char *)&out);
+ for (;;) {
+ if (ioctl(rem, SIOCATMARK, &mark) < 0) {
+ perror("ioctl");
+ break;
+ }
+ if (mark)
+ break;
+ (void) read(rem, waste, sizeof (waste));
+ }
+ if (recv(rem, &mark, 1, MSG_OOB) < 0) {
+ perror("recv");
+ ...
+ }
+ ...
+}
+.DE
+.ce
+Figure 5. Flushing terminal I/O on receipt of out of band data.
+.sp
+.KE
+.PP
+A process may also read or peek at the out-of-band data
+without first reading up to the mark.
+This is more difficult when the underlying protocol delivers
+the urgent data in-band with the normal data, and only sends
+notification of its presence ahead of time (e.g., the TCP protocol
+used to implement streams in the Internet domain).
+With such protocols, the out-of-band byte may not yet have arrived
+when a \fIrecv\fP is done with the MSG_OOB flag.
+In that case, the call will return an error of EWOULDBLOCK.
+Worse, there may be enough in-band data in the input buffer
+that normal flow control prevents the peer from sending the urgent data
+until the buffer is cleared.
+The process must then read enough of the queued data
+that the urgent data may be delivered.
+.PP
+Certain programs that use multiple bytes of urgent data and must
+handle multiple urgent signals (e.g., \fItelnet\fP\|(1C))
+need to retain the position of urgent data within the stream.
+This treatment is available as a socket-level option, SO_OOBINLINE;
+see \fIsetsockopt\fP\|(2) for usage.
+With this option, the position of urgent data (the \*(lqmark\*(rq)
+is retained, but the urgent data immediately follows the mark
+within the normal data stream returned without the MSG_OOB flag.
+Reception of multiple urgent indications causes the mark to move,
+but no out-of-band data are lost.
+.NH 2
+Non-Blocking Sockets
+.PP
+It is occasionally convenient to make use of sockets
+which do not block; that is, I/O requests which
+cannot complete immediately and
+would therefore cause the process to be suspended awaiting completion are
+not executed, and an error code is returned.
+Once a socket has been created via
+the \fIsocket\fP call, it may be marked as non-blocking
+by \fIfcntl\fP as follows:
+.DS
+#include <fcntl.h>
+ ...
+int s;
+ ...
+s = socket(AF_INET, SOCK_STREAM, 0);
+ ...
+if (fcntl(s, F_SETFL, FNDELAY) < 0)
+ perror("fcntl F_SETFL, FNDELAY");
+ exit(1);
+}
+ ...
+.DE
+.PP
+When performing non-blocking I/O on sockets, one must be
+careful to check for the error EWOULDBLOCK (stored in the
+global variable \fIerrno\fP), which occurs when
+an operation would normally block, but the socket it
+was performed on is marked as non-blocking.
+In particular, \fIaccept\fP, \fIconnect\fP, \fIsend\fP, \fIrecv\fP,
+\fIread\fP, and \fIwrite\fP can
+all return EWOULDBLOCK, and processes should be prepared
+to deal with such return codes.
+If an operation such as a \fIsend\fP cannot be done in its entirety,
+but partial writes are sensible (for example, when using a stream socket),
+the data that can be sent immediately will be processed,
+and the return value will indicate the amount actually sent.
+.NH 2
+Interrupt driven socket I/O
+.PP
+The SIGIO signal allows a process to be notified
+via a signal when a socket (or more generally, a file
+descriptor) has data waiting to be read. Use of
+the SIGIO facility requires three steps: First,
+the process must set up a SIGIO signal handler
+by use of the \fIsignal\fP or \fIsigvec\fP calls. Second,
+it must set the process id or process group id which is to receive
+notification of pending input to its own process id,
+or the process group id of its process group (note that
+the default process group of a socket is group zero).
+This is accomplished by use of an \fIfcntl\fP call.
+Third, it must enable asynchronous notification of pending I/O requests
+with another \fIfcntl\fP call. Sample code to
+allow a given process to receive information on
+pending I/O requests as they occur for a socket \fIs\fP
+is given in Figure 6. With the addition of a handler for SIGURG,
+this code can also be used to prepare for receipt of SIGURG signals.
+.KF
+.DS
+#include <fcntl.h>
+ ...
+int io_handler();
+ ...
+signal(SIGIO, io_handler);
+
+/* Set the process receiving SIGIO/SIGURG signals to us */
+
+if (fcntl(s, F_SETOWN, getpid()) < 0) {
+ perror("fcntl F_SETOWN");
+ exit(1);
+}
+
+/* Allow receipt of asynchronous I/O signals */
+
+if (fcntl(s, F_SETFL, FASYNC) < 0) {
+ perror("fcntl F_SETFL, FASYNC");
+ exit(1);
+}
+.DE
+.ce
+Figure 6. Use of asynchronous notification of I/O requests.
+.sp
+.KE
+.NH 2
+Signals and process groups
+.PP
+Due to the existence of the SIGURG and SIGIO signals each socket has an
+associated process number, just as is done for terminals.
+This value is initialized to zero,
+but may be redefined at a later time with the F_SETOWN
+\fIfcntl\fP, such as was done in the code above for SIGIO.
+To set the socket's process id for signals, positive arguments
+should be given to the \fIfcntl\fP call. To set the socket's
+process group for signals, negative arguments should be
+passed to \fIfcntl\fP. Note that the process number indicates
+either the associated process id or the associated process
+group; it is impossible to specify both at the same time.
+A similar \fIfcntl\fP, F_GETOWN, is available for determining the
+current process number of a socket.
+.PP
+Another signal which is useful when constructing server processes
+is SIGCHLD. This signal is delivered to a process when any
+child processes have changed state. Normally servers use
+the signal to \*(lqreap\*(rq child processes that have exited
+without explicitly awaiting their termination
+or periodic polling for exit status.
+For example, the remote login server loop shown in Figure 2
+may be augmented as shown in Figure 7.
+.KF
+.DS
+int reaper();
+ ...
+signal(SIGCHLD, reaper);
+listen(f, 5);
+for (;;) {
+ int g, len = sizeof (from);
+
+ g = accept(f, (struct sockaddr *)&from, &len,);
+ if (g < 0) {
+ if (errno != EINTR)
+ syslog(LOG_ERR, "rlogind: accept: %m");
+ continue;
+ }
+ ...
+}
+ ...
+#include <wait.h>
+reaper()
+{
+ union wait status;
+
+ while (wait3(&status, WNOHANG, 0) > 0)
+ ;
+}
+.DE
+.sp
+.ce
+Figure 7. Use of the SIGCHLD signal.
+.sp
+.KE
+.PP
+If the parent server process fails to reap its children,
+a large number of \*(lqzombie\*(rq processes may be created.
+.NH 2
+Pseudo terminals
+.PP
+Many programs will not function properly without a terminal
+for standard input and output. Since sockets do not provide
+the semantics of terminals,
+it is often necessary to have a process communicating over
+the network do so through a \fIpseudo-terminal\fP. A pseudo-
+terminal is actually a pair of devices, master and slave,
+which allow a process to serve as an active agent in communication
+between processes and users. Data written on the slave side
+of a pseudo-terminal is supplied as input to a process reading
+from the master side, while data written on the master side are
+processed as terminal input for the slave.
+In this way, the process manipulating
+the master side of the pseudo-terminal has control over the
+information read and written on the slave side
+as if it were manipulating the keyboard and reading the screen
+on a real terminal.
+The purpose of this abstraction is to
+preserve terminal semantics over a network connection\(em
+that is, the slave side appears as a normal terminal to
+any process reading from or writing to it.
+.PP
+For example, the remote
+login server uses pseudo-terminals for remote login sessions.
+A user logging in to a machine across the network is provided
+a shell with a slave pseudo-terminal as standard input, output,
+and error. The server process then handles the communication
+between the programs invoked by the remote shell and the user's
+local client process.
+When a user sends a character that generates an interrupt
+on the remote machine that flushes terminal output,
+the pseudo-terminal generates a control message for the server process.
+The server then sends an out of band message
+to the client process to signal a flush of data at the real terminal
+and on the intervening data buffered in the network.
+.PP
+Under 4.4BSD, the name of the slave side of a pseudo-terminal is of the form
+\fI/dev/ttyxy\fP, where \fIx\fP is a single letter
+starting at `p' and continuing to `t'.
+\fIy\fP is a hexadecimal digit (i.e., a single
+character in the range 0 through 9 or `a' through `f').
+The master side of a pseudo-terminal is \fI/dev/ptyxy\fP,
+where \fIx\fP and \fIy\fP correspond to the
+slave side of the pseudo-terminal.
+.PP
+In general, the method of obtaining a pair of master and
+slave pseudo-terminals is to
+find a pseudo-terminal which
+is not currently in use.
+The master half of a pseudo-terminal is a single-open device;
+thus, each master may be opened in turn until an open succeeds.
+The slave side of the pseudo-terminal is then opened,
+and is set to the proper terminal modes if necessary.
+The process then \fIfork\fPs; the child closes
+the master side of the pseudo-terminal, and \fIexec\fPs the
+appropriate program. Meanwhile, the parent closes the
+slave side of the pseudo-terminal and begins reading and
+writing from the master side. Sample code making use of
+pseudo-terminals is given in Figure 8; this code assumes
+that a connection on a socket \fIs\fP exists, connected
+to a peer who wants a service of some kind, and that the
+process has disassociated itself from any previous controlling terminal.
+.KF
+.DS
+gotpty = 0;
+for (c = 'p'; !gotpty && c <= 's'; c++) {
+ line = "/dev/ptyXX";
+ line[sizeof("/dev/pty")-1] = c;
+ line[sizeof("/dev/ptyp")-1] = '0';
+ if (stat(line, &statbuf) < 0)
+ break;
+ for (i = 0; i < 16; i++) {
+ line[sizeof("/dev/ptyp")-1] = "0123456789abcdef"[i];
+ master = open(line, O_RDWR);
+ if (master > 0) {
+ gotpty = 1;
+ break;
+ }
+ }
+}
+if (!gotpty) {
+ syslog(LOG_ERR, "All network ports in use");
+ exit(1);
+}
+
+line[sizeof("/dev/")-1] = 't';
+slave = open(line, O_RDWR); /* \fIslave\fP is now slave side */
+if (slave < 0) {
+ syslog(LOG_ERR, "Cannot open slave pty %s", line);
+ exit(1);
+}
+
+ioctl(slave, TIOCGETP, &b); /* Set slave tty modes */
+b.sg_flags = CRMOD|XTABS|ANYP;
+ioctl(slave, TIOCSETP, &b);
+
+i = fork();
+if (i < 0) {
+ syslog(LOG_ERR, "fork: %m");
+ exit(1);
+} else if (i) { /* Parent */
+ close(slave);
+ ...
+} else { /* Child */
+ (void) close(s);
+ (void) close(master);
+ dup2(slave, 0);
+ dup2(slave, 1);
+ dup2(slave, 2);
+ if (slave > 2)
+ (void) close(slave);
+ ...
+}
+.DE
+.ce
+Figure 8. Creation and use of a pseudo terminal
+.sp
+.KE
+.NH 2
+Selecting specific protocols
+.PP
+If the third argument to the \fIsocket\fP call is 0,
+\fIsocket\fP will select a default protocol to use with
+the returned socket of the type requested.
+The default protocol is usually correct, and alternate choices are not
+usually available.
+However, when using ``raw'' sockets to communicate directly with
+lower-level protocols or hardware interfaces,
+the protocol argument may be important for setting up demultiplexing.
+For example, raw sockets in the Internet family may be used to implement
+a new protocol above IP, and the socket will receive packets
+only for the protocol specified.
+To obtain a particular protocol one determines the protocol number
+as defined within the communication domain. For the Internet
+domain one may use one of the library routines
+discussed in section 3, such as \fIgetprotobyname\fP:
+.DS
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+ ...
+pp = getprotobyname("newtcp");
+s = socket(AF_INET, SOCK_STREAM, pp->p_proto);
+.DE
+This would result in a socket \fIs\fP using a stream
+based connection, but with protocol type of ``newtcp''
+instead of the default ``tcp.''
+.PP
+In the NS domain, the available socket protocols are defined in
+<\fInetns/ns.h\fP>. To create a raw socket for Xerox Error Protocol
+messages, one might use:
+.DS
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netns/ns.h>
+ ...
+s = socket(AF_NS, SOCK_RAW, NSPROTO_ERROR);
+.DE
+.NH 2
+Address binding
+.PP
+As was mentioned in section 2,
+binding addresses to sockets in the Internet and NS domains can be
+fairly complex. As a brief reminder, these associations
+are composed of local and foreign
+addresses, and local and foreign ports. Port numbers are
+allocated out of separate spaces, one for each system and one
+for each domain on that system.
+Through the \fIbind\fP system call, a
+process may specify half of an association, the
+<local address, local port> part, while the
+\fIconnect\fP
+and \fIaccept\fP
+primitives are used to complete a socket's association by
+specifying the <foreign address, foreign port> part.
+Since the association is created in two steps the association
+uniqueness requirement indicated previously could be violated unless
+care is taken. Further, it is unrealistic to expect user
+programs to always know proper values to use for the local address
+and local port since a host may reside on multiple networks and
+the set of allocated port numbers is not directly accessible
+to a user.
+.PP
+To simplify local address binding in the Internet domain the notion of a
+\*(lqwildcard\*(rq address has been provided. When an address
+is specified as INADDR_ANY (a manifest constant defined in
+<netinet/in.h>), the system interprets the address as
+\*(lqany valid address\*(rq. For example, to bind a specific
+port number to a socket, but leave the local address unspecified,
+the following code might be used:
+.DS
+#include <sys/types.h>
+#include <netinet/in.h>
+ ...
+struct sockaddr_in sin;
+ ...
+s = socket(AF_INET, SOCK_STREAM, 0);
+sin.sin_family = AF_INET;
+sin.sin_addr.s_addr = htonl(INADDR_ANY);
+sin.sin_port = htons(MYPORT);
+bind(s, (struct sockaddr *) &sin, sizeof (sin));
+.DE
+Sockets with wildcarded local addresses may receive messages
+directed to the specified port number, and sent to any
+of the possible addresses assigned to a host. For example,
+if a host has addresses 128.32.0.4 and 10.0.0.78, and a socket is bound as
+above, the process will be
+able to accept connection requests which are addressed to
+128.32.0.4 or 10.0.0.78.
+If a server process wished to only allow hosts on a
+given network connect to it, it would bind
+the address of the host on the appropriate network.
+.PP
+In a similar fashion, a local port may be left unspecified
+(specified as zero), in which case the system will select an
+appropriate port number for it. This shortcut will work
+both in the Internet and NS domains. For example, to
+bind a specific local address to a socket, but to leave the
+local port number unspecified:
+.DS
+hp = gethostbyname(hostname);
+if (hp == NULL) {
+ ...
+}
+bcopy(hp->h_addr, (char *) sin.sin_addr, hp->h_length);
+sin.sin_port = htons(0);
+bind(s, (struct sockaddr *) &sin, sizeof (sin));
+.DE
+The system selects the local port number based on two criteria.
+The first is that on 4BSD systems,
+Internet ports below IPPORT_RESERVED (1024) (for the Xerox domain,
+0 through 3000) are reserved
+for privileged users (i.e., the super user);
+Internet ports above IPPORT_USERRESERVED (50000) are reserved
+for non-privileged servers. The second is
+that the port number is not currently bound to some other
+socket. In order to find a free Internet port number in the privileged
+range the \fIrresvport\fP library routine may be used as follows
+to return a stream socket in with a privileged port number:
+.DS
+int lport = IPPORT_RESERVED \- 1;
+int s;
+\&...
+s = rresvport(&lport);
+if (s < 0) {
+ if (errno == EAGAIN)
+ fprintf(stderr, "socket: all ports in use\en");
+ else
+ perror("rresvport: socket");
+ ...
+}
+.DE
+The restriction on allocating ports was done to allow processes
+executing in a \*(lqsecure\*(rq environment to perform authentication
+based on the originating address and port number. For example,
+the \fIrlogin\fP(1) command allows users to log in across a network
+without being asked for a password, if two conditions hold:
+First, the name of the system the user
+is logging in from is in the file
+\fI/etc/hosts.equiv\fP on the system he is logging
+in to (or the system name and the user name are in
+the user's \fI.rhosts\fP file in the user's home
+directory), and second, that the user's rlogin
+process is coming from a privileged port on the machine from which he is
+logging. The port number and network address of the
+machine from which the user is logging in can be determined either
+by the \fIfrom\fP result of the \fIaccept\fP call, or
+from the \fIgetpeername\fP call.
+.PP
+In certain cases the algorithm used by the system in selecting
+port numbers is unsuitable for an application. This is because
+associations are created in a two step process. For example,
+the Internet file transfer protocol, FTP, specifies that data
+connections must always originate from the same local port. However,
+duplicate associations are avoided by connecting to different foreign
+ports. In this situation the system would disallow binding the
+same local address and port number to a socket if a previous data
+connection's socket still existed. To override the default port
+selection algorithm, an option call must be performed prior
+to address binding:
+.DS
+ ...
+int on = 1;
+ ...
+setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+bind(s, (struct sockaddr *) &sin, sizeof (sin));
+.DE
+With the above call, local addresses may be bound which
+are already in use. This does not violate the uniqueness
+requirement as the system still checks at connect time to
+be sure any other sockets with the same local address and
+port do not have the same foreign address and port.
+If the association already exists, the error EADDRINUSE is returned.
+A related socket option, SO_REUSEPORT, which allows completely
+duplicate bindings, is described in the IP multicasting section.
+.NH 2
+Socket Options
+.PP
+It is possible to set and get a number of options on sockets
+via the \fIsetsockopt\fP and \fIgetsockopt\fP system calls.
+These options include such things as marking a socket for
+broadcasting, not to route, to linger on close, etc.
+In addition, there are protocol-specific options for IP and TCP,
+as described in
+.IR ip (4),
+.IR tcp (4),
+and in the section on multicasting below.
+.PP
+The general forms of the calls are:
+.DS
+setsockopt(s, level, optname, optval, optlen);
+.DE
+and
+.DS
+getsockopt(s, level, optname, optval, optlen);
+.DE
+.PP
+The parameters to the calls are as follows: \fIs\fP
+is the socket on which the option is to be applied.
+\fILevel\fP specifies the protocol layer on which the
+option is to be applied; in most cases this is
+the ``socket level'', indicated by the symbolic constant
+SOL_SOCKET, defined in \fI<sys/socket.h>.\fP
+The actual option is specified in \fIoptname\fP, and is
+a symbolic constant also defined in \fI<sys/socket.h>\fP.
+\fIOptval\fP and \fIOptlen\fP point to the value of the
+option (in most cases, whether the option is to be turned
+on or off), and the length of the value of the option,
+respectively.
+For \fIgetsockopt\fP, \fIoptlen\fP is
+a value-result parameter, initially set to the size of
+the storage area pointed to by \fIoptval\fP, and modified
+upon return to indicate the actual amount of storage used.
+.PP
+An example should help clarify things. It is sometimes
+useful to determine the type (e.g., stream, datagram, etc.)
+of an existing socket; programs
+under \fIinetd\fP (described below) may need to perform this
+task. This can be accomplished as follows via the
+SO_TYPE socket option and the \fIgetsockopt\fP call:
+.DS
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int type, size;
+
+size = sizeof (int);
+
+if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &type, &size) < 0) {
+ ...
+}
+.DE
+After the \fIgetsockopt\fP call, \fItype\fP will be set
+to the value of the socket type, as defined in
+\fI<sys/socket.h>\fP. If, for example, the socket were
+a datagram socket, \fItype\fP would have the value
+corresponding to SOCK_DGRAM.
+.NH 2
+Broadcasting and determining network configuration
+.PP
+By using a datagram socket, it is possible to send broadcast
+packets on many networks supported by the system.
+The network itself must support broadcast; the system
+provides no simulation of broadcast in software.
+Broadcast messages can place a high load on a network since they force
+every host on the network to service them. Consequently,
+the ability to send broadcast packets has been limited
+to sockets which are explicitly marked as allowing broadcasting.
+Broadcast is typically used for one of two reasons:
+it is desired to find a resource on a local network without prior
+knowledge of its address,
+or important functions such as routing require that information
+be sent to all accessible neighbors.
+.PP
+Multicasting is an alternative to broadcasting.
+Setting up IP multicast sockets is described in the next section.
+.PP
+To send a broadcast message, a datagram socket
+should be created:
+.DS
+s = socket(AF_INET, SOCK_DGRAM, 0);
+.DE
+or
+.DS
+s = socket(AF_NS, SOCK_DGRAM, 0);
+.DE
+The socket is marked as allowing broadcasting,
+.DS
+int on = 1;
+
+setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on));
+.DE
+and at least a port number should be bound to the socket:
+.DS
+sin.sin_family = AF_INET;
+sin.sin_addr.s_addr = htonl(INADDR_ANY);
+sin.sin_port = htons(MYPORT);
+bind(s, (struct sockaddr *) &sin, sizeof (sin));
+.DE
+or, for the NS domain,
+.DS
+sns.sns_family = AF_NS;
+netnum = htonl(net);
+sns.sns_addr.x_net = *(union ns_net *) &netnum; /* insert net number */
+sns.sns_addr.x_port = htons(MYPORT);
+bind(s, (struct sockaddr *) &sns, sizeof (sns));
+.DE
+The destination address of the message to be broadcast
+depends on the network(s) on which the message is to be broadcast.
+The Internet domain supports a shorthand notation for broadcast
+on the local network, the address INADDR_BROADCAST (defined in
+<\fInetinet/in.h\fP>.
+To determine the list of addresses for all reachable neighbors
+requires knowledge of the networks to which the host is connected.
+Since this information should
+be obtained in a host-independent fashion and may be impossible
+to derive, 4.4BSD provides a method of
+retrieving this information from the system data structures.
+The SIOCGIFCONF \fIioctl\fP call returns the interface
+configuration of a host in the form of a
+single \fIifconf\fP structure; this structure contains
+a ``data area'' which is made up of an array of
+of \fIifreq\fP structures, one for each network interface
+to which the host is connected.
+These structures are defined in
+\fI<net/if.h>\fP as follows:
+.DS
+.if t .ta .5i 1.0i 1.5i 3.5i
+.if n .ta .7i 1.4i 2.1i 3.4i
+struct ifconf {
+ int ifc_len; /* size of associated buffer */
+ union {
+ caddr_t ifcu_buf;
+ struct ifreq *ifcu_req;
+ } ifc_ifcu;
+};
+
+#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
+#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
+
+#define IFNAMSIZ 16
+
+struct ifreq {
+ char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ union {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_dstaddr;
+ struct sockaddr ifru_broadaddr;
+ short ifru_flags;
+ caddr_t ifru_data;
+ } ifr_ifru;
+};
+
+.if t .ta \w' #define'u +\w' ifr_broadaddr'u +\w' ifr_ifru.ifru_broadaddr'u
+#define ifr_addr ifr_ifru.ifru_addr /* address */
+#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
+#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+#define ifr_flags ifr_ifru.ifru_flags /* flags */
+#define ifr_data ifr_ifru.ifru_data /* for use by interface */
+.DE
+The actual call which obtains the
+interface configuration is
+.DS
+struct ifconf ifc;
+char buf[BUFSIZ];
+
+ifc.ifc_len = sizeof (buf);
+ifc.ifc_buf = buf;
+if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) {
+ ...
+}
+.DE
+After this call \fIbuf\fP will contain one \fIifreq\fP structure for
+each network to which the host is connected, and
+\fIifc.ifc_len\fP will have been modified to reflect the number
+of bytes used by the \fIifreq\fP structures.
+.PP
+For each structure
+there exists a set of ``interface flags'' which tell
+whether the network corresponding to that interface is
+up or down, point to point or broadcast, etc. The
+SIOCGIFFLAGS \fIioctl\fP retrieves these
+flags for an interface specified by an \fIifreq\fP
+structure as follows:
+.DS
+struct ifreq *ifr;
+
+ifr = ifc.ifc_req;
+
+for (n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++) {
+ /*
+ * We must be careful that we don't use an interface
+ * devoted to an address family other than those intended;
+ * if we were interested in NS interfaces, the
+ * AF_INET would be AF_NS.
+ */
+ if (ifr->ifr_addr.sa_family != AF_INET)
+ continue;
+ if (ioctl(s, SIOCGIFFLAGS, (char *) ifr) < 0) {
+ ...
+ }
+ /*
+ * Skip boring cases.
+ */
+ if ((ifr->ifr_flags & IFF_UP) == 0 ||
+ (ifr->ifr_flags & IFF_LOOPBACK) ||
+ (ifr->ifr_flags & (IFF_BROADCAST | IFF_POINTTOPOINT)) == 0)
+ continue;
+.DE
+.PP
+Once the flags have been obtained, the broadcast address
+must be obtained. In the case of broadcast networks this is
+done via the SIOCGIFBRDADDR \fIioctl\fP, while for point-to-point networks
+the address of the destination host is obtained with SIOCGIFDSTADDR.
+.DS
+struct sockaddr dst;
+
+if (ifr->ifr_flags & IFF_POINTTOPOINT) {
+ if (ioctl(s, SIOCGIFDSTADDR, (char *) ifr) < 0) {
+ ...
+ }
+ bcopy((char *) ifr->ifr_dstaddr, (char *) &dst, sizeof (ifr->ifr_dstaddr));
+} else if (ifr->ifr_flags & IFF_BROADCAST) {
+ if (ioctl(s, SIOCGIFBRDADDR, (char *) ifr) < 0) {
+ ...
+ }
+ bcopy((char *) ifr->ifr_broadaddr, (char *) &dst, sizeof (ifr->ifr_broadaddr));
+}
+.DE
+.PP
+After the appropriate \fIioctl\fP's have obtained the broadcast
+or destination address (now in \fIdst\fP), the \fIsendto\fP call may be
+used:
+.DS
+ sendto(s, buf, buflen, 0, (struct sockaddr *)&dst, sizeof (dst));
+}
+.DE
+In the above loop one \fIsendto\fP occurs for every
+interface to which the host is connected that supports the notion of
+broadcast or point-to-point addressing.
+If a process only wished to send broadcast
+messages on a given network, code similar to that outlined above
+would be used, but the loop would need to find the
+correct destination address.
+.PP
+Received broadcast messages contain the senders address
+and port, as datagram sockets are bound before
+a message is allowed to go out.
+.NH 2
+IP Multicasting
+.PP
+IP multicasting is the transmission of an IP datagram to a "host
+group", a set of zero or more hosts identified by a single IP
+destination address. A multicast datagram is delivered to all
+members of its destination host group with the same "best-efforts"
+reliability as regular unicast IP datagrams, i.e., the datagram is
+not guaranteed to arrive intact at all members of the destination
+group or in the same order relative to other datagrams.
+.PP
+The membership of a host group is dynamic; that is, hosts may join
+and leave groups at any time. There is no restriction on the
+location or number of members in a host group. A host may be a
+member of more than one group at a time. A host need not be a member
+of a group to send datagrams to it.
+.PP
+A host group may be permanent or transient. A permanent group has a
+well-known, administratively assigned IP address. It is the address,
+not the membership of the group, that is permanent; at any time a
+permanent group may have any number of members, even zero. Those IP
+multicast addresses that are not reserved for permanent groups are
+available for dynamic assignment to transient groups which exist only
+as long as they have members.
+.PP
+In general, a host cannot assume that datagrams sent to any host
+group address will reach only the intended hosts, or that datagrams
+received as a member of a transient host group are intended for the
+recipient. Misdelivery must be detected at a level above IP, using
+higher-level identifiers or authentication tokens. Information
+transmitted to a host group address should be encrypted or governed
+by administrative routing controls if the sender is concerned about
+unwanted listeners.
+.PP
+IP multicasting is currently supported only on AF_INET sockets of type
+SOCK_DGRAM and SOCK_RAW, and only on subnetworks for which the interface
+driver has been modified to support multicasting.
+.PP
+The next subsections describe how to send and receive multicast datagrams.
+.NH 3
+Sending IP Multicast Datagrams
+.PP
+To send a multicast datagram, specify an IP multicast address in the range
+224.0.0.0 to 239.255.255.255 as the destination address
+in a
+.IR sendto (2)
+call.
+.PP
+The definitions required for the multicast-related socket options are
+found in \fI<netinet/in.h>\fP.
+All IP addresses are passed in network byte-order.
+.PP
+By default, IP multicast datagrams are sent with a time-to-live (TTL) of 1,
+which prevents them from being forwarded beyond a single subnetwork. A new
+socket option allows the TTL for subsequent multicast datagrams to be set to
+any value from 0 to 255, in order to control the scope of the multicasts:
+.DS
+u_char ttl;
+setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
+.DE
+Multicast datagrams with a TTL of 0 will not be transmitted on any subnet,
+but may be delivered locally if the sending host belongs to the destination
+group and if multicast loopback has not been disabled on the sending socket
+(see below). Multicast datagrams with TTL greater than one may be delivered
+to more than one subnet if there are one or more multicast routers attached
+to the first-hop subnet. To provide meaningful scope control, the multicast
+routers support the notion of TTL "thresholds", which prevent datagrams with
+less than a certain TTL from traversing certain subnets. The thresholds
+enforce the following convention:
+.TS
+center;
+l | l
+l | n.
+_
+Scope Initial TTL
+=
+restricted to the same host 0
+restricted to the same subnet 1
+restricted to the same site 32
+restricted to the same region 64
+restricted to the same continent 128
+unrestricted 255
+_
+.TE
+"Sites" and "regions" are not strictly defined, and sites may be further
+subdivided into smaller administrative units, as a local matter.
+.PP
+An application may choose an initial TTL other than the ones listed above.
+For example, an application might perform an "expanding-ring search" for a
+network resource by sending a multicast query, first with a TTL of 0, and
+then with larger and larger TTLs, until a reply is received, perhaps using
+the TTL sequence 0, 1, 2, 4, 8, 16, 32.
+.PP
+The multicast router
+.IR mrouted (8),
+refuses to forward any
+multicast datagram with a destination address between 224.0.0.0 and
+224.0.0.255, inclusive, regardless of its TTL. This range of addresses is
+reserved for the use of routing protocols and other low-level topology
+discovery or maintenance protocols, such as gateway discovery and group
+membership reporting.
+.PP
+The address 224.0.0.0 is
+guaranteed not to be assigned to any group, and 224.0.0.1 is assigned
+to the permanent group of all IP hosts (including gateways). This is
+used to address all multicast hosts on the directly connected
+network. There is no multicast address (or any other IP address) for
+all hosts on the total Internet. The addresses of other well-known,
+permanent groups are published in the "Assigned Numbers" RFC,
+which is available from the InterNIC.
+.PP
+Each multicast transmission is sent from a single network interface, even if
+the host has more than one multicast-capable interface. (If the host is
+also serving as a multicast router,
+a multicast may be \fIforwarded\fP to interfaces
+other than originating interface, provided that the TTL is greater than 1.)
+The default interface to be used for multicasting is the primary network
+interface on the system.
+A socket option
+is available to override the default for subsequent transmissions from a
+given socket:
+.DS
+struct in_addr addr;
+setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr));
+.DE
+where "addr" is the local IP address of the desired outgoing interface.
+An address of INADDR_ANY may be used to revert to the default interface.
+The local IP address of an interface can be obtained via the SIOCGIFCONF
+ioctl. To determine if an interface supports multicasting, fetch the
+interface flags via the SIOCGIFFLAGS ioctl and see if the IFF_MULTICAST
+flag is set. (Normal applications should not need to use this option; it
+is intended primarily for multicast routers and other system services
+specifically concerned with internet topology.)
+The SIOCGIFCONF and SIOCGIFFLAGS ioctls are described in the previous section.
+.PP
+If a multicast datagram is sent to a group to which the sending host itself
+belongs (on the outgoing interface), a copy of the datagram is, by default,
+looped back by the IP layer for local delivery. Another socket option gives
+the sender explicit control over whether or not subsequent datagrams are
+looped back:
+.DS
+u_char loop;
+setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
+.DE
+where \f2loop\f1 is set to 0 to disable loopback,
+and set to 1 to enable loopback.
+This option
+improves performance for applications that may have no more than one
+instance on a single host (such as a router demon), by eliminating
+the overhead of receiving their own transmissions. It should generally not
+be used by applications for which there may be more than one instance on a
+single host (such as a conferencing program) or for which the sender does
+not belong to the destination group (such as a time querying program).
+.PP
+A multicast datagram sent with an initial TTL greater than 1 may be delivered
+to the sending host on a different interface from that on which it was sent,
+if the host belongs to the destination group on that other interface. The
+loopback control option has no effect on such delivery.
+.NH 3
+Receiving IP Multicast Datagrams
+.PP
+Before a host can receive IP multicast datagrams, it must become a member
+of one or more IP multicast groups. A process can ask the host to join
+a multicast group by using the following socket option:
+.DS
+struct ip_mreq mreq;
+setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))
+.DE
+where "mreq" is the following structure:
+.DS
+struct ip_mreq {
+ struct in_addr imr_multiaddr; /* \fImulticast group to join\fP */
+ struct in_addr imr_interface; /* \fIinterface to join on\fP */
+}
+.DE
+Every membership is associated with a single interface, and it is possible
+to join the same group on more than one interface. "imr_interface" should
+be INADDR_ANY to choose the default multicast interface, or one of the
+host's local addresses to choose a particular (multicast-capable) interface.
+Up to IP_MAX_MEMBERSHIPS (currently 20) memberships may be added on a
+single socket.
+.PP
+To drop a membership, use:
+.DS
+struct ip_mreq mreq;
+setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
+.DE
+where "mreq" contains the same values as used to add the membership. The
+memberships associated with a socket are also dropped when the socket is
+closed or the process holding the socket is killed. However, more than
+one socket may claim a membership in a particular group, and the host
+will remain a member of that group until the last claim is dropped.
+.PP
+The memberships associated with a socket do not necessarily determine which
+datagrams are received on that socket. Incoming multicast packets are
+accepted by the kernel IP layer if any socket has claimed a membership in the
+destination group of the datagram; however, delivery of a multicast datagram
+to a particular socket is based on the destination port (or protocol type, for
+raw sockets), just as with unicast datagrams.
+To receive multicast datagrams
+sent to a particular port, it is necessary to bind to that local port,
+leaving the local address unspecified (i.e., INADDR_ANY).
+To receive multicast datagrams
+sent to a particular group and port, bind to the local port, with
+the local address set to the multicast group address.
+Once bound to a multicast address, the socket cannot be used for sending data.
+.PP
+More than one process may bind to the same SOCK_DGRAM UDP port
+or the same multicast group and port if the
+.I bind
+call is preceded by:
+.DS
+int on = 1;
+setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
+.DE
+All processes sharing the port must enable this option.
+Every incoming multicast or broadcast UDP datagram destined to
+the shared port is delivered to all sockets bound to the port.
+For backwards compatibility reasons, this does not apply to incoming
+unicast datagrams. Unicast
+datagrams are never delivered to more than one socket, regardless of
+how many sockets are bound to the datagram's destination port.
+.PP
+A final multicast-related extension is independent of IP: two new ioctls,
+SIOCADDMULTI and SIOCDELMULTI, are available to add or delete link-level
+(e.g., Ethernet) multicast addresses accepted by a particular interface.
+The address to be added or deleted is passed as a sockaddr structure of
+family AF_UNSPEC, within the standard ifreq structure.
+.PP
+These ioctls are
+for the use of protocols other than IP, and require superuser privileges.
+A link-level multicast address added via SIOCADDMULTI is not automatically
+deleted when the socket used to add it goes away; it must be explicitly
+deleted. It is inadvisable to delete a link-level address that may be
+in use by IP.
+.NH 3
+Sample Multicast Program
+.PP
+The following program sends or receives multicast packets.
+If invoked with one argument, it sends a packet containing the current
+time to an arbitrarily-chosen multicast group and UDP port.
+If invoked with no arguments, it receives and prints these packets.
+Start it as a sender on just one host and as a receiver on all the other hosts.
+.DS
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <time.h>
+#include <stdio.h>
+
+#define EXAMPLE_PORT 60123
+#define EXAMPLE_GROUP "224.0.0.250"
+
+main(argc)
+ int argc;
+{
+ struct sockaddr_in addr;
+ int addrlen, fd, cnt;
+ struct ip_mreq mreq;
+ char message[50];
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ bzero(&addr, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(EXAMPLE_PORT);
+ addrlen = sizeof(addr);
+
+ if (argc > 1) { /* Send */
+ addr.sin_addr.s_addr = inet_addr(EXAMPLE_GROUP);
+ while (1) {
+ time_t t = time(0);
+ sprintf(message, "time is %-24.24s", ctime(&t));
+ cnt = sendto(fd, message, sizeof(message), 0,
+ (struct sockaddr *)&addr, addrlen);
+ if (cnt < 0) {
+ perror("sendto");
+ exit(1);
+ }
+ sleep(5);
+ }
+ } else { /* Receive */
+ if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ perror("bind");
+ exit(1);
+ }
+
+ mreq.imr_multiaddr.s_addr = inet_addr(EXAMPLE_GROUP);
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+ if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &mreq, sizeof(mreq)) < 0) {
+ perror("setsockopt mreq");
+ exit(1);
+ }
+
+ while (1) {
+ cnt = recvfrom(fd, message, sizeof(message), 0,
+ (struct sockaddr *)&addr, &addrlen);
+ if (cnt <= 0) {
+ if (cnt == 0) {
+ break;
+ }
+ perror("recvfrom");
+ exit(1);
+ }
+ printf("%s: message = \e"%s\e"\en",
+ inet_ntoa(addr.sin_addr), message);
+ }
+ }
+}
+.DE
+.\"----------------------------------------------------------------------
+.NH 2
+NS Packet Sequences
+.PP
+The semantics of NS connections demand that
+the user both be able to look inside the network header associated
+with any incoming packet and be able to specify what should go
+in certain fields of an outgoing packet.
+Using different calls to \fIsetsockopt\fP, it is possible
+to indicate whether prototype headers will be associated by
+the user with each outgoing packet (SO_HEADERS_ON_OUTPUT),
+to indicate whether the headers received by the system should be
+delivered to the user (SO_HEADERS_ON_INPUT), or to indicate
+default information that should be associated with all
+outgoing packets on a given socket (SO_DEFAULT_HEADERS).
+.PP
+The contents of a SPP header (minus the IDP header) are:
+.DS
+.if t .ta \w" #define"u +\w" u_short"u +2.0i
+struct sphdr {
+ u_char sp_cc; /* connection control */
+#define SP_SP 0x80 /* system packet */
+#define SP_SA 0x40 /* send acknowledgement */
+#define SP_OB 0x20 /* attention (out of band data) */
+#define SP_EM 0x10 /* end of message */
+ u_char sp_dt; /* datastream type */
+ u_short sp_sid; /* source connection identifier */
+ u_short sp_did; /* destination connection identifier */
+ u_short sp_seq; /* sequence number */
+ u_short sp_ack; /* acknowledge number */
+ u_short sp_alo; /* allocation number */
+};
+.DE
+Here, the items of interest are the \fIdatastream type\fP and
+the \fIconnection control\fP fields. The semantics of the
+datastream type are defined by the application(s) in question;
+the value of this field is, by default, zero, but it can be
+used to indicate things such as Xerox's Bulk Data Transfer
+Protocol (in which case it is set to one). The connection control
+field is a mask of the flags defined just below it. The user may
+set or clear the end-of-message bit to indicate
+that a given message is the last of a given substream type,
+or may set/clear the attention bit as an alternate way to
+indicate that a packet should be sent out-of-band.
+As an example, to associate prototype headers with outgoing
+SPP packets, consider:
+.DS
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netns/ns.h>
+#include <netns/sp.h>
+ ...
+struct sockaddr_ns sns, to;
+int s, on = 1;
+struct databuf {
+ struct sphdr proto_spp; /* prototype header */
+ char buf[534]; /* max. possible data by Xerox std. */
+} buf;
+ ...
+s = socket(AF_NS, SOCK_SEQPACKET, 0);
+ ...
+bind(s, (struct sockaddr *) &sns, sizeof (sns));
+setsockopt(s, NSPROTO_SPP, SO_HEADERS_ON_OUTPUT, &on, sizeof(on));
+ ...
+buf.proto_spp.sp_dt = 1; /* bulk data */
+buf.proto_spp.sp_cc = SP_EM; /* end-of-message */
+strcpy(buf.buf, "hello world\en");
+sendto(s, (char *) &buf, sizeof(struct sphdr) + strlen("hello world\en"),
+ (struct sockaddr *) &to, sizeof(to));
+ ...
+.DE
+Note that one must be careful when writing headers; if the prototype
+header is not written with the data with which it is to be associated,
+the kernel will treat the first few bytes of the data as the
+header, with unpredictable results.
+To turn off the above association, and to indicate that packet
+headers received by the system should be passed up to the user,
+one might use:
+.DS
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netns/ns.h>
+#include <netns/sp.h>
+ ...
+struct sockaddr sns;
+int s, on = 1, off = 0;
+ ...
+s = socket(AF_NS, SOCK_SEQPACKET, 0);
+ ...
+bind(s, (struct sockaddr *) &sns, sizeof (sns));
+setsockopt(s, NSPROTO_SPP, SO_HEADERS_ON_OUTPUT, &off, sizeof(off));
+setsockopt(s, NSPROTO_SPP, SO_HEADERS_ON_INPUT, &on, sizeof(on));
+ ...
+.DE
+.PP
+Output is handled somewhat differently in the IDP world.
+The header of an IDP-level packet looks like:
+.DS
+.if t .ta \w'struct 'u +\w" struct ns_addr"u +2.0i
+struct idp {
+ u_short idp_sum; /* Checksum */
+ u_short idp_len; /* Length, in bytes, including header */
+ u_char idp_tc; /* Transport Control (i.e., hop count) */
+ u_char idp_pt; /* Packet Type (i.e., level 2 protocol) */
+ struct ns_addr idp_dna; /* Destination Network Address */
+ struct ns_addr idp_sna; /* Source Network Address */
+};
+.DE
+The primary field of interest in an IDP header is the \fIpacket type\fP
+field. The standard values for this field are (as defined
+in <\fInetns/ns.h\fP>):
+.DS
+.if t .ta \w" #define"u +\w" NSPROTO_ERROR"u +1.0i
+#define NSPROTO_RI 1 /* Routing Information */
+#define NSPROTO_ECHO 2 /* Echo Protocol */
+#define NSPROTO_ERROR 3 /* Error Protocol */
+#define NSPROTO_PE 4 /* Packet Exchange */
+#define NSPROTO_SPP 5 /* Sequenced Packet */
+.DE
+For SPP connections, the contents of this field are
+automatically set to NSPROTO_SPP; for IDP packets,
+this value defaults to zero, which means ``unknown''.
+.PP
+Setting the value of that field with SO_DEFAULT_HEADERS is
+easy:
+.DS
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netns/ns.h>
+#include <netns/idp.h>
+ ...
+struct sockaddr sns;
+struct idp proto_idp; /* prototype header */
+int s, on = 1;
+ ...
+s = socket(AF_NS, SOCK_DGRAM, 0);
+ ...
+bind(s, (struct sockaddr *) &sns, sizeof (sns));
+proto_idp.idp_pt = NSPROTO_PE; /* packet exchange */
+setsockopt(s, NSPROTO_IDP, SO_DEFAULT_HEADERS, (char *) &proto_idp,
+ sizeof(proto_idp));
+ ...
+.DE
+.PP
+Using SO_HEADERS_ON_OUTPUT is somewhat more difficult. When
+SO_HEADERS_ON_OUTPUT is turned on for an IDP socket, the socket
+becomes (for all intents and purposes) a raw socket. In this
+case, all the fields of the prototype header (except the
+length and checksum fields, which are computed by the kernel)
+must be filled in correctly in order for the socket to send and
+receive data in a sensible manner. To be more specific, the
+source address must be set to that of the host sending the
+data; the destination address must be set to that of the
+host for whom the data is intended; the packet type must be
+set to whatever value is desired; and the hopcount must be
+set to some reasonable value (almost always zero). It should
+also be noted that simply sending data using \fIwrite\fP
+will not work unless a \fIconnect\fP or \fIsendto\fP call
+is used, in spite of the fact that it is the destination
+address in the prototype header that is used, not the one
+given in either of those calls. For almost
+all IDP applications , using SO_DEFAULT_HEADERS is easier and
+more desirable than writing headers.
+.NH 2
+Three-way Handshake
+.PP
+The semantics of SPP connections indicates that a three-way
+handshake, involving changes in the datastream type, should \(em
+but is not absolutely required to \(em take place before a SPP
+connection is closed. Almost all SPP connections are
+``well-behaved'' in this manner; when communicating with
+any process, it is best to assume that the three-way handshake
+is required unless it is known for certain that it is not
+required. In a three-way close, the closing process
+indicates that it wishes to close the connection by sending
+a zero-length packet with end-of-message set and with
+datastream type 254. The other side of the connection
+indicates that it is OK to close by sending a zero-length
+packet with end-of-message set and datastream type 255. Finally,
+the closing process replies with a zero-length packet with
+substream type 255; at this point, the connection is considered
+closed. The following code fragments are simplified examples
+of how one might handle this three-way handshake at the user
+level; in the future, support for this type of close will
+probably be provided as part of the C library or as part of
+the kernel. The first code fragment below illustrates how a process
+might handle three-way handshake if it sees that the process it
+is communicating with wants to close the connection:
+.DS
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netns/ns.h>
+#include <netns/sp.h>
+ ...
+#ifndef SPPSST_END
+#define SPPSST_END 254
+#define SPPSST_ENDREPLY 255
+#endif
+struct sphdr proto_sp;
+int s;
+ ...
+read(s, buf, BUFSIZE);
+if (((struct sphdr *)buf)->sp_dt == SPPSST_END) {
+ /*
+ * SPPSST_END indicates that the other side wants to
+ * close.
+ */
+ proto_sp.sp_dt = SPPSST_ENDREPLY;
+ proto_sp.sp_cc = SP_EM;
+ setsockopt(s, NSPROTO_SPP, SO_DEFAULT_HEADERS, (char *)&proto_sp,
+ sizeof(proto_sp));
+ write(s, buf, 0);
+ /*
+ * Write a zero-length packet with datastream type = SPPSST_ENDREPLY
+ * to indicate that the close is OK with us. The packet that we
+ * don't see (because we don't look for it) is another packet
+ * from the other side of the connection, with SPPSST_ENDREPLY
+ * on it it, too. Once that packet is sent, the connection is
+ * considered closed; note that we really ought to retransmit
+ * the close for some time if we do not get a reply.
+ */
+ close(s);
+}
+ ...
+.DE
+To indicate to another process that we would like to close the
+connection, the following code would suffice:
+.DS
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netns/ns.h>
+#include <netns/sp.h>
+ ...
+#ifndef SPPSST_END
+#define SPPSST_END 254
+#define SPPSST_ENDREPLY 255
+#endif
+struct sphdr proto_sp;
+int s;
+ ...
+proto_sp.sp_dt = SPPSST_END;
+proto_sp.sp_cc = SP_EM;
+setsockopt(s, NSPROTO_SPP, SO_DEFAULT_HEADERS, (char *)&proto_sp,
+ sizeof(proto_sp));
+write(s, buf, 0); /* send the end request */
+proto_sp.sp_dt = SPPSST_ENDREPLY;
+setsockopt(s, NSPROTO_SPP, SO_DEFAULT_HEADERS, (char *)&proto_sp,
+ sizeof(proto_sp));
+/*
+ * We assume (perhaps unwisely)
+ * that the other side will send the
+ * ENDREPLY, so we'll just send our final ENDREPLY
+ * as if we'd seen theirs already.
+ */
+write(s, buf, 0);
+close(s);
+ ...
+.DE
+.NH 2
+Packet Exchange
+.PP
+The Xerox standard protocols include a protocol that is both
+reliable and datagram-oriented. This protocol is known as
+Packet Exchange (PEX or PE) and, like SPP, is layered on top
+of IDP. PEX is important for a number of things: Courier
+remote procedure calls may be expedited through the use
+of PEX, and many Xerox servers are located by doing a PEX
+``BroadcastForServers'' operation. Although there is no
+implementation of PEX in the kernel,
+it may be simulated at the user level with some clever coding
+and the use of one peculiar \fIgetsockopt\fP. A PEX packet
+looks like:
+.DS
+.if t .ta \w'struct 'u +\w" struct idp"u +2.0i
+/*
+ * The packet-exchange header shown here is not defined
+ * as part of any of the system include files.
+ */
+struct pex {
+ struct idp p_idp; /* idp header */
+ u_short ph_id[2]; /* unique transaction ID for pex */
+ u_short ph_client; /* client type field for pex */
+};
+.DE
+The \fIph_id\fP field is used to hold a ``unique id'' that
+is used in duplicate suppression; the \fIph_client\fP
+field indicates the PEX client type (similar to the packet
+type field in the IDP header). PEX reliability stems from the
+fact that it is an idempotent (``I send a packet to you, you
+send a packet to me'') protocol. Processes on each side of
+the connection may use the unique id to determine if they have
+seen a given packet before (the unique id field differs on each
+packet sent) so that duplicates may be detected, and to indicate
+which message a given packet is in response to. If a packet with
+a given unique id is sent and no response is received in a given
+amount of time, the packet is retransmitted until it is decided
+that no response will ever be received. To simulate PEX, one
+must be able to generate unique ids -- something that is hard to
+do at the user level with any real guarantee that the id is really
+unique. Therefore, a means (via \fIgetsockopt\fP) has been provided
+for getting unique ids from the kernel. The following code fragment
+indicates how to get a unique id:
+.DS
+long uniqueid;
+int s, idsize = sizeof(uniqueid);
+ ...
+s = socket(AF_NS, SOCK_DGRAM, 0);
+ ...
+/* get id from the kernel -- only on IDP sockets */
+getsockopt(s, NSPROTO_PE, SO_SEQNO, (char *)&uniqueid, &idsize);
+ ...
+.DE
+The retransmission and duplicate suppression code required to
+simulate PEX fully is left as an exercise for the reader.
+.NH 2
+Inetd
+.PP
+One of the daemons provided with 4.4BSD is \fIinetd\fP, the
+so called ``internet super-server.''
+Having one daemon listen for requests for many daemons
+instead of having each daemon listen for its own requests
+reduces the number of idle daemons and simplies their implementation.
+.I Inetd
+handles
+two types of services: standard and TCPMUX.
+A standard service has a well-known port assigned to it and
+is listed in
+.I /etc/services
+(see \f2services\f1(5));
+it may be a service that implements an official Internet standard or is a
+BSD-specific service.
+TCPMUX services are nonstandard and do not have a
+well-known port assigned to them.
+They are invoked from
+.I inetd
+when a program connects to the "tcpmux" well-known port and specifies
+the service name.
+This is useful for adding locally-developed servers.
+.PP
+\fIInetd\fP is invoked at boot
+time, and determines from the file \fI/etc/inetd.conf\fP the
+servers for which it is to listen. Once this information has been
+read and a pristine environment created, \fIinetd\fP proceeds
+to create one socket for each service it is to listen for,
+binding the appropriate port number to each socket.
+.PP
+\fIInetd\fP then performs a \fIselect\fP on all these
+sockets for read availability, waiting for somebody wishing
+a connection to the service corresponding to
+that socket. \fIInetd\fP then performs an \fIaccept\fP on
+the socket in question, \fIfork\fPs, \fIdup\fPs the new
+socket to file descriptors 0 and 1 (stdin and
+stdout), closes other open file
+descriptors, and \fIexec\fPs the appropriate server.
+.PP
+Servers making use of \fIinetd\fP are considerably simplified,
+as \fIinetd\fP takes care of the majority of the IPC work
+required in establishing a connection. The server invoked
+by \fIinetd\fP expects the socket connected to its client
+on file descriptors 0 and 1, and may immediately perform
+any operations such as \fIread\fP, \fIwrite\fP, \fIsend\fP,
+or \fIrecv\fP. Indeed, servers may use
+buffered I/O as provided by the ``stdio'' conventions, as
+long as as they remember to use \fIfflush\fP when appropriate.
+.PP
+One call which may be of interest to individuals writing
+servers under \fIinetd\fP is the \fIgetpeername\fP call,
+which returns the address of the peer (process) connected
+on the other end of the socket. For example, to log the
+Internet address in ``dot notation'' (e.g., ``128.32.0.4'')
+of a client connected to a server under
+\fIinetd\fP, the following code might be used:
+.DS
+struct sockaddr_in name;
+int namelen = sizeof (name);
+ ...
+if (getpeername(0, (struct sockaddr *)&name, &namelen) < 0) {
+ syslog(LOG_ERR, "getpeername: %m");
+ exit(1);
+} else
+ syslog(LOG_INFO, "Connection from %s", inet_ntoa(name.sin_addr));
+ ...
+.DE
+While the \fIgetpeername\fP call is especially useful when
+writing programs to run with \fIinetd\fP, it can be used
+under other circumstances. Be warned, however, that \fIgetpeername\fP will
+fail on UNIX domain sockets.
+.PP
+Standard TCP
+services are assigned unique well-known port numbers in the range of
+0 to 1023 by the
+Internet Assigned Numbers Authority (IANA@ISI.EDU).
+The limited number of ports in this range are
+assigned to official Internet protocols.
+The TCPMUX service allows you to add
+locally-developed protocols without needing an official TCP port assignment.
+The TCPMUX protocol described in RFC-1078 is simple:
+.QP
+``A TCP client connects to a foreign host on TCP port 1. It sends the
+service name followed by a carriage-return line-feed <CRLF>.
+The service name is never case sensitive.
+The server replies with a
+single character indicating positive ("+") or negative ("\-")
+acknowledgment, immediately followed by an optional message of
+explanation, terminated with a <CRLF>. If the reply was positive,
+the selected protocol begins; otherwise the connection is closed.''
+.LP
+In 4.4BSD, the TCPMUX service is built into
+.IR inetd ,
+that is,
+.IR inetd
+listens on TCP port 1 for requests for TCPMUX services listed
+in \f2inetd.conf\f1.
+.IR inetd (8)
+describes the format of TCPMUX entries for \f2inetd.conf\f1.
+.PP
+The following is an example TCPMUX server and its \f2inetd.conf\f1 entry.
+More sophisticated servers may want to do additional processing
+before returning the positive or negative acknowledgement.
+.DS
+#include <sys/types.h>
+#include <stdio.h>
+
+main()
+{
+ time_t t;
+
+ printf("+Go\er\en");
+ fflush(stdout);
+ time(&t);
+ printf("%d = %s", t, ctime(&t));
+ fflush(stdout);
+}
+.DE
+The \f2inetd.conf\f1 entry is:
+.DS
+tcpmux/current_time stream tcp nowait nobody /d/curtime curtime
+.DE
+Here's the portion of the client code that handles the TCPMUX handshake:
+.DS
+char line[BUFSIZ];
+FILE *fp;
+ ...
+
+/* Use stdio for reading data from the server */
+fp = fdopen(sock, "r");
+if (fp == NULL) {
+ fprintf(stderr, "Can't create file pointer\en");
+ exit(1);
+}
+
+/* Send service request */
+sprintf(line, "%s\er\en", "current_time");
+if (write(sock, line, strlen(line)) < 0) {
+ perror("write");
+ exit(1);
+}
+
+/* Get ACK/NAK response from the server */
+if (fgets(line, sizeof(line), fp) == NULL) {
+ if (feof(fp)) {
+ die();
+ } else {
+ fprintf(stderr, "Error reading response\en");
+ exit(1);
+ }
+}
+
+/* Delete <CR> */
+if ((lp = index(line, '\r')) != NULL) {
+ *lp = '\0';
+}
+
+switch (line[0]) {
+ case '+':
+ printf("Got ACK: %s\en", &line[1]);
+ break;
+ case '-':
+ printf("Got NAK: %s\en", &line[1]);
+ exit(0);
+ default:
+ printf("Got unknown response: %s\en", line);
+ exit(1);
+}
+
+/* Get rest of data from the server */
+while ((fgets(line, sizeof(line), fp)) != NULL) {
+ fputs(line, stdout);
+}
+.DE
diff --git a/share/doc/psd/21.ipc/Makefile b/share/doc/psd/21.ipc/Makefile
new file mode 100644
index 00000000000..2a366be9fbb
--- /dev/null
+++ b/share/doc/psd/21.ipc/Makefile
@@ -0,0 +1,10 @@
+# @(#)Makefile 8.1 (Berkeley) 6/8/93
+
+DIR= psd/21.ipc
+SRCS= 0.t 1.t 2.t 3.t 4.t 5.t
+MACROS= -ms
+
+paper.ps: ${SRCS}
+ ${TBL} ${SRCS} | ${ROFF} > ${.TARGET}
+
+.include <bsd.doc.mk>
diff --git a/share/doc/psd/21.ipc/spell.ok b/share/doc/psd/21.ipc/spell.ok
new file mode 100644
index 00000000000..02b45d4d26d
--- /dev/null
+++ b/share/doc/psd/21.ipc/spell.ok
@@ -0,0 +1,347 @@
+4.2bsd
+AF
+ANYP
+BUFSIZ
+BUFSIZE
+BroadcastForServers
+CF
+CLR
+CRMOD
+Clearinghouse
+DARPA
+DESTPORT
+DGRAM
+DONTROUTE
+Datagram
+EADDRINUSE
+EADDRNOTAVAIL
+EAGAIN
+ECONNREFUSED
+EHOSTDOWN
+EHOSTUNREACH
+EINTR
+ENDREPLY
+ENETDOWN
+ENETUNREACH
+ENOBUFS
+EPROTONOSUPPORT
+EPROTOTYPE
+ETIMEDOUT
+EWOULDBLOCK
+Ethernet
+FASYNC
+FCREATE
+FD
+FNDELAY
+FTP
+FTRUNCATE
+FWRITE
+FWRONLY
+Fabry
+GETOWN
+Gethostybyname
+IDP
+IFF
+IFNAMSIZ
+INADDR
+INET
+INFO
+IP
+IPC
+IPPORT
+ISSET
+Inetd
+LF
+LH
+LOOPBACK
+Lapsley
+Leffler
+MSG
+MYADDRESS
+MYPORT
+NS
+NSPROTO
+OB
+OOB
+OOBINLINE
+Optlen
+Optval
+PE
+PEX
+POINTTOPOINT
+PS1:8
+RDONLY
+RDWR
+REUSEADDR
+RF
+RH
+RWHODIR
+SEQNO
+SEQPACKET
+SETFL
+SETOWN
+SETSIZE
+SIGALRM
+SIGCHLD
+SIGIO
+SIGURG
+SIOCATMARK
+SIOCGIFBRDADDR
+SIOCGIFCONF
+SIOCGIFDSTADDR
+SIOCGIFFLAGS
+SIOCGPGRP
+SIOCSPGRP
+SOF
+SP
+SPP
+SPPSST
+Science:UofMaryland
+TCP
+TELNET
+TIOCFLUSH
+TIOCGETP
+TIOCNOTTY
+TIOCSETP
+TRUNC
+Torek
+Tutorial''PS1:8
+USERRESERVED
+VAX
+WNOHANG
+WRONLY
+XSIS
+XTABS
+ack
+addr
+addr.s
+addr.sa
+addr.sun
+addr.x
+addrtype
+alo
+argc
+argv
+arpa
+b.sg
+bcmp
+bcopy
+broadaddr
+buf
+buf.buf
+buf.proto
+buflen
+bzero
+c.f
+cad
+caddr
+calder
+daemons
+dali
+databuf
+datagram
+datastream
+dev
+dna
+doit
+dst
+dst.sin
+dst.sns
+dstaddr
+dt
+dup2
+en0
+endhostent
+endif
+ernie
+errno
+es
+esvax
+exceptmask
+execptfds
+fcntl
+fcntl.h
+fd
+fflush
+file.h
+foo
+fprintf
+from.sin
+fromlen
+gethostbyaddr
+gethostbyname
+gethostbynameandnet
+gethostent
+gethostname
+getnetbyname
+getnetbynumber
+getnetent
+getpeername
+getprotobyname
+getprotobynumber
+getprotoent
+getservbyname
+getservbyport
+getservent
+getsockopt
+goto
+gotpty
+gyre
+gyre:Computer
+hardcoding
+hopcount
+host.c
+hostent
+hostname
+hostnames
+hosts.equiv
+htonl
+htons
+idp
+idp.h
+idp.idp
+idsize
+if.h
+ifc
+ifc.ifc
+ifconf
+ifcu
+ifcu.ifcu
+ifndef
+ifr
+ifreq
+ifru
+ifru.ifru
+in.h
+inet
+inetd
+inetd.conf
+ing
+ingres
+io
+ioctl.h
+ipc
+kim
+len
+localnet
+lport
+lq
+makeaddr
+matisse
+medea
+miro
+monet
+name.sin
+namelen
+nameserver
+nb
+netdb.h
+netent
+netinet
+netns
+netnum
+netof
+newsock
+newtcp
+nfds
+ns
+ns.h
+ntoa
+ntohl
+ntohs
+onalrm
+oob
+optlen
+optname
+optval
+oz
+pathname
+pathnames
+pex
+pgrp
+ph
+pp
+proto
+protoent
+pt
+pty
+ptyXX
+ptyp
+ptyxy
+queueing
+readfds
+readmask
+recv
+recvfrom
+recvtime
+rem
+req
+rhosts
+rlogin
+rlogind
+rq
+rresvport
+ruptime
+rwho
+rwhod
+sendto
+servent
+server.sin
+server.sun
+sethostent
+setsockopt
+sid
+sigvec
+sin.sin
+sizeof
+sna
+snew
+sns
+sns.sns
+sockaddr
+socket.h
+sp
+sp.h
+sp.sp
+sphdr
+spp
+spp.sp
+sprintf
+statbuf
+statvax
+std
+stderr
+stdin
+stdio.h
+stdout
+strcmp
+strcpy
+strlen
+syslog
+ta
+tcp
+telnet
+time.h
+timeval
+tmp
+tolen
+ttyxy
+tuples
+types.h
+ucbvax
+udp
+un
+un.h
+uniqueid
+useable
+usec
+val
+wait.h
+wait.tv
+wd
+wd.wd
+whod
+wildcard
+wildcarded
+writefds
+writemask
diff --git a/share/doc/psd/Makefile b/share/doc/psd/Makefile
new file mode 100644
index 00000000000..eb5be4921d7
--- /dev/null
+++ b/share/doc/psd/Makefile
@@ -0,0 +1,36 @@
+# @(#)Makefile 8.1 (Berkeley) 6/8/93
+
+# The following modules do not build/install:
+# 10.gdb, 13.rcs
+
+# Missing:
+# 07.pascal 14.sccs 17.m4
+
+# Missing from 4.4BSD-Lite:
+# 01.cacm 02.implement 03.iosys 04.uprog 06.Clang 08.f77 09.f77io
+# 11.adb 15.yacc 16.lex
+
+BINDIR= /usr/share/doc/psd
+FILES= 00.contents Makefile Title
+SUBDIR= 05.sysman 20.ipctut 21.ipc
+.if exists(12.make)
+SUBDIR+= 12.make
+.endif
+.if exists(18.gprof)
+SUBDIR+= 18.gprof
+.endif
+.if exists(19.curses)
+SUBDIR+= 19.curses
+.endif
+
+Title.ps: ${FILES}
+ groff Title > ${.TARGET}
+
+contents.ps: ${FILES}
+ groff -ms 00.contents > ${.TARGET}
+
+beforeinstall:
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${FILES} \
+ ${DESTDIR}${BINDIR}
+
+.include <bsd.subdir.mk>
diff --git a/share/doc/psd/Title b/share/doc/psd/Title
new file mode 100644
index 00000000000..2ec146c51c6
--- /dev/null
+++ b/share/doc/psd/Title
@@ -0,0 +1,131 @@
+.\" Copyright (c) 1986, 1993 The Regents of the University of California.
+.\" 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 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.
+.\"
+.\" @(#)Title 8.2 (Berkeley) 4/19/94
+.\"
+.ps 18
+.vs 22
+.sp 2.75i
+.ft B
+.ce 3
+UNIX Programmer's Supplementary Documents
+(PSD)
+.ps 14
+.vs 16
+.sp |4i
+.ce 2
+4.4 Berkeley Software Distribution
+.sp |5.75i
+.ft R
+.pt 12
+.vs 16
+.ce
+June, 1993
+.sp |8.2i
+.ce 5
+Computer Systems Research Group
+Computer Science Division
+Department of Electrical Engineering and Computer Science
+University of California
+Berkeley, California 94720
+.bp
+\&
+.sp |1i
+.hy 0
+.ps 10
+.vs 12p
+Copyright 1979, 1980, 1983, 1986, 1993
+The Regents of the University of California. All rights reserved.
+.sp 2
+Other than the specific documents listed below as copyrighted by AT&T,
+redistribution and use of this manual in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+.sp 0.5
+.in +0.2i
+.ta 0.2i
+.ti -0.2i
+1) Redistributions of this manual must retain the copyright
+notices on this page, this list of conditions and the following disclaimer.
+.ti -0.2i
+2) Software or documentation that incorporates part of this manual must
+reproduce the copyright notices on this page, this list of conditions and
+the following disclaimer in the documentation and/or other materials
+provided with the distribution.
+.ti -0.2i
+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.''
+.ti -0.2i
+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.
+.in -0.2i
+.sp
+\fB\s-1THIS 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.\s+1\fP
+.sp 2
+Documents PSD:1, 2, 3, 4, 6, 11, 15, 16, and 17
+are copyright 1979, AT&T Bell Laboratories, Incorporated.
+Document PSD:8 is a modification of an earlier document that
+is copyrighted 1979 by AT&T Bell Laboratories, Incorporated.
+Holders of \x'-1p'UNIX\v'-4p'\s-3TM\s0\v'4p'/32V,
+System III, or System V software licenses are
+permitted to copy these documents, or any portion of them,
+as necessary for licensed use of the software,
+provided this copyright notice and statement of permission
+are included.
+.sp 2
+Document PSD:10 is part of the user contributed software and is
+copyright 1992 by the Free Software Foundation, Inc.
+Permission is granted to make and distribute verbatim copies of
+this document provided the copyright notice and this permission notice
+are preserved on all copies.
+.sp 2
+Document PSD:13 is part of the user contributed software and is
+copyright 1983 by Walter F. Tichy.
+Permission to copy the RCS documentation or any portion thereof as
+necessary for licensed use of the software is granted to licensees
+of this software, provided this copyright notice is included.
+.sp 2
+The views and conclusions contained in this manual are those of the
+authors and should not be interpreted as representing official policies,
+either expressed or implied, of the Regents of the University of California.