Hello!

I have rewritten sponge(1) so stdout is not such of a special case
anymore.  Now it also writes to symbolic links' destinations instead and
supports other kinds of files.  Also output to stdout works as it should
now (soaks it up first).  In my opinion it is okay to have sponge called
without arguments to write to stdout.

This version uses util/concat.c to copy stdin to a temporary file and
writing it back to the output file afterwards.

Now the temporary file creation is also done safer than before.

Regards,
Jakob Kramer
diff --git a/LICENSE b/LICENSE
index d959501..8f1caaf 100644
--- a/LICENSE
+++ b/LICENSE
@@ -12,6 +12,7 @@ MIT/X Consortium License
 © 2012 Christoph Lohmann <2...@r-36.net> 
 © 2012 David Galos <galos...@students.rowan.edu> 
 © 2012 Robert Ransom <rransom.8...@gmail.com>
+© 2013 Jakob Kramer <jakob.kra...@gmx.de>
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
diff --git a/Makefile b/Makefile
index 9aeb5c4..7f91bac 100644
--- a/Makefile
+++ b/Makefile
@@ -61,6 +61,7 @@ SRC = \
 	sleep.c    \
 	sort.c     \
 	split.c    \
+	sponge.c   \
 	sync.c     \
 	tail.c     \
 	tee.c      \
diff --git a/sponge.1 b/sponge.1
new file mode 100644
index 0000000..dca95b9
--- /dev/null
+++ b/sponge.1
@@ -0,0 +1,14 @@
+.TH SPONGE 1 sbase\-VERSION
+.SH NAME
+sponge \- soak up standard input and write to a file
+.SH SYNOPSIS
+.B sponge
+.RI [ file ]
+.SH DESCRIPTION
+.B sponge
+reads stdin and writes to the specified file or stdout if no file is given.
+This makes it possible to easily create pipes which read from and write to
+the same file.
+
+If the given file is a symbolic link, it writes to the links's destination
+instead.
diff --git a/sponge.c b/sponge.c
new file mode 100644
index 0000000..456b2d4
--- /dev/null
+++ b/sponge.c
@@ -0,0 +1,51 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+
+#include "text.h"
+#include "util.h"
+
+static void
+usage(void)
+{
+	eprintf("usage: %s [file]\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+	FILE *fp, *tmpfp;
+	char *outname;
+
+	ARGBEGIN {
+	default:
+		usage();
+	} ARGEND;
+
+	switch(argc) {
+	case 0:
+		fp = stdout;
+		outname = "<stdout>";
+		break;
+	case 1:
+		outname = argv[0];
+		break;
+	default:
+		usage();
+	}
+
+	if(!(tmpfp = tmpfile()))
+		eprintf("tmpfile:");
+
+	concat(stdin, "<stdin>", tmpfp, "<tmpfile>");
+	rewind(tmpfp);
+
+	if(fp != stdout)
+		if(!(fp = fopen(argv[0], "w")))
+			eprintf("fopen %s:", argv[0]);
+	concat(tmpfp, "<tmpfile>", fp, outname);
+
+	fclose(fp);
+	fclose(tmpfp);
+
+	return 0;
+}

Reply via email to