0% found this document useful (0 votes)
6 views

Systems Programming In Unixlinux Kc Wang pdf download

The document is an overview of the book 'Systems Programming in Unix/Linux' by K.C. Wang, which serves as a textbook for teaching systems programming. It emphasizes the importance of systems programming in computer science education, providing students with essential skills for advanced studies and practical programming projects. The book includes detailed examples and source code, making it suitable for both classroom use and self-study.

Uploaded by

rhyceweegebp
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Systems Programming In Unixlinux Kc Wang pdf download

The document is an overview of the book 'Systems Programming in Unix/Linux' by K.C. Wang, which serves as a textbook for teaching systems programming. It emphasizes the importance of systems programming in computer science education, providing students with essential skills for advanced studies and practical programming projects. The book includes detailed examples and source code, making it suitable for both classroom use and self-study.

Uploaded by

rhyceweegebp
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 66

Systems Programming In Unixlinux Kc Wang

download

https://ebookbell.com/product/systems-programming-in-unixlinux-
kc-wang-49158110

Explore and download more ebooks at ebookbell.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Practical System Programming With C Pragmatic Example Applications In


Linux And Unixbased Operating Systems 1st Ed Sri Manikanta Palakollu

https://ebookbell.com/product/practical-system-programming-with-c-
pragmatic-example-applications-in-linux-and-unixbased-operating-
systems-1st-ed-sri-manikanta-palakollu-30719010

Practical System Programming With C Pragmatic Example Applications In


Linux And Unixbased Operating Systems 1st Edition Sri Manikanta
Palakollu

https://ebookbell.com/product/practical-system-programming-with-c-
pragmatic-example-applications-in-linux-and-unixbased-operating-
systems-1st-edition-sri-manikanta-palakollu-34873360

Programming In C Unix System Calls And Subroutines Using C A D


Marshall

https://ebookbell.com/product/programming-in-c-unix-system-calls-and-
subroutines-using-c-a-d-marshall-2444736

Integer Linear Programming In Computational And Systems Biology An


Entrylevel Text And Course Dan Gusfield

https://ebookbell.com/product/integer-linear-programming-in-
computational-and-systems-biology-an-entrylevel-text-and-course-dan-
gusfield-11022832
Handson Reactive Programming In Spring 5 Build Cloudready Reactive
Systems With Spring 5 And Project Reactor Dokuka

https://ebookbell.com/product/handson-reactive-programming-in-
spring-5-build-cloudready-reactive-systems-with-spring-5-and-project-
reactor-dokuka-38234934

C How To Program With Case Studies In Applications And Systems


Programming 9 Global Paul Deitel Harvey Deitel

https://ebookbell.com/product/c-how-to-program-with-case-studies-in-
applications-and-systems-programming-9-global-paul-deitel-harvey-
deitel-43761396

Go In 24 Hours Sams Teach Yourself Next Generation Systems Programming


With Golang 1st Edition Ornbo

https://ebookbell.com/product/go-in-24-hours-sams-teach-yourself-next-
generation-systems-programming-with-golang-1st-edition-ornbo-23264456

Survey Of Methodologies Approaches And Challenges In Parallel


Programming Using Highperformance Computing Systems Pawe Czarnul

https://ebookbell.com/product/survey-of-methodologies-approaches-and-
challenges-in-parallel-programming-using-highperformance-computing-
systems-pawe-czarnul-10718998

Programming Languages And Systems In Computational Economics And


Finance 2002th Edition Jaime R Marquez

https://ebookbell.com/product/programming-languages-and-systems-in-
computational-economics-and-finance-2002th-edition-jaime-r-
marquez-54965484
K.C. Wang

Systems
Programming
in Unix/Linux
Systems Programming in Unix/Linux
K. C. Wang

Systems Programming
in Unix/Linux
K. C. Wang
School of Electrical Engineering
Washington State University
Pullman, WA, USA

ISBN 978-3-319-92428-1 ISBN 978-3-319-92429-8 (eBook)


https://doi.org/10.1007/978-3-319-92429-8

Library of Congress Control Number: 2018945425

# Springer International Publishing AG, part of Springer Nature 2018


This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or
part of the material is concerned, specifically the rights of translation, reprinting, reuse of
illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way,
and transmission or information storage and retrieval, electronic adaptation, computer software, or
by similar or dissimilar methodology now known or hereafter developed.
The use of general descriptive names, registered names, trademarks, service marks, etc. in this
publication does not imply, even in the absence of a specific statement, that such names are
exempt from the relevant protective laws and regulations and therefore free for general use.
The publisher, the authors, and the editors are safe to assume that the advice and information in
this book are believed to be true and accurate at the date of publication. Neither the publisher nor
the authors or the editors give a warranty, express or implied, with respect to the material
contained herein or for any errors or omissions that may have been made. The publisher
remains neutral with regard to jurisdictional claims in published maps and institutional affiliations.

This Springer imprint is published by the registered company Springer Nature Switzerland AG
The registered company address is: Gewerbestrasse 11, 6330 Cham, Switzerland
Dedicated to
Cindy
Preface

Systems programming is an indispensable part of Computer Science and


Computer Engineering education. System programming courses in Computer
Science/Engineering curriculums play two important roles. First, it provides
students with a wide range of knowledge about computer system software and
advanced programming skills, allowing them to interface with operating
system kernel, perform file operations and network programming, and make
efficient use of system resources to develop application programs. Second, it
prepares students with needed background to pursue advanced studies in
Computer Science/Engineering, such as operating systems, embedded
systems, database systems, data mining, artificial intelligence, computer
networks, and distributed and parallel computing. Due to its importance,
systems programming in Unix/Linux has been a popular subject matter in
CS/CE education and also for self-study by advanced programmers. As a
result, there are a tremendous number of books and online articles in this area.
Despite these, I still find it difficult to choose a suitable book for the Systems
Programming course I teach at WSU. For many years, I had to use my own
class notes and programming assignments in the course. After careful think-
ing, I have decided to put together the materials into a book form.
The purpose of this book is to provide a suitable platform for teaching and
learning the theory and practice of systems programming. Unlike most other
books, this book covers systems programming topics in greater depth and
it stresses programming practice. It uses a series of programming projects to
let students apply their acquired knowledge and programming skills to
develop practical and useful programs. The book is intended as a textbook
in technical-oriented systems programming courses. It contains detailed
example programs with complete source code, making it suitable for self-
study also.
Undertaking this book project has proved to be another very demanding
and time-consuming endeavor. While preparing the manuscripts for publica-
tion, I have been blessed with the encouragement and help from many people.
I would like to take this opportunity to thank all of them. I want to especially
thank Yan Zhang for his help in preparing figures for the book and proof-
reading the manuscript.

vii
viii Preface

Special thanks go to Cindy for her continuing support and inspirations,


which have made this book possible. Above all, I would like to thank my
family for bearing with me with endless excuses of being busy all the time.
Sample solutions of programming projects in the book are available for
download at http://wang.eecs.wsu.edu/~kcw. For source code, please contact
the author by email.

Pullman, WA, USA K. C. Wang


April, 2018
Contents

1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 About This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Roles of Systems Programming . . . . . . . . . . . . . . . . . . . 1
1.3 Objectives of This Book . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.1 Strengthen Students Programming
Background . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.2 Applications of Dynamic Data Structures . . . . 2
1.3.3 Process Concept and Process
Management . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.4 Concurrent Programming . . . . . . . . . . . . . . . . 3
1.3.5 Timer and Time Functions . . . . . . . . . . . . . . . 3
1.3.6 Signals, Signal Processing and IPC . . . . . . . . . 3
1.3.7 File system . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3.8 TCP/IP and Network Programming . . . . . . . . . 4
1.4 Intended Audience . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5 Unique Features of This Book . . . . . . . . . . . . . . . . . . . 4
1.6 Use This Book As Textbook in Systems
Programming Courses . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.7 Other Reference Books . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.8 Introduction to Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.8.1 AT&T Unix . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.8.2 Berkeley Unix . . . . . . . . . . . . . . . . . . . . . . . . 8
1.8.3 HP Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.8.4 IBM Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.8.5 Sun Unix . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.9 Introduction to Linux . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.10 Linux Versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.10.1 Debian Linux . . . . . . . . . . . . . . . . . . . . . . . . 9
1.10.2 Ubuntu Linux . . . . . . . . . . . . . . . . . . . . . . . . 9
1.10.3 Linux Mint . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.10.4 RPM-Based Linux . . . . . . . . . . . . . . . . . . . . . 10
1.10.5 Slackware Linux . . . . . . . . . . . . . . . . . . . . . . 10
1.11 Linux Hardware Platforms . . . . . . . . . . . . . . . . . . . . . . 10

ix
x Contents

1.12 Linux on Virtual Machines . . . . . . . . . . . . . . . . . . . . . . 10


1.12.1 VirtualBox . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.12.2 VMware . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.12.3 Dual Boot Slackware and Ubuntu Linux . . . . . 14
1.13 Use Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.13.1 Linux kernel image . . . . . . . . . . . . . . . . . . . . 15
1.13.2 Linux Booters . . . . . . . . . . . . . . . . . . . . . . . . 15
1.13.3 Linux Booting . . . . . . . . . . . . . . . . . . . . . . . . 15
1.13.4 Linux Run-levels . . . . . . . . . . . . . . . . . . . . . . 16
1.13.5 Login Process . . . . . . . . . . . . . . . . . . . . . . . . 16
1.13.6 Command Executions . . . . . . . . . . . . . . . . . . 16
1.14 Use Ubuntu Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.14.1 Ubuntu Versions . . . . . . . . . . . . . . . . . . . . . . 16
1.14.2 Special Features of Ubuntu Linux . . . . . . . . . . 17
1.15 Unix/Linux File System Organization . . . . . . . . . . . . . . 18
1.15.1 File Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.15.2 File Pathnames . . . . . . . . . . . . . . . . . . . . . . . 19
1.15.3 Unix/Linux Commands . . . . . . . . . . . . . . . . . 19
1.15.4 Linux Man Pages . . . . . . . . . . . . . . . . . . . . . 19
1.16 Ubuntu Linux System Administration . . . . . . . . . . . . . . 20
1.16.1 User Accounts . . . . . . . . . . . . . . . . . . . . . . . . 20
1.16.2 Add New User . . . . . . . . . . . . . . . . . . . . . . . 20
1.16.3 The sudo Command . . . . . . . . . . . . . . . . . . . . 21
1.17 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2 Programming Background . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.1 Text Editors in Linux . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.1.1 Vim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.1.2 Gedit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.1.3 Emacs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.2 Use Text Editors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.2.1 Use Emacs . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.2.2 Emacs Menus . . . . . . . . . . . . . . . . . . . . . . . . 26
2.2.3 IDE of Emacs . . . . . . . . . . . . . . . . . . . . . . . . 26
2.3 Program Development . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.3.1 Program Development Steps . . . . . . . . . . . . . 27
2.3.2 Variables in C . . . . . . . . . . . . . . . . . . . . . . . . 27
2.3.3 Compile-Link in GCC . . . . . . . . . . . . . . . . . . 28
2.3.4 Static vs. Dynamic Linking . . . . . . . . . . . . . . 29
2.3.5 Executable File Format . . . . . . . . . . . . . . . . . 30
2.3.6 Contents of a.out File . . . . . . . . . . . . . . . . . . . 30
2.3.7 Program Execution . . . . . . . . . . . . . . . . . . . . 31
2.3.8 Program Termination . . . . . . . . . . . . . . . . . . . 32
2.4 Function Call in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.4.1 Run-Time Stack Usage in 32-Bit GCC . . . . . . 33
2.4.2 Stack Frames . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.4.3 Return From Function Call . . . . . . . . . . . . . . . 35
Contents xi

2.4.4 Long Jump . . . . . . . . . . . . . . . . . . . . . . . . . . 36


2.4.5 Run-Time Stack Usage in 64-Bit GCC . . . . . . 37
2.5 Link C Program with Assembly Code . . . . . . . . . . . . . . 40
2.5.1 Programming in Assembly . . . . . . . . . . . . . . . 41
2.5.2 Implement Functions in Assembly . . . . . . . . . 43
2.5.3 Call C functions from Assembly . . . . . . . . . . . 44
2.6 Link Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
2.6.1 Static Link Library . . . . . . . . . . . . . . . . . . . . 45
2.6.2 Dynamic Link Library . . . . . . . . . . . . . . . . . . 46
2.7 Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
2.7.1 Makefile Format . . . . . . . . . . . . . . . . . . . . . . 46
2.7.2 The make Program . . . . . . . . . . . . . . . . . . . . 46
2.7.3 Makefile Examples . . . . . . . . . . . . . . . . . . . . 47
2.8 The GDB Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
2.8.1 Use GDB in Emacs IDE . . . . . . . . . . . . . . . . 53
2.8.2 Advices on Using Debugging Tools . . . . . . . . 58
2.8.3 Common Errors in C programs . . . . . . . . . . . . 58
2.9 Structures in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
2.9.1 Structure and Pointers . . . . . . . . . . . . . . . . . . 64
2.9.2 Typecast in C . . . . . . . . . . . . . . . . . . . . . . . . 64
2.10 Link List Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
2.10.1 Link Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
2.10.2 Link List Operations . . . . . . . . . . . . . . . . . . . 66
2.10.3 Build Link List . . . . . . . . . . . . . . . . . . . . . . . 67
2.10.4 Link List Traversal . . . . . . . . . . . . . . . . . . . . 70
2.10.5 Search Link List . . . . . . . . . . . . . . . . . . . . . . 72
2.10.6 Insert Operation . . . . . . . . . . . . . . . . . . . . . . . 72
2.10.7 Priority Queue . . . . . . . . . . . . . . . . . . . . . . . . 73
2.10.8 Delete Operation . . . . . . . . . . . . . . . . . . . . . . 74
2.10.9 Circular Link List . . . . . . . . . . . . . . . . . . . . . 75
2.10.10 Open-Ended C Structures . . . . . . . . . . . . . . . . 75
2.10.11 Doubly Link Lists . . . . . . . . . . . . . . . . . . . . . 76
2.10.12 Doubly Link Lists Example Programs . . . . . . . 76
2.11 Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
2.12 Binary Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
2.12.1 Binary Search Tree . . . . . . . . . . . . . . . . . . . . 85
2.12.2 Build a Binary Search Tree (BST) . . . . . . . . . 86
2.12.3 Binary Tree Traversal Algorithms . . . . . . . . . . 87
2.12.4 Depth-First Traversal Algorithms . . . . . . . . . . 87
2.12.5 Breadth-First Traversal Algorithms . . . . . . . . . 88
2.13 Programming Project: Unix/Linux File System
Tree Simulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
2.13.1 Unix/Linux File System Tree . . . . . . . . . . . . . 90
2.13.2 Implement General Tree by Binary Tree . . . . . 90
2.13.3 Project Specification and Requirements . . . . . . 90
2.13.4 Commands Specification . . . . . . . . . . . . . . . . 91
2.13.5 Program Organization . . . . . . . . . . . . . . . . . . 91
xii Contents

