commit 8e595a498d1835ac8515200142477251c2dd4e89
parent f93bc3de44e7de77994865b862783316b4736f75
Author: Jacob R. Edwards <jacobouno@protonmail.com>
Date: Sat, 19 Dec 2020 22:04:03 -0800
Add fully functional gopher-text format piping
Diffstat:
M | main.c | | | 50 | ++++++++++++++++++++++++++++++++++++++++++++++++-- |
1 file changed, 48 insertions(+), 2 deletions(-)
diff --git a/main.c b/main.c
@@ -25,6 +25,7 @@
#include <limits.h>
#include <netdb.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -35,6 +36,8 @@
#define ARGV_MAX 16
#define ARG_SEP ":\t "
+static char *gphfmt[] = { "gophmt", NULL };
+
int gawk(int depth, const char *tmpdir, const char *host, const char *path, const char *port);
int
@@ -230,7 +233,9 @@ putfile(const char *path)
return 1;
while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) {
- if (fwrite(buf, 1, bytes, stdout) != bytes) {
+ /* NOTE: using fwrite and `stdout` causes piping
+ * to not work. */
+ if (write(STDOUT_FILENO, buf, bytes) != bytes) {
fclose(in);
warn("unable to write buffer");
return 1;
@@ -274,8 +279,49 @@ gphcache(const char *cache, const char *host, const char *path, const char *port
int
gawkat(const char *path)
{
- if (putfile(path) != 0)
+ int fds[2];
+ int i;
+
+ if (pipe(fds) == -1) {
+ warn("unable to setup pipe");
+ return 1;
+ }
+
+ switch (fork()) {
+ case -1:
+ warn("unable to fork");
return 1;
+ case 0:
+ if (dup2(fds[0], STDIN_FILENO) == -1 || close(fds[0]) || close(fds[1])) {
+ warn("unable to setup child pipe");
+ _exit(EXIT_FAILURE);
+ }
+ execvp(*gphfmt, gphfmt);
+ warn("execvp '%s'", *gphfmt);
+ _exit(EXIT_FAILURE);
+ }
+
+ switch (fork()) {
+ case -1:
+ warn("unable to fork");
+ return 1;
+ case 0:
+ if (dup2(fds[1], STDOUT_FILENO) == -1 || close(fds[0]) || close(fds[1])) {
+ warn("unable to setup parent pipe");
+ _exit(1);
+ }
+ if (putfile(path) != 0)
+ _exit(1);
+ _exit(0);
+ }
+
+ for (i = 0; i < 2; ++i)
+ close(fds[i]);
+ for (i = 0; i < 2; ++i) {
+ if (wait(0) == -1)
+ warn("unable to wait");
+ }
+
return 0;
}