From: Jonathan McDowell Date: Fri, 15 Sep 2023 12:55:51 +0000 (+0530) Subject: Switch charfuncs to returning number of read/written characters X-Git-Tag: onak-0.6.3~8 X-Git-Url: http://the.earth.li/gitweb/?p=onak.git;a=commitdiff_plain;h=35e886f23fde338387c8e2a3a74c9251f7735c3b Switch charfuncs to returning number of read/written characters The charfuncs prototypes were returning 0 for success ("I wrote all the characters you asked me to") or 1 for failure. When we get to verifying signatures over data we may not know how much to read, so change them to returning 0 on error/no more data and otherwise the count of the amount of data read/written. --- diff --git a/armor.c b/armor.c index 1341950..f218b55 100644 --- a/armor.c +++ b/armor.c @@ -96,7 +96,7 @@ struct armor_context { /** A running CRC24 of the data we've seen. */ long crc24; /** The function to output a character. */ - int (*putchar_func)(void *ctx, size_t count, void *c); + size_t (*putchar_func)(void *ctx, size_t count, void *c); /** Context for putchar_func. */ void *ctx; }; @@ -203,7 +203,7 @@ static int armor_putchar_int(void *ctx, unsigned char c) } -static int armor_putchar(void *ctx, size_t count, void *c) +static size_t armor_putchar(void *ctx, size_t count, void *c) { int i; @@ -211,8 +211,8 @@ static int armor_putchar(void *ctx, size_t count, void *c) for (i = 0; i < count; i++) { armor_putchar_int(ctx, ((char *) c)[i]); } - - return 0; + + return count; } /** @@ -228,7 +228,7 @@ struct dearmor_context { /** A running CRC24 of the data we've seen. */ long crc24; /** The function to get the next character. */ - int (*getchar_func)(void *ctx, size_t count, void *c); + size_t (*getchar_func)(void *ctx, size_t count, void *c); /** Context for getchar_func. */ void *ctx; }; @@ -309,7 +309,7 @@ static int dearmor_getchar(void *ctx, unsigned char *c) return (tmpc == 64); } -static int dearmor_getchar_c(void *ctx, size_t count, void *c) +static size_t dearmor_getchar_c(void *ctx, size_t count, void *c) { int i, rc = 0; @@ -317,10 +317,10 @@ static int dearmor_getchar_c(void *ctx, size_t count, void *c) rc = dearmor_getchar(ctx, &((unsigned char *) c)[i]); } - return rc; + return (rc == 0) ? i : 0; } -int armor_openpgp_stream(int (*putchar_func)(void *ctx, size_t count, +int armor_openpgp_stream(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, struct openpgp_packet_list *packets) @@ -348,7 +348,7 @@ int armor_openpgp_stream(int (*putchar_func)(void *ctx, size_t count, return 0; } -int dearmor_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, +int dearmor_openpgp_stream(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx, struct openpgp_packet_list **packets) @@ -363,7 +363,7 @@ int dearmor_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, * with :s in them, then a blank line, then the data. */ state = 1; - while (state != 4 && !getchar_func(ctx, 1, &curchar)) { + while (state != 4 && getchar_func(ctx, 1, &curchar) == 1) { switch (state) { case 0: if (curchar == '\n') { diff --git a/armor.h b/armor.h index bb660a1..7245589 100644 --- a/armor.h +++ b/armor.h @@ -31,7 +31,7 @@ * This function ASCII armors a list of OpenPGP packets and outputs it * using putchar_func. */ -int armor_openpgp_stream(int (*putchar_func)(void *ctx, size_t count, +int armor_openpgp_stream(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, struct openpgp_packet_list *packets); @@ -46,7 +46,7 @@ int armor_openpgp_stream(int (*putchar_func)(void *ctx, size_t count, * armored OpenPGP stream and outputs the data as a linked list of * packets. */ -int dearmor_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, +int dearmor_openpgp_stream(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx, struct openpgp_packet_list **packets); diff --git a/cgi/hashquery.c b/cgi/hashquery.c index 84efe97..7b8c6c4 100644 --- a/cgi/hashquery.c +++ b/cgi/hashquery.c @@ -74,7 +74,7 @@ int main(__unused int argc, __unused char *argv[]) } hashes = (uint8_t **) unmarshal_array(buffer_fetchchar, &cgipostbuf, - (void * (*)(int (*)(void *, size_t, void *), void *)) + (void * (*)(size_t (*)(void *, size_t, void *), void *)) unmarshal_skshash, &count); free(cgipostbuf.buffer); @@ -115,7 +115,7 @@ int main(__unused int argc, __unused char *argv[]) puts("Content-Type: pgp/keys\n"); marshal_array(stdout_putchar, NULL, - (void (*)(int (*)(void *, size_t, void *), + (void (*)(size_t (*)(void *, size_t, void *), void *, const void *)) marshal_publickey, (void **) keys, found); printf("\n"); diff --git a/charfuncs.c b/charfuncs.c index 3aee0b0..59c8ca3 100644 --- a/charfuncs.c +++ b/charfuncs.c @@ -29,20 +29,20 @@ * @count: The number of characters to get from the buffer. * @c: Where to put the characters retrieved. */ -int buffer_fetchchar(void *ctx, size_t count, void *c) +size_t buffer_fetchchar(void *ctx, size_t count, void *c) { struct buffer_ctx *buf = NULL; buf = (struct buffer_ctx *) ctx; if (buf->offset + count > buf->size) { - return 1; + count = buf->size - buf->offset; } - + memcpy(c, &buf->buffer[buf->offset], count); buf->offset += count; - return 0; + return count; } /* @@ -55,7 +55,7 @@ int buffer_fetchchar(void *ctx, size_t count, void *c) * fill it then we double the size of the current buffer and then add the * rest. */ -int buffer_putchar(void *ctx, size_t count, void *c) +size_t buffer_putchar(void *ctx, size_t count, void *c) { struct buffer_ctx *buf = NULL; size_t newsize = 0; @@ -73,37 +73,41 @@ int buffer_putchar(void *ctx, size_t count, void *c) memcpy(&buf->buffer[buf->offset], c, count); buf->offset += count; - return 1; + return count; } /* * Fetches a char from a file. */ -int file_fetchchar(void *fd, size_t count, void *c) +size_t file_fetchchar(void *fd, size_t count, void *c) { - return !(read( *(int *) fd, c, count)); + ssize_t ret = read( *(int *) fd, c, count); + + return (ret > 0) ? ret : 0; } /* * Puts a char to a file. */ -int file_putchar(void *fd, size_t count, void *c) +size_t file_putchar(void *fd, size_t count, void *c) { - return !(write( *(int *) fd, c, count)); + size_t ret = write( *(int *) fd, c, count); + + return (ret > 0) ? ret : 0; } /* * Gets a char from stdin. */ -int stdin_getchar(__unused void *ctx, size_t count, void *c) +size_t stdin_getchar(__unused void *ctx, size_t count, void *c) { - return (fread(c, 1, count, stdin) != count); + return fread(c, 1, count, stdin); } /* * Puts a char to stdout. */ -int stdout_putchar(__unused void *ctx, size_t count, void *c) +size_t stdout_putchar(__unused void *ctx, size_t count, void *c) { - return (fwrite(c, 1, count, stdout) != count); + return fwrite(c, 1, count, stdout); } diff --git a/charfuncs.h b/charfuncs.h index 5dadf66..4d8997b 100644 --- a/charfuncs.h +++ b/charfuncs.h @@ -40,7 +40,7 @@ struct buffer_ctx { * @param count The number of characters to get from the buffer. * @param c Where to put the characters retrieved. */ -int buffer_fetchchar(void *ctx, size_t count, void *c); +size_t buffer_fetchchar(void *ctx, size_t count, void *c); /** * @brief Puts a char to a buffer. @@ -52,26 +52,26 @@ int buffer_fetchchar(void *ctx, size_t count, void *c); * fill it then we double the size of the current buffer and then add the * rest. */ -int buffer_putchar(void *ctx, size_t count, void *c); +size_t buffer_putchar(void *ctx, size_t count, void *c); /** * @brief Fetches a char from a file. */ -int file_fetchchar(void *fd, size_t count, void *c); +size_t file_fetchchar(void *fd, size_t count, void *c); /** * @brief Puts a char to a file. */ -int file_putchar(void *fd, size_t count, void *c); +size_t file_putchar(void *fd, size_t count, void *c); /** * @brief Gets a char from stdin. */ -int stdin_getchar(void *ctx, size_t count, void *c); +size_t stdin_getchar(void *ctx, size_t count, void *c); /** * @brief Puts a char to stdout. */ -int stdout_putchar(void *ctx, size_t count, void *c); +size_t stdout_putchar(void *ctx, size_t count, void *c); #endif /* __CHARFUNCS_H__ */ diff --git a/keydb/keydb_pg.c b/keydb/keydb_pg.c index c8392f7..85c16cc 100644 --- a/keydb/keydb_pg.c +++ b/keydb/keydb_pg.c @@ -47,21 +47,28 @@ struct pg_fc_ctx { /** * keydb_fetchchar - Fetches a char from a file. */ -static int keydb_fetchchar(void *_ctx, size_t count, void *c) +static size_t keydb_fetchchar(void *_ctx, size_t count, void *c) { + int ret; + struct pg_fc_ctx *ctx = (struct pg_fc_ctx *) _ctx; - return (!lo_read(ctx->dbconn, ctx->fd, (char *) c, count)); + ret = lo_read(ctx->dbconn, ctx->fd, (char *) c, count); + + return (ret > 0) ? ret : 0; } /** * keydb_putchar - Puts a char to a file. */ -static int keydb_putchar(void *_ctx, size_t count, void *c) +static size_t keydb_putchar(void *_ctx, size_t count, void *c) { struct pg_fc_ctx *ctx = (struct pg_fc_ctx *) _ctx; + int ret; + + ret = lo_write(ctx->dbconn, ctx->fd, (char *) c, count); - return !(lo_write(ctx->dbconn, ctx->fd, (char *) c, count)); + return (ret > 0) ? ret : 0; } /** diff --git a/marshal.c b/marshal.c index 9eb3ccb..5f26cff 100644 --- a/marshal.c +++ b/marshal.c @@ -27,7 +27,7 @@ #include "mem.h" #include "parsekey.h" -void marshal_publickey(int (*putchar_func)(void *ctx, size_t count, +void marshal_publickey(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, const struct openpgp_publickey *key) @@ -52,7 +52,7 @@ void marshal_publickey(int (*putchar_func)(void *ctx, size_t count, free_packet_list(packets); } -void marshal_skshash(int (*putchar_func)(void *ctx, size_t count, +void marshal_skshash(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, const struct skshash *hash) @@ -65,14 +65,14 @@ void marshal_skshash(int (*putchar_func)(void *ctx, size_t count, putchar_func(ctx, sizeof(hash->hash), (void *) hash->hash); } -struct skshash *unmarshal_skshash(int (*getchar_func)(void *ctx, size_t count, +struct skshash *unmarshal_skshash(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx) { uint32_t len; struct skshash *hash; - if (getchar_func(ctx, sizeof(len), &len)) { + if (getchar_func(ctx, sizeof(len), &len) != sizeof(len)) { return NULL; } len = ntohl(len); @@ -80,7 +80,7 @@ struct skshash *unmarshal_skshash(int (*getchar_func)(void *ctx, size_t count, return NULL; } hash = calloc(sizeof(struct skshash), 1); - if (getchar_func(ctx, len, hash->hash)) { + if (getchar_func(ctx, len, hash->hash) != len) { free(hash); return NULL; } @@ -88,7 +88,7 @@ struct skshash *unmarshal_skshash(int (*getchar_func)(void *ctx, size_t count, return hash; } -void marshal_string(int (*putchar_func)(void *ctx, size_t count, +void marshal_string(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, const char *string) @@ -102,19 +102,19 @@ void marshal_string(int (*putchar_func)(void *ctx, size_t count, putchar_func(ctx, len, &string); } -char *unmarshal_string(int (*getchar_func)(void *ctx, size_t count, +char *unmarshal_string(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx) { uint32_t len; char *string; - if (getchar_func(ctx, sizeof(len), &len)) { + if (getchar_func(ctx, sizeof(len), &len) != sizeof(len)) { return NULL; } len = ntohl(len); string = malloc(len + 1); - if (getchar_func(ctx, len, string)) { + if (getchar_func(ctx, len, string) != len) { free(string); return NULL; } @@ -123,10 +123,10 @@ char *unmarshal_string(int (*getchar_func)(void *ctx, size_t count, return string; } -void marshal_array(int (*putchar_func)(void *ctx, size_t count, +void marshal_array(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, - void (*marshal_func)(int + void (*marshal_func)(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, const void *item), @@ -145,10 +145,10 @@ void marshal_array(int (*putchar_func)(void *ctx, size_t count, } } -void **unmarshal_array(int (*getchar_func)(void *ctx, size_t count, +void **unmarshal_array(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx, - void *(*unmarshal_func)(int + void *(*unmarshal_func)(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx), @@ -158,7 +158,7 @@ void **unmarshal_array(int (*getchar_func)(void *ctx, size_t count, void **array; int i; - if (getchar_func(ctx, sizeof(len), &len)) { + if (getchar_func(ctx, sizeof(len), &len) != sizeof(len)) { return NULL; } *size = ntohl(len); diff --git a/marshal.h b/marshal.h index 3edb612..8b487b4 100644 --- a/marshal.h +++ b/marshal.h @@ -32,7 +32,7 @@ * a 32 bit size of the forthcoming data in network byte order and * then the flattened byte representation of the key. */ -void marshal_publickey(int (*putchar_func)(void *ctx, size_t count, +void marshal_publickey(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, const struct openpgp_publickey *key); @@ -45,7 +45,7 @@ void marshal_publickey(int (*putchar_func)(void *ctx, size_t count, * Returns an OpenPGP structure which is the unmarshalled result of * the input byte stream - ie the inverse of marshal_publickey. */ -struct openpgp_publickey *unmarshal_publickey(int (*getchar_func)(void *ctx, +struct openpgp_publickey *unmarshal_publickey(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx); @@ -60,7 +60,7 @@ struct openpgp_publickey *unmarshal_publickey(int (*getchar_func)(void *ctx, * a 32 bit size of the forthcoming data (16 bytes) in network byte order * and then the byte representation of the hash. */ -void marshal_skshash(int (*putchar_func)(void *ctx, size_t count, +void marshal_skshash(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, const struct skshash *hash); @@ -73,7 +73,7 @@ void marshal_skshash(int (*putchar_func)(void *ctx, size_t count, * Returns an SKS hash structure which is the unmarshalled result of * the input byte stream - ie the inverse of marshal_skshash. */ -struct skshash *unmarshal_skshash(int (*getchar_func)(void *ctx, size_t count, +struct skshash *unmarshal_skshash(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx); @@ -86,7 +86,7 @@ struct skshash *unmarshal_skshash(int (*getchar_func)(void *ctx, size_t count, * Takes a string and marshals it to a byte stream - writes a 32 bit size * of the forthcoming data in network byte order and then the string. */ -void marshal_string(int (*putchar_func)(void *ctx, size_t count, +void marshal_string(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, const char *string); @@ -99,7 +99,7 @@ void marshal_string(int (*putchar_func)(void *ctx, size_t count, * Returns a string which is the unmarshalled result of the input byte * stream - ie the inverse of marshal_string. */ -char *unmarshal_string(int (*getchar_func)(void *ctx, size_t count, +char *unmarshal_string(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx); @@ -116,10 +116,10 @@ char *unmarshal_string(int (*getchar_func)(void *ctx, size_t count, * calls marshal_func for each element in the array to provide the * marshalled contents. */ -void marshal_array(int (*putchar_func)(void *ctx, size_t count, +void marshal_array(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, - void (*marshal_func)(int + void (*marshal_func)(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, const void *item), @@ -137,10 +137,10 @@ void marshal_array(int (*putchar_func)(void *ctx, size_t count, * as determined by the supplied unmarshal_func function. ie the reverse * of marshal_array. */ -void **unmarshal_array(int (*getchar_func)(void *ctx, size_t count, +void **unmarshal_array(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx, - void *(*unmarshal_func)(int + void *(*unmarshal_func)(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx), diff --git a/parsekey.c b/parsekey.c index 49b91bf..ceff429 100644 --- a/parsekey.c +++ b/parsekey.c @@ -182,7 +182,7 @@ int debug_packet(struct openpgp_packet *packet) * packet stream and reads the packets into a linked list of packets * ready for parsing as a public key or whatever. */ -onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, +onak_status_t read_openpgp_stream(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx, struct openpgp_packet_list **packets, @@ -204,7 +204,7 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, } while (rc == ONAK_E_OK && (maxnum == 0 || keys < maxnum) && - !getchar_func(ctx, 1, &curchar)) { + (getchar_func(ctx, 1, &curchar) == 1)) { if (curchar & 0x80) { /* * New packet. Allocate memory for it. @@ -231,14 +231,14 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, */ if (curpacket->packet->newformat) { curpacket->packet->tag = (curchar & 0x3F); - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) == 0) { rc = ONAK_E_INVALID_PKT; break; } curpacket->packet->length = curchar; if (curpacket->packet->length > 191 && curpacket->packet->length < 224) { - rc = getchar_func(ctx, 1, &curchar); + rc = getchar_func(ctx, 1, &curchar) ? ONAK_E_OK : ONAK_E_IO_ERROR; curpacket->packet->length -= 192; curpacket->packet->length <<= 8; curpacket->packet->length += curchar; @@ -250,28 +250,28 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, rc = ONAK_E_UNSUPPORTED_FEATURE; } else if (curpacket->packet->length == 255) { /* - * 5 byte length; ie 255 followed by 3 + * 5 byte length; ie 255 followed by 4 * bytes of MSB length. */ - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) != 1) { rc = ONAK_E_INVALID_PKT; break; } curpacket->packet->length = curchar; curpacket->packet->length <<= 8; - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) != 1) { rc = ONAK_E_INVALID_PKT; break; } curpacket->packet->length += curchar; curpacket->packet->length <<= 8; - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) != 1) { rc = ONAK_E_INVALID_PKT; break; } curpacket->packet->length += curchar; curpacket->packet->length <<= 8; - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) != 1) { rc = ONAK_E_INVALID_PKT; break; } @@ -281,45 +281,45 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, curpacket->packet->tag = (curchar & 0x3C) >> 2; switch (curchar & 3) { case 0: - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) != 1) { rc = ONAK_E_INVALID_PKT; break; } curpacket->packet->length = curchar; break; case 1: - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) != 1) { rc = ONAK_E_INVALID_PKT; break; } curpacket->packet->length = curchar; curpacket->packet->length <<= 8; - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) != 1) { rc = ONAK_E_INVALID_PKT; break; } curpacket->packet->length += curchar; break; case 2: - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) != 1) { rc = ONAK_E_INVALID_PKT; break; } curpacket->packet->length = ((unsigned) curchar << 24); - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) != 1) { rc = ONAK_E_INVALID_PKT; break; } curpacket->packet->length += (curchar << 16); - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) != 1) { rc = ONAK_E_INVALID_PKT; break; } curpacket->packet->length += (curchar << 8); - if (getchar_func(ctx, 1, &curchar)) { + if (getchar_func(ctx, 1, &curchar) != 1) { rc = ONAK_E_INVALID_PKT; break; } @@ -346,7 +346,8 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, } else { rc = getchar_func(ctx, curpacket->packet->length, - curpacket->packet->data); + curpacket->packet->data) ? + ONAK_E_OK : ONAK_E_IO_ERROR; } } } else { @@ -422,7 +423,7 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, * This function uses putchar_func to write characters to an OpenPGP * packet stream from a linked list of packets. */ -onak_status_t write_openpgp_stream(int (*putchar_func)(void *ctx, size_t count, +onak_status_t write_openpgp_stream(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, struct openpgp_packet_list *packets) diff --git a/parsekey.h b/parsekey.h index c237aa9..edf44c2 100644 --- a/parsekey.h +++ b/parsekey.h @@ -59,7 +59,7 @@ int debug_packet(struct openpgp_packet *packet); * then only the public key component of the last key will be returned, * none of the other packets of the key will be read. */ -onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, +onak_status_t read_openpgp_stream(size_t (*getchar_func)(void *ctx, size_t count, void *c), void *ctx, struct openpgp_packet_list **packets, @@ -74,7 +74,7 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, * This function uses putchar_func to write characters to an OpenPGP * packet stream from a linked list of packets. */ -onak_status_t write_openpgp_stream(int (*putchar_func)(void *ctx, size_t count, +onak_status_t write_openpgp_stream(size_t (*putchar_func)(void *ctx, size_t count, void *c), void *ctx, struct openpgp_packet_list *packets); diff --git a/sendsync.c b/sendsync.c index e81da7d..429b8f7 100644 --- a/sendsync.c +++ b/sendsync.c @@ -29,11 +29,9 @@ #include "parsekey.h" #include "sendsync.h" -int fd_putchar(void *ctx, size_t count, void *c) +size_t fd_putchar(void *ctx, size_t count, void *c) { - fwrite(c, sizeof(char), count, ctx); - - return 0; + return fwrite(c, sizeof(char), count, ctx); } /**