/* Creates and adds an example file. */ static char *add_example(struct manifest *m, struct ccan_file *source, struct doc_section *example) { char *name, *linemarker; unsigned int i; int fd; struct ccan_file *f; name = tal_fmt(m, "example-%s-%s", source->name, example->function); /* example->function == 'struct foo' */ while (strchr(name, ' ')) *strchr(name, ' ') = '_'; name = temp_file(m, ".c", take(name)); f = new_ccan_file(m, take(path_dirname(m, name)), take(path_basename(m, name))); tal_steal(f, name); list_add_tail(&m->examples, &f->list); fd = open(f->fullname, O_WRONLY | O_CREAT | O_EXCL, 0600); if (fd < 0) return tal_fmt(m, "Creating temporary file %s: %s", f->fullname, strerror(errno)); /* Add #line to demark where we are from, so errors are correct! */ linemarker = tal_fmt(f, "#line %i \"%s\"\n", example->srcline+2, source->fullname); if (write(fd, linemarker, strlen(linemarker)) != (int)strlen(linemarker)) { close(fd); return cast_const(char *, "Failure writing to temporary file"); }
static struct io_plan *write_json(struct io_conn *conn, struct json_connection *jcon) { struct json_output *out; out = list_pop(&jcon->output, struct json_output, list); if (!out) { if (jcon->stop) { log_unusual(jcon->log, "JSON-RPC shutdown"); /* Return us to toplevel lightningd.c */ io_break(jcon->dstate); return io_close(conn); } /* Reader can go again now. */ io_wake(jcon); return io_out_wait(conn, jcon, write_json, jcon); } jcon->outbuf = tal_steal(jcon, out->json); tal_free(out); log_io(jcon->log, false, jcon->outbuf, strlen(jcon->outbuf)); return io_write(conn, jcon->outbuf, strlen(jcon->outbuf), write_json, jcon); }
/* Wrap (and own!) member inside Pkt */ static Pkt *make_pkt(const tal_t *ctx, Pkt__PktCase type, const void *msg) { Pkt *pkt = tal(ctx, Pkt); pkt__init(pkt); pkt->pkt_case = type; /* This is a union, so doesn't matter which we assign. */ pkt->error = (Error *)tal_steal(pkt, msg); /* This makes sure all packets are valid. */ #ifndef NDEBUG { size_t len; u8 *packed; Pkt *cpy; len = pkt__get_packed_size(pkt); packed = tal_arr(pkt, u8, len); pkt__pack(pkt, packed); cpy = pkt__unpack(NULL, len, memcheck(packed, len)); assert(cpy); pkt__free_unpacked(cpy, NULL); tal_free(packed); } #endif return pkt; }
static struct pending_tx *new_pending_tx(const tal_t *ctx, const union protocol_tx *tx) { struct pending_tx *pend; pend = tal(ctx, struct pending_tx); pend->tx = tal_steal(pend, tx); return pend; }
static void add_to_unknown_pending(struct state *state, const union protocol_tx *tx) { struct pending_unknown_tx *unk; unk = tal(state->pending, struct pending_unknown_tx); unk->tx = tal_steal(unk, tx); list_add_tail(&state->pending->unknown_tx, &unk->list); state->pending->num_unknown++; }
static struct io_plan *got_shard(struct io_conn *conn, struct generator *gen) { gen->solution->shard[gen->solution->shards_read++] = tal_steal(gen->solution, gen->pkt_in); if (gen->solution->shards_read != tal_count(gen->solution->shard)) return io_read_packet(conn, &gen->pkt_in, got_shard, gen); /* We've got all the shards! */ recv_block_from_generator(gen->state, gen->log, gen->solution->block, gen->solution->shard); return io_close(conn); }
/* May allocate a new type if not already found (steals @name) */ static struct cdump_type *get_type(struct cdump_definitions *defs, enum cdump_type_kind kind, const char *name) { struct cdump_map *m; struct cdump_type *t; switch (kind) { case CDUMP_STRUCT: m = &defs->structs; break; case CDUMP_UNION: m = &defs->unions; break; case CDUMP_ENUM: m = &defs->enums; break; case CDUMP_UNKNOWN: case CDUMP_ARRAY: case CDUMP_POINTER: m = NULL; } /* Do we already have it? */ if (m) { t = strmap_get(m, name); if (t) return t; } t = tal(defs, struct cdump_type); t->kind = kind; t->name = name ? tal_steal(t, name) : NULL; /* These are actually the same, but be thorough */ t->u.members = NULL; t->u.enum_vals = NULL; if (m) strmap_add(m, t->name, t); return t; }
= tal_steal(gen->solution, gen->pkt_in); if (gen->solution->shards_read != tal_count(gen->solution->shard)) return io_read_packet(conn, &gen->pkt_in, got_shard, gen); /* We've got all the shards! */ recv_block_from_generator(gen->state, gen->log, gen->solution->block, gen->solution->shard); return io_close(conn); } static struct io_plan *got_solution(struct io_conn *conn, struct generator *gen) { gen->solution = tal(gen, struct solution); gen->solution->block = tal_steal(gen->solution, gen->pkt_in); gen->solution->shard = tal_arr(gen->solution, struct protocol_pkt_shard *, 1 << gen->shard_order); gen->solution->shards_read = 0; return io_read_packet(conn, &gen->pkt_in, got_shard, gen); } /* FIXME: If transaction may go over horizon, time out generation */ static void add_update(struct state *state, struct pending_tx *t, size_t shard, size_t txoff) { struct pending_update *update;
/* We've added a whole heap of transactions, recheck them and set input refs. */ void recheck_pending_txs(struct state *state) { unsigned int unknown, known, total; unsigned int i, shard; const union protocol_tx **txs; struct pending_unknown_tx *utx; if (!state->pending->needs_recheck) return; state->pending->needs_recheck = false; /* Size up and allocate an array. */ unknown = state->pending->num_unknown; known = num_pending_known(state); /* Avoid logging if nothing pending. */ if (unknown == 0 && known == 0) return; txs = tal_arr(state, const union protocol_tx *, unknown + known); log_info(state->log, "Rechecking pending (%u known, %u unknown)", known, unknown); /* Now move pending from shards. */ total = 0; for (shard = 0; shard < ARRAY_SIZE(state->pending->pend); shard++) { struct pending_tx **pend = state->pending->pend[shard]; unsigned int i; for (i = 0; i < tal_count(pend); i++) { remove_pending_tx_from_hashes(state, pend[i]->tx); txs[total++] = tal_steal(txs, pend[i]->tx); } } /* And last we move the unknown ones. */ while ((utx = list_pop(&state->pending->unknown_tx, struct pending_unknown_tx, list)) != NULL) { remove_pending_tx_from_hashes(state, utx->tx); txs[total++] = tal_steal(txs, utx->tx); } assert(total == unknown + known); /* Clean up pending (frees everything above as a side effect). */ tal_free(state->pending); state->pending = new_pending_block(state); /* Now re-add them */ for (i = 0; i < tal_count(txs); i++) { unsigned int bad_input_num; struct protocol_double_sha sha; hash_tx(txs[i], &sha); add_pending_tx(state, txs[i], &sha, &bad_input_num, NULL); } /* Just to print the debug! */ known = 0; for (shard = 0; shard < ARRAY_SIZE(state->pending->pend); shard++) known += tal_count(state->pending->pend[shard]); log_info(state->log, "Now have %u known, %u unknown", known, state->pending->num_unknown); /* Restart generator on this block. */ restart_generating(state); }