2.13.6 Command Algorithms . . . . . . . . . . . . . . . . . . 94


2.13.7 Sample Solution . . . . . . . . . . . . . . . . . . . . . . 97
2.14 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
3 Process Management in Unix/Linux . . . . . . . . . . . . . . . . . . . . 101
3.1 Multitasking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
3.2 The Process Concept . . . . . . . . . . . . . . . . . . . . . . . . . . 102
3.3 A Multitasking System . . . . . . . . . . . . . . . . . . . . . . . . . 103
3.3.1 type.h file . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
3.3.2 The ts.s file . . . . . . . . . . . . . . . . . . . . . . . . . . 103
3.3.3 The queue.c file . . . . . . . . . . . . . . . . . . . . . . . 104
3.3.4 The t.c file . . . . . . . . . . . . . . . . . . . . . . . . . . 105
3.3.5 Explanations of the Multitasking
System Code . . . . . . . . . . . . . . . . . . . . . . . . . 108
3.4 Process Synchronization . . . . . . . . . . . . . . . . . . . . . . . . 111
3.4.1 Sleep Operation . . . . . . . . . . . . . . . . . . . . . . . 111
3.4.2 Wakeup Operation . . . . . . . . . . . . . . . . . . . . . 112
3.5 Process Termination . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
3.5.1 Algorithm of kexit() . . . . . . . . . . . . . . . . . . . . 112
3.5.2 Process Family Tree . . . . . . . . . . . . . . . . . . . 113
3.5.3 Wait for Child Process Termination . . . . . . . . 114
3.6 Process Management in the MT Multitasking
System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
3.7 Processes in Unix/Linux . . . . . . . . . . . . . . . . . . . . . . . . 115
3.7.1 Process Origin . . . . . . . . . . . . . . . . . . . . . . . . 115
3.7.2 INIT and Daemon Processes . . . . . . . . . . . . . 116
3.7.3 Login Processes . . . . . . . . . . . . . . . . . . . . . . 117
3.7.4 Sh Process . . . . . . . . . . . . . . . . . . . . . . . . . . 117
3.7.5 Process Execution Modes . . . . . . . . . . . . . . . . 117
3.8 System Calls for Process Management . . . . . . . . . . . . . . 118
3.8.1 fork() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
3.8.2 Process Execution Order . . . . . . . . . . . . . . . . 120
3.8.3 Process Termination . . . . . . . . . . . . . . . . . . . 121
3.8.4 Wait for Child Process Termination . . . . . . . . 122
3.8.5 Subreaper Process in Linux . . . . . . . . . . . . . . 123
3.8.6 exec(): Change Process Execution Image . . . . 125
3.8.7 Environment Variables . . . . . . . . . . . . . . . . . . 126
3.9 I/O Redirection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
3.9.1 FILE Streams and File Descriptors . . . . . . . . . 129
3.9.2 FILE Stream I/O and System Call . . . . . . . . . . 130
3.9.3 Redirect stdin . . . . . . . . . . . . . . . . . . . . . . . . 130
3.9.4 Redirect stdout . . . . . . . . . . . . . . . . . . . . . . . 131
3.10 Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
3.10.1 Pipe Programming in Unix/Linux . . . . . . . . . . 131
3.10.2 Pipe Command Processing . . . . . . . . . . . . . . . 134
3.10.3 Connect PIPE writer to PIPE reader . . . . . . . . 134
3.10.4 Named pipes . . . . . . . . . . . . . . . . . . . . . . . . . 135
Contents xiii

3.11 Programming Project: sh Simulator . . . . . . . . . . . . . . . . 137


3.11.1 Single Command with I/O Redirection . . . . . . 137
3.11.2 Commands with Pipes . . . . . . . . . . . . . . . . . . 138
3.11.3 ELF executable vs. sh script files . . . . . . . . . . 138
3.11.4 Sample Solution . . . . . . . . . . . . . . . . . . . . . . 138
3.12 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
4 Concurrent Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
4.1 Introduction to Parallel Computing . . . . . . . . . . . . . . . . 141
4.1.1 Sequential Algorithms vs. Parallel
Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . 142
4.1.2 Parallelism vs. Concurrency . . . . . . . . . . . . . . 142
4.2 Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
4.2.1 Principle of Threads . . . . . . . . . . . . . . . . . . . . 143
4.2.2 Advantages of Threads . . . . . . . . . . . . . . . . . 143
4.2.3 Disadvantages of Threads . . . . . . . . . . . . . . . 144
4.3 Threads Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
4.4 Threads Management Functions . . . . . . . . . . . . . . . . . . 144
4.4.1 Create Thread . . . . . . . . . . . . . . . . . . . . . . . . 145
4.4.2 Thread ID . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
4.4.3 Thread Termination . . . . . . . . . . . . . . . . . . . . 146
4.4.4 Thread Join . . . . . . . . . . . . . . . . . . . . . . . . . . 146
4.5 Threads Example Programs . . . . . . . . . . . . . . . . . . . . . 147
4.5.1 Sum of Matrix by Threads . . . . . . . . . . . . . . . 147
4.5.2 Quicksort by Threads . . . . . . . . . . . . . . . . . . . 148
4.6 Threads Synchronization . . . . . . . . . . . . . . . . . . . . . . . 151
4.6.1 Mutex Locks . . . . . . . . . . . . . . . . . . . . . . . . . 151
4.6.2 Deadlock Prevention . . . . . . . . . . . . . . . . . . . 154
4.6.3 Condition Variables . . . . . . . . . . . . . . . . . . . . 155
4.6.4 Producer-Consumer Problem . . . . . . . . . . . . . 156
4.6.5 Semaphores . . . . . . . . . . . . . . . . . . . . . . . . . 159
4.6.6 Barriers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
4.6.7 Solve System of Linear Equations by
Concurrent Threads . . . . . . . . . . . . . . . . . . . . 161
4.6.8 Threads in Linux . . . . . . . . . . . . . . . . . . . . . . 165
4.7 Programming Project: User-Level Threads . . . . . . . . . . . 165
4.7.1 Project Base Code: A Multitasking System . . . 165
4.7.2 User-Level Threads . . . . . . . . . . . . . . . . . . . . 169
4.7.3 Implementation of Thread Join Operation . . . . 172
4.7.4 Implementation of Mutex Operations . . . . . . . 176
4.7.5 Test Project with Mutex by Concurrent
Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
4.7.6 Implementation of Semaphores . . . . . . . . . . . . 181
4.7.7 Producer-Consumer Problem using
Semaphores . . . . . . . . . . . . . . . . . . . . . . . . . 181
4.8 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
xiv Contents

5 Timers and Time Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187


5.1 Hardware Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
5.2 PC Timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
5.3 CPU Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
5.4 Interrupt Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
5.5 Time Service Functions . . . . . . . . . . . . . . . . . . . . . . . . 189
5.5.1 Gettimeofday-Settimeofday . . . . . . . . . . . . . . 189
5.5.2 The Time System Call . . . . . . . . . . . . . . . . . . 191
5.5.3 The Times System Call . . . . . . . . . . . . . . . . . 191
5.5.4 Time and Date Commands . . . . . . . . . . . . . . . 192
5.6 Interval Timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
5.7 REAL Mode Interval Timer . . . . . . . . . . . . . . . . . . . . . 195
5.8 Programming Project . . . . . . . . . . . . . . . . . . . . . . . . . . 195
5.8.1 System Base Code . . . . . . . . . . . . . . . . . . . . . 195
5.8.2 Timer Interrupts . . . . . . . . . . . . . . . . . . . . . . 199
5.8.3 Timer Queue . . . . . . . . . . . . . . . . . . . . . . . . . 200
5.8.4 Critical Regions . . . . . . . . . . . . . . . . . . . . . . . 202
5.8.5 Advanced Topics . . . . . . . . . . . . . . . . . . . . . . 203
5.9 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
6 Signals and Signal Processing . . . . . . . . . . . . . . . . . . . . . . . . . 205
6.1 Signals and Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . 205
6.2 Examples of Unix/Linux Signals . . . . . . . . . . . . . . . . . . 207
6.3 Signal Processing in Unix/Linux . . . . . . . . . . . . . . . . . . 208
6.3.1 Signal Types . . . . . . . . . . . . . . . . . . . . . . . . . 208
6.3.2 Origin of Signals . . . . . . . . . . . . . . . . . . . . . . 209
6.3.3 Signals in Process PROC Structure: . . . . . . . . 209
6.3.4 Signal Handlers . . . . . . . . . . . . . . . . . . . . . . . 209
6.3.5 Install Signal Catchers . . . . . . . . . . . . . . . . . . 210
6.4 Signal Processing Steps . . . . . . . . . . . . . . . . . . . . . . . . 212
6.5 Signals and Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . 213
6.6 Signals as IPC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
6.7 IPC in Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
6.7.1 Pipes and FIFOs . . . . . . . . . . . . . . . . . . . . . . 215
6.7.2 Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
6.7.3 System V IPC . . . . . . . . . . . . . . . . . . . . . . . . 215
6.7.4 POSIX Message Queues . . . . . . . . . . . . . . . . 216
6.7.5 Threads Synchronization Mechanisms . . . . . . . 216
6.7.6 Sockets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
6.8 Programming Project: Implement an IPC
for Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
6.9 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
7 File Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
7.1 File Operation Levels . . . . . . . . . . . . . . . . . . . . . . . . . . 221
7.2 File I/O Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Contents xv

7.3 Low Level File Operations . . . . . . . . . . . . . . . . . . . . . . 226


7.3.1 Partitions . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
7.3.2 Format Partitions . . . . . . . . . . . . . . . . . . . . . . 229
7.3.3 Mount Partitions . . . . . . . . . . . . . . . . . . . . . . 230
7.4 Introduction to EXT2 File System . . . . . . . . . . . . . . . . . 231
7.4.1 EXT2 File System Data Structures . . . . . . . . . 231
7.4.2 Superblock . . . . . . . . . . . . . . . . . . . . . . . . . . 231
7.4.3 Group Descriptor . . . . . . . . . . . . . . . . . . . . . . 232
7.4.4 Bitmaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
7.4.5 Inodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
7.4.6 Directory Entries . . . . . . . . . . . . . . . . . . . . . . 234
7.5 Programming Examples . . . . . . . . . . . . . . . . . . . . . . . . 235
7.5.1 Display Superblock . . . . . . . . . . . . . . . . . . . . 235
7.5.2 Display Bitmaps . . . . . . . . . . . . . . . . . . . . . . 237
7.5.3 Display root Inode . . . . . . . . . . . . . . . . . . . . . 239
7.5.4 Display Directory Entries . . . . . . . . . . . . . . . . 241
7.6 Programming Project: Convert File Pathname to Inode . . 243
7.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
8 System Calls for File Operations . . . . . . . . . . . . . . . . . . . . . . 245
8.1 Systems Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
8.2 System Call Man Pages . . . . . . . . . . . . . . . . . . . . . . . . 245
8.3 System Calls for File Operations . . . . . . . . . . . . . . . . . . 246
8.4 Commonly used system Calls . . . . . . . . . . . . . . . . . . . . 248
8.5 Link Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
8.5.1 Hard Link Files . . . . . . . . . . . . . . . . . . . . . . . 250
8.5.2 Symbolic Link Files . . . . . . . . . . . . . . . . . . . 250
8.6 The stat Systen Call . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
8.6.1 Stat File Status . . . . . . . . . . . . . . . . . . . . . . . 251
8.6.2 The stat Structure . . . . . . . . . . . . . . . . . . . . . 252
8.6.3 Stat and File Inode . . . . . . . . . . . . . . . . . . . . 253
8.6.4 File Type and Permissions . . . . . . . . . . . . . . . 254
8.6.5 Opendir-Readdir Functions . . . . . . . . . . . . . . 255
8.6.6 Readlink Function . . . . . . . . . . . . . . . . . . . . . 256
8.6.7 The ls Program . . . . . . . . . . . . . . . . . . . . . . . 256
8.7 open-close-lseek System Calls . . . . . . . . . . . . . . . . . . . 258
8.7.1 Open File and File Descriptor . . . . . . . . . . . . . 258
8.7.2 Close File Descriptor . . . . . . . . . . . . . . . . . . . 259
8.7.3 lseek File Descriptor . . . . . . . . . . . . . . . . . . . 259
8.8 Read() System Call . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
8.9 Write() System Call . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
8.10 File Operation Example Programs . . . . . . . . . . . . . . . . . 260
8.10.1 Display File Contents . . . . . . . . . . . . . . . . . . 260
8.10.2 Copy Files . . . . . . . . . . . . . . . . . . . . . . . . . . 261
8.10.3 Selective File Copy . . . . . . . . . . . . . . . . . . . . 262
8.11 Programming Project: Recursive Copy Files
using System Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
xvi Contents

8.11.1 Hints and Helps . . . . . . . . . . . . . . . . . . . . . . . 264


