COMP 3150Operating Systems

01 Introduction

Lesson 1.1 introduced the two roles of an operating system. This lesson makes them concrete by cataloguing the services that an operating system actually provides. A service, in this context, is something the OS does for the benefit of programs, users, or the system as a whole.

Not every operating system provides exactly the same set of services. A mobile operating system emphasises different services than a server operating system. An embedded OS may strip services to the minimum. But there is a common core, and understanding it is essential for reasoning about what an OS can and cannot do.

A useful organising distinction is between services that help programs and services that help the system itself. The first category is what application developers interact with daily. The second is what keeps the machine running safely and efficiently.

02 Learning objectives

By the end of this lesson you will be able to

  • Identify major OS services.
  • Explain program execution services.
  • Explain I/O and file services.
  • Describe protection and security services.
  • Analyse service support for applications.

This lesson contributes to U1.3 and course learning outcome CLO1.

03 Required reading

  • Operating System Concepts — Chapter 2, Operating-System Structures, Section 2.1, Operating-System Services.
  • Skim man 2 syscalls in your Linux VM. You do not need to memorise the list; the goal is to see the shape of the interface.

04 Core content

4.1 Two categories of service

Operating-system services fall into two groups with different audiences.

Services that help programs and users

  • Program execution
  • I/O operations
  • File-system manipulation
  • Communications
  • Error detection

Services that help the system itself

  • Resource allocation
  • Logging and accounting
  • Protection and security
  • Scheduling
  • System management

The distinction is useful because it clarifies why some services have user-visible APIs while others do not. A program calls open() to manipulate a file; a program does not call a function to "log CPU usage" — that is a system concern.

Operating-system services, grouped by audience A diagram showing eleven OS services arranged in two groups. User-facing services — program execution, I/O, file system, communications, error detection — sit above a boundary. System-facing services — resource allocation, accounting, protection and security, scheduling, system management — sit below. OPERATING-SYSTEM SERVICES SERVICES FOR PROGRAMS AND USERS Program execution I/O operations File system Communi- cations Error detection Requested by application code through system calls and libraries. Examples: open, read, write, fork, exec, socket, connect. KERNEL BOUNDARY SERVICES FOR THE SYSTEM ITSELF Resource allocation Logging & accounting Protection & security Scheduling & dispatch System management Not directly exposed to application code. Examples: process scheduler, page-replacement policy, audit subsystem. Some are indirectly configurable — for example via nice, ulimit, or a sandbox policy.
Figure 1.3 — Operating-system services grouped by audience. The upper group is exposed to programs; the lower group serves the system and is only indirectly configurable by users.

4.2 Program execution

The most fundamental service is simply running programs. To run a program, the operating system must be able to:

  • Load the program's executable image from persistent storage into memory.
  • Set up an address space with the code, static data, heap, and stack laid out correctly.
  • Initialise execution context — registers, program counter, stack pointer, file descriptors (including standard input, output, and error).
  • Transfer control to the program's entry point.
  • Reclaim resources when the program terminates, normally or abnormally.

This service is also responsible for the interface between programs and each other. A process can, with OS permission, create a child process, wait for it to complete, or send it a signal. The POSIX fork/exec/wait trio is the canonical example of a program-execution service.

4.3 I/O operations

Programs cannot and should not touch device registers directly. Instead, the operating system provides an I/O service that hides device specifics behind uniform interfaces.

The uniformity is significant. A program that writes to a file, a pipe, a network socket, or a terminal can often use the same write() system call. The operating system handles the translation into whatever device operations are required.

/* All three use the same write() call. */
write(file_fd,    buf, len);   /* regular file   */
write(pipe_fd,    buf, len);   /* pipe           */
write(socket_fd,  buf, len);   /* network socket */

This design is a direct illustration of the "extended machine" view from Lesson 1.1. The program sees a uniform interface; the OS sees three very different devices.

4.4 File-system manipulation

Programs need to read and write data, and they need a way to name and organise that data persistently. The file-system service provides:

  • Files — named containers for sequences of bytes.
  • Directories — named containers for files and other directories, forming a tree.
  • Metadata — ownership, permissions, size, modification time, and so on.
  • Operations — create, open, read, write, seek, close, delete, rename.
  • Access control — which users may perform which operations on which files.

The file system is explored in depth in Module 4. For now, the essential point is that the file-system service provides both a storage abstraction and a namespace in which programs find their data.

4.5 Communications

Processes frequently need to exchange data, either on the same machine or across a network. The operating system provides two broad styles of communication:

