Esempio n. 1
0
static void
serve_file(int nfd, const char *fn)
{
	struct stat	sb;
	knc_ctx		ctx;
	int		fd;
	int		ret;

	fd = open(fn, O_RDONLY, 0);
	if (fd == -1) {
		fprintf(stderr, "open(\"%s\"): %s\n", fn, strerror(errno));
		exit(1);
	}

	ret = fstat(fd, &sb);
	if (ret == -1) {
		fprintf(stderr, "stat: %s\n", strerror(errno));
		exit(1);
	}

	ctx = knc_ctx_init();

	if (!ctx) {
		fprintf(stderr, "out of memory\n");
		exit(1);
	}

	knc_set_debug(ctx, debug);
	knc_set_net_fd(ctx, nfd);

	knc_accept(ctx);

	knc_authenticate(ctx);

	/* XXXrcd: st_size is an off_t, but we take a size_t there.  punt. */
	knc_put_mmapbuf(ctx, KNC_DIR_SEND, sb.st_size, MAP_PRIVATE, fd, 0);
	close(fd);

	knc_flush(ctx, KNC_DIR_SEND, -1);

	if (knc_error(ctx))
		fprintf(stderr, "KNC ERROR: %s\n", knc_errstr(ctx));
	else
		knc_close(ctx);

	knc_ctx_destroy(ctx);
	return;
}
Esempio n. 2
0
File: unit.c Progetto: satrac/knc
int
knc_loop(struct knc_ctx *ctx)
{
	fd_set	 rd, wr;
	int	 fd;
	int	 i;
	int	 ret;
	int	 valrecv = 0;
	int	 valsend = 0;
	char	*buf;

	fd = knc_get_net_fd(ctx);

	/* XXXrcd: Set non-blocking? */
	ret = fcntl(fd, F_SETFL, O_NONBLOCK);
	if (ret == -1)
		fprintf(stderr, "%d: set nonblocking, %s\n",
		    getpid(), strerror(errno));

	for (;;) {
		fprintf(stderr, "%d: loop start, recv'd = %d sent = %d.\n",
		    getpid(), valrecv, valsend);

		if (knc_error(ctx))
			break;

		if (knc_get_net_fd(ctx) == -1)
			break;

		/*
		 * The data that we are sending and receiving is a simple
		 * steam of incrementing single byte integers modulo 11.
		 * Both sides send the same data, so it can be validated.
		 */

		if (knc_avail_buf(ctx, KNC_DIR_SEND) < UNIT_BUFSIZ) {
			ret = knc_get_ibuf(ctx, KNC_DIR_SEND,
			    (void **)&buf, 8192);
			if (ret == -1)
				fprintf(stderr, "%d: ret == -1 for sending\n",
				    getpid());

			for (i=0; i < ret; i++)
				buf[i] = valsend++ % 11;

			if (ret > 0)
				knc_fill_buf(ctx, KNC_DIR_SEND, ret);
		}

		if (knc_avail_buf(ctx, KNC_DIR_RECV) > 0) {

			ret = knc_get_obuf(ctx, KNC_DIR_RECV,
			    (void **)&buf, 8192);
			if (ret < 0)
				fprintf(stderr, "%d: ret == %d for receiving\n",
				    getpid(), ret);

			for (i=0; i < ret; i++) {
				if (buf[i] != valrecv++ % 11) {
					fprintf(stderr, "Malformed input\n");
					return -1;
				}
			}

			if (ret > 0)
				knc_drain_buf(ctx, KNC_DIR_RECV, ret);
		}

		FD_ZERO(&rd);
		FD_ZERO(&wr);

		if (knc_avail_buf(ctx, KNC_DIR_RECV) < UNIT_BUFSIZ)
			FD_SET(fd, &rd);

		if (knc_avail_buf(ctx, KNC_DIR_SEND) > 0)
			FD_SET(fd, &wr);

		ret = select(fd+1, &rd, &wr, NULL, NULL);
		if (ret < 0) {
			fprintf(stderr, "select: %s\n", strerror(errno));
			break;
		}

		if (FD_ISSET(fd, &rd))
			knc_fill(ctx, KNC_DIR_RECV);

		if (FD_ISSET(fd, &wr))
			knc_flush(ctx, KNC_DIR_SEND);

		knc_garbage_collect(ctx);
	}

	ret = 0;
	if (knc_error(ctx)) {
		fprintf(stderr, "KNC UNIT TEST ERROR: %s\n", knc_errstr(ctx));
		ret = 1;
	}

	knc_ctx_close(ctx);
	close(fd);
	return ret;
}