8.11.2 Sample Solution . . . . . . . . . . . . . . . . . . . . . . 264
8.12 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
9 Library I/O Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
9.1 Library I/O Functions . . . . . . . . . . . . . . . . . . . . . . . . . . 267
9.2 Library I/O Functions vs. System Calls . . . . . . . . . . . . . 267
9.3 Algorithms of Library I/O Functions . . . . . . . . . . . . . . . 271
9.3.1 Algorithm of fread . . . . . . . . . . . . . . . . . . . . . 271
9.3.2 Algorithm of fwrite . . . . . . . . . . . . . . . . . . . . 271
9.3.3 Algorithm of fclose . . . . . . . . . . . . . . . . . . . . 271
9.4 Use Library I/O Function or System Call . . . . . . . . . . . . 272
9.5 Library I/O Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
9.5.1 Char Mode I/O . . . . . . . . . . . . . . . . . . . . . . . 272
9.5.2 Line mode I/O . . . . . . . . . . . . . . . . . . . . . . . . 273
9.5.3 Formatted I/O . . . . . . . . . . . . . . . . . . . . . . . . 274
9.5.4 In-memory Conversion Functions . . . . . . . . . . 274
9.5.5 Other Library I/O Functions . . . . . . . . . . . . . . 274
9.5.6 Restriction on Mixed fread-fwrite . . . . . . . . . . 275
9.6 File Stream Buffering . . . . . . . . . . . . . . . . . . . . . . . . . . 275
9.7 Functions with Varying Parameters . . . . . . . . . . . . . . . . 276
9.8 Programming Project: Printf-like Function . . . . . . . . . . . 277
9.8.1 Project Specification . . . . . . . . . . . . . . . . . . . 278
9.8.2 Base Code of Project . . . . . . . . . . . . . . . . . . . 278
9.8.3 Algorithm of myprintf() . . . . . . . . . . . . . . . . . 279
9.8.4 Project Refinements . . . . . . . . . . . . . . . . . . . . 279
9.8.5 Project Demonstration and Sample
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
9.9 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
10 Sh Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
10.1 sh Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
10.2 sh Scripts vs. C Programs . . . . . . . . . . . . . . . . . . . . . . . 284
10.3 Command-line parameters . . . . . . . . . . . . . . . . . . . . . . 284
10.4 Sh Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
10.5 Quotes in sh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
10.6 sh Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
10.7 sh Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
10.7.1 Built-in Commands . . . . . . . . . . . . . . . . . . . . 286
10.7.2 Linux Commands . . . . . . . . . . . . . . . . . . . . . 287
10.8 Command Substitution . . . . . . . . . . . . . . . . . . . . . . . . . 288
10.9 Sh Control Statements . . . . . . . . . . . . . . . . . . . . . . . . . 288
10.9.1 if-else-fi statement . . . . . . . . . . . . . . . . . . . . . 288
10.9.2 for Statement . . . . . . . . . . . . . . . . . . . . . . . . . 290
10.9.3 while Statement . . . . . . . . . . . . . . . . . . . . . . . 291
10.9.4 until-do Statement . . . . . . . . . . . . . . . . . . . . . 291
Contents xvii

10.9.5 case Statement . . . . . . . . . . . . . . . . . . . . . . . . 292


10.9.6 continue and break Statements . . . . . . . . . . . . 292
10.10 I/O Redirection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
10.11 Here Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
10.12 sh Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
10.13 Wild Cards in sh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
10.14 Command Grouping . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
10.15 eval Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
10.16 Debugging sh Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . 296
10.17 Applications of sh scripts . . . . . . . . . . . . . . . . . . . . . . . 296
10.18 Programming Project: Recursive File Copy
by sh Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
10.19 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
11 EXT2 File System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
11.1 EXT2 File System . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
11.2 EXT2 File System Data Structures . . . . . . . . . . . . . . . . 302
11.2.1 Create Virtual Disk by mkfs . . . . . . . . . . . . . . 302
11.2.2 Virtual Disk Layout . . . . . . . . . . . . . . . . . . . . 302
11.2.3 Superblock . . . . . . . . . . . . . . . . . . . . . . . . . . 302
11.2.4 Group Descriptors . . . . . . . . . . . . . . . . . . . . . 303
11.2.5 Block and Inode Bitmaps . . . . . . . . . . . . . . . . 304
11.2.6 Inodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
11.2.7 Data Blocks . . . . . . . . . . . . . . . . . . . . . . . . . 305
11.2.8 Directory Entries . . . . . . . . . . . . . . . . . . . . . . 305
11.3 Mailman’s Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . 306
11.3.1 Test-Set-Clear Bits in C . . . . . . . . . . . . . . . . . 306
11.3.2 Convert INODE Number to INODE
on Disk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
11.4 Programming Examples . . . . . . . . . . . . . . . . . . . . . . . . 307
11.4.1 Display Superblock . . . . . . . . . . . . . . . . . . . . 308
11.4.2 Display Bitmaps . . . . . . . . . . . . . . . . . . . . . . 310
11.4.3 Display Root Inode . . . . . . . . . . . . . . . . . . . . 312
11.4.4 Display Directory Entries . . . . . . . . . . . . . . . . 313
11.5 Traverse EXT2 File System Tree . . . . . . . . . . . . . . . . . 315
11.5.1 Traversal Algorithm . . . . . . . . . . . . . . . . . . . . 315
11.5.2 Convert Pathname to INODE . . . . . . . . . . . . . 317
11.5.3 Display INODE Disk Blocks . . . . . . . . . . . . . 317
11.6 Implementation of EXT2 File System . . . . . . . . . . . . . . 317
11.6.1 File System Organization . . . . . . . . . . . . . . . . 317
11.6.2 Files System Levels . . . . . . . . . . . . . . . . . . . . 318
11.7 Base File System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
11.7.1 type.h file . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
11.7.2 Utility Functions . . . . . . . . . . . . . . . . . . . . . . 323
11.7.3 Mount-Root . . . . . . . . . . . . . . . . . . . . . . . . . 327
11.7.4 Implementation of Base File System . . . . . . . . 331
xviii Contents

11.8 File System Level-1 Functions . . . . . . . . . . . . . . . . . . . 332


11.8.1 Algorithm of mkdir . . . . . . . . . . . . . . . . . . . . 332
11.8.2 Algorithm of creat . . . . . . . . . . . . . . . . . . . . . 336
11.8.3 Implementation of mkdir-creat . . . . . . . . . . . . 336
11.8.4 Algorithm of rmdir . . . . . . . . . . . . . . . . . . . . 337
11.8.5 Implementation of rmdir . . . . . . . . . . . . . . . . 340
11.8.6 Algorithm of link . . . . . . . . . . . . . . . . . . . . . 340
11.8.7 Algorithm of unlink . . . . . . . . . . . . . . . . . . . . 342
11.8.8 Algorithm of symlink . . . . . . . . . . . . . . . . . . 343
11.8.9 Algorithm of readlink . . . . . . . . . . . . . . . . . . 343
11.8.10 Other Level-1 Functions . . . . . . . . . . . . . . . . 343
11.8.11 Programming Project #1: Implementation
of File System Level-1 . . . . . . . . . . . . . . . . . . 344
11.9 File System Level-2 Functions . . . . . . . . . . . . . . . . . . . 344
11.9.1 Algorithm of open . . . . . . . . . . . . . . . . . . . . . 345
11.9.2 lseek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
11.9.3 Algorithm of close . . . . . . . . . . . . . . . . . . . . . 346
11.9.4 Read Regular Files . . . . . . . . . . . . . . . . . . . . 346
11.9.5 Write Regular Files . . . . . . . . . . . . . . . . . . . . 348
11.9.6 Opendir-Readdir . . . . . . . . . . . . . . . . . . . . . . 350
11.9.7 Programming Project #2: Implementation
of File System Level-2 . . . . . . . . . . . . . . . . . . 350
11.10 File System Level-3 . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
11.10.1 Algorithm of mount . . . . . . . . . . . . . . . . . . . . 351
11.10.2 Algorithm of umount . . . . . . . . . . . . . . . . . . . 352
11.10.3 Cross Mounting Points . . . . . . . . . . . . . . . . . . 352
11.10.4 File Protection . . . . . . . . . . . . . . . . . . . . . . . . 353
11.10.5 Real and Effective uid . . . . . . . . . . . . . . . . . . 353
11.10.6 File Locking . . . . . . . . . . . . . . . . . . . . . . . . . 354
11.10.7 Programming Project #3: Implementation
of Complete File System . . . . . . . . . . . . . . . . 354
11.11 Extensions of File System Project . . . . . . . . . . . . . . . . . 354
11.12 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
12 Block Device I/O and Buffer Management . . . . . . . . . . . . . . . 357
12.1 Block Device I/O Buffers . . . . . . . . . . . . . . . . . . . . . . . 357
12.2 Unix I/O Buffer Management Algorithm . . . . . . . . . . . . 359
12.2.1 Shortcomings of Unix Algorithm . . . . . . . . . . 362
12.3 New I/O Buffer Management Algorithm . . . . . . . . . . . . 362
12.3.1 Buffer Management Algorithm using
Semaphores . . . . . . . . . . . . . . . . . . . . . . . . . 363
12.4 PV Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
12.5 Programming Project: Comparison of I/O Buffer
Management Algorithms . . . . . . . . . . . . . . . . . . . . . . . 365
12.5.1 System Organization . . . . . . . . . . . . . . . . . . . 365
12.5.2 Multitasking System . . . . . . . . . . . . . . . . . . . 366
12.5.3 Buffer Manager . . . . . . . . . . . . . . . . . . . . . . . 367
Contents xix

12.5.4 Disk Driver . . . . . . . . . . . . . . . . . . . . . . . . . . 367


12.5.5 Disk Controller . . . . . . . . . . . . . . . . . . . . . . . 368
12.5.6 Disk Interrupts . . . . . . . . . . . . . . . . . . . . . . . 368
12.5.7 Virtual Disks . . . . . . . . . . . . . . . . . . . . . . . . . 368
12.5.8 Project Requirements . . . . . . . . . . . . . . . . . . . 368
12.5.9 Sample Base Code . . . . . . . . . . . . . . . . . . . . . 369
12.5.10 Sample Solutions . . . . . . . . . . . . . . . . . . . . . . 374
12.6 Refinements of Simulation System . . . . . . . . . . . . . . . . 375
12.7 Refinements of PV Algorithm . . . . . . . . . . . . . . . . . . . . 375
12.8 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
13 TCP/IP and Network Programming . . . . . . . . . . . . . . . . . . . . 377
13.1 Introduction to Network Programming . . . . . . . . . . . . . . 377
13.2 TCP/IP Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
13.3 IP Host and IP address . . . . . . . . . . . . . . . . . . . . . . . . . 379
13.4 IP Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
13.5 IP Packet Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
13.6 Routers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
13.7 UDP User Datagram Protocol . . . . . . . . . . . . . . . . . . . . 380
13.8 TCP Transmission Control Protocol . . . . . . . . . . . . . . . 380
13.9 Port Number . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
13.10 Network and Host Byte Orders . . . . . . . . . . . . . . . . . . . 381
13.11 Data Flow in TCP/IP Networks . . . . . . . . . . . . . . . . . . . 381
13.12 Network Programming . . . . . . . . . . . . . . . . . . . . . . . . . 382
13.12.1 Network Programming Platforms . . . . . . . . . . 382
13.12.2 Server-Client Computing Model . . . . . . . . . . . 383
13.13 Socket Programming . . . . . . . . . . . . . . . . . . . . . . . . . . 383
13.13.1 Socket Address . . . . . . . . . . . . . . . . . . . . . . . 383
13.13.2 The Socket API . . . . . . . . . . . . . . . . . . . . . . . 384
13.14 UDP Echo Server-Client Program . . . . . . . . . . . . . . . . . 385
13.15 TCP Echo Server-Client Program . . . . . . . . . . . . . . . . . 387
13.16 Hostname and IP Address . . . . . . . . . . . . . . . . . . . . . . . 391
13.17 TCP Programming Project: File Server on Internet . . . . . 394
13.17.1 Project Specification . . . . . . . . . . . . . . . . . . . 394
13.17.2 Helps and Hints . . . . . . . . . . . . . . . . . . . . . . . 395
13.17.3 Multi-threaded TCP Server . . . . . . . . . . . . . . . 396
13.18 Web and CGI Programming . . . . . . . . . . . . . . . . . . . . . 396
13.18.1 HTTP Programming Model . . . . . . . . . . . . . . 396
13.18.2 Web Pages . . . . . . . . . . . . . . . . . . . . . . . . . . 397
13.18.3 Hosting Web Pages . . . . . . . . . . . . . . . . . . . . 399
13.18.4 Configure HTTPD for Web Pages . . . . . . . . . . 400
13.18.5 Dynamic Web Pages . . . . . . . . . . . . . . . . . . . 401
13.18.6 PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
13.18.7 CGI Programming . . . . . . . . . . . . . . . . . . . . . 406
13.18.8 Configure HTTPD for CGI . . . . . . . . . . . . . . . 406
xx Contents

13.19 CGI Programming Project: Dynamic Webpage


by CGI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
13.20 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
14 MySQL Database System . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
14.1 Introduction to MySQL . . . . . . . . . . . . . . . . . . . . . . . . 413
14.2 Install MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
14.2.1 Ubuntu Linux . . . . . . . . . . . . . . . . . . . . . . . . 414
14.2.2 Slackware Linux . . . . . . . . . . . . . . . . . . . . . . 414
14.3 Use MySQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
14.3.1 Connect to MySQL Server . . . . . . . . . . . . . . . 415
14.3.2 Show Databases . . . . . . . . . . . . . . . . . . . . . . 415
14.3.3 Create New database . . . . . . . . . . . . . . . . . . . 416
14.3.4 Drop Database . . . . . . . . . . . . . . . . . . . . . . . 416
14.3.5 Choose Database . . . . . . . . . . . . . . . . . . . . . . 417
14.3.6 Create Tables . . . . . . . . . . . . . . . . . . . . . . . . 417
14.3.7 Drop Tables . . . . . . . . . . . . . . . . . . . . . . . . . 418
14.3.8 Data Types in MySQL . . . . . . . . . . . . . . . . . . 419
14.3.9 Insert Rows . . . . . . . . . . . . . . . . . . . . . . . . . . 419
14.3.10 Delete Rows . . . . . . . . . . . . . . . . . . . . . . . . . 420
14.3.11 Update Table . . . . . . . . . . . . . . . . . . . . . . . . 421
14.3.12 Alter Table . . . . . . . . . . . . . . . . . . . . . . . . . . 422
14.3.13 Related Tables . . . . . . . . . . . . . . . . . . . . . . . . 424
14.3.14 Join Operations . . . . . . . . . . . . . . . . . . . . . . . 427
14.3.15 MySQL Database Diagram . . . . . . . . . . . . . . 429
14.3.16 MySQL Scripts . . . . . . . . . . . . . . . . . . . . . . . 429
14.4 MySQL Programming in C . . . . . . . . . . . . . . . . . . . . . . 433
14.4.1 Build MySQL Client Program in C . . . . . . . . . 433
14.4.2 Connect to MySQL Server in C . . . . . . . . . . . 433
14.4.3 Build MySQL Database in C . . . . . . . . . . . . . 435
14.4.4 Retrieve Results of MySQL Queries in C . . . . 437
14.5 MySQL Programming in PHP . . . . . . . . . . . . . . . . . . . 440
14.5.1 Connect to MySQL Server in PHP . . . . . . . . . 441
14.5.2 Create Database Tables in PHP . . . . . . . . . . . 442
14.5.3 Insert Records into Table in PHP . . . . . . . . . . 442
14.5.4 Retrieve Results of MySQL Queries
in PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
14.5.5 Update Operation in PHP . . . . . . . . . . . . . . . . 446
14.5.6 Delete Rows in PHP . . . . . . . . . . . . . . . . . . . 447
14.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
About the Author

