February 8, 2019
For today:
1) Finish Homework 2
2) Read Head First C, Chapter 2.5
3) Finish Linux tutorial, part two, whatever we don't do in class.
Today:
1) What's a process
2) Homework 2 debrief
3) Head First C, Chapter 2.5
4) Homework 2.5?
For next time:
1) Read Think OS Chapter 3 (make sure you get version 0.8.1) and do the reading quiz
2) Start Homework 2.5
What's the difference between a program and a process?
A program is just the code (source code or machine code).
A process is an operating system data structure that contains everything we need to know about a running program:
In Julia's diagram, "memory" refers to the whole virtual address space: text, constants, globals, heap, and stack.
Download this solution: adder.c
Exercise: improve the interface of read_integer.
1) Take a pointer as an argument.
2) Store the result at the pointee of the pointer.
3) Return 0 for success and -1 otherwise (or different error codes for different errors).
4) Optional challenge: replace atoi with strtol so the user can enter 0. See the strtol man page.
HFC Chapter 2.5
Using a library actually involves two steps:
1) Include the header file so the compiler knows what functions and constants are in the library.
2) Link with the library to get the actual code.
What to do about the minutia (like the differences between fgets and fscanf)? This kind of knowledge is hard to keep fresh. But you can (1) remember the red flag and (2) check the docs.
The functions described in string.h provide a low-level API.
They don't do very much, so they have simple, fast implementations.
Most of them don't do any memory management, so the caller has control over allocation and copying.
They provide almost no error checking, so the caller can minimize overhead.
All of this is good for learning, and good for low-level programming, but bad for application programming.
Development time is slow because programmers end up rebuilding the same support code.
The resulting programs tend to have hard-to-find bugs and security problems.
Which brings us to buffer overflow (see https://en.wikipedia.org/wiki/Buffer_overflow).
Buffer overflows can allow users to violate security constraints. For example, by sending a carefully crafted request to a web server, you might cause the server to execute arbitrary code on your behalf. See the example here.
The core of this exploit is usually to overwrite a return address stored on the run time stack.
In my opinion, the decision to sacrifice critical security for irrelevant performance will be regarded in retrospect as one of the most costly and unwise engineering failures of the 20th/21st Century, along with reinforced concrete.
If you are interested in this kind of vulnerability, consider a security-related project.
Later in the semester, you will have a chance to work with GLib, which provides a higher-level string API. Or you could consider a project using GLib.