Elie De Brauwer pointed out that xputs() isn't reliably reporting errors because there's no flush. Rather than change the output granularity, flush before exit and check errors there. (We still need xputc() doing it so "yes" doesn't continue forever.)
diff --git a/main.c b/main.c
index 829b787..0cd1cb2 100644
--- a/main.c
+++ b/main.c
@@ -102,6 +102,7 @@
   if (!which) return;
   toy_init(which, argv);
   toys.which->toy_main();
+  if (fflush(NULL) || ferror(stdout)) perror_exit("write");
   exit(toys.exitval);
 }