K. C. Wang received the BSEE degree from


National Taiwan University in 1960 and the
PhD degree in Electrical Engineering from
Northwestern University, Evanston, IL, in
1965. He is currently a professor in the School
of Electrical Engineering and Computer Science
at Washington State University. His academic
interests are in operating systems, distributed
systems, and parallel computing.

xxi
Introduction
1

Abstract
This chapter presents an introduction to the book. It describes the book’s scope, intended audience
and its suitability as a textbook in Computer Science/Engineering curriculums. It presents a brief
history of Unix, which includes early versions of Unix at Bell Labs, AT&T System V and other
developments of Unix, such as BSD, HP UX, IBM AIX and Sun/Solaris Unix. It describes the
development of Linux and various Linux distributions, which include Debian, Ubuntu, Mint, Red
Hat and Slackware. It lists both the hardware platforms and virtual machines for Linux. It shows
how to install Ubuntu Linux to both VirtualBox and Vmware virtual machines inside the Microsoft
Windows. It explains the startup sequence of Linux, from booting the Linux kernel to user login and
command execution. It describes the Unix/Linux file system organization, file types and commonly
used Unix/Linux commands. Lastly, it describes system administration tasks for users to manage
and maintain their Linux systems.

1.1 About This Book

This book is about systems programming in the Unix/Linux (Thompson and Ritchie 1974, 1978; Bach
1986; Linux 2017) environment. It covers all the essential components of Unix/Linux, which include
process management, concurrent programming, timer and time service, file systems, network program-
ming and MySQL database system. In addition to covering the functionalities of Unix/Linux, it
stresses on programming practice. It uses programming exercises and realistic programming projects
to allow students to practice systems programming with hands-on experiences.

1.2 Roles of Systems Programming

Systems programming is an indispensable part of Computer Science and Computer Engineering


education. System programming courses in Computer Science/Engineering curriculums serve two
main purposes. First, it provides students with a wide range of knowledge about computer system
software and advanced programming skills, allowing them to interface with operating system kernel,
make efficient use of system resources to develop application software. Second, it prepares students

# Springer International Publishing AG, part of Springer Nature 2018 1


K. C. Wang, Systems Programming in Unix/Linux, https://doi.org/10.1007/978-3-319-92429-8_1
2 1 Introduction

with the needed background to pursue advanced studies in Computer Science/Engineering, such as
operating systems, embedded systems, database systems, data mining, artificial intelligence, computer
networks, network security, distributed and parallel computing.

1.3 Objectives of This Book

This book is intended to achieve the following objectives.

1.3.1 Strengthen Students Programming Background

Computer Science/Engineering students usually take introductory programming courses in their first or
second year. Such courses typically cover basic programming in C, C++ or Java. Due to time
limitations, these courses can only cover the basic syntax of a programming language, data types,
simple program structures and using library functions for I/O. Students coming out of such course are
rather weak in programming skills due to a lack of sufficient practices. For instance, they usually do not
know much about the software tools, the steps of program development and run-time environment of
program executions. The first object of this book is to provide students with the needed background
and skills to do advanced programming. This book covers program development steps in detail. These
include assembler, compiler, linker, link library, executable file contents, program execution image,
function call conventions, parameter passing schemes, local variables, stack frames, link C program
with assembly code, program termination and exception handling. In addition, it also shows how to use
Makefiles to manage large programming projects and how to debug program executions by GDB.

1.3.2 Applications of Dynamic Data Structures

Most elementary data structure courses cover the concepts of link lists, queues, stacks and trees, etc.
but they rarely show where and how are these dynamic data structures used in practice. This book
covers these topics in detail. These include C structures, pointers, link lists and trees. It uses
programming exercises and programming projects to let the students apply dynamic data structures
in real life. Case in point: a programming exercise is for the students to display the stack contents of a
program with many levels of function calls, allowing them to see the function calling sequence, passed
parameters, local variables and stack frames. Another programming exercise is to let students imple-
ment a printf-like function with varying parameters, which requires them to apply parameter passing
schemes to access varying parameters on stack. Yet another programming exercise is to print the
partitions of a disk, in which the extended partitions form a “link list” in the disk, but not by the
conventional pointers as they learned in programming languages. A programming project is to
implement a binary tree to simulate the Unix/Linux file system tree, which supports pwd, ls, cd,
mkdir, rmdir, creat, rm operations as in a real file system. Besides using dynamic data structures, the
programming project allows them to apply a wide range of programming techniques, such as string
tokenization, search for nodes in a tree, insert and delete tree nodes, etc. It also allows them to apply
binary tree traversal algorithms to save binary trees as files and reconstruct binary trees from saved
files.
1.3 Objectives of This Book 3

1.3.3 Process Concept and Process Management

The major focus of systems programming is the abstract notion of processes, which is rather hard to
grasp. This book uses a simple C program together with a piece of assembly code to let students see
real processes in action. The program implements a multitasking environment to simulate process
operations in an OS kernel. It allows the students to create processes, schedule processes by priority,
run different processes by context switching, maintain process relations by a binary tree, use sleep and
wakeup to implement wait for child process termination, etc. This concrete example makes it much
easier for students to understand processes and process management functions. Then it covers process
management in Unix/Linux in detail, which includes fork(), exit(), wait() and change process execu-
tion image by exec(). It also covers I/O redirection and pipes. It uses a programming project to let the
students implement a sh simulator for command execution. The sh simulator behaves exactly the same
as the bash of Linux. It can execute all Unix/Linux commands with I/O redirections, as well as
compound commands connected by pipes.

1.3.4 Concurrent Programming

Parallel computing is the future of computing. It is imperative to introduce parallel computing and
concurrent programming to CS/CE students at an early stage. This book covers parallel computing and
concurrent programming. It explains the concept of threads and their advantages over processes. It
covers Pthreads (Pthreads 2017) programming in detail. It explains the various kinds of threads
synchronization tools, such as threads join, mutex lock, condition variables, semaphores and barriers.
It demonstrates applications of threads by practical examples, which include matrix computation,
quicksort and solving system of linear equations by concurrent threads. It also introduces the concepts
of race conditions, critical regions, deadlock and deadlock prevention schemes. In addition to using
Pthreads, it uses a programming project to let students experiment with user-level threads, implement
threads synchronization tools and practice concurrent programming by user-level threads.

1.3.5 Timer and Time Functions

Timer and time functions are essential to process management and file systems. This book covers the
principle of hardware timers, timer interrupts and time service function in Unix/Linux in detail. It
shows how to use interval timers and timer generated signals in systems programming. In addition, it
uses a programming project to let students implement interval timer support for concurrent tasks.

1.3.6 Signals, Signal Processing and IPC

Signals and signal processing are keys to understanding program exceptions and Inter-Process
Communication (IPC). This book covers signals, signal processing and IPC in Unix/Linux. It explains
signal origins, signal delivery and processing in the OS kernel and the relation between signals and
exceptions. It shows how to install signal catchers to handle program exceptions in user mode. It uses a
programming project to let students use Linux signals and pipes to implement an IPC mechanism for
concurrent tasks to exchange messages.
4 1 Introduction

1.3.7 File system

Besides process management, file system is the second major component of an operating system. This
book provides an in depth coverage of file systems. It describes file operations at different levels and
explains their relationships. These include storage devices, file system support in Unix/Linux kernel,
system calls for file operations, library I/O functions, user commands and sh scripts. It uses a series of
programming exercises to let the students implement a complete EXT2 file system that is totally Linux
compatible. These not only allow the students to have a thorough understanding of file operations but
also provide them with the unique experience of writing a complete file system. Another programming
project is to implement and compare the performances of different I/O buffer management algorithms.
The simulation system supports I/O operations between processes and disk controllers. It allows the
students to practice I/O programming, interrupts processing and synchronization between processes
and I/O devices.

1.3.8 TCP/IP and Network Programming

Network programming is the third major component of an operating system. This book covers TCP/IP
protocols, socket API, UDP and TCP programming using sockets and the server-client model in
network computing. A programming project is for the students to implement a server-client based
system for remote file operations across the Internet. As of now, WWW and Internet services have
become an indispensable part of daily lives. It is essential to introduce CS/CE students to this
technology. This book covers HTTP and Web programming in detail. It allows the students to
configure the HTTPD server on their Linux machines to support HTTP programming. It shows how
to use HTML for static Web pages and PHP to create dynamic Web pages. It covers the MySQL
database system, shows how to create and manage databases in both command and batch modes and
interface MySQL with both C and PHP. A programming project is for the students to implement a Web
server to support file operations by HTTP forms and dynamic Web pages using CGI programming.

1.4 Intended Audience

This book is intended as a textbook for systems programming courses in technically oriented
Computer Science/Engineering curriculums that emphasize both theory and programming practice.
The book contains many detailed working example programs with complete source code. It is also
suitable for self-study by advanced programmers and computer enthusiasts.

1.5 Unique Features of This Book

This book has many unique features which distinguishes it from other books.

1. This book is self-contained. It includes all the foundation and background information for studying
systems programming. These include program development steps, program execution and termi-
nation, function call conventions, run-time stack usage and link C programs with assembly code. It
also covers C structures, pointers and dynamic data structures, such as link lists, queues and binary
trees. It shows applications of dynamic data structures in system programming.
1.5 Unique Features of This Book 5

2. It uses a simple multitasking system to introduce and illustrate the abstract notion of processes.
The multitasking system allows students to create processes, schedule and run different processes
by context switching, implement process synchronization mechanisms, control and observe
process executions. This unique approach allows the students to have a concrete feeling and better
understanding of process operations in real operating systems.
3. It describes the origin and roles of processes in Unix/Linux in detail, from system booting to INIT
process, daemon processes, login processes and the user sh process. It describes the execution
environment of user processes, such as stdin, stdout, stderr file streams and environment variables.
It also explains how does the sh process execute user commands.
4. It covers process management functions in Unix/Linux in detail. These include fork(), exit(), wait
(), changing process execution image by exec(), I/O redirection and pipes. Moreover, it allows the
students to apply these concepts and programming techniques to implement a sh simulator for
command execution. The sh simulator behaves exactly the same as the standard bash of Linux. It
supports executions of simple commands with I/O redirections, as well as compound commands
connected by pipes.
5. It introduces parallel computing and concurrent programming. It covers Pthreads programming by
detailed examples, which include matrix computation, quicksort and solving systems of linear
equations by concurrent threads, and it demonstrate the use of threads synchronization tools of
join, mutex lock, condition variables and barriers. It also introduces the important concepts and
problems in concurrent programming, such as race conditions, critical regions, deadlock and
deadlock prevention schemes. In addition, it allows the students to experiment with user-level
threads, design and implement threads synchronizing tools, such as threads join, mutex lock,
semaphores and demonstrate the capabilities of user-level threads by concurrent programs. These
allow the students to have a deeper understanding how threads work in Linux.
6. It covers timers and time service functions in detail. It also allows the reader to implement interval
timers for concurrent tasks in a multitasking system.
7. It presents a unified treatment of interrupts and signals, treating signals as interrupts to processes,
similar to interrupts to a CPU. It explains signal sources, signal types, signal generation and signal
processing in great detail. It shows how to install signal catchers to allow processes to handle
signals in user mode. It discusses how to use signals for IPC and other IPC mechanisms in Linux.
It uses a programming project to let the students use Linux signals and pipes to implement an IPC
mechanism for tasks to exchange messages in a multitasking system.
8. It organizes file operations into a hierarchy of different levels, ranging from storage devices, file
system support in Unix/Linux kernel, system calls for file operations, library I/O functions, user
commands and sh scripts. This hierarchical view provides the reader with a complete picture of file
operations. It covers file operations at the various levels in detail and explains their relationships. It
shows how to use system calls to develop file operation commands, such as ls for listing directory
and file information, cat for displaying file contents and cp for copying files.
9. It uses a programming project to lead the students to implement a complete EXT2 file system. The
programming project has been used in the CS360, System Programming course, at Washington
State University for many years, and it has proved to be very successful. It provides students with
the unique experience of writing a complete file system that not only works but is also totally
Linux compatible. This is perhaps the most unique feature of this book.
10. It covers TCP/IP protocols, socket API, UDP and TCP programming using sockets and the server-
client model in network programming. It uses a programming project to let the students implement
a server-client based system for remote file operations across the Internet. It also covers HTTP and
Web programming in detail. It shows how to configure the Linux HTTPD server to support HTTP
6 1 Introduction

