Files
frostbyte/user/hcat.c
T

58 lines
1.9 KiB
C

#include "ulib.h"
/*
* Left half of shell.c's new `cmd1 <<< TEXT | cmd2` here-string-into-
* pipeline live demo -- jobctl.c's new jobctlSpawnPipedHereString wires
* THIS process's fd 0 to a real pipe the shell itself writes the typed
* `<<<` text into, AND its fd 1 to the pipeline's shared pipe (right
* half's fd 0), both BEFORE this process ever runs a single instruction.
* From this program's own point of view there is nothing special about
* either fd: it is simply "cat" -- read stdin to real EOF, then write
* exactly those bytes to stdout -- with no idea either end is a pipe
* rather than a real file or console. Named "hcat" (not "cat") purely so
* the driver thread's typed line (binary name + `<<<` + text + `|` +
* binary name) stays clearly under keyboard.c's 32-byte
* consoleReaderBufferSize per line -- see kmain.c's FALA 31 lesson,
* documented right where stderrDriverThread's own path length once
* crossed that exact boundary.
*
* Diagnostics go to fd 2 (never fd 1) for the same reason pipesrc.c's own
* printErr does: fd 1 here is the real pipeline payload hsink.c compares
* byte-for-byte, and print()/printDec() (ulib.h) are both hardcoded to
* fd 1.
*/
static void printErr(const char* text)
{
userWrite(2, text, stringLength(text));
}
int main(void)
{
printErr("hcat: reading here-string stdin\n");
char buffer[64];
unsigned long total = 0;
for (;;) {
long got = userRead(0, buffer + total, sizeof(buffer) - 1 - total);
if (got < 0) {
printErr("hcat: FAIL read\n");
return 1;
}
if (got == 0)
break;
total += (unsigned long)got;
if (total >= sizeof(buffer) - 1)
break;
}
long written = userWrite(1, buffer, total);
if (written != (long)total) {
printErr("hcat: FAIL short/failed write\n");
return 1;
}
printErr("hcat: forwarded payload\n");
return 0;
}