Source

pcw / cw.c

Full commit
#include <sys/stat.h>
#include <errno.h>
#include <sys/select.h>
#include <sys/inotify.h>
#include <stdio.h>


int main(int argc, char **argv)
{
    int evq, in_wd;
    FILE *in, *out;
    char buf[4096];
    fd_set rd;
    struct stat st;
    struct inotify_event *cur;

    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()");

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

    if (stat(argv[2], &st) < 0 && errno == ENOENT && mkfifo(argv[2], 0700) < 0)
	err(1, "failed to mkfifo %s\n", argv[2]);

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

    fputs("NOTICE: waiting for other side to open out fifo...\n", stdout);
    fflush(stdout);

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

    fputs("OK\n", stdout);
	fflush(stdout);

    for (;;) {
	FD_ZERO(&rd);
	FD_SET(0, &rd);
	FD_SET(evq, &rd);

	select(evq + 1, &rd, 0, 0, NULL);

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

	    fgets(buf, sizeof(buf), in);
	    fputs(buf, stdout);
	    fflush(stdout);
	}
	if (FD_ISSET(0, &rd)) {
	    fgets(buf, sizeof(buf), stdin);
	    fputs(buf, out);
	    fflush(out);
	}
    }
    return 0;
}