Source

pcw / cw.c

Evan Gates 40154d1 
Evan Gates 6e996e0 
Evan Gates 9c1102c 
Evan Gates bc957ba 
Evan Gates 40154d1 

Evan Gates f27bb1a 
Evan Gates 6e996e0 
Evan Gates 40154d1 
Evan Gates c24bf03 
Evan Gates 0bdea5b 
Evan Gates 6e996e0 
Evan Gates 0bdea5b 
Evan Gates 67beb39 
Evan Gates bc957ba 
Evan Gates 67beb39 
Evan Gates 63cc74a 
Evan Gates 002918d 
Evan Gates 0bdea5b 
Evan Gates b83b271 
Evan Gates 2cd12da 
Evan Gates b83b271 
Evan Gates 99b91d9 

Evan Gates c24bf03 







Evan Gates 255e465 
Evan Gates 99b91d9 





Evan Gates 0bdea5b 

Evan Gates 9c1102c 
Evan Gates b83b271 
Evan Gates 007fcc5 
Evan Gates e08b191 
Evan Gates 0bdea5b 
Evan Gates f09b27b 





Evan Gates 6e996e0 


Evan Gates f09b27b 



Evan Gates 6e996e0 
Evan Gates 9c1102c 



Evan Gates f09b27b 

Evan Gates 007fcc5 
Evan Gates 99b91d9 


Evan Gates 002918d 
Evan Gates e08b191 

Evan Gates 6e996e0 
Evan Gates 002918d 
Evan Gates 0bdea5b 
Evan Gates 6e996e0 
Evan Gates 007fcc5 



Evan Gates 6e996e0 
Evan Gates e08b191 
Evan Gates 6e996e0 
Evan Gates 007fcc5 






Evan Gates 6e996e0 
Evan Gates e08b191 
Evan Gates f09b27b 
Evan Gates 3348f49 
Evan Gates e08b191 
Evan Gates 002918d 
Evan Gates f5382cc 

Evan Gates e08b191 

Evan Gates 0bdea5b 
Evan Gates e08b191 
Evan Gates 0bdea5b 
Evan Gates 633719c 
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

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

#define STDIN  0
#define STDOUT 1
#define STDERR 2
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))

static FILE *in = NULL, *out = NULL;
static char buf[4096];

static void sigwinch(int unused)
{
	struct winsize ws;

	if (ioctl(STDERR, TIOCGWINSZ, &ws) < 0)
		warn("failed ioctl");

	printf("SIZE %d %d\n", ws.ws_row, ws.ws_col);
	fflush(stdout);

	rewind(in);

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

int main(int argc, char **argv)
{
	int evq, len, fd;
	int in_wd = 0, out_wd = 0;
	struct inotify_event *cur;
	fd_set rd;

	if (argc != 3) {
		printf("Usage: cw infile outfile\n");
		printf("cw-"VERSION" © Evan Gates\n");
		exit(1);
	}

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

	if ((in = fopen(argv[1], "r")) == NULL)
		err(1, "failed to fopen %s", argv[1]);
	if ((in_wd = inotify_add_watch(evq, argv[1], IN_MODIFY)) < 0)
		err(1, "failed inotify_add_watch on %s", argv[1]);

	if ((fd = open(argv[2], O_WRONLY)) < 0)
		err(1, "failed to open %s", argv[2]);
	if ((out = fdopen(fd, "w")) == NULL)
		err(1, "failed to fdopen %s on fd %d", argv[2], fd);
	if ((out_wd = inotify_add_watch(evq, argv[2], IN_CLOSE_NOWRITE)) < 0)
		err(1, "failed inotify_add_watch on %s", argv[2]);

	sigwinch(0);
	if (signal(SIGWINCH, sigwinch) == SIG_ERR)
		err(1, "failed to install SIGWINCH handler");

	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 ((len = read(evq, buf, sizeof(buf))) < 0 && errno != EINTR)
				warn("failed to read from inotify event queue");
			for (cur = (struct inotify_event *)buf;
				 (char *)cur - buf < len;
				 cur = (struct inotify_event *)((char *)cur + sizeof(struct inotify_event) + cur->len))
				if(cur->wd == out_wd)
					errx(1, "outfile %s no longer being read", argv[2]);

			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;
}

/* vim: set ts=4 sw=4 noexpandtab: */