File: redirect.c

package info (click to toggle)
libuev 2.4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,944 kB
  • sloc: sh: 4,665; ansic: 1,428; makefile: 102
file content (69 lines) | stat: -rw-r--r-- 1,463 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/* Example of how to handle stdin redirect
 *
 * The problem is non-trivial since Linux epoll, which libuEv uses, does
 * not support I/O watchers for regular files or directories.
 *
 * This works:
 *                  echo foo | redirect
 * This doesn't:
 *                  redirect < foo.txt
 *
 * However, with a little bit of hacking libuEv can be made to handle
 * reading from stdin as a special case.
 */

#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include "src/uev.h"

void process_stdin(uev_t *w, void *arg, int events)
{
	char buf[256];
	int len;

	if (UEV_ERROR == events) {
		warnx("Spurious problem with the stdin watcher, restarting.");
		uev_io_start(w);
	}

	len = read(w->fd, buf, sizeof(buf));
	if (len == -1) {
		warn("Error reading from stdin");
		return;
	}

	if (len == 0 || UEV_HUP == events) {
		warnx("Connection closed.");
		return;
	}

	printf("Read %d bytes\n", len);
	if (write(STDOUT_FILENO, buf, len) != len)
		warn("Failed writing to stdout");
}

int main(int argc, char **argv)
{
	uev_ctx_t ctx;
	uev_t watcher;
	int ret;

	uev_init(&ctx);

	ret = uev_io_init(&ctx, &watcher, process_stdin, NULL, STDIN_FILENO, UEV_READ);
	if (ret)
		err(errno, "Failed setting up STDIN watcher");

	return uev_run(&ctx, 0);
}

/**
 * Local Variables:
 *  compile-command: "make redirect; echo hej > hej.txt; ./redirect < hej.txt"
 *  indent-tabs-mode: t
 *  c-file-style: "linux"
 * End:
 */