0% found this document useful (0 votes)
16 views7 pages

HOMEWORK Week 12

nice
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)
16 views7 pages

HOMEWORK Week 12

nice
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/ 7

Week 12 System-Level IO

Nguyen Thien Sang 20214972


10.1
Unix processes begin life with open descriptors assigned to stdin (descriptor 0), stdout (descriptor 1),
and stderr (descriptor 2). The open function always re turns the lowest unopened descriptor, so the
first call to open returns descriptor 3. The call to the close function frees up descriptor 3. The final call to
open returns descriptor 3, and thus the output of the program is fd2 = 3

Output:

10.2
Output:

The descriptors fd1 and fd2 each have their own open file table entry, so each descriptor has its own file
position for foobar.txt. Thus, the read from fd2 reads the first byte of foobar.txt, and the output is c=f
and not c=o.

10.3
Recall that the child inherits the parent’s descriptor table and that all processes shared the same open
file table. Thus, the descriptor fd in both the parent and child points to the same open file table entry.
When the child reads the first byte of the file, the file position increases by 1. Thus, the parent reads the
second byte, and the output is c=o

Output:

10.4
To redirect standard input (descriptor 0) to descriptor 5, we would call dup2(5,0), or equivalently,
dup2(5,STDIN_FILENO).

10.5
Output:
10.6

Result: File descriptor 0, 1 and 2 are reserved as follows: 0: stdin, 1: stdout, 2: stderr. -> 3: “foo.txt”, 4:
“bar.txt” -> 3: “foo.txt”, 4: “baz.txt”

10.7
// *
// Modify the cpfile program in Figure 10.5 it uses the RIO functions to
copy
// standard input to standard output, MAXBUF bytes at a time.

#include "csapp.h"

ssize_t cpfile(int srcfd, int dstfd) {


ssize_t total = 0, n;
char buf[MAXBUF];
do {
n = rio_readn(srcfd, buf, MAXBUF);
total += n;
if (n == -1) {
return -1;
}
rio_writen(dstfd, buf, n);
} while (n == MAXBUF);
return total;
}
int main() {
cpfile(STDIN_FILENO, STDOUT_FILENO);
}

Result:

10.8
// **
// Write a version of the statcheck program in Figure 10.10 called
fstatcheck
// that takes a descriptor number on the command line rather than a
filename.

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

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

mode_t fstatcheck(int fd) {


struct stat st;
int err = fstat(fd, &st);
if (err == -1)
return ~(mode_t)0;
return st.st_mode;
}

int main(int argc, char **argv) {

if (argc != 2) {
fprintf(stderr, "%s: Please specify the file descriptor.\n", argv[0]);
return EXIT_FAILURE;
}

int fd = atoi(argv[1]);
mode_t mode = fstatcheck(fd);

if (mode == ~(mode_t)0) {
fprintf(stderr, "fstat: %s\n", strerror(errno));
return EXIT_FAILURE;
}

const char *type, *readable;

switch (mode & S_IFMT) {


case S_IFSOCK: type = "socket"; break;
case S_IFLNK: type = "symbolic link"; break;
case S_IFREG: type = "regular file"; break;
case S_IFBLK: type = "block device"; break;
case S_IFDIR: type = "directory"; break;
case S_IFCHR: type = "character device"; break;
case S_IFIFO: type = "FIFO"; break;
}

char ur = mode & S_IRUSR ? 'r' : '-';


char uw = mode & S_IWUSR ? 'w' : '-';
char ux = mode & S_IXUSR ? 'x' : '-';
char gr = mode & S_IRGRP ? 'r' : '-';
char gw = mode & S_IWGRP ? 'w' : '-';
char gx = mode & S_IXGRP ? 'x' : '-';
char or = mode & S_IROTH ? 'r' : '-';
char ow = mode & S_IWOTH ? 'w' : '-';
char ox = mode & S_IXOTH ? 'x' : '-';

printf("file type: %s\nprivilege: %c%c%c%c%c%c%c%c%c\n", type,


ur, uw, ux, gr, gw, gx, or, ow, ox);

Result:
10.9
Consider the following invocation of the fstatcheck would fetch and display metadata for the
file foo.txt. However, when we run it on our system, it fails with a "bad file descriptor." Given
this behavior, fill in the pseudocode that the shell must be executing between fork and execve
calls:

if (Fork() == 0) { /* child */
/* What code is the shell executing right here? */
execve("fstatcheck", argv, envp);
}

Answer:

if (Fork() == 0) { /* child */
int foo = open("foo.txt", O_RDONLY, 0);
dup2(foo, STDIN_FILENO);
execve("execve", argv, envp);
}

You might also like