#include #include #include #include #include #include "pipe-filter.h" void dummy_read_cb (char *buf, size_t nread, void *data) { } void read_cb (char *buf, size_t nread, void *data) { write (STDOUT_FILENO, buf, nread); } int filter_writes (struct filter *f, const char *s) { filter_write (f, s, strlen (s)); } int main () { struct filter *f; const char *m4 = getenv ("M4"); const char *path[] = { NULL, NULL }; char buf[512]; int rc; if (!m4) m4 = "/usr/bin/m4"; /* Test writing to a nonexistent program traps sooner or later. */ path[0] = "/nonexistent/blah"; f = filter_create ("pipe-filter-test", path[0], path, true, false, buf, sizeof(buf), dummy_read_cb, NULL); sleep (1); signal (SIGPIPE, SIG_IGN); if (filter_write (f, "", 1) != -1) abort (); if (filter_close (f) != 127) abort (); /* Test whether we have m4, and test returning the exit status. */ path[0] = m4; f = filter_create ("pipe-filter-test", m4, path, true, false, buf, sizeof(buf), dummy_read_cb, NULL); sleep (1); if (filter_write (f, "", 1) == -1) exit (77); filter_writes (f, "m4exit(1)"); if (filter_close (f) != 1) abort (); /* Same, but test returning the status in filter_write. */ path[0] = m4; f = filter_create ("pipe-filter-test", m4, path, true, false, buf, sizeof(buf), dummy_read_cb, NULL); filter_writes (f, "m4exit(1)"); sleep (1); rc = filter_write (f, "", 1); if (rc != 1 && rc != -1) abort (); if (filter_close (f) != 1) abort (); /* Now test asynchronous I/O. */ f = filter_create ("pipe-filter-test", m4, path, true, true, buf, sizeof(buf), read_cb, NULL); filter_writes (f, "divert(`-1')\n"); filter_writes (f, "define(`forloop', `pushdef(`$1', `$2')" "_$0($@)popdef(`$1')')\n"); filter_writes (f, "define(`_forloop', `$4`'ifelse($1, `$3', `', " "`define(`$1', incr($1))$0($@)')')divert`'dnl\n"); filter_writes (f, "forloop(`i', `1', `500', `i\n')"); filter_writes (f, "forloop(`i', `501', `1000', `i\n')"); filter_close (f); }