programming, and how to use PHP to create dynamic Web pages. It uses a programming project to
let the students implement a Web server to support file operations via HTTP forms and dynamic
Web pages using CGI programming.
11. It emphasizes on programming practice. Throughout the book, it illustrates system programming
techniques by complete and concrete example programs. Above all, it uses a series of program-
ming projects to let students practice system programming. The programming projects include
(1) Implement a binary tree to simulate the Unix/Linux file system tree for file operations
(Chap. 2).
(2) Implement a sh simulator for command executions, including I/O redirections and pipes
(Chap. 3).
(3) Implement user-level threads, threads synchronization and concurrent programming
(Chap. 4).
(4) Implement interval timers for concurrent tasks in a multitasking system (Chap. 5).
(5) Use Linux signals and pipes to implement an IPC mechanism for concurrent task to exchange
messages (Chap. 6).
(6) Convert file pathname to file’s INODE in an EXT2 file system (Chap. 7).
(7) Recursive file copy by system calls (Chap. 8).
(8) Implement a printf-like function for formatted printing using only the basic operation of
putchar() (Chap. 9).
(9) Recursive file copy using sh functions and sh scripts (Chap. 10).
(10) Implement a complete and Linux compatible EXT2 file system (Chap. 11).
(11) Implement and compare I/O buffer management algorithms in an I/O system simulator
(Chap. 12).
(12) Implement a file server and clients on the Internet (Chap. 13).
(13) Implement a file server using HTTP forms and dynamic Web pages by CGI programming
(Chap. 13).
Among the programming projects, (1)–(3), (6)–(9), (12)–(13) are standard programming
assignments of the CS360 course at Washington State University. (10) has been the class project
of the CS360 course for many years. Many of the programming projects, e.g. (12)–(13) and
especially the file system project (10), require the students to form two-person teams, allowing
them to acquire and practice the skills of communication and cooperation with peers in a team-
oriented working environment.

1.6 Use This Book As Textbook in Systems Programming Courses

This book is suitable as a textbook for systems programming courses in technically oriented Computer
Science/Engineering curriculums that emphasize both theory and practice. A one-semester course
based on this book may include the following topics.

1. Introduction to Unix/Linux (Chap. 1)


2. Programming background (Chap. 2).
3. Process management in Unix/Linux (Chap. 3)
4. Concurrent programming (Parts of Chap. 4)
5. Timer and time Service functions (Parts of Chap. 5)
6. Signals and signal processing (Chap. 6)
1.8 Introduction to Unix 7

7. File operation levels (Chap. 7)


8. File system support in OS kernel and system calls for file operations (Chap. 8)
9. I/O library functions and file operation commands (Chap. 9)
10. Sh programming and sh scripts for file operations (Chap. 10)
11. Implementation of EXT2 file system (Chap. 11)
12. TCP/IP and network programming, HTTP and Web programming (Chap. 13).
13. Introduction to MySQL database system (Parts of Chap. 14).

The problems section of each chapter contains questions designed to review the concepts and
principles presented in the chapter. Many problems are suitable as programming projects to let students
gain more experience and skills in systems programming.
Most materials of this book have been used and tested in the Systems Programming course, CS360,
in EECS at Washington State University. The course has been the backbone of both Computer Science
and Computer Engineering programs in EECS at WSU. The current CS360 course syllabus, class notes
and programming assignments are available for review and scrutiny at

http://www.eecs.wsu.edu/~cs360

The course project is to lead students to implement a complete EXT2 file system that is totally Linux
compatible. The programming project has proved to be the most successful part of the CS360 course,
with excellent feedbacks from both industrial employers and academic institutions.

1.7 Other Reference Books

Due to its importance, systems programming in Unix/Linux has been a popular subject matter in
CS/CE education and also for self-study by advanced programmers. As a result, there are a tremendous
number of books and online articles in this area. Some of these books are listed in the reference section
(Curry 1996; Haviland et al. 1998; Kerrisk 2010; Love 2013; Robbins and Robbins 2003; Rochkind
2008; Stevens and Rago 2013). Many of these books are excellent programmer’s guides, which are
suitable as additional reference books.

1.8 Introduction to Unix

Unix (Thompson and Ritchie 1974, 1978) is a general purpose operating system. It was developed by
Ken Thompson and Dennis Ritchie on the PDP-11 minicomputers at Bell Labs in the early 70s. In
1975, Bell Labs released Unix to the general public. Initial recipients of this Unix system were mostly
universities and non-profit institutions. It was known as the V6 Unix. This early version of Unix,
together with the classic book on the C programming language (Kernighan and Ritchie 1988) started
the Unix revolution on Operating Systems, with long-lasting effects even to this day.

1.8.1 AT&T Unix

Development of Unix at AT&T continued throughout the 1980s, cumulating in the release of the
AT&T System V Unix (Unix System V 2017), which has been the representative Unix of AT&T.
8 1 Introduction

System V Unix was a uniprocessor (single CPU) system. It was extended to multiprocessor versions in
the late 80s (Bach 1986).

1.8.2 Berkeley Unix

Berkeley Unix (Leffler et al. 1989, 1996) refers to a set of variants of the Unix operating system
developed by the Berkeley Software Distribution (BSD) at the University of California, Berkeley, from
1977 to 1985. The most significant contributions of BSD Unix are implementation of the TCP/IP suite
and the socket interface, which are incorporated into almost all other operating systems as a standard
means of networking, which has helped the tremendous growth of the Internet in the 90s. In addition,
BSD Unix advocates open source from the beginning, which stimulated further porting and develop-
ment of BSD Unix. Later releases of BSD Unix provided a basis for several open source development
projects, which include FreeBSD (McKusick et al. 2004), OpenBSD and NetBSD, etc. that are still
ongoing to this day.

1.8.3 HP Unix

HP-UX (HP-UX 2017) is Hewlett Packard’s proprietary implementation of the Unix operating
system, first released in 1984. Recent versions of HP-UX support the HP 9000 series computer
systems, based on the PA-RISC processor architecture, and HP Integrity systems, based on Intel’s
Itanium. The unique features of HP-UX include a built-in logical volume manager for large file
systems and access control lists as an alternative to the standard rwx file permissions of Unix.

1.8.4 IBM Unix

AIX (IBM AIX 2017) is a series of proprietary Unix operating systems developed by IBM for several
of its computer platforms. Originally released for the IBM 6150 RISC workstation, AIX now supports
or has supported a wide variety of hardware platforms, including the IBM RS/6000 series and later
POWER and PowerPC-based systems, IBM System I, System/370 mainframes, PS/2 personal
computers, and the Apple Network Server. AIX is based on UNIX System V with BSD4.3-compatible
extensions.

1.8.5 Sun Unix

Solaris (Solaris 2017) is a Unix operating system originally developed by Sun Microsystems (Sun OS
2017). Since January 2010, it was renamed Oracle Solaris. Solaris is known for its scalability,
especially on SPARC systems. Solaris supports SPARC-based and x86-based workstations and
servers from Oracle and other vendors.
As can be seen, most Unix systems are proprietary and tied to specific hardware platforms. An
average person may not have access to these systems. This present a challenge to readers who wishes to
practice systems programming in the Unix environment. For this reason, we shall use Linux as the
platform for programming exercises and practice.
1.10 Linux Versions 9

1.9 Introduction to Linux

Linux (Linux 2017) is a Unix-like system. It started as an experimental kernel for the Intel x86 based
PCs by Linus Torvalds in 1991. Subsequently, it was developed by a group of people world-wide. A
big milestone of Linux occurred in the late 90s when it combined with GNU (Stallman 2017) by
incorporating many GNU software, such as the GCC compiler, GNU Emacs editor and bash, etc.
which greatly facilitated the further development of Linux. Not long after that, Linux implemented the
TCP/IP suite to access the Internet and ported X11 (X-windows) to support GUI, making it a
complete OS.
Linux includes many features of other Unix systems. In some sense, it represents a union of the
most popular Unix systems. To a large extent, Linux is POSIX compliant. Linux has been ported to
many hardware architectures, such as Motorola, SPARC and ARM, etc. The predominate Linux
platform is still the Intel x86 based PCs, including both desktops and laptops, which are widely
available. Also, Linux is free and easy to install, which makes it popular with computer science
students.

1.10 Linux Versions

The development of Linux kernel is under the strict supervision of the Linux kernel development
group. All Linux kernels are the same except for different release versions. However, depending on
distributions, Linux has many different versions, which may differ in distribution packages, user
interface and service functions. The following lists some of the most popular versions of Linux
distributions.

1.10.1 Debian Linux

Debian is a Linux distribution that emphasizes on free software. It supports many hardware
platforms. Debian distributions use the .deb package format and the dpkg package manager and its
front ends.

1.10.2 Ubuntu Linux

Ubuntu is a Linux distribution based on Debian. Ubuntu is designed to have regular releases, a
consistent user experience and commercial support on both desktops and servers. Ubuntu Linux has
several official distributions. These Ubuntu variants simply install a set of packages different from the
original Ubuntu. Since they draw additional packages and updates from the same repositories as
Ubuntu, the same set of software is available in all of them.

1.10.3 Linux Mint

Linux Mint is a community-driven Linux distribution based on Debian and Ubuntu. According to
Linux Mint, it strives to be a “modern, elegant and comfortable operating system which is both
powerful and easy to use”. Linux Mint provides full out-of-the-box multimedia support by including
10 1 Introduction

some proprietary software, and it comes bundled with a variety of free and open-source applications.
For this reason, it was welcomed by many beginner Linux users.

1.10.4 RPM-Based Linux

Red Hat Linux and SUSE Linux were the original major distributions that used the RPM file format,
which is still used in several package management systems. Both Red Hat and SUSE Linux divided
into commercial and community-supported distributions. For example, Red Hat Linux provides a
community-supported distribution sponsored by Red Hat called Fedora, and a commercially supported
distribution called Red Hat Enterprise Linux, whereas SUSE divided into openSUSE and SUSE Linux
Enterprise

1.10.5 Slackware Linux

Slackware Linux is known as a highly customizable distribution that stresses on ease of maintenance
and reliability over cutting-edge software and automated tools. Slackware Linux is considered as a
distribution for advanced Linux users. It allows users to choose Linux system components to install
and configure the installed system, allowing them to learn the inner workings of the Linux operating
system.

1.11 Linux Hardware Platforms

Linux was originally designed for the Intel x86 based PCs. Earlier versions of Linux run on Intel x86
based PCs in 32-bit protected mode. It is now available in both 32-bit and 64-bit modes. In addition to
the Intel x86, Linux has bee ported to many other computer architectures, which include MC6800 of
Motorola, MIP, SPARC, PowerPC and recently ARM. But the predominant hardware platform of
Linux is still the Intel x86 based PCs, although ARM based Linux for embedded systems are gaining
popularity rapidly.

1.12 Linux on Virtual Machines

Presently, most Intel x86 based PCs are equipped with Microsoft Windows, e.g. Windows 7, 8 or
10, as the default operating system. It is fairly easy to install Linux alongside Windows on the same PC
and use dual-boot to boot up either Windows or Linux when the PC starts. However, most users are
reluctant to do so due to either technical difficulty or preference to stay in the Windows environment. A
common practice is to install and run Linux on a virtual machine inside the Windows host. In the
following, we shall show how to install and run Linux on virtual machines inside the Microsoft
Windows 10.

1.12.1 VirtualBox

VirtualBox (VirtualBox 2017) is a powerful x86 and AMD64/Intel64 virtualization product of Oracle.
VirtualBox runs on Windows, Linux, Macintosh, and Solaris hosts. It supports a large number of guest
1.12 Linux on Virtual Machines 11

operating systems, including Windows (NT 4.0, 2000, XP, Vista, Windows 7, Windows 8, Windows
10) and Linux (2.4, 2.6, 3.x and 4.x), Solaris and OpenSolaris, OS/2, and OpenBSD. To install
virtualBox on Windows 10, follow these steps.

(1). Download VirtualBox.


At the VirtualBox website, http://download.virtualbox.org, you will find links to VirtualBox
binaries and its source code. For Windows hosts, the VirtualBox binary is
VirtualBox-5.1.12-112440-win.exe
In addition, you should also download the
VirtualBox 5.1.12 Oracle VM VirtualBox Extension Pack
which provides support for USB 2.0 and USB 3.0 devices, VirtualBox RDP, disk encryption,
NVMe and PXE boot for Intel cards.

(2). Install VirtualBox


After downloading the VirtualBox-5.1.12-112440-win.exe file, double click on the file name to run
it, which will install the VirtualBox VM under Windows 10. It also creates an Oracle VM VirtualBox
icon on the desktop.

(3). Create a VirtualBox Virtual Machine


Start up the VirtualBox. An initial VM window will appear, as shown in Fig. 1.1.
Choose the New button to create a new VM with 1024 MB memory and a virtual disk of 12GB.

(4). Install Ubuntu 14.04 to VirtualBox VM


Insert the Ubuntu 14.04 install DVD to a DVD drive. Start up the VM, which will boot up from the
DVD to install Ubuntu 14.04 to the VM.

(5). Adjust Display Size


For some unknown reason, when Ubuntu first starts up, the screen size will be stuck at the
640  480 resolution. To change the display resolution, open a terminal and enter the command line
xdiagnose. On the X Diagnostic settings window, enable all the options under Debug, which
consist of

Extra graphic debug message


Display boot messages
Enable automatic crash bug reporting

Although none of these options seems to be related to the screen resolution, it does change the
resolution to 1024  768 for a normal Ubuntu display screen. Figure 1.2 shows the screen of Ubuntu
on the VirtualBox VM.

Fig. 1.1 VirtualBox VM Window


12 1 Introduction

Fig. 1.2 Ubuntu Linux on VirtualBox VM

(6). Test C programming under Ubuntu


Ubuntu 14.04 has the gcc package installed. After installing Ubuntu, the user may create C source
files, compile them and run the C programs. If the user needs emacs, install it by

sudo apt-get install emacs

Emacs provides an Integrated Development Environment (IDE) for text-edit, compile C programs and
run the resulting binary executables under GDB. We shall cover and demonstrate the emacs IDE in
Chap. 2.

1.12.2 VMware

VMware is another popular VM for x86 based PCs. The full versions of VMware, which include VM
servers, are not free, but VMware Workstation Players, which are sufficient for simple VM tasks,
are free.

(1). Install VMware Player on Windows 10


The reader may get VMware Workstation Player from VMware’s download site. After
downloading, double click on the file name to run it, which will install VMware and create a VMware
Workstation icon on the Desktop. Click on the icon to start up the VMware VM, which displays a
VMware VM window, as shown in Fig. 1.3.
1.12 Linux on Virtual Machines 13

Fig. 1.3 VMware VM Window

(2). Install Ubuntu 15.10 on VMware VM


