diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-06-11 10:13:59 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-06-11 10:23:40 +0300 |
commit | 7a0e63726f1722492f92cd92723f1be46a89e04f (patch) | |
tree | 84c2ea787894eb530e692e8fe4a32d8853f6abe1 | |
parent | 972b32f76ffb55ca0244caa18109405facdf7209 (diff) | |
download | smap-7a0e63726f1722492f92cd92723f1be46a89e04f.tar.gz smap-7a0e63726f1722492f92cd92723f1be46a89e04f.tar.bz2 |
Revamp stream support.
Use fully fledged I/O streams (based on my earlier implementation
for Mailutils and Dico). Construct a sockmap stream which allows
to do all interactions transparently as if it were a line-oriented
protocol. Update everything accordingly.
* include/smap/ostr.h: delete
* lib/ostr.c: delete
* lib/smapostr.c: delete
* include/smap/printf.h: New file.
* include/smap/stream.h: New file.
* include/smap/streamdef.h: New file.
* lib/asnprintf.c: New file.
* lib/asprintf.c: New file.
* lib/fileoutstr.c: New file.
* lib/sockmapstr.c: New file.
* lib/syslogstr.c: New file.
* lib/stream.c: New file.
* lib/stream_printf.c: New file.
* lib/stream_vprintf.c: New file.
* lib/vasnprintf.c: New file.
* lib/xscript.c: New file.
* include/smap/Makefile.am: Update.
* lib/Makefile.am: Update.
* include/smap/diag.h (smap_error_str)
(smap_debug_str, smap_trace_str): Change type.
* include/smap/module.h (smap_module)<smap_query>: Change type of
ostr.
* lib/debug.c: Rewrite for new stream subsystem.
* lib/diag.c: Likewise.
* lib/stderr.c: Likewise.
* lib/syslog.c: Likewise.
* modules/echo/echo.c: Likewise.
* modules/guile/guile.c: Likewise.
* modules/mailutils/mailutils.c: Likewise.
* src/query.c: Likewise.
* src/smapc.c: Likewise.
* src/smapd.c: Likewise.
* src/smapd.h: Likewise.
-rw-r--r-- | include/smap/Makefile.am | 4 | ||||
-rw-r--r-- | include/smap/diag.h | 8 | ||||
-rw-r--r-- | include/smap/module.h | 2 | ||||
-rw-r--r-- | include/smap/ostr.h | 38 | ||||
-rw-r--r-- | include/smap/printf.h | 26 | ||||
-rw-r--r-- | include/smap/stream.h | 122 | ||||
-rw-r--r-- | include/smap/streamdef.h | 73 | ||||
-rw-r--r-- | lib/Makefile.am | 14 | ||||
-rw-r--r-- | lib/asnprintf.c | 40 | ||||
-rw-r--r-- | lib/asprintf.c | 41 | ||||
-rw-r--r-- | lib/debug.c | 4 | ||||
-rw-r--r-- | lib/diag.c | 14 | ||||
-rw-r--r-- | lib/fileoutstr.c | 93 | ||||
-rw-r--r-- | lib/ostr.c | 197 | ||||
-rw-r--r-- | lib/sockmapstr.c | 477 | ||||
-rw-r--r-- | lib/stderr.c | 42 | ||||
-rw-r--r-- | lib/stream.c | 976 | ||||
-rw-r--r-- | lib/stream_printf.c | 32 | ||||
-rw-r--r-- | lib/stream_vprintf.c (renamed from lib/smapostr.c) | 42 | ||||
-rw-r--r-- | lib/syslog.c | 22 | ||||
-rw-r--r-- | lib/syslogstr.c | 82 | ||||
-rw-r--r-- | lib/vasnprintf.c | 77 | ||||
-rw-r--r-- | lib/xscript.c | 223 | ||||
-rw-r--r-- | modules/echo/echo.c | 12 | ||||
-rw-r--r-- | modules/guile/guile.c | 12 | ||||
-rw-r--r-- | modules/mailutils/mailutils.c | 26 | ||||
-rw-r--r-- | src/query.c | 6 | ||||
-rw-r--r-- | src/smapc.c | 92 | ||||
-rw-r--r-- | src/smapd.c | 137 | ||||
-rw-r--r-- | src/smapd.h | 7 |
30 files changed, 2456 insertions, 485 deletions
diff --git a/include/smap/Makefile.am b/include/smap/Makefile.am index 93c65f5..1f3fec6 100644 --- a/include/smap/Makefile.am +++ b/include/smap/Makefile.am @@ -15,11 +15,13 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. pkginclude_HEADERS = \ - ostr.h\ wordsplit.h\ kwtab.h\ module.h\ diag.h\ parseopt.h\ + printf.h\ + stream.h\ + streamdef.h\ url.h diff --git a/include/smap/diag.h b/include/smap/diag.h index 46bc5c9..a8d76d8 100644 --- a/include/smap/diag.h +++ b/include/smap/diag.h @@ -17,11 +17,11 @@ #ifndef __SMAP_DIAG_H #define __SMAP_DIAG_H -#include "smap/ostr.h" +#include "smap/stream.h" -extern smap_ostream_t smap_error_str; -extern smap_ostream_t smap_debug_str; -extern smap_ostream_t smap_trace_str; +extern smap_stream_t smap_error_str; +extern smap_stream_t smap_debug_str; +extern smap_stream_t smap_trace_str; void smap_verror(const char *fmt, va_list ap); void smap_error(const char *fmt, ...); diff --git a/include/smap/module.h b/include/smap/module.h index 5375cd8..1c4a6eb 100644 --- a/include/smap/module.h +++ b/include/smap/module.h @@ -44,7 +44,7 @@ struct smap_module { int (*smap_open) (smap_database_t hp); int (*smap_close) (smap_database_t hp); int (*smap_query)(smap_database_t dbp, - smap_ostream_t ostr, + smap_stream_t ostr, const char *map, const char *key, struct smap_conninfo const *conninfo); }; diff --git a/include/smap/ostr.h b/include/smap/ostr.h deleted file mode 100644 index 63252c1..0000000 --- a/include/smap/ostr.h +++ /dev/null @@ -1,38 +0,0 @@ -/* This file is part of smf. - Copyright (C) 2006, 2007, 2010 Sergey Poznyakoff - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef __SMAP_OSTR_H -#define __SMAP_OSTR_H - -/* ostr.c */ -#include <unistd.h> -#include <stdio.h> -#include <stdarg.h> - -typedef struct smap_output_stream *smap_ostream_t; -int smap_ostream_write(smap_ostream_t str, const char *buf, size_t len); -int smap_ostream_vprintf(smap_ostream_t str, const char *fmt, va_list ap); -int smap_ostream_printf(smap_ostream_t str, const char *fmt, ...); -int smap_ostream_flush(smap_ostream_t str); -smap_ostream_t smap_ostream_create(void (*flush)(void *data, char *buf), - void *data); -void smap_ostream_free(smap_ostream_t str); -void smap_ostream_destroy(smap_ostream_t *str); - -extern size_t smap_mapstr_debug_idx; -extern smap_ostream_t smap_map_ostream_create(FILE *fp); - -#endif diff --git a/include/smap/printf.h b/include/smap/printf.h new file mode 100644 index 0000000..b4ea1bf --- /dev/null +++ b/include/smap/printf.h @@ -0,0 +1,26 @@ +/* This file is part of smap. + Copyright (C) 2006, 2007, 2010 Sergey Poznyakoff + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef __SMAP_IO_H +#define __SMAP_IO_H + +#include <stdarg.h> + +int smap_vasnprintf(char **pbuf, size_t *psize, const char *fmt, va_list ap); +int smap_asnprintf(char **pbuf, size_t *psize, const char *fmt, ...); +int smap_asprintf(char **pbuf, const char *fmt, ...); + +#endif diff --git a/include/smap/stream.h b/include/smap/stream.h new file mode 100644 index 0000000..bd801bc --- /dev/null +++ b/include/smap/stream.h @@ -0,0 +1,122 @@ +/* This file is part of smap. + Copyright (C) 2009, 2010 Sergey Poznyakoff + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef __SMAP_STREAM_H +#define __SMAP_STREAM_H + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +enum smap_buffer_type { + smap_buffer_none, + smap_buffer_line, + smap_buffer_full +}; + +typedef struct _smap_transport *smap_transport_t; +typedef struct _smap_stream *smap_stream_t; + +/* FIXME */ +typedef off_t smap_off_t; + +#define SMAP_SEEK_SET 0 +#define SMAP_SEEK_CUR 1 +#define SMAP_SEEK_END 2 + +#define SMAP_STREAM_READ 0x00000001 +#define SMAP_STREAM_WRITE 0x00000002 +#define SMAP_STREAM_RDWR (SMAP_STREAM_READ|SMAP_STREAM_WRITE) +#define SMAP_STREAM_SEEK 0x00000004 +#define SMAP_STREAM_APPEND 0x00000008 +#define SMAP_STREAM_CREAT 0x00000010 +#define SMAP_STREAM_NONBLOCK 0x00000020 +#define SMAP_STREAM_NO_CLOSE 0x00000040 +#define SMAP_STREAM_EXPBUF 0x00000080 + +#define SMAP_IOCTL_GET_TRANSPORT 1 +#define SMAP_IOCTL_SET_TRANSPORT 2 +#define SMAP_IOCTL_SET_DEBUG_IDX 3 +#define SMAP_IOCTL_SET_DEBUG_PFX 4 + +void smap_stream_ref(smap_stream_t stream); +void smap_stream_unref(smap_stream_t stream); +void smap_stream_destroy(smap_stream_t *pstream); +int smap_stream_open(smap_stream_t stream); +const char *smap_stream_strerror(smap_stream_t stream, int rc); +int smap_stream_err(smap_stream_t stream); +int smap_stream_last_error(smap_stream_t stream); +void smap_stream_clearerr(smap_stream_t stream); +int smap_stream_eof(smap_stream_t stream); +int smap_stream_seek(smap_stream_t stream, smap_off_t offset, int whence, + smap_off_t *pres); +int smap_stream_skip_input_bytes(smap_stream_t stream, smap_off_t count, + smap_off_t *pres); + +int smap_stream_set_buffer(smap_stream_t stream, enum smap_buffer_type type, + size_t size); +int smap_stream_read(smap_stream_t stream, void *buf, size_t size, + size_t *pread); +int smap_stream_readdelim(smap_stream_t stream, char *buf, size_t size, + int delim, size_t *pread); +int smap_stream_readline(smap_stream_t stream, char *buf, size_t size, + size_t *pread); +int smap_stream_getdelim(smap_stream_t stream, char **pbuf, size_t *psize, + int delim, size_t *pread); +int smap_stream_getline(smap_stream_t stream, char **pbuf, size_t *psize, + size_t *pread); +int smap_stream_write(smap_stream_t stream, const void *buf, size_t size, + size_t *pwrite); +int smap_stream_writeline(smap_stream_t stream, const char *buf, size_t size); +int smap_stream_flush(smap_stream_t stream); +int smap_stream_close(smap_stream_t stream); +int smap_stream_size(smap_stream_t stream, smap_off_t *psize); +smap_off_t smap_stream_bytes_in(smap_stream_t stream); +smap_off_t smap_stream_bytes_out(smap_stream_t stream); +int smap_stream_ioctl(smap_stream_t stream, int code, void *ptr); +int smap_stream_truncate(smap_stream_t stream, smap_off_t); +int smap_stream_shutdown(smap_stream_t stream, int how); + +#define SMAP_STREAM_READY_RD 0x1 +#define SMAP_STREAM_READY_WR 0x2 +#define SMAP_STREAM_READY_EX 0x4 +struct timeval; /* Needed for the following declaration */ + +int smap_stream_wait(smap_stream_t stream, int *pflags, struct timeval *); + +void smap_stream_get_flags(smap_stream_t stream, int *pflags); +int smap_stream_set_flags(smap_stream_t stream, int fl); +int smap_stream_clr_flags(smap_stream_t stream, int fl); + +int smap_stream_vprintf(smap_stream_t str, const char *fmt, va_list ap); +int smap_stream_printf(smap_stream_t stream, const char *fmt, ...); + + +int smap_fileout_stream_create (smap_stream_t *pstream, FILE *file, + const char *pfx, int pgopt); +int smap_syslog_stream_create (smap_stream_t *pstream, int prio, + const char *pfx); + +int smap_sockmap_stream_create(smap_stream_t *pstream, int fd, int flags); +int smap_sockmap_stream_create2(smap_stream_t *pstream, int fd[], int flags); + +int smap_transcript_stream_create(smap_stream_t *pstream, + smap_stream_t transport, + smap_stream_t logstr, + const char *prefix[]); + + +#endif diff --git a/include/smap/streamdef.h b/include/smap/streamdef.h new file mode 100644 index 0000000..98ecac4 --- /dev/null +++ b/include/smap/streamdef.h @@ -0,0 +1,73 @@ +/* This file is part of smap. + Copyright (C) 2009, 2010 Sergey Poznyakoff + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef __SMAP_STREAMDEF_H +#define __SMAP_STREAMDEF_H + +#define _SMAP_STR_DIRTY 0x01000 /* Buffer dirty */ +#define _SMAP_STR_WRT 0x02000 /* Unflushed write pending */ +#define _SMAP_STR_ERR 0x04000 /* Permanent error state */ +#define _SMAP_STR_EOF 0x08000 /* EOF encountered */ +#define _SMAP_STR_MORESPC 0x10000 +#define _SMAP_STR_INTERN_MASK 0xff000 + +struct _smap_stream { + int ref_count; + + enum smap_buffer_type buftype; + size_t bufsize; + char *buffer; + size_t level; + char *cur; + + int flags; + smap_off_t offset; + smap_off_t bytes_in, bytes_out; + + size_t size_hint; + int last_err; + + int (*read)(struct _smap_stream *, char *, size_t, size_t *); + int (*readdelim)(struct _smap_stream *, char *, size_t, int, size_t *); + int (*write)(struct _smap_stream *, const char *, size_t, size_t *); + int (*flush)(struct _smap_stream *); + int (*open)(struct _smap_stream *); + int (*close)(struct _smap_stream *); + void (*done)(struct _smap_stream *); + int (*seek)(struct _smap_stream *, smap_off_t, smap_off_t *); + int (*size)(struct _smap_stream *, smap_off_t *); + int (*ctl)(struct _smap_stream *, int, void *); + int (*wait)(struct _smap_stream *, int *, struct timeval *); + int (*truncate)(struct _smap_stream *, smap_off_t); + int (*shutdown)(struct _smap_stream *, int); + + const char *(*error_string)(struct _smap_stream *, int); + +}; + +#define _stream_cleareof(s) ((s)->flags &= ~_SMAP_STR_EOF) +#define _stream_advance_buffer(s,n) ((s)->cur += n, (s)->level -= n) +#define _stream_buffer_offset(s) ((s)->cur - (s)->buffer) +#define _stream_orig_level(s) ((s)->level + _stream_buffer_offset(s)) + +smap_stream_t _smap_stream_create(size_t size, int flags); +int smap_stream_read_unbuffered(smap_stream_t stream, void *buf, size_t size, + int full_read, size_t *pnread); +int smap_stream_write_unbuffered(smap_stream_t stream, + const void *buf, size_t size, + int full_write, size_t *pnwritten); + +#endif diff --git a/lib/Makefile.am b/lib/Makefile.am index 49ca368..3c5d629 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -17,17 +17,25 @@ lib_LTLIBRARIES = libsmap.la libsmap_la_SOURCES = \ + asnprintf.c\ + asprintf.c\ debug.c\ diag.c\ + fileoutstr.c\ kwtab.c\ - ostr.c\ + sockmapstr.c\ parseopt.c\ progname.c\ - smapostr.c\ stderr.c\ + stream.c\ + stream_printf.c\ + stream_vprintf.c\ syslog.c\ + syslogstr.c\ url.c\ - wordsplit.c + vasnprintf.c\ + wordsplit.c\ + xscript.c libsmap_la_LDFLAGS = -version-info 0:0:0 diff --git a/lib/asnprintf.c b/lib/asnprintf.c new file mode 100644 index 0000000..26d45c5 --- /dev/null +++ b/lib/asnprintf.c @@ -0,0 +1,40 @@ +/* This file is part of smap. + Copyright (C) 2009, 2010 Sergey Poznyakoff + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <stdarg.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include <smap/printf.h> + +int +smap_asnprintf(char **pbuf, size_t *psize, const char *fmt, ...) +{ + int rc; + va_list ap; + + va_start (ap, fmt); + rc = smap_vasnprintf(pbuf, psize, fmt, ap); + va_end (ap); + return rc; +} + diff --git a/lib/asprintf.c b/lib/asprintf.c new file mode 100644 index 0000000..8c30504 --- /dev/null +++ b/lib/asprintf.c @@ -0,0 +1,41 @@ +/* This file is part of smap. + Copyright (C) 2009, 2010 Sergey Poznyakoff + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <stdarg.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include <smap/printf.h> + +int +smap_asprintf(char **pbuf, const char *fmt, ...) +{ + int rc; + va_list ap; + size_t size; + + va_start (ap, fmt); + rc = smap_vasnprintf(pbuf, &size, fmt, ap); + va_end (ap); + return rc; +} + diff --git a/lib/debug.c b/lib/debug.c index 8cc0000..471efb2 100644 --- a/lib/debug.c +++ b/lib/debug.c @@ -108,8 +108,8 @@ smap_debug_printf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - smap_ostream_vprintf(smap_debug_str, fmt, ap); - smap_ostream_write(smap_debug_str, "\n", 1); + smap_stream_vprintf(smap_debug_str, fmt, ap); + smap_stream_write(smap_debug_str, "\n", 1, NULL); va_end(ap); } @@ -19,17 +19,17 @@ #endif #include <stdlib.h> #include <stdio.h> -#include "smap/ostr.h" +#include "smap/stream.h" #include "smap/diag.h" -smap_ostream_t smap_error_str; -smap_ostream_t smap_debug_str; -smap_ostream_t smap_trace_str; +smap_stream_t smap_error_str; +smap_stream_t smap_debug_str; +smap_stream_t smap_trace_str; void smap_verror(const char *fmt, va_list ap) { - if (smap_ostream_vprintf(smap_error_str, fmt, ap) < 0) { + if (smap_stream_vprintf(smap_error_str, fmt, ap) < 0) { vfprintf(stderr, fmt, ap); fputc('\n', stderr); fprintf(stderr, @@ -37,8 +37,8 @@ smap_verror(const char *fmt, va_list ap) "initialized, please report\n"); abort(); } - smap_ostream_write(smap_error_str, "\n", 1); - smap_ostream_flush(smap_error_str); + smap_stream_write(smap_error_str, "\n", 1, NULL); + smap_stream_flush(smap_error_str); } void diff --git a/lib/fileoutstr.c b/lib/fileoutstr.c new file mode 100644 index 0000000..884d075 --- /dev/null +++ b/lib/fileoutstr.c @@ -0,0 +1,93 @@ +/* This file is part of smap. + Copyright (C) 2006, 2007, 2010 Sergey Poznyakoff + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include "smap/diag.h" +#include "smap/stream.h" +#include "smap/streamdef.h" + +struct fileout_stream { + struct _smap_stream base; + FILE *file; + char *pfx; + int pgopt; +}; + +static int +_fileout_stream_write(struct _smap_stream *stream, const char *buf, + size_t size, size_t *pret) +{ + struct fileout_stream *str = (struct fileout_stream *)stream; + size_t n; + + if (str->pgopt) + fprintf(str->file, "%s: ", smap_progname); + if (str->pfx) + fprintf(str->file, "%s: ", str->pfx); + n = fwrite(buf, 1, size, str->file); + *pret = n; + if (n != size) + return errno; + return 0; +} + +static int +_fileout_stream_flush(struct _smap_stream *stream) +{ + struct fileout_stream *str = (struct fileout_stream *)stream; + if (fflush(str->file)) + return errno; + return 0; +} + +static void +_fileout_stream_destroy(struct _smap_stream *stream) +{ + struct fileout_stream *str = (struct fileout_stream *)stream; + free(str->pfx); +} + +int +smap_fileout_stream_create (smap_stream_t *pstream, FILE *file, + const char *pfx, int pgopt) +{ + struct fileout_stream *str = + (struct fileout_stream *) + _smap_stream_create(sizeof(*str), SMAP_STREAM_WRITE); + if (!str) + return ENOMEM; + if (pfx) { + str->pfx = strdup(pfx); + if (!str->pfx) { + free(str); + return ENOMEM; + } + } else + str->pfx = NULL; + str->file = file; + str->pgopt = pgopt; + str->base.write = _fileout_stream_write; + str->base.flush = _fileout_stream_flush; + str->base.done = _fileout_stream_destroy; + *pstream = (smap_stream_t) str; + smap_stream_set_buffer(*pstream, smap_buffer_line, 1024); + return 0; +} diff --git a/lib/ostr.c b/lib/ostr.c deleted file mode 100644 index 91fb02e..0000000 --- a/lib/ostr.c +++ /dev/null @@ -1,197 +0,0 @@ -/* This file is part of smap. - Copyright (C) 2006, 2007, 2010 Sergey Poznyakoff - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include "smap/ostr.h" - -struct smap_output_stream { - char *buf; - size_t size; - size_t level; - void (*flush) (void *data, char *buf); - void *data; -}; - -static int -_chkbuf(struct smap_output_stream *str, size_t size) -{ - if (str->level + size + 1 > str->size) { - size_t newsize = str->level + size + 1; - char *newbuf = realloc(str->buf, newsize); - if (!newbuf) - return -1; - str->size = newsize; - str->buf = newbuf; - } - return 0; -} - -static void -_flushbuf(struct smap_output_stream *str) -{ - char *ptr = str->buf; - size_t size = str->level; - - while (size) { - size_t len; - char *p = memchr(ptr, '\n', size); - if (!p) - break; - *p++ = 0; - str->flush(str->data, ptr); - len = p - ptr; - ptr += len; - size -= len; - } - if (ptr > str->buf && size) - memmove(str->buf, ptr, size); - str->level = size; -} - -int -smap_ostream_write(smap_ostream_t str, const char *buf, size_t len) -{ - if (!str) { - errno = EINVAL; - return -1; - } - if (_chkbuf(str, len)) - return -1; - memcpy(str->buf + str->level, buf, len); - str->level += len; - _flushbuf(str); - return 0; -} - -int -smap_ostream_vprintf(smap_ostream_t str, const char *fmt, va_list ap) -{ - int n; - - if (!str) { - errno = EINVAL; - return -1; - } - if (!str->buf) { - if (str->size == 0) - str->size = 512; /* Initial allocation */ - - str->buf = calloc(1, str->size); - if (!str->buf) - return -1; - str->level = 0; - } - - for (;;) { - size_t buflen = str->size - str->level; - n = vsnprintf(str->buf + str->level, buflen, fmt, ap); - - if (n < 0 || n >= buflen - || !memchr (str->buf + str->level, '\0', n + 1)) { - char *newbuf; - size_t newlen = str->size * 2; - if (newlen < str->size) { - errno = ENOMEM; - return -1; - } - newbuf = realloc(str->buf, newlen); - if (!newbuf) - return -1; - str->size = newlen; - str->buf = newbuf; - } else { - str->level += n; - break; - } - } - _flushbuf(str); - return n; -} - -int -smap_ostream_printf(smap_ostream_t str, const char *fmt, ...) -{ - va_list ap; - int n; - - if (!str) { - errno = EINVAL; - return -1; - } - va_start(ap, fmt); - n = smap_ostream_vprintf(str, fmt, ap); - va_end(ap); - return n; -} - -int -smap_ostream_flush(smap_ostream_t str) -{ - if (!str) { - errno = EINVAL; - return -1; - } - _flushbuf(str); - if (str->level) { - str->buf[str->level] = 0; - str->flush(str->data, str->buf); - str->level = 0; - } - return 0; -} - -smap_ostream_t -smap_ostream_create(void (*flush)(void *data, char *buf), void *data) -{ - struct smap_output_stream *str = calloc(1, sizeof(str[0])); - if (!str) - return NULL; - str->flush = flush; - str->data = data; - str->size = 512; - str->buf = malloc(str->size); - if (!str->buf) { - free(str); - return NULL; - } - return str; -} - -void -smap_ostream_free(smap_ostream_t str) -{ - if (!str) - return; - free(str->buf); - free(str); -} - -void -smap_ostream_destroy(smap_ostream_t *str) -{ - if (!str) - return; - if (*str) { - smap_ostream_free(*str); - *str = NULL; - } -} diff --git a/lib/sockmapstr.c b/lib/sockmapstr.c new file mode 100644 index 0000000..267dff0 --- /dev/null +++ b/lib/sockmapstr.c @@ -0,0 +1,477 @@ +/* This file is part of smap. + Copyright (C) 2006, 2007, 2010 Sergey Poznyakoff + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <sys/types.h> +#include <sys/socket.h> +#include <limits.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include "smap/diag.h" +#include "smap/stream.h" +#include "smap/streamdef.h" + +/* Bound on length of the string representing a size_t. + log10 (2.0) < 146/485; */ +#define SIZE_T_STRLEN_BOUND ((sizeof(size_t) * CHAR_BIT) * 146 / 485 + 1) + + +struct sockmap_output_stream { + struct _smap_stream base; + int fd; + size_t bufsize; + char *buf; + int debug_idx; + char *debug_pfx; +}; + +static char * +format_len(char *buf, size_t arg) +{ + char *p = buf + SIZE_T_STRLEN_BOUND; + + *--p = 0; + while (arg) { + unsigned n = arg % 10; + *--p = '0' + n; + arg /= 10; + } + return p; +} + +static int +_sockmap_output_stream_write(struct _smap_stream *stream, const char *buf, + size_t len, size_t *pret) +{ + struct sockmap_output_stream *sp = + (struct sockmap_output_stream *)stream; + char nbuf[SIZE_T_STRLEN_BOUND+1], *p; + size_t size, n; + + if (smap_trace_str) { + smap_stream_write(smap_trace_str, buf, len, NULL); + } + len--; + p = format_len(nbuf, len); + n = strlen(p); + size = n + 3 + len; + if (size > sp->bufsize) { + char *newbuf = realloc(sp->buf, size); + if (!newbuf) + return ENOMEM; + sp->buf = newbuf; + sp->bufsize = size; + } + memcpy(sp->buf, p, n); + sp->buf[n++] = ':'; |