Example #1
0
static void docheckservice (void)
{
   struct stat st;
   char *reason = "maintenance";
   char buf[256];
   char *p;

   if (0 == stat(".noservice", &st))
   {
      if (st.st_size)
         if (-1 != topline(NULL, ".noservice", buf, sizeof (buf)))
            reason = buf;
      args_write(1, "400 Service going down: %s\r\n", reason);
      cleanup();
      _exit(0);
   }
   if (0 == stat(".nopost", &st))
      posting_ok = FALSE;
   else if ((p = getenv("POSTING_OK")))
      posting_ok = TRUE;
   else
      posting_ok = FALSE;
   openfifo();
   checkservice = FALSE;
}
Example #2
0
/*
 * POSIX does not allow lseek(2) on fifos, so we expect ESPIPE as a result.
 */
static void
test_lseek(void)
{
	int reader_fd, writer_fd;

	makefifo("testfifo", __func__);

	if (openfifo("testfifo", __func__, &reader_fd, &writer_fd) < 0) {
		warn("%s: openfifo", __func__);
		cleanfifo("testfifo", -1, -1);
		exit(-1);
	}

	if (lseek(reader_fd, 1, SEEK_CUR) >= 0) {
		warnx("%s: lseek succeeded instead of returning ESPIPE",
		    __func__);
		cleanfifo("testfifo", reader_fd, writer_fd);
		exit(-1);
	}
	if (errno != ESPIPE) {
		warn("%s: lseek returned instead of ESPIPE", __func__);
		cleanfifo("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	cleanfifo("testfifo", reader_fd, writer_fd);
}
Example #3
0
/*
 * Write one byte to an empty fifo, then try to read one byte and make sure
 * we don't get back EAGAIN.
 */
static void
test_nonblocking_one_byte(void)
{
	int reader_fd, ret, timedout, writer_fd;
	ssize_t len;
	u_char ch;

	makefifo("testfifo", __func__);
	if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
	    < 0) {
		warn("test_nonblocking: openfifo: testfifo");
		cleanfifo2("testfifo", -1, -1);
		exit(-1);
	}

	if (set_nonblocking(reader_fd, __func__) < 0) {
		cleanfifo2("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	ch = 0xfe;
	ret = timed_write(writer_fd, &ch, sizeof(ch), &len, 5, &timedout,
	    __func__);
	if (ret < 0) {
		warn("test_nonblocking_one_byte: timed_write");
		cleanfifo2("testfifo", reader_fd, writer_fd);
		exit(-1);
	}
	if (len != sizeof(ch)) {
		warnx("test_nonblocking_one_byte: timed_write: tried to write "
		    "%zu, wrote %zd", sizeof(ch), len);
		cleanfifo2("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	ch = 0xab;
	ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
	    __func__);
	if (ret < 0) {
		warn("test_nonblocking_one_byte: timed_read");
		cleanfifo2("testfifo", reader_fd, writer_fd);
		exit(-1);
	}
	if (len != sizeof(ch)) {
		warnx("test_nonblocking_one_byte: timed_read: wanted %zu, read "
		    "%zd", sizeof(ch), len);
		cleanfifo2("testfifo", reader_fd, writer_fd);
		exit(-1);
	}
	if (ch != 0xfe) {
		warnx("test_nonblocking_one_byte: timed_read: expected to read "
		    "0x%02x, read 0x%02x", 0xfe, ch);
		cleanfifo2("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	cleanfifo2("testfifo", reader_fd, writer_fd);
}
Example #4
0
/*
 * Simple I/O test: write ten integers, and make sure we get back the same
 * integers in the same order.  This assumes a minimum fifo buffer > 10
 * bytes in order to not block and deadlock.
 */
static void
test_simpleio(void)
{
    int i, reader_fd, writer_fd;
    u_char buffer[10];
    ssize_t len;

    makefifo("testfifo", __func__);
    if (openfifo("testfifo", &reader_fd, &writer_fd)
            < 0) {
        warn("test_simpleio: openfifo: testfifo");
        cleanfifo2("testfifo", -1, -1);
        exit(-1);
    }

    for (i = 0; i < 10; i++)
        buffer[i] = i;

    len = write(writer_fd, (char *)buffer, sizeof(buffer));
    if (len < 0) {
        warn("test_simpleio: write");
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }
    if (len != sizeof(buffer)) {
        warnx("test_simplio: tried %zu but wrote %zd", sizeof(buffer),
              len);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    len = read(reader_fd, (char *)buffer, sizeof(buffer));
    if (len < 0) {
        warn("test_simpleio: read");
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }
    if (len != sizeof(buffer)) {
        warnx("test_simpleio: tried %zu but read %zd", sizeof(buffer),
              len);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }
    for (i = 0; i < 10; i++) {
        if (buffer[i] == i)
            continue;
        warnx("test_simpleio: write byte %d as 0x%02x, but read "
              "0x%02x", i, i, buffer[i]);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    cleanfifo2("testfifo", reader_fd, writer_fd);
}
Example #5
0
/*
 * First of two test cases involving a 512K buffer: write the buffer into a
 * blocking file descriptor.  We'd like to know it blocks, but the closest we
 * can get is to see if SIGALRM fired during the I/O resulting in a partial
 * write.
 */
static void
test_blocking_partial_write(void)
{
	int reader_fd, ret, timedout, writer_fd;
	u_char *buffer;
	ssize_t len;

	makefifo("testfifo", __func__);
	if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
	    < 0) {
		warn("test_blocking_partial_write: openfifo: testfifo");
		cleanfifo2("testfifo", -1, -1);
		exit(-1);
	}

	if (set_blocking(writer_fd, __func__) < 0) {
		cleanfifo2("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	buffer = malloc(512*1024);
	if (buffer == NULL) {
		warn("test_blocking_partial_write: malloc");
		cleanfifo2("testfifo", reader_fd, writer_fd);
		exit(-1);
	}
	bzero(buffer, 512*1024);

	ret = timed_write(writer_fd, buffer, 512*1024, &len, 5, &timedout,
	    __func__);
	if (ret < 0) {
		warn("test_blocking_partial_write: timed_write");
		free(buffer);
		cleanfifo2("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	if (!timedout) {
		warnx("test_blocking_partial_write: timed_write: blocking "
		    "socket didn't time out");
		free(buffer);
		cleanfifo2("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	free(buffer);

	if (drain_fd(reader_fd, __func__) < 0) {
		cleanfifo2("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	cleanfifo2("testfifo", reader_fd, writer_fd);
}
Example #6
0
/*
 * test_events() uses poll(), select(), and kevent() to query the status of
 * fifo file descriptors and determine whether they match expected state
 * based on earlier semantic tests: specifically, whether or not poll/select/
 * kevent will correctly inform on readable/writable state following I/O.
 *
 * It would be nice to also test status changes as a result of closing of one
 * or another fifo endpoint.
 */
static void
test_events_outofbox(void)
{
    int kqueue_fd, reader_fd, writer_fd;

    makefifo("testfifo", __func__);
    if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
        warn("test_events_outofbox: openfifo: testfifo");
        cleanfifo2("testfifo", -1, -1);
        exit(-1);
    }

    kqueue_fd = kqueue();
    if (kqueue_fd < 0) {
        warn("%s: kqueue", __func__);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    /*
     * Make sure that fresh, out-of-the-box fifo file descriptors have
     * good initial states.  The reader_fd should have no active state,
     * since it will not be readable (no data in pipe), writable (it's
     * a read-only descriptor), and there's no reason for error yet.
     */
    if (assert_status(reader_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
                      NOT_EXCEPTION, __func__, "create", "reader_fd") < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    /*
     * Make sure that fresh, out-of-the-box fifo file descriptors have
     * good initial states.  The writer_fd should be ready to write.
     */
    if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
                      NOT_EXCEPTION, __func__, "create", "writer_fd") < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
}
Example #7
0
/*
 * Test that various ioctls can be issued against the file descriptor.  We
 * don't currently test the semantics of these changes here.
 */
static void
test_ioctl(void)
{
	int reader_fd, writer_fd;

	makefifo("testfifo", __func__);

	if (openfifo("testfifo", __func__, &reader_fd, &writer_fd) < 0) {
		warn("%s: openfifo", __func__);
		cleanfifo("testfifo", -1, -1);
		exit(-1);
	}

	/*
	 * Set and remove the non-blocking I/O flag.
	 */
	if (test_ioctl_setclearflag(reader_fd, FIONBIO, __func__,
	    "reader_fd", "FIONBIO") < 0) {
		cleanfifo("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	if (test_ioctl_setclearflag(writer_fd, FIONBIO, __func__,
	    "writer_fd", "FIONBIO") < 0) {
		cleanfifo("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	/*
	 * Set and remove the async I/O flag.
	 */
	if (test_ioctl_setclearflag(reader_fd, FIOASYNC, __func__,
	    "reader_fd", "FIOASYNC") < 0) {
		cleanfifo("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	if (test_ioctl_setclearflag(writer_fd, FIOASYNC, __func__,
	    "writer_fd", "FIONASYNC") < 0) {
		cleanfifo("testfifo", reader_fd, writer_fd);
		exit(-1);
	}

	cleanfifo("testfifo", reader_fd, writer_fd);
}
Example #8
0
/*
 * test_coalesce_big_write() verifies that data mingles in the fifo across
 * message boundaries by performing one big write, then two smaller reads
 * that should return sequential elements of data from the write.
 */
static void
test_coalesce_big_write(void)
{
    int i, reader_fd, writer_fd;
    u_char buffer[10];
    ssize_t len;

    makefifo("testfifo", __func__);
    if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
        warn("test_coalesce_big_write: openfifo: testfifo");
        cleanfifo2("testfifo", -1, -1);
        exit(-1);
    }

    /* Write ten, read five, read five. */
    for (i = 0; i < 10; i++)
        buffer[i] = i;

    len = write(writer_fd, buffer, 10);
    if (len < 0) {
        warn("test_coalesce_big_write: write 10");
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }
    if (len != 10) {
        warnx("test_coalesce_big_write: write 10 wrote %zd", len);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    len = read(reader_fd, buffer, 5);
    if (len < 0) {
        warn("test_coalesce_big_write: read 5");
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }
    if (len != 5) {
        warnx("test_coalesce_big_write: read 5 read %zd", len);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    len = read(reader_fd, buffer + 5, 5);
    if (len < 0) {
        warn("test_coalesce_big_write: read 5");
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }
    if (len != 5) {
        warnx("test_coalesce_big_write: read 5 read %zd", len);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    for (i = 0; i < 10; i++) {
        if (buffer[i] == i)
            continue;
        warnx("test_coalesce_big_write: expected to read 0x%02x, "
              "read 0x%02x", i, buffer[i]);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    cleanfifo2("testfifo", -1, -1);
}
Example #9
0
/*
 * Write a 512K buffer to an empty fifo using a non-blocking file descriptor,
 * and make sure it doesn't block.
 */
static void
test_nonblocking_partial_write(void)
{
    int reader_fd, ret, timedout, writer_fd;
    u_char *buffer;
    ssize_t len;

    makefifo("testfifo", __func__);
    if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
        warn("test_blocking_partial_write: openfifo: testfifo");
        cleanfifo2("testfifo", -1, -1);
        exit(-1);
    }

    if (set_nonblocking(writer_fd, __func__) < 0) {
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    buffer = malloc(512*1024);
    if (buffer == NULL) {
        warn("test_blocking_partial_write: malloc");
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }
    bzero(buffer, 512*1024);

    ret = timed_write(writer_fd, buffer, 512*1024, &len, 5, &timedout,
                      __func__);
    if (ret < 0) {
        warn("test_blocking_partial_write: timed_write");
        free(buffer);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    if (timedout) {
        warnx("test_blocking_partial_write: timed_write: "
              "non-blocking socket timed out");
        free(buffer);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    if (len == 0 || len >= 512*1024) {
        warnx("test_blocking_partial_write: timed_write: requested "
              "%d, sent %zd", 512*1024, len);
        free(buffer);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    free(buffer);

    if (drain_fd(reader_fd, __func__) < 0) {
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    cleanfifo2("testfifo", reader_fd, writer_fd);
}
Example #10
0
/*
 * This test operates on blocking and non-blocking fifo file descriptors, in
 * order to determine whether they block at good moments or not.  By good we
 * mean: don't block for non-blocking sockets, and do block for blocking
 * ones, assuming there isn't I/O buffer to satisfy the request.
 *
 * We use a timeout of 5 seconds, concluding that in 5 seconds either all I/O
 * that can take place will, and that if we reach the end of the timeout,
 * then blocking has occurred.
 *
 * We assume that the buffer size on a fifo is <512K, and as such, that
 * writing that much data without an active reader will result in blocking.
 */
static void
test_blocking_read_empty(void)
{
    int reader_fd, ret, timedout, writer_fd;
    ssize_t len;
    u_char ch;

    makefifo("testfifo", __func__);
    if (openfifo("testfifo", &reader_fd, &writer_fd)
            < 0) {
        warn("test_blocking_read_empty: openfifo: testfifo");
        cleanfifo2("testfifo", -1, -1);
        exit(-1);
    }

    /*
     * Read one byte from an empty blocking fifo, block as there is no
     * data.
     */
    if (set_blocking(reader_fd, __func__) < 0) {
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
                     __func__);
    if (ret != -1) {
        warnx("test_blocking_read_empty: timed_read: returned "
              "success");
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }
    if (errno != EINTR) {
        warn("test_blocking_read_empty: timed_read");
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    /*
     * Read one byte from an empty non-blocking fifo, return EAGAIN as
     * there is no data.
     */
    if (set_nonblocking(reader_fd, __func__) < 0) {
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
                     __func__);
    if (ret != -1) {
        warnx("test_blocking_read_empty: timed_read: returned "
              "success");
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }
    if (errno != EAGAIN) {
        warn("test_blocking_read_empty: timed_read");
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    cleanfifo2("testfifo", reader_fd, writer_fd);
}
Example #11
0
/*
 * Write a 512k buffer to the fifo in non-blocking mode, and make sure that
 * the write end becomes un-writable as a result of a partial write that
 * fills the fifo buffer.
 */
static void
test_events_partial_write(void)
{
    int kqueue_fd, reader_fd, writer_fd;
    u_char *buffer;
    ssize_t len;

    makefifo("testfifo", __func__);
    if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
        warn("test_events_partial_write: openfifo: testfifo");
        cleanfifo2("testfifo", -1, -1);
        exit(-1);
    }

    kqueue_fd = kqueue();
    if (kqueue_fd < 0) {
        warn("%s: kqueue", __func__);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    if (set_nonblocking(writer_fd, "test_events") < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    buffer = malloc(512*1024);
    if (buffer == NULL) {
        warn("test_events_partial_write: malloc");
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }
    bzero(buffer, 512*1024);

    len = write(writer_fd, buffer, 512*1024);
    if (len < 0) {
        warn("test_events_partial_write: write");
        free(buffer);
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    free(buffer);

    if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
                      NOT_EXCEPTION, __func__, "big write", "writer_fd") < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    if (drain_fd(reader_fd, "test_events") < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    /*
     * Test that the writer_fd has been restored to writable state after
     * draining.
     */
    if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
                      NOT_EXCEPTION, __func__, "big write + drain", "writer_fd") < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
}
Example #12
0
static void
test_events_write_read_byte(void)
{
    int kqueue_fd, reader_fd, writer_fd;
    ssize_t len;
    u_char ch;

    makefifo("testfifo", __func__);
    if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
        warn("test_events_write_read_byte: openfifo: testfifo");
        cleanfifo2("testfifo", -1, -1);
        exit(-1);
    }

    kqueue_fd = kqueue();
    if (kqueue_fd < 0) {
        warn("%s: kqueue", __func__);
        cleanfifo2("testfifo", reader_fd, writer_fd);
        exit(-1);
    }

    if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    /*
     * Write a byte to the fifo, and make sure that the read end becomes
     * readable, and that the write end remains writable (small write).
     */
    ch = 0x00;
    len = write(writer_fd, &ch, sizeof(ch));
    if (len < 0) {
        warn("%s: write", __func__);
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    if (assert_status(reader_fd, kqueue_fd, READABLE, NOT_WRITABLE,
                      NOT_EXCEPTION, __func__, "write", "reader_fd") < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    /*
     * the writer_fd should remain writable.
     */
    if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
                      NOT_EXCEPTION, __func__, "write", "writer_fd") < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    /*
     * Read the byte from the reader_fd, and now confirm that that fifo
     * becomes unreadable.
     */
    len = read(reader_fd, &ch, sizeof(ch));
    if (len < 0) {
        warn("%s: read", __func__);
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    if (assert_status(reader_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
                      NOT_EXCEPTION, __func__, "write+read", "reader_fd") < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    /*
     * The writer_fd should remain writable.
     */
    if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
                      NOT_EXCEPTION, __func__, "write+read", "writer_fd") < 0) {
        cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
        exit(-1);
    }

    cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
}