Skip to content

Commit

Permalink
ccan: update and add more.
Browse files Browse the repository at this point in the history
We need the following additional modules for the daemon:
	io, time, timer, pipecmd

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Jan 21, 2016
1 parent 906a5e4 commit 888389e
Show file tree
Hide file tree
Showing 105 changed files with 18,347 additions and 44 deletions.
19 changes: 18 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ CCAN_OBJS := \
ccan-crypto-shachain.o \
ccan-err.o \
ccan-ilog.o \
ccan-io-io.o \
ccan-io-poll.o \
ccan-isaac.o \
ccan-isaac64.o \
ccan-list.o \
Expand All @@ -79,14 +81,16 @@ CCAN_OBJS := \
ccan-opt-parse.o \
ccan-opt-usage.o \
ccan-opt.o \
ccan-pipecmd.o \
ccan-read_write_all.o \
ccan-str-hex.o \
ccan-str.o \
ccan-take.o \
ccan-tal-grab_file.o \
ccan-tal-str.o \
ccan-tal.o \
ccan-time.o
ccan-time.o \
ccan-timer.o

# For tests
CCAN_EXTRA_OBJS := \
Expand All @@ -113,6 +117,9 @@ CCAN_HEADERS := \
$(CCANDIR)/ccan/htable/htable.h \
$(CCANDIR)/ccan/htable/htable_type.h \
$(CCANDIR)/ccan/ilog/ilog.h \
$(CCANDIR)/ccan/io/backend.h \
$(CCANDIR)/ccan/io/io.h \
$(CCANDIR)/ccan/io/io_plan.h \
$(CCANDIR)/ccan/isaac/isaac.h \
$(CCANDIR)/ccan/isaac/isaac64.h \
$(CCANDIR)/ccan/likely/likely.h \
Expand All @@ -122,6 +129,7 @@ CCAN_HEADERS := \
$(CCANDIR)/ccan/opt/opt.h \
$(CCANDIR)/ccan/opt/private.h \
$(CCANDIR)/ccan/order/order.h \
$(CCANDIR)/ccan/pipecmd/pipecmd.h \
$(CCANDIR)/ccan/ptrint/ptrint.h \
$(CCANDIR)/ccan/read_write_all/read_write_all.h \
$(CCANDIR)/ccan/short_types/short_types.h \
Expand All @@ -140,6 +148,7 @@ CCAN_HEADERS := \
$(CCANDIR)/ccan/tal/talloc/talloc.h \
$(CCANDIR)/ccan/tcon/tcon.h \
$(CCANDIR)/ccan/time/time.h \
$(CCANDIR)/ccan/timer/timer.h \
$(CCANDIR)/ccan/typesafe_cb/typesafe_cb.h

TEST_CLI_HEADERS := test-cli/gather_updates.h \
Expand Down Expand Up @@ -369,3 +378,11 @@ ccan-isaac64.o: $(CCANDIR)/ccan/isaac/isaac64.c
$(CC) $(CFLAGS) -c -o $@ $<
ccan-time.o: $(CCANDIR)/ccan/time/time.c
$(CC) $(CFLAGS) -c -o $@ $<
ccan-timer.o: $(CCANDIR)/ccan/timer/timer.c
$(CC) $(CFLAGS) -c -o $@ $<
ccan-io-io.o: $(CCANDIR)/ccan/io/io.c
$(CC) $(CFLAGS) -c -o $@ $<
ccan-io-poll.o: $(CCANDIR)/ccan/io/poll.c
$(CC) $(CFLAGS) -c -o $@ $<
ccan-pipecmd.o: $(CCANDIR)/ccan/pipecmd/pipecmd.c
$(CC) $(CFLAGS) -c -o $@ $<
2 changes: 1 addition & 1 deletion ccan/README
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
CCAN imported from http://ccodearchive.net.

CCAN version: init-2084-gb87f63c
CCAN version: init-2136-g64e9e71
1 change: 1 addition & 0 deletions ccan/ccan/io/LICENSE
88 changes: 88 additions & 0 deletions ccan/ccan/io/SCENARIOS
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
Simple:
step1(conn): read(conn), then step2
step2(conn): write(conn), then close

Pass-through:
step1(conn): read(conn), then step2
step2(conn): write(otherconn), then step1

Pass-through-and-connect:
step1(conn): read(conn), then step2
step2(conn): connect(otherconn), then step3
step3(conn): write(otherconn), then step1

Chatroom:
step1(conn): read(conn), then step2
step2(conn): for c in allcons: write(c). goto step1

Simple:

void event(struct io_event *done)
{
char *buf = done->priv;
struct io_event *e;

e = queue_read(done, done->conn, buf, 100);
e = queue_write(e, done->conn, buf, 100);
queue_close(e, done->conn);
}

Pass-through:
struct passthru {
char buf[100];
struct conn *rconn, *wconn;
};

void event(struct io_event *done)
{
struct passthru *p = done->priv;
struct io_event *e;

e = queue_read(done, p->rconn, p->buf, 100);
e = queue_write(e, p->wconn, buf, 100);
queue_event(e, event);
}

Chatroom:
struct list_head clients;

struct buffer {
char buf[100];
unsigned int ref;
};