Shared memory
Two or more processes map the same region of physical memory into their address spaces. Reading and writing proceed at memory speed, but access must be synchronised explicitly by the processes — this is a topic in Module 2.
Message passing
Processes exchange discrete messages through a kernel-mediated channel: a pipe, a socket, a message queue, or a remote procedure call. The kernel handles buffering and delivery, so the processes do not need to synchronise memory access themselves.

Pipes, FIFOs, UNIX-domain sockets, TCP/IP sockets, and shared memory segments are all communication services provided by a modern OS. They differ in scope (local versus networked), semantics (stream versus datagram), and performance.

4.6 Error detection

Programs make mistakes, and hardware fails. The operating system detects and, where possible, contains errors.

  • Hardware errors. Memory parity failures, device failures, power interruptions, and network errors are reported to the OS by hardware and by device drivers.
  • Software errors. Arithmetic overflow, illegal memory access, division by zero, and misuse of system calls are detected by hardware or by the kernel itself.
  • Response. Depending on the error and the policy, the OS may return an error code to the program, terminate the offending process, or take more drastic action.

Containment matters

A bug in one program should not be able to take down the machine. This is one of the reasons isolation — a protection service, discussed below — is fundamental.

4.7 Resource allocation

When multiple users or multiple jobs run concurrently, each needs resources. The operating system allocates:

  • CPU time — through the process scheduler.
  • Memory — through the memory allocator and the virtual-memory subsystem.
  • Storage — through file-system allocation and quota mechanisms.
  • Devices — through device scheduling and exclusive-access mechanisms.
  • Network bandwidth — through traffic shaping and quality-of-service mechanisms.

Allocation is intimately tied to scheduling. The resources in shortest supply — CPU cycles and physical memory — are managed most aggressively, and the policies governing them are a recurring theme in Modules 2 and 3.

4.8 Logging and accounting

Operating systems track what happens on the machine. Logging supports debugging and security auditing; accounting supports billing and resource-usage analysis. On Linux, the audit subsystem can record file accesses, process executions, and system-call invocations, and utilities such as sa and acct can summarise historical resource usage.

4.9 Protection and security

This service is treated separately in Unit 12, but its foundation belongs here. Protection and security in an operating system address three related questions:

  • Isolation. How do we prevent one process from reading or modifying another's memory?
  • Authentication. How do we know that a user is who they claim to be?
  • Authorization. Given an authenticated user, what are they allowed to do?

On a multi-user system, protection is enforced by hardware support (user mode and kernel mode, an MMU, a timer) plus kernel policy. On a single-user system, the same mechanisms still matter, because a single user typically runs many programs of varying trustworthiness.

4.10 Support for applications

The final consideration is how the services combine to support real application software. Consider a modern web browser rendering a page:

Browser operations and the OS services they rely on
Browser operation OS service used
Open a socket to a web server Communications, I/O
Read the HTTP response I/O, communications
Parse and lay out the page Memory allocation, program execution
Cache assets to disk File-system manipulation
Render to the screen I/O (graphics device)
Sandbox each tab Protection and security
Handle a network timeout gracefully Error detection
Run in the background while another app has focus Resource allocation, scheduling

Every nontrivial application leans on the same set of services. When you design software, knowing which services exist and what guarantees they provide is as important as knowing the language you write in.

05 Worked example

Trace a small program that reads a file and writes a summary, and identify which service is responsible for each step.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "usage: %s FILE\n", argv[0]);
        return 1;
    }

    FILE *f = fopen(argv[1], "r");
    if (!f) {
        perror("fopen");
        return 1;
    }

    long lines = 0;
    int c;
    while ((c = fgetc(f)) != EOF) {
        if (c == '\n') lines++;
    }

    fclose(f);
    printf("%ld\n", lines);
    return 0;
}

Services invoked, step by step

  1. Program execution. The shell asks the kernel to run this program. The kernel creates a new process, loads the executable, and transfers control to main.
  2. Error detection. The program's argument check and its fopen check are the program's own responsibility, but the underlying failure that fopen reports — such as a missing file or a permission denial — is detected by the OS and returned as an error code.
  3. File-system manipulation. fopen eventually calls the open system call. The kernel resolves the path, checks permissions, locates the inode, and returns a file descriptor.
  4. I/O operations. Each fgetc pulls a character from the standard library's buffer; periodically the buffer is refilled by a read system call, which the kernel translates into device operations.
  5. Memory allocation. The standard library allocates a small buffer for file I/O; the heap grows in response to demand. The kernel maps additional pages into the process address space as needed.
  6. Resource allocation. While this program runs, the scheduler is sharing the CPU with every other process on the system. Its share is not visible to the program but is governed by the OS.
  7. Communications. The printf call writes to standard output, which — when the program is run from a shell in a terminal — is a file descriptor connected to a pseudoterminal, a form of interprocess communication.
  8. Program termination. Returning from main causes the runtime to call exit, which flushes buffers and asks the kernel to reclaim the process's resources.