To install Ubuntu 15.10 on the VMware VM, follow the following steps.
1. Download Ubuntu 15.10 install DVD image; burn it to a DVD disc.
2. Download Vmware Workstation Player 12 exe file for Windows 10.
3. Install Vmware Player.
4. Start up Vmware Player
Choose: Create a new virtual machine;
Choose: Installer disc: DVD RW Drive (D:)
¼> insert the installer disc until it is ready to install
Then, enter Next
Choose: Linux
Version: ubuntu
Virtual machine name: change to a suitable name, e.g. ubuntu
Vmware will create a VM with 20GB disk size, 1GB memory, etc.
Choose Finish to finish creating the new VM
Next Screen: Choose: play virtual machine to start the VM.
The VM will boot from the Ubuntu install DVD to install Ubuntu.
5. Run C Program under Ubuntu Linux
Figure 1.4 shows the startup screen of Ubuntu and running a C program under Ubuntu.
14 1 Introduction

Fig. 1.4 Ubuntu on VMware VM

Fig. 1.5 Dual-Boot Window of Slackware and Ubuntu Linux

1.12.3 Dual Boot Slackware and Ubuntu Linux

It seems that free VMware Player only supports 32-bit VMs. The install steps are identical to above
except the installer disc is the Slackware14.2 install DVD. After installing both Slackware 14.2 and
Ubuntu 15.10, set up LILO to boot up either system when the VM starts up. If the reader installs
Slackware first followed by installing Ubuntu, Ubuntu will recognize Slackware and configure GRUB
for dual boot. The following figure shows the dual-boot menu of LILO (Fig. 1.5).
1.13 Use Linux 15

1.13 Use Linux

1.13.1 Linux kernel image

In a typical Linux system, Linux kernel images are in the /boot directory. Bootable Linux kernel
images are named as

vmlinuz-generic-VERSION_NUMBER
initrd as the initial ramdisk image for the Linux kernel.

A bootable Linux kernel image is composed of three pieces:

| BOOT | SETUP | linux kernel |

BOOT is a 512-byte booter for booting early versions of Linux from floppy disk images. It is no longer
used for Linux booting but it contains some parameters for SETUP to use. SETUP is a piece of 16-bit
and 32-bit assembly code, which provides transition from the 16-bit mode to 32-bit protected mode
during booting. Linux kernel is the actual kernel image of Linux. It is in compressed form but it has a
piece of decompressing code at beginning, which decompresses the Linux kernel image and relocates
it to high memory.

1.13.2 Linux Booters

The Linux kernel can be booted up by several different boot-loaders. The most popular Linux boot-
loaders are GRUB and LILO. Alternatively, the HD booter of (Wang 2015) can also be used to boot up
Linux.

1.13.3 Linux Booting

During booting, the Linux boot-loader first locates the Linux kernel image (file). Then it loads

BOOT+SETUP to 090000 in real mode memory


Linux kernel to 1MB in high memory.

For generic Linux kernel images, it also loads an initial ramdisk image, initrd, to high memory. Then it
transfers control to run SETUP code at 0902000, which starts up the Linux kernel. When the Linux
kernel first starts up, it runs on initrd as a temporary root file system. The Linux kernel executes a sh
script, which directs the kernel to load the needed modules for the real root device. When the real root
device is activated and ready, the kernel abandons the initial ramdisk and mounts the real root device as
the root file system, thus completing a two-phase booting of the Linux kernel.
16 1 Introduction

1.13.4 Linux Run-levels

The Linux kernel starts up in the single user mode. It mimics the run-levels of System V Unix to run in
multi-user mode. Then it creates and run the INIT process P1, which creates the various daemon
processes and also terminal processes for users to login. Then the INIT process waits for any child
process to terminate.

1.13.5 Login Process

Each login process opens three file streams, stdin for input, stdout for output and stderr for error
output, on its terminal. Then it waits for users to login. On Linux systems using X-windows as user
interface, the X-window server usually acts as an interface for users to login. After a user login, the
(pseudo) terminals belong to the user by default.

1.13.6 Command Executions

After login, the user process typically executes the command interpreter sh, which prompts the user for
commands to execute. Some special commands, such as cd (change directory), exit, logout, &, are
performed by sh directly. Non-special commands are usually executable files. For a non-special
command, sh forks a child process and waits for the child to terminate. The child process changes
its execution image to the file and executes the new image. When the child process terminates, it wakes
up the parent sh, which prompts for another command, etc. In addition to simple commands, sh also
supports I/O redirections and compound commands connected by pipes. In addition to built-in
commands, the user may develop programs, compile-link them into binary executable files and run
the programs as commands.

1.14 Use Ubuntu Linux

1.14.1 Ubuntu Versions

Among the different versions of Linux, we recommend Ubuntu Linux 15.10 or later for the following
reasons.

(1) It is very easy to install. It can be installed online if the user has connection to the Internet.
(2) It is very easy to install additional software packages by
sudo apt-get install PACKAGE
(3) It is updated and improved regularly with new releases.
(4) It has a large user base, with many problems and solutions posted in discussion forums online.
(5) It provides easy connections to wireless networks and access to the Internet.
1.14 Use Ubuntu Linux 17

1.14.2 Special Features of Ubuntu Linux

Here are some helps on how to use the Ubuntu Linux.

(1) When installing Ubuntu on a desktop or laptop computer, it will ask for a user name and a
password to create a user account with a default home directory /home/username. When Ubuntu
boots up, it immediately runs in the environment of the user because it already has the default user
logged in automatically. Enter Control-Alter-T to open a pseudo-terminal. Right click the Term
icon and choose “lock to launcher” to lock the Term icon in the menu bar. Subsequently, launch
new terminals by choosing the terminal->new terminal on the menu bar. Each new terminal runs
a sh for the user to execute commands.
(2) For security reasons, the user is an ordinary user, not the root or superuser. In order to run any
privileged commands, the user must enter

sudo command

which will verify the user’s password first.


(3) The user’s PATH environment variable setting usually does not include the user’s current
directory. In order to run programs in the current directory, the user must enter ./a.out every
time. For convenience, the users should change the PATH setting to include the current directory.
In the user’s home directory, create a .bashrc file containing

PATH=$PATH:./

Every time the user opens a pseudo-terminal, sh will execute the .bashrc file first to set PATH to
include the current working directory ./
(4) Many users may have installed 64-bit Ubuntu Linux. Some of the programming exercises and
assignments in this book are intended for 32-bit machines. In 64-bit Linux, use

gcc -m32 t.c # compile t.c into 32-bit code

to generate 32-bit code. If the 64-bit Linux does not take the -m32 option, the user must install
additional support for gcc to generate 32-bit code.
(5) Ubuntu provides an excellent GUI user interface. Many users are so accustomed to the GUI that
they tend to rely on it too much, often wasting time by repeatedly dragging and clicking the
pointing device. In systems programming, the user should also learn how to use command lines
and sh scripts, which are much more general and powerful than GUI.
(6) Nowadays, most users can connect to computer networks. Ubuntu supports both wired and
wireless connections to networks. When Ubuntu runs on a PC/laptop with wireless hardware, it
displays a wireless icon on top and it allows wireless connections by a simple user interface. Open
the wireless icon. It will show a list of available wireless networks near by. Select a network and
open the Edit Connections submenu to edit the connection file by entering the required login
name and password. Close the Edit submenu. Ubuntu will try to login to the selected wireless
network automatically.
18 1 Introduction

Fig. 1.6 Unix/Linux File System Tree

1.15 Unix/Linux File System Organization

The Unix/Linux file system is organized as a tree, which is shown (sideway) in Fig. 1.6.
Unix/Linux considers everything that can store or provide information as a file. In a general sense,
each node of the file system tree is a FILE. In Unix/Linux, files have the following types.

1.15.1 File Types

(1). Directory files: A directory may contain other directories and (non-directory) files.

(2). Non-directory files: Non-directory files are either REGULAR or SPECIAL files, which can only
be leaf-nodes in the file system tree. Non-directory files can be classified further as

(2).1 REGULAR files: Regular files are also called ORDINARY files. They contain either ordinary
text or executable binary code.

(2).2 SPECIAL files: Special files are entries in the /dev directory. They represent I/O devices, which
are further classified as

CHAR special files: I/O by chars, e.g. /dev/tty0, /dev/pts/1, etc.


BLOCK special files: I/O by blocks, e.g. /dev/had, /dev/sda, etc.
Other types such as network (socket) special files, named pipes, etc.

(3). Symbolic LINK files: These are Regular files whose contents are pathnames of other files. As
such, they act as pointers to other files. As an example, the Linux command

ln -s aVeryLongFileName myLink

creates a symbolic link file, mylink, which points to aVeryLongFileName. Access to myLink will be
redirected to the actual file aVeryLongFileName.
1.15 Unix/Linux File System Organization 19

1.15.2 File Pathnames

The root node of a Unix/Linux file system tree, symbolized by /, is called the root directory or simply
the root. Each node of the file system tree is specified by a pathname of the form

/a/b/c/d OR a/b/c/d

A pathname is ABSOLUTE if it begins with a /. Otherwise, it is RELATIVE to the Current


Working Directory (CWD) of the process. When a user login to Unix/Linux, the CWD is set to
the user’s HOME directory. The CWD can be changed by the cd (change directory) command. The
pwd command prints the absolute pathname of the CWD.

1.15.3 Unix/Linux Commands

When using an operating system, the user must learn how to use the system commands. The following
lists the most often used commands in Unix/Linux.

ls: ls dirname: list the contents of CWD or a directory


cd dirname: change directory
pwd: print absolute pathname of CWD
touch filename: change filename timestamp (create file if it does not exist)
cat filename: display file contents
cp src dest: copy files
mv src dest: move or rename files
mkdir dirname: create directory
rmdir dirname: remove (empty) directory
rm filename: remove or delete file
ln oldfile newfile: create links between files
find: search for files
grep: search file for lines containing a pattern
ssh: login to remote hosts
gzip filename: compress filename to .gz file
gunzip file.gz: uncompress .gz file
tar –zcvf file.tgz . : create compressed tar file from current directory
tar -zxvf file.tgz . : extract files from .tgz file
man: display online manual pages
zip file.zip filenames : compress files to .zip file
unzip file.zip : uncompress .zip file

1.15.4 Linux Man Pages

Linux maintains online man (manual) pages in the standard /usr/man/directory. In Ubuntu Linux, it is
in /usr/share/man directory. The man pages are organized into several different categories, denoted by
man1, man2, etc.
20 1 Introduction

/usr/man/
|-- man1: commonly used commands: ls, cat, mkdir ...., etc.
|-- man2: system calls
|-- man3: library functions: strtok, strcat, basename, dirname
etc.

All the man pages are compressed .gz files. They contain text describing how to use the command with
input parameters and options. man is a program, which reads man page files and displays their contents
in a user friendly format. Here are some examples of using man pages.

man ls : show man page of ls in man1


man 2 open : show man page of open in man2
man strtok : show man page of strtok in man 3, etc.
man 3 dirname : show dirname in man3, NOT that of man1

Whenever needed, the reader should consult the man pages for how to use a specific Linux command.
Many of the so called Unix/Linux systems programming books are essentially condensed versions of
the Unix/Linux man pages.

1.16 Ubuntu Linux System Administration

1.16.1 User Accounts

As in all Linux, user accounts are maintained in the /etc/passwd file, which is owned by the superuser
but readable by anyone. Each user has a line in the /etc/passwd file of the form

loginName:x:gid:uid:usefInfo:homeDir:initialProgram

where the second field x indicates checking user password. Encrypted user passwords are maintained
in the /etc/shadow file. Each line of the shadow file contains the encrypted user password, followed by
optional aging limit information, such as expiration date and time, etc. When a user tries to login with a
login name and password, Linux will check both the /etc/passwd and /etc/shadow files to authenticate
the user. After a user login successfully, the login process becomes the user process by acquiring the
user’s gid and uid, changes directory to the user’s homeDir and executes the listed initialProgram,
which is usually the command interpreter sh.

1.16.2 Add New User

This may be a pathological case for most users who run Ubuntu Linux on their personal PCs or laptops.
But let’s assume that the reader may want to add a family member to use the same computer but as a
different user. As in all Linux, Ubuntu supports an adduser command, which can be run as

sudo adduer username


References 21

It adds a new user by creating an account and also a default home directory /home/username for the
new user. Henceforth, Ubuntu will display a list of user names in its “About The Computer” menu. The
new user may login to the system by selecting the new username.

1.16.3 The sudo Command

For security reasons, the root or superuser account is disabled in Ubuntu, which prevents anyone from
login as the root user (well, not quite; there is a way but I won’t disclose it). sudo (“superuser do”)
allows a user to execute a command as another user, usually the superuser. It temporarily elevates the
user process to the superuser privilege while executing a command. When the command execution
finishes, the user process reverts back to its original privilege level. In order to be able to use sudo, the
user’s name must be in the /etc/sudoers file. To allow a user to issue sudo, simply add a line to sudoers
files, as in

username ALL(ALL) ALL

However, the /etc/sudoers file has a very rigid format. Any syntax error in the file could breech the
system security. Linux recommends editing the file only by the special command visudo, which
invokes the vi editor but with checking and validation.

1.17 Summary

This chapter presents an introduction to the book. It describes the book’s scope, intended audience and
its suitability as textbook in Computer Science/Engineering curriculums. It presents a brief history of
Unix, which includes early versions of Unix at Bell Labs, AT&T System V and other developments of
Unix, such as BSD, HP UX, IBM AIX and Sun/Solaris Unix. It describes the development of Linux
and various Linux distributions, which include Debian, Ubuntu, Mint, Red Hat and Slackware. It lists
both the hardware platforms and virtual machines for Linux. It shows how to install Ubuntu Linux to
both VirtualBox and Vmware virtual machines inside the Microsoft Windows. It explains the startup
sequence of Linux, from booting the Linux kernel to user login and command execution. It describes
the Linux file system organization, file types and commonly used Unix/Linux commands. Lastly, it
describes some system administration tasks for users to manage and maintain their Linux systems.