struct client {
struct list_node list;
struct connection *conn;
struct buffer *rbuf, *wbuf;
};

void broadcast(struct io_event *done)
{
struct client *i, *c = done->conn->priv;
struct io_event *e;

list_for_each(&clients, i, list) {
e = queue_write(done, i->conn, c->buf->buf, 100);
e->priv = c->buf;
c->buf->ref++;
queue_event(e, drop_ref);
}



void event(struct io_event *done)
{
struct client *c = done->conn->priv;
struct io_event *e;

assert(c->conn == done->conn);
c->buf = malloc(sizeof(*c->buf));
c->buf->ref = 0;
e = queue_read(done, c->conn, c->buf->buf, 100);
e = queue_event(e, broadcast);
}


step1(conn): read(conn), then step2
step2(conn): for c in allcons: write(c). goto step1
146 changes: 146 additions & 0 deletions ccan/ccan/io/_info
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#include "config.h"
#include <stdio.h>
#include <string.h>

/**
* io - simple library for asynchronous io handling.
*
* io provides a mechanism to write I/O servers with multiple
* connections. Each callback indicates what I/O they plan next
* (eg. read, write). It is also possible to write custom I/O
* plans.
*
* Example:
* // Given "tr A-Z a-z" outputs tr a-z a-z
* #include <ccan/io/io.h>
* #include <ccan/err/err.h>
* #include <assert.h>
* #include <stdlib.h>
* #include <signal.h>
* #include <sys/types.h>
* #include <sys/wait.h>
* #include <string.h>
*
* struct buffer {
* bool finished;
* size_t start, end, rlen, wlen;
* char buf[4096];
* };
*
* static void finish(struct io_conn *c, struct buffer *b)
* {
* // Mark us finished.
* b->finished = true;
* // Wake writer just in case it's asleep.
* io_wake(b);
* }
*
* static struct io_plan *read_in(struct io_conn *c, struct buffer *b)
* {
* // Add what we just read.
* b->end += b->rlen;
* assert(b->end <= sizeof(b->buf));
*
* // If we just read something, wake writer.
* if (b->rlen != 0)
* io_wake(b);
*
* // If buffer is empty, return to start.
* if (b->start == b->end)
* b->start = b->end = 0;
*
* // No room? Wait for writer
* if (b->end == sizeof(b->buf))
* return io_wait(c, b, read_in, b);
*
* return io_read_partial(c, b->buf + b->end, sizeof(b->buf) - b->end,
* &b->rlen, read_in, b);
* }
*
* static struct io_plan *write_out(struct io_conn *c, struct buffer *b)
* {
* // Remove what we just wrote.
* b->start += b->wlen;
* assert(b->start <= sizeof(b->buf));
*
* // If we wrote something, wake writer.
* if (b->wlen != 0)
* io_wake(b);
*
* // Nothing to write? Wait for reader.
* if (b->end == b->start) {
* if (b->finished)
* return io_close(c);
* return io_wait(c, b, write_out, b);
* }
*
* return io_write_partial(c, b->buf + b->start, b->end - b->start,
* &b->wlen, write_out, b);
* }
*
* // Feed a program our stdin, gather its stdout, print that at end.
* int main(int argc, char *argv[])
* {
* int tochild[2], fromchild[2];
* struct buffer to, from;
* int status;
* struct io_conn *reader;
*
* if (argc == 1)
* errx(1, "Usage: runner <cmdline>...");
*
* if (pipe(tochild) != 0 || pipe(fromchild) != 0)
* err(1, "Creating pipes");
*
* if (!fork()) {
* // Child runs command.
* close(tochild[1]);
* close(fromchild[0]);
*
* dup2(tochild[0], STDIN_FILENO);
* dup2(fromchild[1], STDOUT_FILENO);
* execvp(argv[1], argv + 1);
* exit(127);
* }
*
* close(tochild[0]);
* close(fromchild[1]);
* signal(SIGPIPE, SIG_IGN);
*
* // Read from stdin, write to child.
* memset(&to, 0, sizeof(to));
* reader = io_new_conn(NULL, STDIN_FILENO, read_in, &to);
* io_set_finish(reader, finish, &to);
* io_new_conn(NULL, tochild[1], write_out, &to);
*
* // Read from child, write to stdout.
* reader = io_new_conn(NULL, fromchild[0], read_in, &from);
* io_set_finish(reader, finish, &from);
* io_new_conn(NULL, STDOUT_FILENO, write_out, &from);
*
* io_loop(NULL, NULL);
* wait(&status);
*
* return WIFEXITED(status) ? WEXITSTATUS(status) : 2;
* }
*
* License: LGPL (v2.1 or any later version)
* Author: Rusty Russell <[email protected]>
*/
int main(int argc, char *argv[])
{
if (argc != 2)
return 1;

if (strcmp(argv[1], "depends") == 0) {
printf("ccan/container_of\n");
printf("ccan/list\n");
printf("ccan/tal\n");
printf("ccan/time\n");
printf("ccan/timer\n");
printf("ccan/typesafe_cb\n");
return 0;
}

return 1;
}
Loading

0 comments on commit 888389e

Please sign in to comment.