Created
February 5, 2020 19:31
-
-
Save HotelCalifornia/a34e4c26a6c0855b6d8d349e2f9f9c31 to your computer and use it in GitHub Desktop.
automate xinu console tools for great workflow good
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <errno.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <unistd.h> | |
#define READ 0 | |
#define WRITE 1 | |
int main() { | |
printf("start\n"); | |
int writer[2]; | |
int reader[2]; | |
if (pipe(writer) < 0) { | |
fprintf(stderr, "error: writer pipe: %s\n", strerror(errno)); | |
return EXIT_FAILURE; | |
} | |
if (pipe(reader) < 0) { | |
close(writer[READ]); close(writer[WRITE]); | |
fprintf(stderr, "error: reader pipe: %s\n", strerror(errno)); | |
return EXIT_FAILURE; | |
} | |
printf("pipes made\n"); | |
pid_t pid = fork(); | |
if (pid == 0) { | |
// child proc | |
// duplicate read end of the writer pipe onto stdin (so parent can write to child's stdin) | |
if (dup2(writer[READ], STDIN_FILENO) < 0) { | |
fprintf(stderr, "error: writer dup2: %s\n", strerror(errno)); | |
exit(EXIT_FAILURE); | |
} | |
// duplicate write end of the reader pipe onto stdout and stderr (so parent can read child's stdout/err) | |
if (dup2(reader[WRITE], STDOUT_FILENO) < 0) { | |
fprintf(stderr, "error: reader dup2 (stdin): %s\n", strerror(errno)); | |
exit(EXIT_FAILURE); | |
} | |
if (dup2(reader[WRITE], STDERR_FILENO) < 0) { | |
fprintf(stderr, "error: reader dup2 (stderr): %s\n", strerror(errno)); | |
exit(EXIT_FAILURE); | |
} | |
// close unused pipes (dup2 silently closes some of these so we have a couple no-ops. nbd) | |
close(writer[READ]); close(writer[WRITE]); | |
close(reader[READ]); close(writer[WRITE]); | |
// | |
char* args[] = {"/p/xinu/bin/cs-console", "-c", "quark", NULL}; | |
char* env[] = {"CS_FILENAME=/homes/brookea/cs/cs354/xinu-spring2020/compile/xinu.xbin", NULL}; | |
exit(execve(args[0], args, env)); | |
} else if (pid > 0) { | |
printf("parent\n"); | |
// parent proc | |
// close unneeded pipe ends | |
close(writer[READ]); | |
close(reader[WRITE]); | |
// send our cursed input to the child | |
dprintf(writer[WRITE], "%cd", '\0'); | |
sleep(1); | |
dprintf(writer[WRITE], "\n"); | |
sleep(1); | |
dprintf(writer[WRITE], "%cp", '\0'); | |
int wstatus; | |
while (waitpid(pid, &wstatus, WNOHANG)) { | |
printf("loop\n"); | |
// echo child's output in parent | |
char c; | |
while (read(reader[READ], &c, 1) == 1) { | |
write(STDOUT_FILENO, &c, 1); | |
} | |
// pass parent's stdin to child | |
while (read(STDIN_FILENO, &c, 1) == 1) { | |
write(writer[WRITE], &c, 1); | |
} | |
} | |
printf("loop done\n"); | |
if (WIFEXITED(wstatus)) { | |
printf("child exited normally with code %d\n", WEXITSTATUS(wstatus)); | |
} | |
// wait for child proc to finish | |
// waitpid(pid, NULL, 0); | |
close(writer[WRITE]); | |
close(reader[READ]); | |
} else { | |
// failure | |
close(writer[READ]); close(writer[WRITE]); | |
close(reader[READ]); close(reader[WRITE]); | |
return EXIT_FAILURE; | |
} | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment