程序代写 CS162 ©UCB Spring 2022

Recall: Process Creating
• pid_t fork() – copy the current process – New process has different pid
– New process contains a single thread
• Return value from fork(): pid (like an integer)

Copyright By PowCoder代写 加微信 powcoder

– When > 0:
» Running in (original) Parent process » return value is pid of new child
– When = 0:
» Running in new Child process
– When < 0: » Error! Must handle somehow » Running in original process • State of original process duplicated in both Parent and Child! – Address Space (Memory), File Descriptors (covered later), etc... Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Recall: fork1.c #include
#include
#include
#include
int main(int argc, char *argv[]) {
pid_t cpid, mypid;
pid_t pid = getpid();
printf(“Parent pid: %d\n”, pid);
cpid = fork();
/* get current processes PID */
1/27/2022 }
Joseph & Kubiatowicz CS162 ©UCB Spring 2022
if (cpid > 0) { /* Parent Process */ mypid = getpid();
printf(“[%d] parent of [%d]\n”, mypid, cpid);
} else if (cpid == 0) { /* Child Process */ mypid = getpid();
printf(“[%d] child\n”, mypid);
perror(“Fork failed”);

Recall: fork1.c
if (cpid > 0) { /* Parent Process */ mypid = getpid();
printf(“[%d] parent of [%d]\n”, mypid, cpid);
} else if (cpid == 0) { /* Child Process */ mypid = getpid();
printf(“[%d] child\n”, mypid);
perror(“Fork failed”);
#include
#include
#include
#include
int main(int argc, char *argv[]) {
pid_t cpid, mypid;
pid_t pid = getpid();
printf(“Parent pid: %d\n”, pid);
cpid = fork();
/* get current processes PID */
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

pid_t cpid = fork();
if (cpid > 0) {
for (i = 0; i < 10; i++) { printf("Parent: %d\n", i); // sleep(1); } else if (cpid == 0) { for (i = 0; i > -10; i–) {
printf(“Child: %d\n”, i);
// sleep(1);
Recall: a process consists of one or more threads executing in an address space
• Here, each process has a single thread
• These threads execute concurrently
Mystery: fork_race.c
• What does this print?
• Would adding the calls to sleep() matter?
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Process Management API
• exit – terminate a process
• fork – copy the current process
• exec – change the program being run by the current process
• wait – wait for a process to finish
• kill – send a signal (interrupt-like notification) to another process • sigaction – set handlers for signals
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Starting new Program: variants of exec
cpid = fork();
if (cpid > 0) { /* Parent Process */
tcpid = wait(&status);
} else if (cpid == 0) { /* Child Process */
char *args[] = {“ls”, “-l”, NULL};
execv(“/bin/ls”, args);
/* execv doesn’t return when it works.
So, if we got here, it failed! */
perror(“execv”);
exit(1); }
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

fork2.c – parent waits for child to finish
int status; pid_t tcpid;
cpid = fork(); if (cpid > 0) {
/* Parent Process */
mypid = getpid();
printf(“[%d] parent of [%d]\n”, mypid, cpid);
tcpid = wait(&status);
printf(“[%d] bye %d(%d)\n”, mypid, tcpid, status);
} else if (cpid == 0) { /* Child Process */
mypid = getpid();
printf(“[%d] child\n”, mypid);
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Process Management:The Shell pattern
pid=fork(); if (pid==0) exec(…);
wait(&stat)
pid=fork(); if (pid==0) exec(…);
wait(&stat)
pid=fork(); if (pid==0) exec(…);
wait(&stat)
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Process Management API
• exit – terminate a process
• fork – copy the current process
• exec – change the program being run by the current process
• wait – wait for a process to finish
• kill – send a signal (interrupt-like notification) to another process • sigaction – set handlers for signals
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

inf_loop.c
#include
#include
#include
#include
#include
void signal_callback_handler(int signum) {
printf(“Caught signal!\n”);
int main() {
struct sigaction sa;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sa.sa_handler = signal_callback_handler;
sigaction(SIGINT, &sa, NULL);
while (1) {}
Q:What would happen if the process receives a SIGINT signal, but does not register a signal handler?
A:The process dies!
For each signal, there is a default handler defined by the system
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Common POSIX Signals
• SIGINT – control-C
• SIGTERM – default for kill shell command
• SIGSTP – control-Z (default action: stop process)
• SIGKILL, SIGSTOP – terminate/stop process – Can’t be changed with sigaction
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Recall: UNIX System Structure
Applications Standard Libs
Kernel Mode
Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.12

A Kind of Narrow Waist
Compilers Word Processing Web Browsers Email
Web Servers
Application / Service
Portable OS Library OS
Portable OS Kernel Platform support, Device Drivers
System Call Interface
Software Hardware
Ethernet (1Gbs/10Gbs) 802.11 a/g/n/ac SCSI Graphics Thunderbolt
PowerPC ARM
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Recall: OS Library (libc) Issues Syscalls
Proc 1 2…n
Window Manager
libc OS library
OS library
OS library
• OS Library: Code linked into the user-level application that provides a clean or more functional API to the user than just the raw syscalls
– Most of this code runs at user level, but makes syscalls (which run at kernel level)
1/27/2022 Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.14

Unix/POSIX Idea: Everything is a “File”
• Identical interface for: – Files on disk
– Devices (terminals, printers, etc.)
– Regular files on disk
– Networking (sockets)
– Local interprocess communication (pipes, sockets)
• Based on the system calls open(), read(), write(), and close()
• Additional: ioctl() for custom configuration that doesn’t quite fit
• Note that the “Everything is a File” idea was a radical idea when proposed
– and described this idea in their seminal paper on UNIX called “The UNIX Time-Sharing System” from 1974
– I posted this on the resources page if you are curious
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Aside: POSIX interfaces
• POSIX: Portable Operating System Interface (for uniX?) – Interface for application programmers (mostly)
– Defines the term “Unix,” derived from AT&T Unix
– Created to bring order to many Unix-derived OSes, so applications are portable » Partially available on non-Unix OSes, like Windows
– Requires standard system call interface
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

The File System Abstraction
– Named collection of data in a file system
– POSIX File data: sequence of bytes
» Could be text, binary, serialized objects, …
– File Metadata: information about the file
» Size, Modification Time, Owner, Security info, Access control
• Directory
– “Folder” containing files & directories
– Hierachical (graphical) naming
» Path through the directory graph
» Uniquely identifies a file or directory
• /home/ff/cs162/public_html/fa14/index.html – Links and Volumes (later)
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Connecting Processes, File Systems, and Users
• Every process has a current working directory (CWD) – Can be set with system call:
int chdir(const char *path); //change CWD
• Absolute paths ignore CWD – /home/oski/cs162
• Relative paths are relative to CWD
– index.html, ./index.html
» Refers to index.html in current working directory
– ../index.html
» Refers to index.html in parent of current working directory
– ~/index.html, ~cs162/index.html
» Refers to index.html in the home directory
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

I/O and Storage Layers
Application / Service
Streams (buffered I/O)
File Descriptors
open(), read(), write(), close(), … Open File Descriptions
Files/Directories/Indexes Commands and DataTransfers
Disks, Flash, Controllers, DMA
Joseph & Kubiatowicz CS162 ©UCB Spring 2022
High Level I/O
Low Level I/O
File System

C High-Level File API – Streams
• Operates on “streams” – unformatted sequences of bytes (wither text or binary data), with a position:
#include
FILE *fopen( const char *filename, const char );
int fclose( FILE *fp );
Mode Text r
Binary Descriptions
rb Open existing file for reading
wb Open for writing; created if does not exist
ab Open for appending; created if does not exist
rb+ Open existing file for reading & writing.
wb+ Open for reading & writing; truncated to zero if exists, create otherwise
ab+ Open for reading & writing. Created if does not exist. Read from beginning, write as append
• Open stream represented by pointer to a FILE data structure – Error reported by returning a NULL pointer
1/27/2022 Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.20

C API Standard Streams – stdio.h
• Three predefined streams are opened implicitly when the program is executed. – FILE *stdin – normal source of input, can be redirected
– FILE *stdout – normal source of output, can too
– FILE *stderr – diagnostics and errors
• STDIN / STDOUT enable composition in Unix
• All can be redirected
– cat hello.txt | grep “World!”
– cat’s stdout goes to grep’s stdin
1/27/2022 Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.21

C High-Level File API
// character oriented
int fputc( int c, FILE *fp ); // rtn c or EOF on err int fputs( const char *s, FILE *fp ); // rtn > 0 or EOF
int fgetc( FILE * fp );
char *fgets( char *buf, int n, FILE *fp );
// block oriented
size_t fread(void *ptr, size_t size_of_elements,
size_t number_of_elements, FILE *a_file);
size_t fwrite(const void *ptr, size_t size_of_elements,
size_t number_of_elements, FILE *a_file);
// formatted
int fprintf(FILE *restrict stream, const char *restrict format, …);
int fscanf(FILE *restrict stream, const char *restrict format, … );
1/27/2022 Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.22

C Streams: Char-by-Char I/O
int main(void) {
FILE* input = fopen(“input.txt”, “r”);
FILE* output = fopen(“output.txt”, “w”);
c = fgetc(input);
while (c != EOF) {
fputc(output, c);
c = fgetc(input);
fclose(input);
fclose(output);
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

C High-Level File API
// character oriented
int fputc( int c, FILE *fp ); // rtn c or EOF on err int fputs( const char *s, FILE *fp ); // rtn > 0 or EOF
int fgetc( FILE * fp );
char *fgets( char *buf, int n, FILE *fp );
// block oriented
size_t fread(void *ptr, size_t size_of_elements,
size_t number_of_elements, FILE *a_file);
size_t fwrite(const void *ptr, size_t size_of_elements,
size_t number_of_elements, FILE *a_file);
// formatted
int fprintf(FILE *restrict stream, const char *restrict format, …);
int fscanf(FILE *restrict stream, const char *restrict format, … );
1/27/2022 Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.24

C Streams: Block-by-Block I/O
#define BUFFER_SIZE 1024
int main(void) {
FILE* input = fopen(“input.txt”, “r”);
FILE* output = fopen(“output.txt”, “w”);
char buffer[BUFFER_SIZE];
size_t length;
length = fread(buffer, BUFFER_SIZE, sizeof(char), input);
while (length > 0) {
fwrite(buffer, length, sizeof(char), output);
length = fread(buffer, BUFFER_SIZE, sizeof(char), input);
fclose(input);
fclose(output);
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Aside: Check your Errors!
• Systems programmers should always be paranoid! – Otherwise you get intermittently buggy code
• We should really be writing things like:
FILE* input = fopen(“input.txt”, “r”);
if (input == NULL) {
// Prints our string and error msg.
perror(“Failed to open input file”)
• Be thorough about checking return values!
– Want failures to be systematically caught and dealt with
• I may be a bit loose with error checking for examples in class (to keep short)
– Do as I say,not as I show in class!
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

C High-Level File API: Positioning The Pointer
int fseek(FILE *stream, long int offset, int whence); long int ftell (FILE *stream)
void rewind (FILE *stream)
• For fseek(), the offset is interpreted based on the whence argument (constants in stdio.h):
– SEEK_SET:Then offset interpreted from beginning (position 0) – SEEK_END:Then offset interpreted backwards from end of file – SEEK_CUR:Then offset interpreted from current position
offset offset (SEEK_SET) (SEEK_END)
• Overall preserves high(S-EleEvKe_lCaUbRs)traction of a uniform stream of objects
1/27/2022 Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.27

I/O and Storage Layers
Application / Service
Streams (buffered I/O)
File Descriptors
open(), read(), write(), close(), … Open File Descriptions
Files/Directories/Indexes Commands and DataTransfers
Disks, Flash, Controllers, DMA
Joseph & Kubiatowicz CS162 ©UCB Spring 2022
High Level I/O
Low Level I/O
File System

Low-Level File I/O:The RAW system-call interface
#include
#include
#include
int open (const char *filename, [, mode_t mode])
int creat (const char *filename, mode_t mode)
int close (int filedes)
Bit vector of:
• Access modes (Rd,Wr, …)
• Open Flags (Create, …)
• Operating modes (Appends, …)
Bit vector of Permission Bits:
• User|Group|Other X R|W|X
• Integer return from open() is a file descriptor
– Error indicated by return < 0: the global errno variable set with error (see man pages) • Operations on file descriptors: – Open system call created an open file description entry in system-wide table of open files – Open file description object in the kernel represents an instance of an open file – Why give user an integer instead of a pointer to the file description in kernel? 1/27/2022 Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.29 C Low-Level (pre-opened) Standard Descriptors #include
STDIN_FILENO – macro has value 0
STDOUT_FILENO – macro has value 1
STDERR_FILENO – macro has value 2
// Get file descriptor inside FILE *
int fileno (FILE *stream)
// Make FILE * from descriptor
FILE * fdopen (int filedes, const char *opentype)
1/27/2022 Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.30

Low-Level File API
• Read data from open file using file descriptor:
ssize_t read (int filedes, void *buffer, size_t maxsize) – Reads up to maxsize bytes – might actually read less!
– returns bytes read, 0 => EOF, -1 => error
• Write data to open file using file descriptor
ssize_t write (int filedes, const void *buffer, size_t size) – returns number of bytes written
• Reposition file offset within kernel (this is independent of any position held by high-level FILE descriptor for this file!
off_t lseek (int filedes, off_t offset, int whence)
1/27/2022 Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.31

Example: lowio.c
int main() {
char buf[1000];
int fd = open(“lowio.c”, O_RDONLY, S_IRUSR | S_IWUSR);
ssize_t rd = read(fd, buf, sizeof(buf));
int err = close(fd);
ssize_t wr = write(STDOUT_FILENO, buf, rd);
• How many bytes does this program read?
1/27/2022 Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.32

POSIX I/O: Design Patterns
• Open before use
– Access control check, setup happens here
• Byte-oriented
– Least common denominator
– OS responsible for hiding the fact that real devices may not work this way (e.g. hard drive stores data in blocks)
• Explicit close
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

POSIX I/O: Kernel Buffering
• Reads are buffered inside kernel
– Part of making everything byte-oriented
– Process is blocked while waiting for device
– Let other processes run while gathering result
• Writes are buffered inside kernel
– Complete in background (more later on)
– Return to user when data is “handed off ” to kernel
• This buffering is part of global buffer management and caching for block devices (such as disks)
– Items typically cached in quanta of disk block sizes
– We will have many interesting things to say about this buffering when we dive into the kernel
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Low-Level I/O: Other Operations
• Operations specific to terminals, devices, networking, … – e.g.,ioctl
• Duplicating descriptors
– int dup2(int old, int new); – int dup(int old);
• Pipes – channel
– int pipe(int pipefd[2]);
– Writes to pipefd[1] can be read from pipefd[0]
• File Locking
• Memory-Mapping Files
• Asynchronous I/O
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

High-Level vs. Low-Level File API
High-Level Operation: size_t fread(…) {
Do some work like a normal fn…
asm code … syscall # into %eax put args into registers %ebx, … special trap instruction
Low-Level Operation: ssize_t read(…) {
asm code … syscall # into %eax put args into registers %ebx, … special trap instruction
get args from regs
dispatch to system func
Do the work to read from the file Store return value in %eax
get args from regs
dispatch to system func
Do the work to read from the file Store return value in %eax
get return values from regs
Do some more work like a normal fn… };
get return values from regs };
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

High-Level vs. Low-Level File API
• Streams are buffered in user memory:
printf(“Beginning of line “);
sleep(10); // sleep for 10 seconds
printf(“and end of line\n”);
Prints out everything at once
• Operations on file descriptors are visible immediately
write(STDOUT_FILENO, “Beginning of line “, 18);
sleep(10);
write(“and end of line \n”, 16);
Outputs “Beginning of line” 10 seconds earlier than “and end of line”
1/27/2022 Joseph & Kubiatowicz CS162 ©UCB Spring 2022 Lec 4.37

What’s below the surface ??
Application / Service
High Level I/O
Low Level I/O
File System
I/O Driver
handles registers descriptors
Commands and Data Transfers Disks, Flash, Controllers, DMA
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

Recall: SYSCALL
• Low level lib parameters are set up in registers and syscall instruction is issued
– A type of synchronous exception that enters well-defined entry points into kernel
Joseph & Kubiatowicz CS162 ©UCB Spring 2022

What’s below the surface ??
Application / Service
High Level I/O
Low Level I/O
File System
I/O Driver
handles registers descriptors
Commands and Data Transfers Disks, Flash, Controllers, DMA
Joseph & Kubiatowicz CS162 ©UCB Spring 2022
File descriptor number – an int
File Descriptors
• a struct with all the info
about the files

What’s in an Open File Description?
Inside Kernel!
For our pur

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com