44 lines
1.7 KiB
C
44 lines
1.7 KiB
C
#include "ulib.h"
|
|
|
|
/*
|
|
* Live ring-3 proof for shell.c's new `cmd > file` / `cmd >> file` file
|
|
* redirection (jobctlApplyRedirects/jobctlSpawnForegroundRedirected,
|
|
* jobctl.h): from this program's own point of view it just writes its
|
|
* stdout exactly like pipesrc.c already does for the pipe case -- it has
|
|
* no idea whether fd 1 is the real console, a pipe, or (here) a real file
|
|
* on tmpfs, the same "redirection is invisible to the child" property a
|
|
* real shell's dup2()-before-exec gives every Unix program. fd 2 is
|
|
* deliberately left alone (only fd 0/fd 1 are ever redirected, matching
|
|
* jobctlSpawnPiped's own pipeline convention), so the diagnostic line
|
|
* below reaches the real console even while fd 1's own payload goes to
|
|
* the file instead -- writing it through fd 1 would corrupt the exact
|
|
* bytes redirreader.c later compares.
|
|
*
|
|
* kmain.c's redirDriverThread runs this program TWICE against the same
|
|
* path -- once through `>` (truncate/create) and once through `>>`
|
|
* (append) -- so the resulting file holds two back-to-back copies of this
|
|
* same payload with no separator, proving `>>` genuinely continues from
|
|
* the end of what `>` already wrote rather than overwriting it.
|
|
*/
|
|
#define redirectPayload "redirect-payload-ok"
|
|
|
|
static void printErr(const char* text)
|
|
{
|
|
userWrite(2, text, stringLength(text));
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
printErr("redirwriter: writing payload to stdout (redirected)\n");
|
|
|
|
unsigned long length = stringLength(redirectPayload);
|
|
long written = userWrite(1, redirectPayload, length);
|
|
if (written != (long)length) {
|
|
printErr("redirwriter: FAIL short/failed write\n");
|
|
return 1;
|
|
}
|
|
|
|
printErr("redirwriter: wrote payload\n");
|
|
return 0;
|
|
}
|