An important habit

Once you can name the OS services a program relies on, you can reason about its performance and security. A bottleneck might be file-system allocation, not the algorithm. A vulnerability might be a failure to check an error return, not a flaw in the logic.

06 Interactive activity

Activity · map a real command to the service list

In your VM, run each command below and identify which OS services are involved. At least two services apply to every command.

  1. cat /etc/hostname — start with the easy one.
  2. cp /etc/hostname /tmp/copy.txt — a second file is created.
  3. ping -c 1 127.0.0.1 — network communication is involved.
  4. sleep 5 & — a process runs in the background; observe it with jobs.
  5. echo hello | grep hell — a pipe connects two processes.

For each command, note: which service was most prominent, which was least visible, and whether any errors were possible that the OS would have detected.

07 Knowledge check

Check your understanding

Question 1

Why does the operating system expose a single write() call for files, pipes, sockets, and terminals, rather than a different call for each?

Show answer
Because the extended-machine view is more valuable when the abstractions are uniform. A program that writes to standard output does not need to know whether the destination is a file, a pipe, or a socket. The OS hides the device-specific differences behind a single interface, which makes programs composable and portable. This is precisely the design that makes shell pipelines possible: prog1 | prog2 works because prog2 reads from its standard input regardless of whether the producer is a file or another program.

Question 2

Distinguish shared-memory communication from message-passing communication. What is the main trade-off between them?

Show answer
In shared memory, processes map the same physical pages and read and write directly. In message passing, processes exchange discrete messages through a kernel-mediated channel. The trade-off is speed versus convenience and safety: shared memory is faster once set up, but the processes must synchronise access explicitly and avoid subtle bugs. Message passing imposes kernel overhead on every message but handles synchronisation and buffering for the programmer.

Question 3

Which service is responsible for detecting that a program has tried to write to an address outside its address space? What happens if it does?

Show answer
This is the error-detection service, aided by the protection service and the MMU. When the CPU attempts an access to an address that is not mapped in the process's page table, the MMU raises a page fault or a protection fault. The kernel's fault handler determines that the access was invalid — not a legitimate demand-paging event — and typically terminates the process with a segmentation violation (SIGSEGV on Linux). Other processes and the kernel continue unaffected.

08 Unit discussion

Discussion prompt

The lesson groups OS services into those that help programs and those that help the system. Some services, such as scheduling, are only indirectly configurable by users — through nice, ulimit, or a container's resource limits. Pick one such indirect control and argue whether users should have more, less, or the same amount of control over it. Justify your answer with reference to a real workload or system.

Post your response to the Unit 1 discussion forum and reply to at least two classmates. Supports CLO1.

09 Practice exercise

  1. Classify the calls. Read the man page man 2 syscalls and pick ten system calls at random. Classify each under one of the service categories from this lesson.
  2. Trace a command. Run strace -f -e trace=openat,read,write cp /etc/hostname /tmp/x. Identify at least three distinct services at work.
  3. Design a service. Imagine an OS for a wearable device with a small battery. Which services from this lesson would you prioritise? Which would you trim or omit? Write a short rationale (200–300 words).
  4. Read one real interface. Read man 2 open in full. Note at least three flags that affect protection or error handling.

10 Summary

  • OS services fall into two groups: those that help programs and users, and those that help the system itself.
  • Program-execution services load programs, set up address spaces, transfer control, and reclaim resources on termination.
  • I/O, file-system, and communication services present uniform abstractions over diverse hardware and protocols.
  • Error detection, resource allocation, logging, and accounting keep the machine healthy and observable.
  • Protection and security services address isolation, authentication, and authorization — and rest on hardware support plus kernel policy.
  • Any nontrivial application relies on all of these services. Being able to identify them for a given program is a skill worth developing.

Looking ahead

Lesson 1.4 examines the mechanism by which programs request these services — the system call, and the mode switch that separates user space from kernel space.

11 References

  • Silberschatz, A., Galvin, P. B., & Gagne, G. Operating System Concepts, Chapter 2.
  • Arpaci-Dusseau, R. H., & Arpaci-Dusseau, A. C. Operating Systems: Three Easy Pieces, Chapters 2 and 4.
  • Linux man-pages project: man 2 intro, man 2 syscalls.
👤