Source

pcw / cw.c

#include <err.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/inotify.h>

#define STDOUT 1
#define MAX(a,b) (((a) > (b)) ? (a) : (b))

FILE *in, *out;
char buf[4096];

void sigwinch(int unused)
{
	rewind(in);

	while (fgets(buf, sizeof(buf), in))
		fputs(buf, stdout);
	fflush(stdout);
}

int main(int argc, char **argv)
{
	int evq, in_wd;
	fd_set rd;

	if (argc != 3) {
		printf("Usage: cw infile outfile\n");
		printf("cw-"VERSION" © Evan Gates\n");
		exit(1);
	}
	if (signal(SIGWINCH, sigwinch) == SIG_ERR)
		err(1, "failed to install sigwinch handler");

	if ((in = fopen(argv[1], "r")) == NULL)
		err(1, "failed to fopen %s", argv[1]);

	if ((evq = inotify_init()) < 0)
		err(1, "failed inotify_init()");

	if ((in_wd = inotify_add_watch(evq, argv[1], IN_MODIFY)) < 0)
		err(1, "failed inotify_add_watch()");

	while (fgets(buf, sizeof(buf), in))
		fputs(buf, stdout);
	fflush(stdout);

	if ((out = fopen(argv[2], "w")) == NULL)
		err(1, "failed to fopen %s", argv[2]);

	for (;;) {
		FD_ZERO(&rd);
		FD_SET(evq, &rd);
		FD_SET(fileno(stdin), &rd);

		if (select(evq + 1, &rd, 0, 0, NULL) < 0) {
		    if (errno == EINTR)
			continue;
		    else
			warn("error on select");
		}

		if (FD_ISSET(evq, &rd)) {
			if (read(evq, buf, sizeof(buf)) < 0 && errno != EINTR)
				err(1, "failed read() on evq");

			while (fgets(buf, sizeof(buf), in))
				fputs(buf, stdout);
			fflush(stdout);
		}
		if (FD_ISSET(fileno(stdin), &rd)) {
			if (fgets(buf, sizeof(buf), stdin))
				fputs(buf, out);
			fflush(out);
		}
	}
	return 0;
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.