Blocking I/O (On A File): What is That?

Reading a File

  • Reading something from disk is not a trivial task

    • Rotating (hence the name disk, alas)

    • Head positioning

    • Interrupt when done

    • Direct Memory Access (DMA), done by controller chip

    • Interrupt when done

    • ⟶ requires a lot of coordination

  • abstractions are in order

  • ⟶ a job for an Operating System

Abstractions

  • What do we read?

    • Bytes from files

    • Organized in directories

    • File system

  • How do we read that?

    • Don’t want to position heads, and rotate moving parts

    • Worse: don’t want to hardwire my code to rotating disks. SSD? Network storage? RAM?

    • Don’t want to handle interrupts

    • Don’t even know what DMA is

    • ⟶ Only want to read that file

Simplicity

  • System call: open()

  • System call: read()

  • System call: write()

  • System call: close()

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


int main(void)
{
    // rotate disk, or whatever is necessary to get a hand on
    // /etc/passwd --> FILE DESCRIPTOR
    int fd = open("/etc/passwd", O_RDONLY);

    // error handling (/etc/passwd might not exist, o rI might not
    // have permissions to read it)
    if (fd == -1) {
        perror("open()");
        exit(1);
    }

    // allocate buffer, and *read* in a loop until done
    char buffer[16];
    while (1) {
        ssize_t nbytes_read = read(fd, buffer, sizeof(buffer));
        if (nbytes_read == 0) // end-of-file (EOF) -> done
            break;
        write(STDOUT_FILENO, buffer, nbytes_read);
    }

    // free resources
    close(fd);

    return 0;
}

Build, Run, Look

$ gcc -o read-file read-file.c
$ ls -l read-file
-rwxrwxr-x. 1 jfasch jfasch 24608 Mar  5 17:46 read-file
$ ./read-file
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...

Watch: Run Under strace Supervision

See what it does …

$ strace ./read-file
openat(AT_FDCWD, "/etc/passwd", O_RDONLY) = 3
read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 1024) = 1024
write(1, "root:x:0:0:root:/root:/bin/bash\n"..., 1024root:x:0:0:root:/root:/bin/bash
read(3, "nager:/:/sbin/nologin\ncolord:x:9"..., 1024) = 698
write(1, "nager:/:/sbin/nologin\ncolord:x:9"..., 698nager:/:/sbin/nologin
read(3, "", 1024)                       = 0
close(3)                                = 0