diff --git a/ostep/hw5/Makefile b/ostep/hw5/Makefile index 15dbb62..b780505 100644 --- a/ostep/hw5/Makefile +++ b/ostep/hw5/Makefile @@ -1,4 +1,10 @@ -TARGETS := hw5_1 +TARGETS := hw5_1 \ + hw5_2 \ + hw5_3 \ + hw5_5 \ + hw5_6 \ + hw5_7 \ + hw5_8 all: $(TARGETS) diff --git a/ostep/hw5/hw5_2.c b/ostep/hw5/hw5_2.c new file mode 100644 index 0000000..5e6bf56 --- /dev/null +++ b/ostep/hw5/hw5_2.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include + +const char default_path[] = "hello.txt"; + +int +main(int argc, char *argv[]) +{ + char buf[2] = {0x41, 0x0a}; + char *pathname = (char *)default_path; + int fd = -1; + + if (argc > 1) { + pathname = argv[1]; + } + + fd = open(pathname, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR); + if (fd == -1) { + perror("open"); + exit(1); + } + + pid_t pid = fork(); + if (pid < 0) { + perror("fork"); + exit(1); + } + else if (pid > 0) { + for (int i = 0; i < 5; i++) { + write(fd, buf, 2); + sleep(1); + } + } + else { + buf[0] = 0x42; + for (int i = 0; i < 5; i++) { + write(fd, buf, 2); + sleep(1); + } + } + + close(fd); + exit(0); +} + diff --git a/ostep/hw5/hw5_3.c b/ostep/hw5/hw5_3.c new file mode 100644 index 0000000..1cac4a3 --- /dev/null +++ b/ostep/hw5/hw5_3.c @@ -0,0 +1,34 @@ +#include +#include +#include + +int +main(void) +{ + int pipefd[2]; + + if (pipe(pipefd) == -1) { + perror("pipe"); + exit(1); + } + + pid_t pid = fork(); + if (pid < 0) { + perror("fork"); + exit(1); + } + else if (pid > 0) { + close(pipefd[1]); + + char buf[1]; + read(pipefd[0], buf, 1); + printf("goodbye\n"); + } + else { + sleep(1); + close(pipefd[0]); + + printf("hello\n"); + close(pipefd[1]); + } +} diff --git a/ostep/hw5/hw5_5.c b/ostep/hw5/hw5_5.c new file mode 100644 index 0000000..de14466 --- /dev/null +++ b/ostep/hw5/hw5_5.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +int +main(void) +{ + int status = 0; + + pid_t pid = fork(); + if (pid < 0) { + perror("fork"); + exit(EXIT_FAILURE); + } + else if (pid > 0) { + wait(&status); + if (!WIFEXITED(status)) { + fprintf(stderr, "child exited due to an error\n"); + } + printf("goodbye: %d\n", status); + } + else { + wait(&status); + if (!WIFEXITED(status)) { + fprintf(stderr, "child exited due to an error\n"); + } + printf("hello: %d\n", status); + } + + exit(EXIT_SUCCESS); +} diff --git a/ostep/hw5/hw5_6.c b/ostep/hw5/hw5_6.c new file mode 100644 index 0000000..1bc6670 --- /dev/null +++ b/ostep/hw5/hw5_6.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include + +int +main(void) +{ + int status = 0; + + pid_t pid = fork(); + if (pid < 0) { + perror("fork"); + exit(EXIT_FAILURE); + } + else if (pid > 0) { + waitpid(pid, &status, 0); + if (!WIFEXITED(status)) { + fprintf(stderr, "child exited due to an error\n"); + } + printf("goodbye: %d\n", status); + } + else { + printf("hello: %d\n", status); + } + + exit(EXIT_SUCCESS); +} diff --git a/ostep/hw5/hw5_7.c b/ostep/hw5/hw5_7.c new file mode 100644 index 0000000..5846787 --- /dev/null +++ b/ostep/hw5/hw5_7.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +int +main(void) +{ + pid_t pid; + + pid = fork(); + if (pid < 0) { + perror("fork"); + exit(1); + } + // child + else if (pid > 0) { + close(STDOUT_FILENO); + printf("screaming into the void...\n"); + } + else { + wait(NULL); + printf("the darkness\n"); + } + + exit(EXIT_SUCCESS); +} diff --git a/ostep/hw5/hw5_8.c b/ostep/hw5/hw5_8.c new file mode 100644 index 0000000..de1d5cc --- /dev/null +++ b/ostep/hw5/hw5_8.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include + +int pipefd[2]; + +int +main(void) +{ + if (pipe(pipefd) != 0) { + perror("pipe"); + return EXIT_FAILURE; + } + int pwrite = pipefd[1]; + int pread = pipefd[0]; + + pid_t pid = fork(); + if (pid < 0) { + perror("fork"); + return EXIT_FAILURE; + } + /* the first child */ + else if (pid == 0) { + /* + * Close standard output and reassign it to the pipe. + * The close is done automagically by dup2. + */ + dup2(pwrite, STDOUT_FILENO); + + /* Close unnecessary pipe read file descriptor. */ + close(pread); + + /* Now we do the thing. */ + printf("Hello, world.\n"); + + /* ¡Adios! */ + return EXIT_SUCCESS; + } + + /* + * We are now in the parent. We must fork again, and do the + * child dance. + */ + if ((pid = fork()) < 0) { + perror("fork"); + return EXIT_FAILURE; + } + /* the second of the children */ + else if (pid == 0) { + /* Close standard input and reassign it to the pipe. */ + dup2(pread, STDIN_FILENO); + + /* Close unnecessary pipe write file descriptor. */ + close(pwrite); + + /* Read the thing. */ + char data[16]; + ssize_t rl; + + memset(data, 0, 16); + rl = read(STDIN_FILENO, data, 15); + if (rl < 1) { + perror("read"); + return EXIT_FAILURE; + } + + printf("%s", data); + return EXIT_SUCCESS; + } + + /* wait for the children to die so we can reap them */ + /* there are two, they should drop dead on their own. */ + int status1, status2; + waitpid(-1, &status1, 0); + waitpid(-1, &status2, 0); + + if (WIFEXITED(status1) && WIFEXITED(status2)) { + printf("Goodbye.\n"); + return EXIT_SUCCESS; + } + fprintf(stderr, "At least one child died abnormally.\n"); + return EXIT_FAILURE; +}