--- /dev/null
+Return-Path: <amdragon@mit.edu>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id 8BD82431FBF\r
+ for <notmuch@notmuchmail.org>; Tue, 1 Apr 2014 20:26:56 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.7\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
+ tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id arQb2BlrWfO3 for <notmuch@notmuchmail.org>;\r
+ Tue, 1 Apr 2014 20:26:48 -0700 (PDT)\r
+Received: from dmz-mailsec-scanner-2.mit.edu (dmz-mailsec-scanner-2.mit.edu\r
+ [18.9.25.13])\r
+ (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\r
+ (No client certificate requested)\r
+ by olra.theworths.org (Postfix) with ESMTPS id 86B08431FBD\r
+ for <notmuch@notmuchmail.org>; Tue, 1 Apr 2014 20:26:48 -0700 (PDT)\r
+X-AuditID: 1209190d-f79776d000000ce9-3a-533b83778d2e\r
+Received: from mailhub-auth-3.mit.edu ( [18.9.21.43])\r
+ (using TLS with cipher AES256-SHA (256/256 bits))\r
+ (Client did not present a certificate)\r
+ by dmz-mailsec-scanner-2.mit.edu (Symantec Messaging Gateway) with SMTP\r
+ id F4.61.03305.7738B335; Tue, 1 Apr 2014 23:26:47 -0400 (EDT)\r
+Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11])\r
+ by mailhub-auth-3.mit.edu (8.13.8/8.9.2) with ESMTP id s323QkkI020348; \r
+ Tue, 1 Apr 2014 23:26:47 -0400\r
+Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])\r
+ (authenticated bits=0)\r
+ (User authenticated as amdragon@ATHENA.MIT.EDU)\r
+ by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id s323Qi9D007890\r
+ (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT);\r
+ Tue, 1 Apr 2014 23:26:46 -0400\r
+Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.80)\r
+ (envelope-from <amdragon@mit.edu>)\r
+ id 1WVBp6-0004YY-MZ; Tue, 01 Apr 2014 23:26:44 -0400\r
+Date: Tue, 1 Apr 2014 23:26:44 -0400\r
+From: Austin Clements <amdragon@MIT.EDU>\r
+To: David Bremner <david@tethera.net>\r
+Subject: Re: [Patch v5 3/6] util: add gz_readline\r
+Message-ID: <20140402032644.GB25677@mit.edu>\r
+References: <1396401381-18128-1-git-send-email-david@tethera.net>\r
+ <1396401381-18128-4-git-send-email-david@tethera.net>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=us-ascii\r
+Content-Disposition: inline\r
+In-Reply-To: <1396401381-18128-4-git-send-email-david@tethera.net>\r
+User-Agent: Mutt/1.5.21 (2010-09-15)\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFuplleLIzCtJLcpLzFFi42IR4hTV1i1vtg42uDRL2+JGazejxfWbM5kd\r
+ mDyerbrF7LHl0HvmAKYoLpuU1JzMstQifbsEroye3RfYCuZrVJxqdWlg/CPXxcjJISFgIjH/\r
+ 7EM2CFtM4sK99UA2F4eQwGwmiZ6mzUwQzgZGiUfHlzGDVAkJnGKS2LTKDMJewihx7LINiM0i\r
+ oCLRvb6ZBcRmE9CQ2LZ/OSOILSKgKnF122SwDcwC0hLffjczgdjCAoYS/5c9A6vnFdCROLJh\r
+ NwvEzEqJnvWLmCDighInZz5hgejVkrjx7yVQnANszvJ/HCBhTgEniTentoOViAKdMOXkNrYJ\r
+ jEKzkHTPQtI9C6F7ASPzKkbZlNwq3dzEzJzi1GTd4uTEvLzUIl0jvdzMEr3UlNJNjOCQluTd\r
+ wfjuoNIhRgEORiUe3gPnrYKFWBPLiitzDzFKcjApifJyBFsHC/El5adUZiQWZ8QXleakFh9i\r
+ lOBgVhLh/e4LlONNSaysSi3Kh0lJc7AoifO+tQaaJJCeWJKanZpakFoEk5Xh4FCS4PVuAmoU\r
+ LEpNT61Iy8wpQUgzcXCCDOcBGi4HUsNbXJCYW5yZDpE/xajL8WnDmkYmIZa8/LxUKXFeJZAi\r
+ AZCijNI8uDmwVPSKURzoLWFefZAqHmAag5v0CmgJE9AS7nVWIEtKEhFSUg2Mgs4FZ5daeLgt\r
+ dOeolJQ5M2PjL955fR9qWCLXLJ5ofZx5h+eVsLIbBZ5OhW1hLtuWrwg6f7W/fPVfpROf2cv3\r
+ K2289PP58n2f0o9NKD9r1vJ0A1v6vE59pXfWq7rYsy/PNtC/IJYv4yGUOsPI7Ue8s6AIn0ty\r
+ fOKHbvPcczKZB5mMb/C8lVdSYinOSDTUYi4qTgQARaRAISADAAA=\r
+Cc: notmuch@notmuchmail.org\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Wed, 02 Apr 2014 03:26:56 -0000\r
+\r
+Quoth David Bremner on Apr 01 at 10:16 pm:\r
+> The idea is to provide a more or less drop in replacement for readline\r
+> to read from zlib/gzip streams. Take the opportunity to replace\r
+> malloc with talloc.\r
+> ---\r
+> util/Makefile.local | 2 +-\r
+> util/util.h | 12 +++++++++\r
+> util/zlib-extra.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++\r
+> util/zlib-extra.h | 11 ++++++++\r
+> 4 files changed, 100 insertions(+), 1 deletion(-)\r
+> create mode 100644 util/util.h\r
+> create mode 100644 util/zlib-extra.c\r
+> create mode 100644 util/zlib-extra.h\r
+> \r
+> diff --git a/util/Makefile.local b/util/Makefile.local\r
+> index 29c0ce6..e2a5b65 100644\r
+> --- a/util/Makefile.local\r
+> +++ b/util/Makefile.local\r
+> @@ -4,7 +4,7 @@ dir := util\r
+> extra_cflags += -I$(srcdir)/$(dir)\r
+> \r
+> libutil_c_srcs := $(dir)/xutil.c $(dir)/error_util.c $(dir)/hex-escape.c \\r
+> - $(dir)/string-util.c $(dir)/talloc-extra.c\r
+> + $(dir)/string-util.c $(dir)/talloc-extra.c $(dir)/zlib-extra.c\r
+> \r
+> libutil_modules := $(libutil_c_srcs:.c=.o)\r
+> \r
+> diff --git a/util/util.h b/util/util.h\r
+> new file mode 100644\r
+> index 0000000..8663cfc\r
+> --- /dev/null\r
+> +++ b/util/util.h\r
+> @@ -0,0 +1,12 @@\r
+> +#ifndef _UTIL_H\r
+> +#define _UTIL_H\r
+> +\r
+> +typedef enum util_status {\r
+> + UTIL_SUCCESS = 0,\r
+> + UTIL_ERROR = 1,\r
+> + UTIL_OUT_OF_MEMORY,\r
+> + UTIL_EOF,\r
+> + UTIL_FILE,\r
+> +} util_status_t;\r
+> +\r
+> +#endif\r
+> diff --git a/util/zlib-extra.c b/util/zlib-extra.c\r
+> new file mode 100644\r
+> index 0000000..cb1eba0\r
+> --- /dev/null\r
+> +++ b/util/zlib-extra.c\r
+> @@ -0,0 +1,76 @@\r
+> +/* zlib-extra.c - Extra or enhanced routines for compressed I/O.\r
+> + *\r
+> + * Copyright (c) 2014 David Bremner\r
+> + *\r
+> + * This program is free software: you can redistribute it and/or modify\r
+> + * it under the terms of the GNU General Public License as published by\r
+> + * the Free Software Foundation, either version 3 of the License, or\r
+> + * (at your option) any later version.\r
+> + *\r
+> + * This program is distributed in the hope that it will be useful,\r
+> + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+> + * GNU General Public License for more details.\r
+> + *\r
+> + * You should have received a copy of the GNU General Public License\r
+> + * along with this program. If not, see http://www.gnu.org/licenses/ .\r
+> + *\r
+> + * Author: David Bremner <david@tethera.net>\r
+> + */\r
+> +\r
+> +#include "zlib-extra.h"\r
+> +#include <talloc.h>\r
+> +#include <stdio.h>\r
+> +#include <string.h>\r
+> +\r
+> +/* mimic POSIX/glibc getline, but on a zlib gzFile stream, and using talloc */\r
+> +util_status_t\r
+> +gz_getline (void *talloc_ctx, char **bufptr, size_t *bufsiz, ssize_t *bytes_read,\r
+\r
+Talloc chunks know their size, so rather than taking bufsize, use\r
+talloc_get_size (or talloc_array_length if you switch to talloc array\r
+functions below).\r
+\r
+> + gzFile stream)\r
+> +{\r
+> + size_t len = *bufsiz;\r
+> + char *buf = *bufptr;\r
+> + size_t offset = 0;\r
+> +\r
+> + if (len == 0 || buf == NULL) {\r
+> + /* same as getdelim from gnulib */\r
+> + len = 120;\r
+\r
+This is presumably because glibc's malloc has an 8 byte header. Fun\r
+fact: talloc has a 104 byte header (on 64-bit and including the malloc\r
+header).\r
+\r
+> + buf = talloc_size (talloc_ctx, len);\r
+> + if (buf == NULL)\r
+> + return UTIL_OUT_OF_MEMORY;\r
+> + }\r
+> +\r
+> + while (1) {\r
+> + if (! gzgets (stream, buf + offset, len - offset)) {\r
+> + int zlib_status = 0;\r
+> + (void) gzerror (stream, &zlib_status);\r
+> + switch (zlib_status) {\r
+> + case Z_OK:\r
+> + /* follow getline behaviour */\r
+> + *bytes_read = -1;\r
+\r
+Is this really what getline does when the last line of a file isn't\r
+\n-terminated?\r
+\r
+> + return UTIL_EOF;\r
+> + break;\r
+> + case Z_ERRNO:\r
+> + return UTIL_FILE;\r
+> + break;\r
+> + default:\r
+> + return UTIL_ERROR;\r
+> + }\r
+> + }\r
+> +\r
+> + offset += strlen (buf + offset);\r
+> +\r
+> + if ( buf[offset - 1] == '\n' )\r
+\r
+Too many spaces!\r
+\r
+> + break;\r
+> +\r
+> + len *= 2;\r
+> + buf = talloc_realloc (talloc_ctx, buf, char, len);\r
+\r
+Or talloc_realloc_size, to match the initial talloc_size.\r
+Alternatively, the initial talloc_size could be a talloc_array.\r
+\r
+> + if (buf == NULL)\r
+> + return UTIL_OUT_OF_MEMORY;\r
+> + }\r
+> +\r
+> + *bufptr = buf;\r
+> + *bufsiz = len;\r
+> + *bytes_read = offset;\r
+> + return UTIL_SUCCESS;\r
+> +}\r
+> diff --git a/util/zlib-extra.h b/util/zlib-extra.h\r
+> new file mode 100644\r
+> index 0000000..ed46ac1\r
+> --- /dev/null\r
+> +++ b/util/zlib-extra.h\r
+> @@ -0,0 +1,11 @@\r
+> +#ifndef _ZLIB_EXTRA_H\r
+> +#define _ZLIB_EXTRA_H\r
+> +\r
+> +#include <zlib.h>\r
+> +#include "util.h"\r
+\r
+I'd put "util.h" first so we're more likely to catch missing header\r
+dependencies (obviously util.h doesn't have any right now, but in the\r
+future).\r
+\r
+Also, I'd put a blank line after the #includes.\r
+\r
+> +/* Like getline, but read from a gzFile. Allocation is with talloc */\r
+> +util_status_t\r
+> +gz_getline (void *ctx, char **lineptr, size_t *line_size, ssize_t *bytes_read,\r
+> + gzFile stream);\r
+> +\r
+> +#endif\r