References
Bach M., “The Design of the UNIX Operating System”, Prentice-Hall, 1986
Curry, David A., Unix Systems Programming for SRV4, O’Reilly, 1996.
Haviland, Keith, Gray, Dian, Salama, Ben, Unix System Programming, Second Edition, Addison-Wesley, 1998.
HP-UX, http://www.operating-system.org/betriebssystem/_english/bs-hpux.htm, 2017
IBM AIX, https://www.ibm.com/power/operating-systems/aix, 2017
Kernighan, B.W., Ritchie D.M, “The C Programming Language” 2nd Edition, 1988
Kerrisk, Michael, The Linux Programming Interface: A Linux and UNIX System Programming Handbook, 1st Edition,
No Starch Press Inc, 2010.
Leffler, S.J., McKusick, M. K, Karels, M. J. Quarterman, J., “The Design and Implementation of the 4.3BSD UNIX
Operating System”, Addison Wesley, 1989
Leffler, S.J., McKusick, M. K, Karels, M. J. Quarterman, J., “The Design and Implementation of the 4.4BSD UNIX
Operating System”, Addison Wesley, 1996
22 1 Introduction

Linux, https://en.wikipedia.org/wiki/Linux , 2017


Love, Robert, Linux System Programming: Talking Directly to the Kernel and C Library, 2nd Edition, O’Reilly, 2013.
McKusick, M. K, Karels, Neville-Neil, G.V., “The Design and Implementation of the FreeBSD Operating System”,
Addison Wesley, 2004
Robbins Kay, Robbins, Steve, UNIX Systems Programming: Communication, Concurrency and Threads: Communica-
tion, Concurrency and Threads, 2nd Edition, Prentice Hall, 2003.
Pthreads: https://computing.llnl.gov/tutorials/pthreads, 2017
Rochkind, Marc J., Advanced UNIX Programming, 2nd Edition, Addison-Wesley, 2008.
Stallman, R., Linux and the GNU System, 2017
Stevens, W. Richard, Rago, Stephan A., Advanced Programming in the UNIX Environment, 3rd Edition, Addison-
Wesley, 2013.
Solaris, http://www.operating-system.org/betriebssystem/_english/bs-solaris.htm, 2017
Sun OS, https://en.wikipedia.org/wiki/SunOS, 2017
Thompson, K., Ritchie, D. M., “The UNIX Time-Sharing System”, CACM., Vol. 17, No.7, pp. 365-375, 1974.
Thompson, K., Ritchie, D.M.; “The UNIX Time-Sharing System”, Bell System Tech. J. Vol. 57, No.6, pp. 1905–1929,
1978
Unix System V, https://en.wikipedia.org/wiki/UNIX_System V, 2017
VirtualBox, https://www.virtualbox.org, 2017
Wang, K. C., Design and Implementation of the MTX Operating System, Springer International Publishing AG, 2015
Programming Background
2

Abstract
This chapter covers the background information needed for systems programming. It introduces several
GUI based text editors, such as vim, gedit and EMACS, to allow readers to edit files. It shows how to
use the EMACS editor in both command and GUI mode to edit, compile and execute C programs. It
explains program development steps. These include the compile-link steps of GCC, static and dynamic
linking, format and contents of binary executable files, program execution and termination. It explains
function call conventions and run-time stack usage in detail. These include parameter passing, local
variables and stack frames. It also shows how to link C programs with assembly code. It covers the
GNU make facility and shows how to write Makefiles by examples. It shows how to use the GDB
debugger to debug C programs. It points out the common errors in C programs and suggests ways
to prevent such errors during program development. Then it covers advanced programming techniques.
It describes structures and pointer in C. It covers link lists and list processing by detailed examples. It
covers binary trees and tree traversal algorithms. The chapter cumulates with a programming project,
which is for the reader to implement a binary tree to simulate operations in the Unix/Linux file system
tree. The project starts with a single root directory node. It supports mkdir, rmdir, creat, rm, cd, pwd, ls
operations, saving the file system tree as a file and restoring the file system tree from saved file. The
project allows the reader to apply and practice the programming techniques of tokenizing strings,
parsing user commands and using function pointers to invoke functions for command processing.

2.1 Text Editors in Linux

2.1.1 Vim

Vim (Linux Vi and Vim Editor 2017) is the standard built-in editor of Linux. It is an improved version
of the original default Vi editor of Unix. Unlike most other editors, vim has 3 different operating
modes, which are

. Command mode: for entering commands


. Insert mode: for entering and editing text
. Last-line mode: for saving files and exit

# Springer International Publishing AG, part of Springer Nature 2018 23


K. C. Wang, Systems Programming in Unix/Linux, https://doi.org/10.1007/978-3-319-92429-8_2
24 2 Programming Background

When vim starts, it is in the default Command mode, in which most keys denote special commands.
Examples of command keys for moving the cursor are

h: move cursor one char to the left; l: move cursor one char to the right
j: move cursor down one line; k: move cursor up one line

When using vim inside X-window, cursor movements can also be done by arrow keys. To enter text for
editing, the user must switch vim into Insert mode by entering either the i (insert) or a (append)
command:

i: switch to Insert mode to insert text;


a: switch to Insert mode to append text

To exit Insert mode, press the ESC key one or more times. While in Command mode, enter the : key to
enter the Last-line mode, which is for saving texts as files or exit vim:

:w write (save) file


:q exit vim
:wq save and exit
:q! force exit without saving changes

Although many Unix users are used to the different operating modes of vim, others may find it
somewhat unnatural and inconvenient to use as compared with other Graphic User Interface (GUI)
based editors. The following editors belong to what is commonly known as What You See Is What
You Get (WYSIWYG) type of editors. In a WYSIWYG editor, a user may enter text, move the cursor
by arrow keys, just like in regular typing. Commands are usually formed by entering a special meta
key, together with, or followed by, a letter key sequence. For example,

Control-C: abort or exit,


Control-K: delete line into a buffer,
Control-Y: yank or paste from buffer contents
Control-S: save edited text, etc.

Since there is no mode switching necessary, most users, especially beginners, prefer WYSUWYG type
editors over vim.

2.1.2 Gedit

Gedit is the default text editor of the GNOME desktop environment. It is the default editor of Ubuntu,
as well as other Linux that uses the GNOME GUI user interface. It includes tools for editing both
source code and structured text such as markup languages.

2.1.3 Emacs

Emacs (GNU Emacs 2015) is a powerful text editor, which runs on many different platforms. The
most popular version of Emacs is GNU Emacs, which is available in most Linux distributions.
2.2 Use Text Editors 25

All the above editors support direct inputs and editing of text in full screen mode. They also support
search by keywords and replace strings by new text. To use these editors, the user only needs to learn a
few basics, such as how to start up the editor, input text for editing, save edited texts as files and then
exit the editor.
Depending on the Unix/Linux distribution, some of the editors may not be installed by default. For
example, Ubuntu Linux usually comes with gedit, nano and vim, but not emacs. One nice feature of
Ubuntu is that, when a user tries to run a command that is not installed, it will remind the user to install
it. As an example, if a user enters

emacs filename

Ubuntu will display a message saying “The program emacs is currently not installed. You can install it
by typing apt-get install emacs”. Similarly, the user may install other missing software packages by the
apt-get command.

2.2 Use Text Editors

All text editors are designed to perform the same task, which is to allow users to input texts, edit them
and save the edited texts as files. As noted above, there are many different text editors. Which text
editor to use is a matter of personal preference. Most Linux users seem to prefer either gedit or emacs
due to their GUI interface and ease to use. Between the two, we strongly recommend emacs. The
following shows some simple examples of using emacs to create text files.

2.2.1 Use Emacs

First, from a pseudo terminal of X-windows, enter the command line

emacs [FILENAME] # [ ] means optonal

to invoke the emacs editor with an optional file name, e.g. t.c. This will start up emacs in a separate
window as show in Fig. 2.1. On top of the emacs window is a menu bar, each of which can be opened
to show additional commands, which the user can invoke by clicking on the menu icons. To begin
with, we shall not use the menu bar and focus on the simple task of creating a C program source file.
When emacs starts, if the file t.c already exists, it will open the file and load its contents into a buffer for
editing. Otherwise, it will show an empty buffer, ready for user inputs. Fig. 2.1 shows the user input
lines. Emacs recognizes any .c file as source file for C programs. It will indent the lines in accordance
with the C code line conventions, e.g. it will match each left { with a right }with proper indentations
automatically. In fact, it can even detect incomplete C statements and show improper indentations to
alert the user of possible syntax errors in the C source lines.
After creating a source file, enter the meta key sequence Control-x-c to save the file and exit. If the
buffer contains modified and unsaved text, it will prompt the user to save file, as shown on the bottom
line of Fig. 2.2. Entering y will save the file and exit emacs. Alternatively, the user may also click the
Save icon on the menu bar to save and exit.
26 2 Programming Background

Fig. 2.1 Use emacs 1

Fig. 2.2 Use emacs 2

2.2.2 Emacs Menus

At the top of the emacs window is a menu bar, which includes the icons

File Edit Options Buffers Tools C Help

The File menu supports the operations of open file, insert file and save files. It also supports printing
the editing buffer, open new windows and new frames.
The Edit menu supports search and replace operations.
The Options menu supports functions to configure emacs operations.
The Buffers menu supports selection and display of buffers.
The Tools menu supports compilation of source code, execution of binary executables and debugging.
The C menu supports customized editing for C source code.
The Help menu provides support for emacs usage, such as a simple emacs tutorial.

As usual, clicking on a menu item will display a table of submenus, allowing the user to choose
individual operations. Instead of commands, the user may also use the emacs menu bar to do text
editing, such as undo last operation, cut and past, save file and exit, etc.

2.2.3 IDE of Emacs

Emacs is more than a text editor. It provides an Integrated Development Environment (IDE) for
software development, which include compile C programs, run executable images and debugging
2.3 Program Development 27

program executions by GDB. We shall illustrate the IDE capability of emacs in the next section on
program development.

2.3 Program Development

2.3.1 Program Development Steps

The steps of developing an executable program are as follows.

(1). Create source files: Use a text editor, such as gedit or emacs, to create one or more source files of a
program. In systems programming, the most important programming languages are C and assembly.
We begin with C programs first.
Standard comment lines in C comprises matched pairs of /* and */. In addition to the standard
comments, we shall also use // to denote comment lines in C code for convenience. Assume that t1.c
and t2.c are the source files of a C program.

/********************** t1.c file *****************************/


int g = 100; // initialized global variable
int h; // uninitialized global variable
static int s; // static global variable

main(int argc, char *argv[ ]) // main function


{
int a = 1; int b; // automatic local variables
static int c = 3; // static local variable
b = 2;
c = mysum(a,b); // call mysum(), passing a, b
printf("sum=%d\n", c); // call printf()
}
/********************** t2.c file ****************************/
extern int g; // extern global variable
int mysum(int x, int y) // function heading
{
return x + y + g;
}

2.3.2 Variables in C

Variables in C programs can be classified as global, local, static, automatic and registers, etc. as
shown in Fig. 2.3.
Global variables are defined outside of any function. Local variables are defined inside functions.
Global variables are unique and have only one copy. Static globals are visible only to the file in which
they are defined. Non-static globals are visible to all the files of the same program. Global variables
can be initialized or uninitialized. Initialized globals are assigned values at compile time. Uninitialized
globals are cleared to 0 when the program execution starts. Local variables are visible only to the
function in which they are defined. By default, local variables are automatic; they come into existence
28 2 Programming Background

Fig. 2.3 Variables in C

Fig. 2.4 Program


development steps

when the function is entered and they logically disappear when the function exits. For register
variables, the compiler tries to allocate them in CPU registers. Since automatic local variables do
not have any allocated memory space until the function is entered, they cannot be initialized at compile
time. Static local variables are permanent and unique, which can be initialized. In addition, C also
supports volatile variables, which are used as memory-mapped I/O locations or global variables that
are accessed by interrupt handlers or multiple execution threads. The volatile keyword prevents the C
compiler from optimizing the code that operates on such variables.
In the above t1.c file, g is an initialized global, h is an uninitialized global and s is a static global.
Both g and h are visible to the entire program but s is visible only in the t1.c file. So t2.c can reference g
by declaring it as extern, but it cannot reference s because s is visible only in t1.c. In the main()
function, the local variables a, b are automatic and c is static. Although the local variable a is defined as
int a ¼ 1, this is not an initialization because a does not yet exist at compile time. The generated code
will assign the value 1 to the current copy of a when main() is actually entered.

2.3.3 Compile-Link in GCC

(2). Use gcc to convert the source files into a binary executable, as in

gcc t1.c t2.c

which generates a binary executable file named a.out. In Linux, cc is linked to gcc, so they are
the same.

(3). What’s gcc? gcc is a program, which consists of three major steps, as shown in Fig. 2.4.

Step 1. Convert C source files to assembly code files: The first step of cc is to invoke the C
COMPILER, which translates .c files into .s files containing assembly code of the target machine.
The C compiler itself has several phases, such as preprocessing, lexical analysis, parsing and code
generations, etc, but the reader may ignore such details here.
Step 2. Convert assembly Code to OBJECT code: Every computer has its own set of machine
instructions. Users may write programs in an assembly language for a specific machine. An
ASSEMBLER is a program, which translates assembly code into machine code in binary form.
The resulting .o files are called OBJECT code. The second step of cc is to invoke the ASSEMBLER
to translate .s files to .o files. Each .o file consists of
2.3 Program Development 29

. a header containing sizes of CODE, DATA and BSS sections


