This shows you the differences between two versions of the page.
— |
os_cp:fork_exec_pipes:solutions [2024/05/08 14:40] (current) jkonczak utworzono |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <unistd.h> | ||
+ | int main(void) { | ||
+ | sleep(5); | ||
+ | write(1, "about to fork...\n", 17); | ||
+ | fork(); | ||
+ | write(1, "forked.\n", 8); | ||
+ | sleep(5); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | #include <sys/types.h> | ||
+ | #include <unistd.h> | ||
+ | int main(void) { | ||
+ | pid_t f = fork(); | ||
+ | printf("fork: %-10dpid: %-10dppid: %-10d\n", f, getpid(), getppid()); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <unistd.h> | ||
+ | int main(void) { | ||
+ | if (fork()) { | ||
+ | write(1, "parent\n", 7); | ||
+ | } else { | ||
+ | write(1, "child\n", 6); | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <unistd.h> | ||
+ | int main(void) { | ||
+ | if (fork()) { | ||
+ | char c; | ||
+ | read(0, &c, 1); | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | int main(void) { | ||
+ | execlp("ps", "ps", "-F", NULL); | ||
+ | perror("execvp"); | ||
+ | return -1; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <unistd.h> | ||
+ | int main(int argc, char *argv[]) { | ||
+ | char **av = malloc(sizeof(char *) * (argc + 4)); | ||
+ | char a0[] = "ls"; av[0] = a0; | ||
+ | char a1[] = "-l"; av[1] = a1; | ||
+ | char a2[] = "-t"; av[2] = a2; | ||
+ | char a3[] = "-r"; av[3] = a3; | ||
+ | for (int i = 0; i < argc; ++i) | ||
+ | av[i + 4] = argv[i + 1]; | ||
+ | execvp("ls", av); | ||
+ | perror("execvp"); | ||
+ | return -1; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | #include <sys/wait.h> | ||
+ | #include <time.h> | ||
+ | #include <unistd.h> | ||
+ | |||
+ | int main(int argc, char *argv[]) { | ||
+ | struct timespec start, end; | ||
+ | timespec_get(&start, TIME_UTC); | ||
+ | if (!fork()) { | ||
+ | execvp(argv[1], argv + 1); | ||
+ | perror("execvp"); | ||
+ | return -1; | ||
+ | } | ||
+ | wait(NULL); | ||
+ | timespec_get(&end, TIME_UTC); | ||
+ | double elapsedSec = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9; | ||
+ | printf("%f\n", elapsedSec); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <assert.h> | ||
+ | #include <stdio.h> | ||
+ | #include <sys/wait.h> | ||
+ | #include <time.h> | ||
+ | #include <unistd.h> | ||
+ | |||
+ | int main(int argc, char *argv[]) { | ||
+ | struct timespec start, end; | ||
+ | timespec_get(&start, TIME_UTC); | ||
+ | if (!fork()) { | ||
+ | execvp(argv[1], argv + 1); | ||
+ | perror("execvp"); | ||
+ | return -1; | ||
+ | } | ||
+ | close(0); | ||
+ | close(1); | ||
+ | int status; | ||
+ | wait(&status); | ||
+ | timespec_get(&end, TIME_UTC); | ||
+ | double elapsedSec = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9; | ||
+ | if (WIFEXITED(status)) { | ||
+ | // You may test exit status by compiling & using the following program: | ||
+ | // main(int,char**v){return atoi(v[1]);} | ||
+ | fprintf(stderr, "%f (returned %d)\n", elapsedSec, WEXITSTATUS(status)); | ||
+ | } else { | ||
+ | assert(WIFSIGNALED(status)); | ||
+ | fprintf(stderr, "%f (killed by signal %d)\n", elapsedSec, WTERMSIG(status)); | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <fcntl.h> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | |||
+ | int main() { | ||
+ | int fd = open("output", O_WRONLY | O_TRUNC | O_CREAT, 0666); | ||
+ | if (fd == -1) { | ||
+ | perror("output"); | ||
+ | return 1; | ||
+ | } | ||
+ | dup2(fd, 1); | ||
+ | close(fd); | ||
+ | execlp("ps", "ps", "-F", NULL); | ||
+ | return 1; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <fcntl.h> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | |||
+ | int main(int argc, char **argv) { | ||
+ | if (argc < 2) { | ||
+ | write(2, "Too few arguments\n", 18); | ||
+ | return 1; | ||
+ | } | ||
+ | int fd = open(argv[1], O_RDONLY); | ||
+ | if (fd == -1) { | ||
+ | perror(argv[1]); | ||
+ | return 1; | ||
+ | } | ||
+ | dup2(fd, 0); | ||
+ | close(fd); | ||
+ | argv[1] = "tr"; | ||
+ | execvp("tr", argv + 1); | ||
+ | return 1; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <errno.h> | ||
+ | #include <fcntl.h> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | |||
+ | int main() { | ||
+ | int fileFd = open("file", O_WRONLY | O_CREAT | O_TRUNC, 0666); | ||
+ | if (fileFd == -1) { | ||
+ | perror("file"); | ||
+ | return 1; | ||
+ | } | ||
+ | int errorFd = dup(2); | ||
+ | |||
+ | errno = ELOOP; | ||
+ | perror("ELOOP"); | ||
+ | dup2(fileFd, 2); | ||
+ | perror("ELOOP"); | ||
+ | |||
+ | errno = EMFILE; | ||
+ | dup2(errorFd, 2); | ||
+ | perror("EMFILE"); | ||
+ | dup2(fileFd, 2); | ||
+ | perror("EMFILE"); | ||
+ | |||
+ | close(errorFd); | ||
+ | close(fileFd); | ||
+ | return 1; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <stdint.h> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | |||
+ | int32_t doExpensiveComputation() { return 2 + 2; } | ||
+ | |||
+ | int main() { | ||
+ | int pfds[2]; | ||
+ | pipe(pfds); | ||
+ | if (!fork()) { | ||
+ | int32_t result = doExpensiveComputation(); | ||
+ | write(pfds[1], &result, 4); | ||
+ | return 0; | ||
+ | } | ||
+ | int32_t result; | ||
+ | read(pfds[0], &result, 4); | ||
+ | printf("The result is: %d\n", result); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | ++++ The following version does a minimum of error checking. | | ||
+ | <code c> | ||
+ | #include <errno.h> | ||
+ | #include <stdint.h> | ||
+ | #include <unistd.h> | ||
+ | |||
+ | int32_t doExpensiveComputation() { return 2 + 2; } | ||
+ | |||
+ | int main() { | ||
+ | int pfds[2]; | ||
+ | if (pipe(pfds) == -1) { | ||
+ | perror("pipe"); | ||
+ | return 1; | ||
+ | } | ||
+ | int f = fork(); | ||
+ | if (f == -1) { | ||
+ | perror("fork"); | ||
+ | return 1; | ||
+ | } | ||
+ | if (!f) { | ||
+ | int32_t result = doExpensiveComputation(); | ||
+ | write(pfds[1], &result, 4); | ||
+ | return 0; | ||
+ | } | ||
+ | int32_t result; | ||
+ | read(pfds[0], &result, 4); | ||
+ | printf("The result is: %d\n", result); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | ++++ | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <stdint.h> | ||
+ | #include <stdio.h> | ||
+ | #include <sys/wait.h> | ||
+ | #include <unistd.h> | ||
+ | |||
+ | int32_t doExpensiveComputation() { | ||
+ | sleep(3); | ||
+ | return 2 + 2; | ||
+ | } | ||
+ | |||
+ | int main() { | ||
+ | int pfds[2]; | ||
+ | pipe(pfds); | ||
+ | for (int i = 0; i < 3; ++i) { | ||
+ | if (!fork()) { | ||
+ | int32_t result = doExpensiveComputation(); | ||
+ | write(pfds[1], &result, 4); | ||
+ | return 0; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | int32_t result[4]; | ||
+ | result[3] = doExpensiveComputation(); | ||
+ | |||
+ | for (int i = 0; i < 3; ++i) { | ||
+ | read(pfds[0], result + i, 4); | ||
+ | wait(NULL); | ||
+ | } | ||
+ | |||
+ | printf("The result is: %d\n", result[0] + result[1] + result[2] + result[3]); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <ctype.h> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | |||
+ | int main() { | ||
+ | int pfds[2]; | ||
+ | pipe(pfds); | ||
+ | if (!fork()) { | ||
+ | dup2(pfds[1], 1); | ||
+ | close(pfds[0]); | ||
+ | close(pfds[1]); | ||
+ | execlp("ls", "ls", "-l", NULL); | ||
+ | return 1; | ||
+ | } | ||
+ | close(pfds[1]); | ||
+ | char c; | ||
+ | while (1 == read(pfds[0], &c, 1)) { | ||
+ | c = toupper(c); | ||
+ | write(1, &c, 1); | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ~~Exercise.#~~ | ||
+ | <code c> | ||
+ | #include <unistd.h> | ||
+ | |||
+ | int main() { | ||
+ | int pfds[2]; | ||
+ | pipe(pfds); | ||
+ | if (!fork()) { | ||
+ | dup2(pfds[1], 1); | ||
+ | close(pfds[0]); | ||
+ | close(pfds[1]); | ||
+ | execlp("ps", "ps", "-eF", NULL); | ||
+ | return 1; | ||
+ | } | ||
+ | dup2(pfds[0], 0); | ||
+ | close(pfds[0]); | ||
+ | close(pfds[1]); | ||
+ | execlp("sort", "sort", "-nk6", NULL); | ||
+ | return 1; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ~~META: | ||
+ | language = en | ||
+ | ~~ | ||