Virtualization

Process API

2

  1. Write a program that opens a file (with the open()system call)and then calls fork()to create a new process. Can both the child and parent access the file descriptor returned by open()? What happens when they are writing to the file concurrently, i.e., at the same time?

父子进程都可以使用文件描述符。同时写入会导致内容相互覆盖,多次运行结果不一致。

/*
 *     ____              _    
 *    / __ \____ _____  (_)___
 *   / /_/ / __ `/ __ \/ /_  /
 *  / _, _/ /_/ / /_/ / / / /_
 * /_/ |_|\__,_/ .___/_/ /___/
 *            /_/             
 *           code@rapiz.me
 *          Sat, 27 Jun 2020 17:18:45 +0800
 */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

typedef long long ll;
void ww(int fd, int count, const char* str) {
    int len = strlen(str);
    for (int i = 0; i < count; i++) {
        write(fd, str, len);
    }
}
int main() {
    int t = fork();
    int fd = open("/tmp/testfile", O_CREAT | O_WRONLY, S_IRWXU);
    if (t < 0) {
        fprintf(stderr, "opps!\n");
    }
    else if (t == 0) {
        char* child = "imchild";
        ww(fd, 100, child);
    }
    else {
        char* parent = "imparent";
        ww(fd, 100, parent);
    }
}

7

Write a program that creates a child process, and then in the child closes standard output (STDOUT_FILENO). What happens if the child call sprintf()to print some output after closing the descriptor?

Answer

子进程输出不会显示任何字符。

/*
 *     ____              _    
 *    / __ \____ _____  (_)___
 *   / /_/ / __ `/ __ \/ /_  /
 *  / _, _/ /_/ / /_/ / / / /_
 * /_/ |_|\__,_/ .___/_/ /___/
 *            /_/             
 *           code@rapiz.me
 *          Sat, 27 Jun 2020 17:18:45 +0800
 */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

typedef long long ll;
void ww(int fd, int count, const char* str) {
    int len = strlen(str);
    for (int i = 0; i < count; i++) {
        write(fd, str, len);
    }
}
int main() {
    int t = fork();
    int fd = open("/tmp/testfile", O_CREAT | O_WRONLY, S_IRWXU);
    if (t < 0) {
        fprintf(stderr, "opps!\n");
    }
    else if (t == 0) {
        close(STDOUT_FILENO);
        printf("I'm child\n");
    }
    else {
        printf("I'm parent\n");
    }
}

8

Write a program that creates two children, and connects the standard output of one to the standard input of the other, using the pipe() system call.

/*
 *     ____              _    
 *    / __ \____ _____  (_)___
 *   / /_/ / __ `/ __ \/ /_  /
 *  / _, _/ /_/ / /_/ / / / /_
 * /_/ |_|\__,_/ .___/_/ /___/
 *            /_/             
 *           code@rapiz.me
 *          Sat, 27 Jun 2020 17:43:17 +0800
 */
#define _GNU_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
typedef long long ll;
int main() {
    int pipefd[2];
    pipe(pipefd);
    int t = fork();
    if (t < 0) {
        fprintf(stderr,"opps\n");
    }
    else if (t == 0) {
        const char* str = "I'm child one";
        write(pipefd[1], str, strlen(str)); 
    }
    else {
        printf("I'm parent\n");
        int t2 = fork();
        if (t2 == 0) {
            const int LEN = 100;
            char buf[LEN];
            read(pipefd[0], buf, LEN); 
            printf("I'm child two and read: %s\n", buf);
        }
    }
}