--- /dev/null
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+
+
+int main(int argc, char *argv[])
+{
+ /*
+ * Variables definition
+ */
+ int i;
+ int size = 4096;
+ int fd;
+ int len, nwrite;
+ /*
+ * Input section: decode command line parameters
+ * Use getopt function
+ */
+ opterr = 0; /* don't want writing to stderr */
+ while ( (i = getopt(argc, argv, "h")) != -1) {
+ switch (i) {
+ /*
+ * Handling options
+ */
+ case 'h': /* help option */
+ printf("Wrong -h option use\n");
+ usage();
+ return -1;
+ break;
+ case 's': /* take wait time for childen */
+ size = strtol(optarg, NULL, 10); /* convert input */
+ break;
+ case '?': /* unrecognized options */
+ printf("Unrecognized options -%c\n", optopt);
+ usage();
+ default: /* should not reached */
+ usage();
+ }
+ }
+ /*
+ * Main body
+ */
+ if ((argc - optind) != 1) { /* There must two argument */
+ printf("Wrong number of arguments %d\n", argc - optind);
+ usage();
+ }
+ /* open destination file */
+ fd = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ if (fd == -1) {
+ printf("cannot open destination file %s, %s", argv[1],
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ /* tee loop */
+ while (1) {
+ /* copy stdin to stdout */
+ len = tee(STDIN_FILENO, STDOUT_FILENO, size, SPLICE_F_NONBLOCK);
+ if (len < 0) {
+ if (errno == EAGAIN) {
+ continue;
+ } else {
+ perror("error on tee stdin to stdout");
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ if (len == 0) break;
+ }
+ /* write data to the file using splice */
+ while (len > 0) {
+ nwrite = splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
+ if (nwrite < 0) {
+ perror("error on splice stdin to file");
+ break;
+ }
+ len -= nwrite;
+ }
+ }
+ close(fd);
+ exit(EXIT_SUCCESS);
+}