|Author:||W. Richard Stevens|
|Publisher:||Addison Wesley Longman Inc.|
The Migration of a DOS programmer to Linux
This article describes the beginnings of one programmer's migration from DOS to Linux. The article focuses on an actual project which runs under DOS and on a book dealing with Unix that made the programmer believe he could make a Linux port of the project.
In 1992 I wrote a large program designed to work with the real-time, stock market data feed provided by Data Broadcasting Corp. The program is interactive, and it allows a user to display and print (in both textural and graphical modes) current and historical data about stocks, options, and market indices. That is what the user running the program sees, but in the background the program is: receiving serial data (which comes via satellite to a `black box' provided by DBC which connects to a PC's serial port); breaking that data into transactions; storing the transactions in a database; and feeding the transactions as necessary to the display module based on what the user is asking the program to do. I did this in DOS using Watcom's 32-bit compiler and utilize most of the 16 megabytes DOS can address.
Within a few years I began to find DOS's 16 MB limit restraining and so began to look for a new environment in which to work. About the same time I received a sample copy of the Linux Journal. That particular issue (#14, June 1995) had on its cover the words `Intelligent Serial Boards'. They caught my eye. By then I had upgraded my program to work with a Digiboard, and I knew one requirement for a migration to a new OS would include being able to use it or another intelligent board. So, I subscribed to the LJ and began to look for books relating to Linux / Unix.
When I began programming in the early 80's, I learned Basic and Fortran by reading what I call `no-name' books. By that I mean there was nothing memorable about either the books or their authors' style. By contrast I learned Cobol from McCracken and C from Kernighan & Ritchie. Anyone familiar with either book will recognize the difference between those books and `no-name' ones. I realized that if I hoped to port my DOS application to Linux, I needed to find a books which would do for Unix what K&R's book does for C.
In the second half of 1995 and the first part of 1996 I kept running into references to Advanced Programming in the UNIX® Environment by W. Richard Stevens. So, in the Spring of 1996 I ordered the book, and it has turned out to be everything I had hopped it might be.
It is a big book: over 2 inches thick and over 750 pages in length. It is hard cover, and it lies open flat. It is an attractive book: both its cover and the general layout of its pages. In the preface Stevens says he used troff and groff to format and prepare the camera-ready copy for the book. As one who has prepared copy for more than one book, I know that an attractive book does not just happen. It takes expertise and time, and Stevens' effort makes the reader's journey through the book more enjoyable.
The book discusses over 220 functions used by various Unix libraries. When a function is introduced, it is placed in a box together with system include files required by the function, information about what the function returns, and a function prototype. The book has over 10,000 lines of source code (all in C), and it is filled with numerous small program examples. The code is available by ftp and was tested by Stevens on 4 `flavors' of Unix. The book has numerous tables which group together flags of a particular type or other information. It has numerous figures which show the relationships of items under discussion. Where appropriate it includes the output from an example and uses it to clarify or emphasize an item under discussion. It does these things within the context of several variants of Unix (described below). Where necessary a topic is described for each variant. Under a lessor writer the encyclopedic detail would become suffocating, but Stevens surrounds all of the above items with enough text to make a very readable book and an extremely valuable reference.
In the preface Stevens breaks the book into 6 parts and briefly describes each part. The following is a slightly different breakdown with longer descriptions.
1. 160 pages, chapters 1-6. The first two chapters provide a gentle introduction to Unix and a discussion of the variants of Unix described in the book. They are: SVR4 which dates to 1990; 4.3+BSD which refers to the state of BSD in early 1992; and POSIX.1 which dates to 1990. The remaining four chapters in this part (over 100 pages) discuss files, directories, access permissions, inodes, file I/O, and special files such as the password file. This material duplicates chapter 8 (The Unix System Interface) in K&R, but it goes into much more detail and discusses many more topics than K&R does.
2. 100 pages, chapters 7-9. These chapters deal with processes. Topics discussed include: what happens when a process starts and when it stops; how to access program arguments and environment variables; memory allocation; process resource limits; process creation via forks and execs; process IDs and other properties; the relationship between a parent and a child process; and more.
3. 150 pages, chapters 10-12. At this stage we are about one third of the way through the book, and the going has not been too rough. That changes with this part. Chapter 10 deals with signals, chapter 11 with terminal I/O and chapter 12 with advanced terminal I/O. Once Stevens describes each of the (over 30) signals available, he shows how signals in early versions of Unix were unreliable. Then, he describes functions introduced with POSIX.1 which make signals safe to use. Fortunately, these POSIX safe functions are available in Linux. His treatment of terminal I/O begins with an examination of the termios structure which holds over 50 special flags (or switches), characters that are given special treatment during input, and baud rates. He shows how to get and save these values. He describes canonical (i.e. line oriented) and noncanonical I/O. Again, I find his discussion highly applicable to Linux. Chapter 12 deals with various additions to the I/O system discussed in part 1 and chapter 11. Some of the topics included are: nonblocking I/O, record locking, streams, multiplexing (via select or poll), asynchronous I/O, and memory mapped I/O. The select function is available in Linux, but I don't believe all of these topics are. Yet!
4. 100 pages, chapters 13-15. Chapter 13 is a short chapter dealing with daemon processes. Chapters 14 and 15 deal with interprocess communication. That discussion begins with pipes, and winds up 80 pages later with two examples of sets of functions used in client-server programs. Stevens treated part of chapter 15 in much more detail in his 1990 book: UNIX Network Programming.
5. 115 pages, chapters 16-18. At this stage we are only two thirds through the book, and the `advanced' in the title is beginning to show (to this DOS programmer). Each of the chapters in this part is devoted to developing a single program or library: a database program, a PostScript printer program, and a modem dialer. I spent several days studying the printer program and learned how the logging facility used by the kernel and several daemons works.
6. 120 pages, 1 chapter, 3 appendices, bibliography and index. Chapter 19 deals with pseudo terminals. Appendix A is very valuable and provides a 20-page summary of all the functions introduced in the book. The material is arranged alphabetically and includes: a function prototype, return values, required system include functions, and a reference to the page which introduces the function. Appendix B provides source code used by many examples in the book. Appendix C provides solutions to some of the exercises which end each chapter. The index runs 25 pages and is quite complete.
When I finish a book, I have several criteria for deciding if I can recommend it. Where does it now live: on my desk, in a pile of books near my desk, or on a distant shelf? Was the book interesting in a general sort of way or did it change the way I think or act? Stevens' book lives on my desk often open to a particular spot. Also, it has given me many ideas I am using in the port of my stock program to Linux. Three examples are: serial I/O, coordinating multiple workers, error messages.
Chapter 11 made it relatively painless for me to get both standard serial ports and my Digiboard working under Linux. Chapter 10 gave me the idea of adding Unix signals and timers to the central work loop my DOS program uses. This will allow me to use the same program structure the DOS program uses. In addition it will allow the program to sleep when it has no work to do and to be awakened when it does. Thus, it will be Linux `friendly'. Chapters 13 and 17 together with Appendix B showed me how to log errors to a special file. Using a single line, my program can call a function which writes to standard error, a program specific log file or both. The call uses a printf() format which allows a variable number of arguments, and it can either end the program or return to the calling function.
I have felt for many years that programming and construction are related. Migrating from DOS programming to Linux is like moving from wood-frame house construction to the construction of sky scrappers using concrete, steel, and glass. Such a transition requires understanding new materials and how they interact. That is precisely what Stevens' book provides. He describes basic library calls, uses them in small code segments, and pieces them together in several larger projects. I heartily recommend his book and hope your mileage with it is as good as mine is.
David Bausum received a Ph.D. in mathematics from Yale in 1974. Since the early 80's most of his energy has gone into software development and related activities. He coedited The Journal of Military History Cumulative Index: Vols 1-58, 1937-1994.
Bibliography (not included in typeset version)
Kernigham, B. W., and Ritchie, D. M. 1988. The C Programming Language, Second Edition. Prentice-Hall, Englewood Cliffs, NJ.
McCracken, Daniel D. 1976. A Simplified Guide to Structured Cobol Programming. John Wiley & Sons, Inc. New York.
Stevens, W. Richard. 1992. Advanced Programming in the UNIX® Environment. Addison-Wesley Publishing Company, Inc., Reading, Massachusetts.
Stevens, W. Richard. 1990. UNIX Network Programming. Prentice-Hall, Englewood Cliffs, NJ. (Since the review Stevens has come out with a new version of this book.)