. a CODE section containing machine instructions
. a DATA section containing initialized global and initialized static local variables
. a BSS section containing uninitialized global and uninitialized static local variables
. relocation information for pointers in CODE and offsets in DATA and BSS
. a Symbol Table containing non-static globals, function names and their attributes.
Step 3: LINKING: A program may consist of several .o files, which are dependent on one another. In
addition, the .o files may call C library functions, e.g. printf(), which are not present in the source
files. The last step of cc is to invoke the LINKER, which combines all the .o files and the needed
library functions into a single binary executable file. More specifically, the LINKER does the
following:
. Combine all the CODE sections of the .o files into a single Code section. For C programs, the
combined Code section begins with the default C startup code crt0.o, which calls main(). This is
why every C program must have a unique main() function.
. Combine all the DATA sections into a single Data section. The combined Data section contains
only initialized globals and initialized static locals.
. Combine all the BSS sections into a single bss section.
. Use the relocation information in the .o files to adjust pointers in the combined Code section and
offsets in the combined Data and bss sections.
. Use the Symbol Tables to resolve cross references among the individual .o files. For instance,
when the compiler sees c ¼ mysum(a, b) in t1.c, it does not know where mysum is. So it leaves a
blank (0) in t1.o as the entry address of mysum but records in the symbol table that the blank must
be replaced with the entry address of mysum. When the linker puts t1.o and t2.o together, it knows
where mysum is in the combined Code section. It simply replaces the blank in t1.o with the entry
address of mysum. Similarly for other cross referenced symbols. Since static globals are not in the
symbol table, they are unavailable to the linker. Any attempt to reference static globals from
different files will generate a cross reference error. Similarly, if the .o files refer to any undefined
symbols or function names, the linker will also generate cross reference errors. If all the cross
references can be resolved successfully, the linker writes the resulting combined file as a.out,
which is the binary executable file.

2.3.4 Static vs. Dynamic Linking

There are two ways to create a binary executable, known as static linking and dynamic linking. In
static linking, which uses a static library, the linker includes all the needed library function code and
data into a.out. This makes a.out complete and self-contained but usually very large. In dynamic
linking, which uses a shared library, the library functions are not included in a.out but calls to such
functions are recorded in a.out as directives. When execute a dynamically linked a.out file, the
operating system loads both a.out and the shared library into memory and makes the loaded library
code accessible to a.out during execution. The main advantages of dynamic linking are:

. The size of every a.out is reduced.


. Many executing programs may share the same library functions in memory.
. Modifying library functions does not need to re-compile the source files again.
30 2 Programming Background

Libraries used for dynamic linking are known as Dynamic Linking Libraries (DLLs). They are
called Shared Libraries (.so files) in Linux. Dynamically loaded (DL) libraries are shared libraries
which are loaded only when they are needed. DL libraries are useful as plug-ins and dynamically
loaded modules.

2.3.5 Executable File Format

Although the default binary executable is named a.out, the actual file format may vary. Most C
compilers and linkers can generate executable files in several different formats, which include

(1) Flat binary executable: A flat binary executable file consists only of executable code and
initialized data. It is intended to be loaded into memory in its entirety for execution directly. For
example, bootable operating system images are usually flat binary executables, which simplifies
the boot-loader.
(2) a.out executable file: A traditional a.out file consists of a header, followed by code, data and bss
sections. Details of the a.out file format will be shown in the next section.
(3) ELF executable file: An Executable and Linking Format (ELF) (Youngdale 1995) file consists of
one or more program sections. Each program section can be loaded to a specific memory address.
In Linux, the default binary executables are ELF files, which are better suited to dynamic linking.

2.3.6 Contents of a.out File

For the sake of simplicity, we consider the traditional a.out files first. ELF executables will be covered
in later chapters. An a.out file consists of the following sections:

(1) header: the header contains loading information and sizes of the a.out file, where
tsize ¼ size of Code section;
dsize ¼ size of Data section containing initialized globals and static locals;
bsize ¼ size of bss section containing uninitialized globals and static locals;
total_size ¼ total size of a.out to load.
(2) Code Section: also called the Text section, which contains executable code of the program. It
begins with the standard C startup code crt0.o, which calls main().
(3) Data Section: The Data section contains initialized global and static data.
(4) Symbol table: optional, needed only for run-time debugging.

Note that the bss section, which contains uninitialized global and static local variables, is not in the a.
out file. Only its size is recorded in the a.out file header. Also, automatic local variables are not in a.out.
Figure 2.5 shows the layout of an a.out file.
In Fig. 2.5, _brk is a symbolic mark indicating the end of the bss section. The total loading size of a.
out is usually equal to _brk, i.e. equal to tsize+dsize+bsize. If desired, _brk can be set to a higher value
for a larger loading size. The extra memory space above the bss section is the HEAP area for dynamic
memory allocation during execution.
Random documents with unrelated
content Scribd suggests to you:
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright law
in the United States and you are located in the United States, we do
not claim a right to prevent you from copying, distributing,
performing, displaying or creating derivative works based on the
work as long as all references to Project Gutenberg are removed. Of
course, we hope that you will support the Project Gutenberg™
mission of promoting free access to electronic works by freely
sharing Project Gutenberg™ works in compliance with the terms of
this agreement for keeping the Project Gutenberg™ name associated
with the work. You can easily comply with the terms of this
agreement by keeping this work in the same format with its attached
full Project Gutenberg™ License when you share it without charge
with others.

1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside the
United States, check the laws of your country in addition to the
terms of this agreement before downloading, copying, displaying,
performing, distributing or creating derivative works based on this
work or any other Project Gutenberg™ work. The Foundation makes
no representations concerning the copyright status of any work in
any country other than the United States.

1.E. Unless you have removed all references to Project Gutenberg:

1.E.1. The following sentence, with active links to, or other


immediate access to, the full Project Gutenberg™ License must
appear prominently whenever any copy of a Project Gutenberg™
work (any work on which the phrase “Project Gutenberg” appears,
or with which the phrase “Project Gutenberg” is associated) is
accessed, displayed, performed, viewed, copied or distributed:
This eBook is for the use of anyone anywhere in the
United States and most other parts of the world at no
cost and with almost no restrictions whatsoever. You
may copy it, give it away or re-use it under the terms
of the Project Gutenberg License included with this
eBook or online at www.gutenberg.org. If you are not
located in the United States, you will have to check the
laws of the country where you are located before using
this eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is derived


from texts not protected by U.S. copyright law (does not contain a
notice indicating that it is posted with permission of the copyright
holder), the work can be copied and distributed to anyone in the
United States without paying any fees or charges. If you are
redistributing or providing access to a work with the phrase “Project
Gutenberg” associated with or appearing on the work, you must
comply either with the requirements of paragraphs 1.E.1 through
1.E.7 or obtain permission for the use of the work and the Project
Gutenberg™ trademark as set forth in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is posted


with the permission of the copyright holder, your use and distribution
must comply with both paragraphs 1.E.1 through 1.E.7 and any
additional terms imposed by the copyright holder. Additional terms
will be linked to the Project Gutenberg™ License for all works posted
with the permission of the copyright holder found at the beginning
of this work.

1.E.4. Do not unlink or detach or remove the full Project


Gutenberg™ License terms from this work, or any files containing a
part of this work or any other work associated with Project
Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute this


electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1
with active links or immediate access to the full terms of the Project
Gutenberg™ License.

1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if you
provide access to or distribute copies of a Project Gutenberg™ work
in a format other than “Plain Vanilla ASCII” or other format used in
the official version posted on the official Project Gutenberg™ website
(www.gutenberg.org), you must, at no additional cost, fee or
expense to the user, provide a copy, a means of exporting a copy, or
a means of obtaining a copy upon request, of the work in its original
“Plain Vanilla ASCII” or other form. Any alternate format must
include the full Project Gutenberg™ License as specified in
paragraph 1.E.1.

1.E.7. Do not charge a fee for access to, viewing, displaying,


performing, copying or distributing any Project Gutenberg™ works
unless you comply with paragraph 1.E.8 or 1.E.9.

1.E.8. You may charge a reasonable fee for copies of or providing


access to or distributing Project Gutenberg™ electronic works
provided that:

• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”

• You provide a full refund of any money paid by a user who


notifies you in writing (or by e-mail) within 30 days of receipt
that s/he does not agree to the terms of the full Project
Gutenberg™ License. You must require such a user to return or
destroy all copies of the works possessed in a physical medium
and discontinue all use of and all access to other copies of
Project Gutenberg™ works.

• You provide, in accordance with paragraph 1.F.3, a full refund of


any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.

• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.

1.E.9. If you wish to charge a fee or distribute a Project Gutenberg™


electronic work or group of works on different terms than are set
forth in this agreement, you must obtain permission in writing from
the Project Gutenberg Literary Archive Foundation, the manager of
the Project Gutenberg™ trademark. Contact the Foundation as set
forth in Section 3 below.

1.F.

1.F.1. Project Gutenberg volunteers and employees expend


considerable effort to identify, do copyright research on, transcribe
and proofread works not protected by U.S. copyright law in creating
the Project Gutenberg™ collection. Despite these efforts, Project
Gutenberg™ electronic works, and the medium on which they may
be stored, may contain “Defects,” such as, but not limited to,
incomplete, inaccurate or corrupt data, transcription errors, a
copyright or other intellectual property infringement, a defective or
damaged disk or other medium, a computer virus, or computer
codes that damage or cannot be read by your equipment.

1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for


the “Right of Replacement or Refund” described in paragraph 1.F.3,
the Project Gutenberg Literary Archive Foundation, the owner of the
Project Gutenberg™ trademark, and any other party distributing a
Project Gutenberg™ electronic work under this agreement, disclaim
all liability to you for damages, costs and expenses, including legal
fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR
NEGLIGENCE, STRICT LIABILITY, BREACH OF WARRANTY OR
BREACH OF CONTRACT EXCEPT THOSE PROVIDED IN PARAGRAPH
1.F.3. YOU AGREE THAT THE FOUNDATION, THE TRADEMARK
OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL
NOT BE LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT,
CONSEQUENTIAL, PUNITIVE OR INCIDENTAL DAMAGES EVEN IF
YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.

1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you


discover a defect in this electronic work within 90 days of receiving
it, you can receive a refund of the money (if any) you paid for it by
sending a written explanation to the person you received the work
from. If you received the work on a physical medium, you must
return the medium with your written explanation. The person or
entity that provided you with the defective work may elect to provide
a replacement copy in lieu of a refund. If you received the work
electronically, the person or entity providing it to you may choose to
give you a second opportunity to receive the work electronically in
lieu of a refund. If the second copy is also defective, you may
demand a refund in writing without further opportunities to fix the
problem.

1.F.4. Except for the limited right of replacement or refund set forth
in paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO
OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.

1.F.5. Some states do not allow disclaimers of certain implied


warranties or the exclusion or limitation of certain types of damages.
If any disclaimer or limitation set forth in this agreement violates the
law of the state applicable to this agreement, the agreement shall be
interpreted to make the maximum disclaimer or limitation permitted
by the applicable state law. The invalidity or unenforceability of any
provision of this agreement shall not void the remaining provisions.

1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation,


the trademark owner, any agent or employee of the Foundation,
anyone providing copies of Project Gutenberg™ electronic works in
accordance with this agreement, and any volunteers associated with
the production, promotion and distribution of Project Gutenberg™
electronic works, harmless from all liability, costs and expenses,
including legal fees, that arise directly or indirectly from any of the
following which you do or cause to occur: (a) distribution of this or
any Project Gutenberg™ work, (b) alteration, modification, or
additions or deletions to any Project Gutenberg™ work, and (c) any
Defect you cause.

Section 2. Information about the Mission


of Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new computers.
It exists because of the efforts of hundreds of volunteers and
donations from people in all walks of life.

Volunteers and financial support to provide volunteers with the


assistance they need are critical to reaching Project Gutenberg™’s
goals and ensuring that the Project Gutenberg™ collection will
remain freely available for generations to come. In 2001, the Project
Gutenberg Literary Archive Foundation was created to provide a
secure and permanent future for Project Gutenberg™ and future
generations. To learn more about the Project Gutenberg Literary
Archive Foundation and how your efforts and donations can help,
see Sections 3 and 4 and the Foundation information page at
www.gutenberg.org.

Section 3. Information about the Project


Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-profit
501(c)(3) educational corporation organized under the laws of the
state of Mississippi and granted tax exempt status by the Internal
Revenue Service. The Foundation’s EIN or federal tax identification
number is 64-6221541. Contributions to the Project Gutenberg
Literary Archive Foundation are tax deductible to the full extent
permitted by U.S. federal laws and your state’s laws.

The Foundation’s business office is located at 809 North 1500 West,


Salt Lake City, UT 84116, (801) 596-1887. Email contact links and up
to date contact information can be found at the Foundation’s website
and official page at www.gutenberg.org/contact

Section 4. Information about Donations to


the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission of
increasing the number of public domain and licensed works that can
be freely distributed in machine-readable form accessible by the
widest array of equipment including outdated equipment. Many
small donations ($1 to $5,000) are particularly important to
maintaining tax exempt status with the IRS.

The Foundation is committed to complying with the laws regulating


charities and charitable donations in all 50 states of the United
States. Compliance requirements are not uniform and it takes a
considerable effort, much paperwork and many fees to meet and
keep up with these requirements. We do not solicit donations in
locations where we have not received written confirmation of
compliance. To SEND DONATIONS or determine the status of
compliance for any particular state visit www.gutenberg.org/donate.

While we cannot and do not solicit contributions from states where


we have not met the solicitation requirements, we know of no
prohibition against accepting unsolicited donations from donors in
such states who approach us with offers to donate.

International donations are gratefully accepted, but we cannot make


any statements concerning tax treatment of donations received from
outside the United States. U.S. laws alone swamp our small staff.

Please check the Project Gutenberg web pages for current donation
methods and addresses. Donations are accepted in a number of
other ways including checks, online payments and credit card
donations. To donate, please visit: www.gutenberg.org/donate.

Section 5. General Information About


Project Gutenberg™ electronic works
Professor Michael S. Hart was the originator of the Project
Gutenberg™ concept of a library of electronic works that could be
freely shared with anyone. For forty years, he produced and
distributed Project Gutenberg™ eBooks with only a loose network of
volunteer support.
Project Gutenberg™ eBooks are often created from several printed
editions, all of which are confirmed as not protected by copyright in
the U.S. unless a copyright notice is included. Thus, we do not
necessarily keep eBooks in compliance with any particular paper
edition.

Most people start at our website which has the main PG search
facility: www.gutenberg.org.

This website includes information about Project Gutenberg™,


including how to make donations to the Project Gutenberg Literary
Archive Foundation, how to help produce our new eBooks, and how
to subscribe to our email newsletter to hear about new eBooks.
back
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.

More than just a book-buying platform, we strive to be a bridge


connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.

Join us on a journey of knowledge exploration, passion nurturing, and


personal growth every day!

ebookbell.com

You might also like