UNIX Systems Programming for SVR4 By David A Curry O'Reilly & Associates, July 1996 xxi + 596 pages, 24.50 UKP ISBN: 1-56592-163-1 This book aims to teach the reader how to write systems programs in C for UNIX SVR4 (System V Release 4). In sixteen chapters and five appendices of clearly written prose, it manages to achieve this. It is not aimed at the novice programmer (it is assumed the reader is familiar with C programming and UNIX), and so jumps fairly quickly into the meaty stuff. All of the examples in the book are written in ANSI C. The book focuses on three major variants of SVR4: HP-UX 10.0; Silicon Graphics' IRIX 5.3; and Sun's Solaris 2.x. Solaris is covered up to 2.5, so the book is very up to date. Chapter one contains the almost obligatory UNIX history lesson, with some nice notes on SVR4's standards compliance (eg ANSI, POSIX, and XPG/3). The rest of the chapter describes the various compilers used to test the source code, and for completeness' sake, outlines the BSD compatibility package. Chapter two describes what the author calls 'utility routines'. Topics dealt with in this chapter include character and byte string manipulation (the str* and mem* functions prototyped in string.h); dynamic memory (the malloc family, and free); temporary files; and parsing command line arguments. Each section (in this and subsequent chapters) describes what the group of functions does, often with a code example, and usually ends in a very handy 'Porting Notes' subsection. The latter is invaluable for highlighting the subtle differences in implementation between the various flavours of SVR4, and also offers help to those porting old BSD-style programs. The chapter ends with a description of a few miscellaneous routines that didn't fit into one of the other categories: string to number conversion; printing error messages; pausing a program; and exiting. In chapters three and four, the author discusses the low level I/O functions and the standard I/O library. In the (fairly short) first of these, the low level I/O functions (ie, those that take a file descriptor as an argument) are described. These include open; close; read; write; lseek; and the file descriptor duplication functions, dup and dup2. Rather more space is devoted to chapter four, which deals with the standard I/O library. This contains the routines prototyped in stdio.h, and the functions typically take a file pointer as an argument. Also covered is line input and output (with a strong warning against using gets, which I was pleased to see); buffered and formatted I/O; and file pointer repositioning. Chapter five talks about files and directories. It starts off with a brief overview of filesystem concepts, before focusing on SVR4's idea of a filesystem (ie regular and special files, and directories). Next is a section called Removable Filesystems; I believe this is a bit of a misnomer, and perhaps the section should have been called 'Mountable Filesystems': to me, removable implies the media can (easily) be removed from the machine, for example CD-ROMs. The concept of the inode is introduced, and other file types (eg hard and soft links; FIFOs; and UNIX domain sockets) are described. Next, the stat family are presented, followed by (amongst others) access; chmod; and the chown family. Creating and deleting directories are then covered, as is the concept of a working directory, and the directory manipulation functions prototyped in dirent.h. The chapter concludes with an ls-like program, which brings together most of the concepts discussed. In chapter six, special purpose file operations are covered. It kicks off with a discussion of file descriptor attributes, and how to get/set them with ioctl and fcntl. In the next section, managing multiple file descriptors with select and poll are discussed. This is followed by sections on file and record locking, and memory mapped files. The /dev/fd filesystem is given a brief once-over, and the chapter concludes with a quick look at the umask, chroot, and sync functions. Chapter seven talks about the time of day functions, starting with obtaining the current time and timezone, and progresses through converting the machine time to a human readable format, and vice versa. Chapter eight takes a comprehensive look at users and groups. It starts by explaining the difference between login names and user ids, and covers the concepts of real and effective user and group ids. The passwd, group, shadow, utmp[x], wtmp[x], lastlog and shells files are then discussed, as are the functions that manipulate them. The chapter ends with a useful recipe on how to write SUID (set user id) and SGID (set group id) programs, adapted from Matt Bishop's paper, 'How To Write a Setuid Program'. System configuration and resource limits are covered in chapter nine, which starts off with a discussion about the utsname and sysinfo functions. This is followed by a description of sysconf et al, before the process resource limits and resource utilisation functions wrap up the chapter. Chapter ten discusses signals, going from their concepts, to advanced signal concepts, covering topics such as basic signal handling; reliable and unreliable signals; signals and system calls; and using signals for timeouts. The chapter ends with section on porting BSD signals to SVR4. Chapter eleven discusses processes at some length. After covering the concepts, eg PIDs (process IDs), process groups, and controlling terminals, process termination and simple process execution (ie using system (3)) is covered. An in-depth look at fork and exec follows. A look at I/O redirection, job control, and timing process execution concludes the chapter. In chapter twelve, POSIX and pre-POSIX terminal control is discussed; the pre-POSIX discussion is further sub-divided into System V and BSD styles. The chapter ends by discussing terminal window size. IPC (interprocess communication) is the subject matter for chapter thirteen - from pipes to semaphore protected shared memory. FIFOs, message queues, and UNIX domain sockets are also discussed, although the latter is just a primer; the more advanced material is covered in chapters fourteen and fifteen. Chapters fourteen and fifteen cover networking with sockets and TLI (transport layer interface) respectively. Not being a networking book, the details are glossed over somewhat (even though the chapters comprise seventy pages between them). Instead, the reader is pointed at the acknowledged references in the area: Rich Steven's 'UNIX Network Programming' (for sockets), and Steve Rago's 'UNIX System V Network Programming' (for TLI). The final chapter discusses everything that doesn't fit into one of the preceding chapters! Topics include error logging; searching; passwords; database management; regular expressions, etc. With the exception of appendix A (which outlines the changes in ANSI cf K&R C), the appendices cover some of the more esoteric subjects. Appendix B talks about accessing filesystem data structures (concentrating on Solaris 2.x, as the functions differ from one implementation to another). Appendix C covers the /proc filesystem, while appendix D describes pseudo-terminals. The last appendix briefly discusses accessing the network at the link level. A comprehensive index completes the book. I suppose the potential purchaser of this book will be comparing it to Rich Stevens' tome, 'Advanced Programming in the UNIX Environment'. My opinion is that the books complement each other nicely. Certainly, Stevens' book is four years older (it isn't SVR4 specific), and so may seem a bit dated in places, but on the other hand, it does cover some material not in UNIX Systems Programming, most notably, daemons: I was quite disappointed not to see even an appendix on such an important topic. It would have been nice if the book had a lay flat binding, but apart from a couple of minor typos (and mixed case identifiers - ugh!), it is refreshingly easy (for a reference book) to read. Thoroughly recommended, and a welcome addition to my bookshelf. Reviewer's bio: Richard Teer runs his own C/UNIX consultancy, Risc Key Developments Ltd. He is currently working in the OS Group at SunService in Camberley, and can be reached at richard.teer@rkdltd.demon.co.uk, or on the web at www.rkdltd.demon.co.uk.