aboutsummaryrefslogtreecommitdiffstats
path: root/debian/patches/240_win64gc.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/240_win64gc.patch')
-rw-r--r--debian/patches/240_win64gc.patch1235
1 files changed, 0 insertions, 1235 deletions
diff --git a/debian/patches/240_win64gc.patch b/debian/patches/240_win64gc.patch
deleted file mode 100644
index 5005155..0000000
--- a/debian/patches/240_win64gc.patch
+++ /dev/null
@@ -1,1235 +0,0 @@
-Subject: Workaround of GC crash on Cygwin64
-From: AIDA Shinra <shinra@j10n.org>
-Origin: http://www.j10n.org/files/w3m-cvs-1.1055-win64gc.patch
-
- Patch from [w3m-dev:04469] on 2013-10-14.
-
-diff --git a/config.h.in b/config.h.in
-index 59997b4..a4110ea 100644
---- a/config.h.in
-+++ b/config.h.in
-@@ -210,6 +210,10 @@ typedef RETSIGTYPE MySignalHandler;
- #define SUPPORT_WIN9X_CONSOLE_MBCS 1
- #endif
-
-+#if defined(__CYGWIN__) && defined(__x86_64__)
-+#define DONT_CALL_GC_AFTER_FORK
-+#endif
-+
- #if defined(__DJGPP__)
- #define DEFAULT_TERM "dosansi"
- #else
-diff --git a/file.c b/file.c
-index 89c9152..6f4d5b8 100644
---- a/file.c
-+++ b/file.c
-@@ -677,6 +677,7 @@ readHeader(URLFile *uf, Buffer *newBuf, int thru, ParsedURL *pu)
- #endif
- init_stream(&f, SCM_LOCAL, newStrStream(src));
- loadHTMLstream(&f, newBuf, NULL, TRUE);
-+ UFclose(&f);
- for (l = newBuf->lastLine; l && l->real_linenumber;
- l = l->prev)
- l->real_linenumber = 0;
-@@ -7238,16 +7239,17 @@ loadHTMLString(Str page)
- MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;
- Buffer *newBuf;
-
-+ init_stream(&f, SCM_LOCAL, newStrStream(page));
-+
- newBuf = newBuffer(INIT_BUFFER_WIDTH);
- if (SETJMP(AbortLoading) != 0) {
- TRAP_OFF;
- discardBuffer(newBuf);
-+ UFclose(&f);
- return NULL;
- }
- TRAP_ON;
-
-- init_stream(&f, SCM_LOCAL, newStrStream(page));
--
- #ifdef USE_M17N
- newBuf->document_charset = InnerCharset;
- #endif
-@@ -7257,6 +7259,7 @@ loadHTMLString(Str page)
- #endif
-
- TRAP_OFF;
-+ UFclose(&f);
- newBuf->topLine = newBuf->firstLine;
- newBuf->lastLine = newBuf->currentLine;
- newBuf->currentLine = newBuf->firstLine;
-@@ -7486,15 +7489,13 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf)
- !stat(cache->file, &st))
- goto image_buffer;
-
-- TRAP_ON;
- if (IStype(uf->stream) != IST_ENCODED)
- uf->stream = newEncodedStream(uf->stream, uf->encoding);
-+ TRAP_ON;
- if (save2tmp(*uf, cache->file) < 0) {
-- UFclose(uf);
- TRAP_OFF;
- return NULL;
- }
-- UFclose(uf);
- TRAP_OFF;
-
- cache->loaded = IMG_FLAG_LOADED;
-@@ -7514,6 +7515,7 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf)
-
- init_stream(&f, SCM_LOCAL, newStrStream(tmp));
- loadHTMLstream(&f, newBuf, src, TRUE);
-+ UFclose(&f);
- if (src)
- fclose(src);
-
-@@ -7909,6 +7911,8 @@ save2tmp(URLFile uf, char *tmpf)
- clen_t linelen = 0, trbyte = 0;
- MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;
- static JMP_BUF env_bak;
-+ volatile int retval = 0;
-+ char *volatile buf = NULL;
-
- ff = fopen(tmpf, "wb");
- if (ff == NULL) {
-@@ -7945,25 +7949,25 @@ save2tmp(URLFile uf, char *tmpf)
- else
- #endif /* USE_NNTP */
- {
-- Str buf = Strnew_size(SAVE_BUF_SIZE);
-- while (UFread(&uf, buf, SAVE_BUF_SIZE)) {
-- if (Strfputs(buf, ff) != buf->length) {
-- bcopy(env_bak, AbortLoading, sizeof(JMP_BUF));
-- TRAP_OFF;
-- fclose(ff);
-- current_content_length = 0;
-- return -2;
-+ int count;
-+
-+ buf = NewWithoutGC_N(char, SAVE_BUF_SIZE);
-+ while ((count = ISread_n(uf.stream, buf, SAVE_BUF_SIZE)) > 0) {
-+ if (fwrite(buf, 1, count, ff) != count) {
-+ retval = -2;
-+ goto _end;
- }
-- linelen += buf->length;
-+ linelen += count;
- showProgress(&linelen, &trbyte);
- }
- }
- _end:
- bcopy(env_bak, AbortLoading, sizeof(JMP_BUF));
- TRAP_OFF;
-+ xfree(buf);
- fclose(ff);
- current_content_length = 0;
-- return 0;
-+ return retval;
- }
-
- Buffer *
-@@ -8074,7 +8078,8 @@ _MoveFile(char *path1, char *path2)
- FILE *f2;
- int is_pipe;
- clen_t linelen = 0, trbyte = 0;
-- Str buf;
-+ char *buf = NULL;
-+ int count;
-
- f1 = openIS(path1);
- if (f1 == NULL)
-@@ -8092,12 +8097,13 @@ _MoveFile(char *path1, char *path2)
- return -1;
- }
- current_content_length = 0;
-- buf = Strnew_size(SAVE_BUF_SIZE);
-- while (ISread(f1, buf, SAVE_BUF_SIZE)) {
-- Strfputs(buf, f2);
-- linelen += buf->length;
-+ buf = NewWithoutGC_N(char, SAVE_BUF_SIZE);
-+ while ((count = ISread_n(f1, buf, SAVE_BUF_SIZE)) > 0) {
-+ fwrite(buf, 1, count, f2);
-+ linelen += count;
- showProgress(&linelen, &trbyte);
- }
-+ xfree(buf);
- ISclose(f1);
- if (is_pipe)
- pclose(f2);
-@@ -8456,21 +8462,23 @@ uncompress_stream(URLFile *uf, char **src)
- }
- if (pid2 == 0) {
- /* child2 */
-- Str buf = Strnew_size(SAVE_BUF_SIZE);
-+ char *buf = NewWithoutGC_N(char, SAVE_BUF_SIZE);
-+ int count;
- FILE *f = NULL;
-
- setup_child(TRUE, 2, UFfileno(uf));
- if (tmpf)
- f = fopen(tmpf, "wb");
-- while (UFread(uf, buf, SAVE_BUF_SIZE)) {
-- if (Strfputs(buf, stdout) < 0)
-+ while ((count = ISread_n(uf->stream, buf, SAVE_BUF_SIZE)) > 0) {
-+ if (fwrite(buf, 1, count, stdout) != count)
-+ break;
-+ if (f && fwrite(buf, 1, count, f) != count)
- break;
-- if (f)
-- Strfputs(buf, f);
- }
- UFclose(uf);
- if (f)
- fclose(f);
-+ xfree(buf);
- exit(0);
- }
- /* child1 */
-diff --git a/fm.h b/fm.h
-index acdab46..2216b06 100644
---- a/fm.h
-+++ b/fm.h
-@@ -76,6 +76,7 @@ typedef int wc_ces; /* XXX: not used */
- #include "textlist.h"
- #include "funcname1.h"
- #include "terms.h"
-+#include "istream.h"
-
- #ifndef HAVE_BCOPY
- void bcopy(const void *, void *, int);
-@@ -288,8 +289,6 @@ extern int REV_LB[];
- #define inputFilenameHist(p,d,h) inputLineHist(p,d,IN_FILENAME,h)
- #define inputChar(p) inputLine(p,"",IN_CHAR)
-
--#define free(x) GC_free(x) /* let GC do it. */
--
- #ifdef __EMX__
- #define HAVE_STRCASECMP
- #define strcasecmp stricmp
-@@ -895,6 +894,9 @@ global char *index_file init(NULL);
-
- global char *CurrentDir;
- global int CurrentPid;
-+#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE)
-+global char *MyProgramName init("w3m");
-+#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */
- /*
- * global Buffer *Currentbuf;
- * global Buffer *Firstbuf;
-diff --git a/html.h b/html.h
-index 4a2827b..b4b3df9 100644
---- a/html.h
-+++ b/html.h
-@@ -1,19 +1,17 @@
- /* $Id: html.h,v 1.31 2010/08/14 01:29:40 htrb Exp $ */
- #ifndef _HTML_H
- #define _HTML_H
-+#include "config.h"
- #ifdef USE_SSL
- #include <openssl/bio.h>
- #include <openssl/x509.h>
- #include <openssl/ssl.h>
- #endif /* USE_SSL */
-
--#include "istream.h"
--
- #define StrUFgets(f) StrISgets((f)->stream)
- #define StrmyUFgets(f) StrmyISgets((f)->stream)
- #define UFgetc(f) ISgetc((f)->stream)
- #define UFundogetc(f) ISundogetc((f)->stream)
--#define UFread(f,buf,len) ISread((f)->stream,buf,len)
- #define UFclose(f) (void)(ISclose((f)->stream) == 0 && ((f)->stream = NULL))
- #define UFfileno(f) ISfileno((f)->stream)
-
-@@ -62,11 +60,12 @@ typedef struct _ParsedURL {
- int is_nocache;
- } ParsedURL;
-
-+union input_stream;
- typedef struct {
- unsigned char scheme;
- char is_cgi;
- char encoding;
-- InputStream stream;
-+ union input_stream *stream;
- char *ext;
- int compression;
- int content_encoding;
-diff --git a/image.c b/image.c
-index 5f5991a..9d0e9b5 100644
---- a/image.c
-+++ b/image.c
-@@ -90,17 +90,18 @@ termImage()
- static int
- openImgdisplay()
- {
-+ char *cmd;
-+
-+ if (!strchr(Imgdisplay, '/'))
-+ cmd = Strnew_m_charp(w3m_auxbin_dir(), "/", Imgdisplay, NULL)->ptr;
-+ else
-+ cmd = Imgdisplay;
- Imgdisplay_pid = open_pipe_rw(&Imgdisplay_rf, &Imgdisplay_wf);
- if (Imgdisplay_pid < 0)
- goto err0;
- if (Imgdisplay_pid == 0) {
- /* child */
-- char *cmd;
- setup_child(FALSE, 2, -1);
-- if (!strchr(Imgdisplay, '/'))
-- cmd = Strnew_m_charp(w3m_auxbin_dir(), "/", Imgdisplay, NULL)->ptr;
-- else
-- cmd = Imgdisplay;
- myExec(cmd);
- /* XXX: ifdef __EMX__, use start /f ? */
- }
-@@ -333,6 +334,9 @@ loadImage(Buffer *buf, int flag)
- struct stat st;
- int i, draw = FALSE;
- /* int wait_st; */
-+#ifdef DONT_CALL_GC_AFTER_FORK
-+ char *loadargs[7];
-+#endif
-
- if (maxLoadImage > MAX_LOAD_IMAGE)
- maxLoadImage = MAX_LOAD_IMAGE;
-@@ -433,6 +437,24 @@ loadImage(Buffer *buf, int flag)
- image_cache[i] = cache;
-
- flush_tty();
-+#ifdef DONT_CALL_GC_AFTER_FORK
-+ loadargs[0] = MyProgramName;
-+ loadargs[1] = "-$$getimage";
-+ loadargs[2] = conv_to_system(cache->url);
-+ loadargs[3] = conv_to_system(parsedURL2Str(cache->current)->ptr);
-+ loadargs[4] = cache->file;
-+ loadargs[5] = cache->touch;
-+ loadargs[6] = NULL;
-+ if ((cache->pid = fork()) == 0) {
-+ setup_child(FALSE, 0, -1);
-+ execvp(MyProgramName, loadargs);
-+ exit(1);
-+ }
-+ else if (cache->pid < 0) {
-+ cache->pid = 0;
-+ return;
-+ }
-+#else /* !DONT_CALL_GC_AFTER_FORK */
- if ((cache->pid = fork()) == 0) {
- Buffer *b;
- /*
-@@ -458,6 +480,7 @@ loadImage(Buffer *buf, int flag)
- cache->pid = 0;
- return;
- }
-+#endif /* !DONT_CALL_GC_AFTER_FORK */
- }
- }
-
-diff --git a/indep.c b/indep.c
-index 89e86c1..5c5de06 100644
---- a/indep.c
-+++ b/indep.c
-@@ -721,6 +721,111 @@ shell_quote(char *str)
- return str;
- }
-
-+void *
-+xrealloc(void *ptr, size_t size)
-+{
-+ void *newptr = realloc(ptr, size);
-+ if (newptr == NULL) {
-+ fprintf(stderr, "Out of memory\n");
-+ exit(-1);
-+ }
-+ return newptr;
-+}
-+
-+/* Define this as a separate function in case the free() has
-+ * an incompatible prototype. */
-+void
-+xfree(void *ptr)
-+{
-+ free(ptr);
-+}
-+
-+void *
-+w3m_GC_realloc_atomic(void *ptr, size_t size)
-+{
-+ return ptr ? GC_REALLOC(ptr, size) : GC_MALLOC_ATOMIC(size);
-+}
-+
-+void
-+w3m_GC_free(void *ptr)
-+{
-+ GC_FREE(ptr);
-+}
-+
-+void
-+growbuf_init(struct growbuf *gb)
-+{
-+ gb->ptr = NULL;
-+ gb->length = 0;
-+ gb->area_size = 0;
-+ gb->realloc_proc = &w3m_GC_realloc_atomic;
-+ gb->free_proc = &w3m_GC_free;
-+}
-+
-+void
-+growbuf_init_without_GC(struct growbuf *gb)
-+{
-+ gb->ptr = NULL;
-+ gb->length = 0;
-+ gb->area_size = 0;
-+ gb->realloc_proc = &xrealloc;
-+ gb->free_proc = &xfree;
-+}
-+
-+void
-+growbuf_clear(struct growbuf *gb)
-+{
-+ (*gb->free_proc) (gb->ptr);
-+ gb->ptr = NULL;
-+ gb->length = 0;
-+ gb->area_size = 0;
-+}
-+
-+Str
-+growbuf_to_Str(struct growbuf *gb)
-+{
-+ Str s;
-+
-+ if (gb->free_proc == &w3m_GC_free) {
-+ growbuf_reserve(gb, gb->length + 1);
-+ gb->ptr[gb->length] = '\0';
-+ s = New(struct _Str);
-+ s->ptr = gb->ptr;
-+ s->length = gb->length;
-+ s->area_size = gb->area_size;
-+ } else {
-+ s = Strnew_charp_n(gb->ptr, gb->length);
-+ (*gb->free_proc) (gb->ptr);
-+ }
-+ gb->ptr = NULL;
-+ gb->length = 0;
-+ gb->area_size = 0;
-+ return s;
-+}
-+
-+void
-+growbuf_reserve(struct growbuf *gb, int leastarea)
-+{
-+ int newarea;
-+
-+ if (gb->area_size < leastarea) {
-+ newarea = gb->area_size * 3 / 2;
-+ if (newarea < leastarea)
-+ newarea = leastarea;
-+ newarea += 16;
-+ gb->ptr = (*gb->realloc_proc) (gb->ptr, newarea);
-+ gb->area_size = newarea;
-+ }
-+}
-+
-+void
-+growbuf_append(struct growbuf *gb, const char *src, int len)
-+{
-+ growbuf_reserve(gb, gb->length + len);
-+ memcpy(&gb->ptr[gb->length], src, len);
-+ gb->length += len;
-+}
-+
- static char *
- w3m_dir(const char *name, char *dft)
- {
-diff --git a/indep.h b/indep.h
-index cf566fe..84416ed 100644
---- a/indep.h
-+++ b/indep.h
-@@ -12,6 +12,14 @@
- #define FALSE 0
- #endif /* FALSE */
-
-+struct growbuf {
-+ char *ptr;
-+ int length;
-+ int area_size;
-+ void *(*realloc_proc) (void *, size_t);
-+ void (*free_proc) (void *);
-+};
-+
- #define RAW_MODE 0
- #define PAGER_MODE 1
- #define HTML_MODE 2
-@@ -65,6 +73,18 @@ extern Str Str_url_unquote(Str x, int is_form, int safe);
- extern Str Str_form_quote(Str x);
- #define Str_form_unquote(x) Str_url_unquote((x), TRUE, FALSE)
- extern char *shell_quote(char *str);
-+#define xmalloc(s) xrealloc(NULL, s)
-+extern void *xrealloc(void *ptr, size_t size);
-+extern void xfree(void *ptr);
-+extern void *w3m_GC_realloc_atomic(void *ptr, size_t size);
-+extern void w3m_GC_free(void *ptr);
-+extern void growbuf_init(struct growbuf *gb);
-+extern void growbuf_init_without_GC(struct growbuf *gb);
-+extern void growbuf_clear(struct growbuf *gb);
-+extern Str growbuf_to_Str(struct growbuf *gb);
-+extern void growbuf_reserve(struct growbuf *gb, int leastarea);
-+extern void growbuf_append(struct growbuf *gb, const char *src, int len);
-+#define GROWBUF_ADD_CHAR(gb,ch) ((((gb)->length>=(gb)->area_size)?growbuf_reserve(gb,(gb)->length+1):(void)0),(void)((gb)->ptr[(gb)->length++] = (ch)))
-
- extern char *w3m_auxbin_dir();
- extern char *w3m_lib_dir();
-@@ -77,5 +97,8 @@ extern char *w3m_help_dir();
- #define New_N(type,n) ((type*)GC_MALLOC((n)*sizeof(type)))
- #define NewAtom_N(type,n) ((type*)GC_MALLOC_ATOMIC((n)*sizeof(type)))
- #define New_Reuse(type,ptr,n) ((type*)GC_REALLOC((ptr),(n)*sizeof(type)))
-+#define NewWithoutGC(type) ((type*)xmalloc(sizeof(type)))
-+#define NewWithoutGC_N(type,n) ((type*)xmalloc((n)*sizeof(type)))
-+#define NewWithoutGC_Reuse(type,ptr,n) ((type*)xrealloc(ptr,(n)*sizeof(type)))
-
- #endif /* INDEP_H */
-diff --git a/istream.c b/istream.c
-index d8c8e45..3126142 100644
---- a/istream.c
-+++ b/istream.c
-@@ -35,12 +35,14 @@ static int ssl_read(struct ssl_handle *handle, char *buf, int len);
- static int ens_read(struct ens_handle *handle, char *buf, int len);
- static void ens_close(struct ens_handle *handle);
-
-+static void memchop(char *p, int *len);
-+
- static void
- do_update(BaseStream base)
- {
- int len;
- base->stream.cur = base->stream.next = 0;
-- len = base->read(base->handle, base->stream.buf, base->stream.size);
-+ len = (*base->read) (base->handle, base->stream.buf, base->stream.size);
- if (len <= 0)
- base->iseos = TRUE;
- else
-@@ -66,12 +68,12 @@ init_buffer(BaseStream base, char *buf, int bufsize)
- StreamBuffer sb = &base->stream;
- sb->size = bufsize;
- sb->cur = 0;
-+ sb->buf = NewWithoutGC_N(uchar, bufsize);
- if (buf) {
-- sb->buf = (uchar *) buf;
-+ memcpy(sb->buf, buf, bufsize);
- sb->next = bufsize;
- }
- else {
-- sb->buf = NewAtom_N(uchar, bufsize);
- sb->next = 0;
- }
- base->iseos = FALSE;
-@@ -95,10 +97,10 @@ newInputStream(int des)
- InputStream stream;
- if (des < 0)
- return NULL;
-- stream = New(union input_stream);
-+ stream = NewWithoutGC(union input_stream);
- init_base_stream(&stream->base, STREAM_BUF_SIZE);
- stream->base.type = IST_BASIC;
-- stream->base.handle = New(int);
-+ stream->base.handle = NewWithoutGC(int);
- *(int *)stream->base.handle = des;
- stream->base.read = (int (*)())basic_read;
- stream->base.close = (void (*)())basic_close;
-@@ -111,10 +113,10 @@ newFileStream(FILE * f, void (*closep) ())
- InputStream stream;
- if (f == NULL)
- return NULL;
-- stream = New(union input_stream);
-+ stream = NewWithoutGC(union input_stream);
- init_base_stream(&stream->base, STREAM_BUF_SIZE);
- stream->file.type = IST_FILE;
-- stream->file.handle = New(struct io_file_handle);
-+ stream->file.handle = NewWithoutGC(struct io_file_handle);
- stream->file.handle->f = f;
- if (closep)
- stream->file.handle->close = closep;
-@@ -131,10 +133,10 @@ newStrStream(Str s)
- InputStream stream;
- if (s == NULL)
- return NULL;
-- stream = New(union input_stream);
-+ stream = NewWithoutGC(union input_stream);
- init_str_stream(&stream->base, s);
- stream->str.type = IST_STR;
-- stream->str.handle = s;
-+ stream->str.handle = NULL;
- stream->str.read = (int (*)())str_read;
- stream->str.close = NULL;
- return stream;
-@@ -147,10 +149,10 @@ newSSLStream(SSL * ssl, int sock)
- InputStream stream;
- if (sock < 0)
- return NULL;
-- stream = New(union input_stream);
-+ stream = NewWithoutGC(union input_stream);
- init_base_stream(&stream->base, SSL_BUF_SIZE);
- stream->ssl.type = IST_SSL;
-- stream->ssl.handle = New(struct ssl_handle);
-+ stream->ssl.handle = NewWithoutGC(struct ssl_handle);
- stream->ssl.handle->ssl = ssl;
- stream->ssl.handle->sock = sock;
- stream->ssl.read = (int (*)())ssl_read;
-@@ -166,14 +168,14 @@ newEncodedStream(InputStream is, char encoding)
- if (is == NULL || (encoding != ENC_QUOTE && encoding != ENC_BASE64 &&
- encoding != ENC_UUENCODE))
- return is;
-- stream = New(union input_stream);
-+ stream = NewWithoutGC(union input_stream);
- init_base_stream(&stream->base, STREAM_BUF_SIZE);
- stream->ens.type = IST_ENCODED;
-- stream->ens.handle = New(struct ens_handle);
-+ stream->ens.handle = NewWithoutGC(struct ens_handle);
- stream->ens.handle->is = is;
- stream->ens.handle->pos = 0;
- stream->ens.handle->encoding = encoding;
-- stream->ens.handle->s = NULL;
-+ growbuf_init_without_GC(&stream->ens.handle->gb);
- stream->ens.read = (int (*)())ens_read;
- stream->ens.close = (void (*)())ens_close;
- return stream;
-@@ -187,8 +189,10 @@ ISclose(InputStream stream)
- stream->base.type & IST_UNCLOSE)
- return -1;
- prevtrap = mySignal(SIGINT, SIG_IGN);
-- stream->base.close(stream->base.handle);
-+ stream->base.close (stream->base.handle);
- mySignal(SIGINT, prevtrap);
-+ xfree(stream->base.stream.buf);
-+ xfree(stream);
- return 0;
- }
-
-@@ -218,122 +222,97 @@ ISundogetc(InputStream stream)
- return -1;
- }
-
--#define MARGIN_STR_SIZE 10
- Str
--StrISgets(InputStream stream)
-+StrISgets2(InputStream stream, char crnl)
- {
-- BaseStream base;
-- StreamBuffer sb;
-- Str s = NULL;
-- uchar *p;
-- int len;
-+ struct growbuf gb;
-
- if (stream == NULL)
-- return '\0';
-- base = &stream->base;
-- sb = &base->stream;
--
-- while (!base->iseos) {
-- if (MUST_BE_UPDATED(base)) {
-- do_update(base);
-- }
-- else {
-- if ((p = memchr(&sb->buf[sb->cur], '\n', sb->next - sb->cur))) {
-- len = p - &sb->buf[sb->cur] + 1;
-- if (s == NULL)
-- s = Strnew_size(len);
-- Strcat_charp_n(s, (char *)&sb->buf[sb->cur], len);
-- sb->cur += len;
-- return s;
-- }
-- else {
-- if (s == NULL)
-- s = Strnew_size(sb->next - sb->cur + MARGIN_STR_SIZE);
-- Strcat_charp_n(s, (char *)&sb->buf[sb->cur],
-- sb->next - sb->cur);
-- sb->cur = sb->next;
-- }
-- }
-- }
--
-- if (s == NULL)
-- return Strnew();
-- return s;
-+ return NULL;
-+ growbuf_init(&gb);
-+ ISgets_to_growbuf(stream, &gb, crnl);
-+ return growbuf_to_Str(&gb);
- }
-
--Str
--StrmyISgets(InputStream stream)
-+void
-+ISgets_to_growbuf(InputStream stream, struct growbuf *gb, char crnl)
- {
-- BaseStream base;
-- StreamBuffer sb;
-- Str s = NULL;
-- int i, len;
-+ BaseStream base = &stream->base;
-+ StreamBuffer sb = &base->stream;
-+ int i;
-
-- if (stream == NULL)
-- return '\0';
-- base = &stream->base;
-- sb = &base->stream;
-+ gb->length = 0;
-
- while (!base->iseos) {
- if (MUST_BE_UPDATED(base)) {
- do_update(base);
-+ continue;
- }
-- else {
-- if (s && Strlastchar(s) == '\r') {
-- if (sb->buf[sb->cur] == '\n')
-- Strcat_char(s, (char)sb->buf[sb->cur++]);
-- return s;
-+ if (crnl && gb->length > 0 && gb->ptr[gb->length - 1] == '\r') {
-+ if (sb->buf[sb->cur] == '\n') {
-+ GROWBUF_ADD_CHAR(gb, '\n');
-+ ++sb->cur;
- }
-- for (i = sb->cur;
-- i < sb->next && sb->buf[i] != '\n' && sb->buf[i] != '\r';
-- i++) ;
-- if (i < sb->next) {
-- len = i - sb->cur + 1;
-- if (s == NULL)
-- s = Strnew_size(len + MARGIN_STR_SIZE);
-- Strcat_charp_n(s, (char *)&sb->buf[sb->cur], len);
-- sb->cur = i + 1;
-- if (sb->buf[i] == '\n')
-- return s;
-- }
-- else {
-- if (s == NULL)
-- s = Strnew_size(sb->next - sb->cur + MARGIN_STR_SIZE);
-- Strcat_charp_n(s, (char *)&sb->buf[sb->cur],
-- sb->next - sb->cur);
-- sb->cur = sb->next;
-+ break;
-+ }
-+ for (i = sb->cur; i < sb->next; ++i) {
-+ if (sb->buf[i] == '\n' || (crnl && sb->buf[i] == '\r')) {
-+ ++i;
-+ break;
- }
- }
-+ growbuf_append(gb, &sb->buf[sb->cur], i - sb->cur);
-+ sb->cur = i;
-+ if (gb->length > 0 && gb->ptr[gb->length - 1] == '\n')
-+ break;
- }
-
-- if (s == NULL)
-- return Strnew();
-- return s;
-+ growbuf_reserve(gb, gb->length + 1);
-+ gb->ptr[gb->length] = '\0';
-+ return;
- }
-
-+#ifdef unused
- int
- ISread(InputStream stream, Str buf, int count)
- {
-- int rest, len;
-+ int len;
-+
-+ if (count + 1 > buf->area_size) {
-+ char *newptr = GC_MALLOC_ATOMIC(count + 1);
-+ memcpy(newptr, buf->ptr, buf->length);
-+ newptr[buf->length] = '\0';
-+ buf->ptr = newptr;
-+ buf->area_size = count + 1;
-+ }
-+ len = ISread_n(stream, buf->ptr, count);
-+ buf->length = (len > 0) ? len : 0;
-+ buf->ptr[buf->length] = '\0';
-+ return (len > 0) ? 1 : 0;
-+}
-+#endif
-+
-+int
-+ISread_n(InputStream stream, char *dst, int count)
-+{
-+ int len, l;
- BaseStream base;
-
-- if (stream == NULL || (base = &stream->base)->iseos)
-+ if (stream == NULL || count <= 0)
-+ return -1;
-+ if ((base = &stream->base)->iseos)
- return 0;
-
-- len = buffer_read(&base->stream, buf->ptr, count);
-- rest = count - len;
-+ len = buffer_read(&base->stream, dst, count);
- if (MUST_BE_UPDATED(base)) {
-- len = base->read(base->handle, &buf->ptr[len], rest);
-- if (len <= 0) {
-+ l = (*base->read) (base->handle, &dst[len], count - len);
-+ if (l <= 0) {
- base->iseos = TRUE;
-- len = 0;
-+ } else {
-+ len += l;
- }
-- rest -= len;
- }
-- Strtruncate(buf, count - rest);
-- if (buf->length > 0)
-- return 1;
-- return 0;
-+ return len;
- }
-
- int
-@@ -645,6 +624,7 @@ basic_close(int *handle)
- #else
- close(*(int *)handle);
- #endif
-+ xfree(handle);
- }
-
- static int
-@@ -661,6 +641,7 @@ static void
- file_close(struct io_file_handle *handle)
- {
- handle->close(handle->f);
-+ xfree(handle);
- }
-
- static int
-@@ -682,6 +663,7 @@ ssl_close(struct ssl_handle *handle)
- close(handle->sock);
- if (handle->ssl)
- SSL_free(handle->ssl);
-+ xfree(handle);
- }
-
- static int
-@@ -717,38 +699,60 @@ static void
- ens_close(struct ens_handle *handle)
- {
- ISclose(handle->is);
-+ growbuf_clear(&handle->gb);
-+ xfree(handle);
- }
-
- static int
- ens_read(struct ens_handle *handle, char *buf, int len)
- {
-- if (handle->s == NULL || handle->pos == handle->s->length) {
-+ if (handle->pos == handle->gb.length) {
- char *p;
-- handle->s = StrmyISgets(handle->is);
-- if (handle->s->length == 0)
-+ struct growbuf gbtmp;
-+
-+ ISgets_to_growbuf(handle->is, &handle->gb, TRUE);
-+ if (handle->gb.length == 0)
- return 0;
-- cleanup_line(handle->s, PAGER_MODE);
- if (handle->encoding == ENC_BASE64)
-- Strchop(handle->s);
-+ memchop(handle->gb.ptr, &handle->gb.length);
- else if (handle->encoding == ENC_UUENCODE) {
-- if (!strncmp(handle->s->ptr, "begin", 5))
-- handle->s = StrmyISgets(handle->is);
-- Strchop(handle->s);
-+ if (handle->gb.length >= 5 &&
-+ !strncmp(handle->gb.ptr, "begin", 5))
-+ ISgets_to_growbuf(handle->is, &handle->gb, TRUE);
-+ memchop(handle->gb.ptr, &handle->gb.length);
- }
-- p = handle->s->ptr;
-+ growbuf_init_without_GC(&gbtmp);
-+ p = handle->gb.ptr;
- if (handle->encoding == ENC_QUOTE)
-- handle->s = decodeQP(&p);
-+ decodeQP_to_growbuf(&gbtmp, &p);
- else if (handle->encoding == ENC_BASE64)
-- handle->s = decodeB(&p);
-+ decodeB_to_growbuf(&gbtmp, &p);
- else if (handle->encoding == ENC_UUENCODE)
-- handle->s = decodeU(&p);
-+ decodeU_to_growbuf(&gbtmp, &p);
-+ growbuf_clear(&handle->gb);
-+ handle->gb = gbtmp;
- handle->pos = 0;
- }
-
-- if (len > handle->s->length - handle->pos)
-- len = handle->s->length - handle->pos;
-+ if (len > handle->gb.length - handle->pos)
-+ len = handle->gb.length - handle->pos;
-
-- bcopy(&handle->s->ptr[handle->pos], buf, len);
-+ memcpy(buf, &handle->gb.ptr[handle->pos], len);
- handle->pos += len;
- return len;
- }
-+
-+static void
-+memchop(char *p, int *len)
-+{
-+ char *q;
-+
-+ for (q = p + *len; q > p; --q) {
-+ if (q[-1] != '\n' && q[-1] != '\r')
-+ break;
-+ }
-+ if (q != p + *len)
-+ *q = '\0';
-+ *len = q - p;
-+ return;
-+}
-diff --git a/istream.h b/istream.h
-index e710e78..5a04be0 100644
---- a/istream.h
-+++ b/istream.h
-@@ -2,13 +2,13 @@
- #ifndef IO_STREAM_H
- #define IO_STREAM_H
-
-+#include "indep.h"
- #include <stdio.h>
- #ifdef USE_SSL
- #include <openssl/bio.h>
- #include <openssl/x509.h>
- #include <openssl/ssl.h>
- #endif
--#include "Str.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
-@@ -36,7 +36,7 @@ union input_stream;
-
- struct ens_handle {
- union input_stream *is;
-- Str s;
-+ struct growbuf gb;
- int pos;
- char encoding;
- };
-@@ -119,9 +119,14 @@ extern InputStream newEncodedStream(InputStream is, char encoding);
- extern int ISclose(InputStream stream);
- extern int ISgetc(InputStream stream);
- extern int ISundogetc(InputStream stream);
--extern Str StrISgets(InputStream stream);
--extern Str StrmyISgets(InputStream stream);
-+extern Str StrISgets2(InputStream stream, char crnl);
-+#define StrISgets(stream) StrISgets2(stream, FALSE)
-+#define StrmyISgets(stream) StrISgets2(stream, TRUE)
-+void ISgets_to_growbuf(InputStream stream, struct growbuf *gb, char crnl);
-+#ifdef unused
- extern int ISread(InputStream stream, Str buf, int count);
-+#endif
-+int ISread_n(InputStream stream, char *dst, int bufsize);
- extern int ISfileno(InputStream stream);
- extern int ISeos(InputStream stream);
- #ifdef USE_SSL
-diff --git a/local.c b/local.c
-index f5a73a2..959bd66 100644
---- a/local.c
-+++ b/local.c
-@@ -359,6 +359,10 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
- int status;
- pid_t pid;
- char *file = uri, *name = uri, *path_info = NULL, *tmpf = NULL;
-+#ifdef HAVE_CHDIR
-+ char *cgi_dir;
-+#endif
-+ char *cgi_basename;
-
- #ifdef __MINGW32_VERSION
- return NULL;
-@@ -373,7 +377,14 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
- if (!fw)
- return NULL;
- }
-+ if (qstr)
-+ uri = Strnew_m_charp(uri, "?", qstr, NULL)->ptr;
-+#ifdef HAVE_CHDIR
-+ cgi_dir = mydirname(file);
-+#endif
-+ cgi_basename = mybasename(file);
- pid = open_pipe_rw(&fr, NULL);
-+ /* Don't invoke gc after here, or the program might crash in some platforms */
- if (pid < 0)
- return NULL;
- else if (pid) {
-@@ -383,8 +394,6 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
- }
- setup_child(TRUE, 2, fw ? fileno(fw) : -1);
-
-- if (qstr)
-- uri = Strnew_m_charp(uri, "?", qstr, NULL)->ptr;
- set_cgi_environ(name, file, uri);
- if (path_info)
- set_environ("PATH_INFO", path_info);
-@@ -415,11 +424,11 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
- }
-
- #ifdef HAVE_CHDIR /* ifndef __EMX__ ? */
-- chdir(mydirname(file));
-+ chdir(cgi_dir);
- #endif
-- execl(file, mybasename(file), NULL);
-+ execl(file, cgi_basename, NULL);
- fprintf(stderr, "execl(\"%s\", \"%s\", NULL): %s\n",
-- file, mybasename(file), strerror(errno));
-+ file, cgi_basename, strerror(errno));
- exit(1);
- return NULL;
- #endif
-diff --git a/main.c b/main.c
-index c49985d..ec77085 100644
---- a/main.c
-+++ b/main.c
-@@ -11,6 +11,9 @@
- #include <sys/wait.h>
- #endif
- #include <time.h>
-+#if defined(__CYGWIN__) && defined(USE_BINMODE_STREAM)
-+#include <io.h>
-+#endif
- #include "terms.h"
- #include "myctype.h"
- #include "regex.h"
-@@ -407,6 +410,10 @@ main(int argc, char **argv, char **envp)
- wc_ces CodePage;
- #endif
- #endif
-+#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE)
-+ char **getimage_args = NULL;
-+#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */
-+
- GC_INIT();
- #if defined(ENABLE_NLS) || (defined(USE_M17N) && defined(HAVE_LANGINFO_CODESET))
- setlocale(LC_ALL, "");
-@@ -428,6 +435,10 @@ main(int argc, char **argv, char **envp)
-
- CurrentDir = currentdir();
- CurrentPid = (int)getpid();
-+#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE)
-+ if (argv[0] && *argv[0])
-+ MyProgramName = argv[0];
-+#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */
- BookmarkFile = NULL;
- config_file = NULL;
-
-@@ -751,6 +762,15 @@ main(int argc, char **argv, char **envp)
- else if (!strcmp("-reqlog",argv[i])) {
- w3m_reqlog=rcFile("request.log");
- }
-+#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE)
-+ else if (!strcmp("-$$getimage", argv[i])) {
-+ ++i;
-+ getimage_args = argv + i;
-+ i += 4;
-+ if (i > argc)
-+ usage();
-+ }
-+#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */
- else {
- usage();
- }
-@@ -839,6 +859,30 @@ main(int argc, char **argv, char **envp)
-
- if (w3m_backend)
- backend();
-+#if defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE)
-+ if (getimage_args) {
-+ char *image_url = conv_from_system(getimage_args[0]);
-+ char *base_url = conv_from_system(getimage_args[1]);
-+ ParsedURL base_pu;
-+
-+ parseURL2(base_url, &base_pu, NULL);
-+ image_source = getimage_args[2];
-+ newbuf = loadGeneralFile(image_url, &base_pu, NULL, 0, NULL);
-+ if (!newbuf || !newbuf->real_type ||
-+ strncasecmp(newbuf->real_type, "image/", 6))
-+ unlink(getimage_args[2]);
-+#if defined(HAVE_SYMLINK) && defined(HAVE_LSTAT)
-+ symlink(getimage_args[2], getimage_args[3]);
-+#else
-+ {
-+ FILE *f = fopen(getimage_args[3], "w");
-+ if (f)
-+ fclose(f);
-+ }
-+#endif
-+ w3m_exit(0);
-+ }
-+#endif /* defined(DONT_CALL_GC_AFTER_FORK) && defined(USE_IMAGE) */
-
- if (w3m_dump)
- mySignal(SIGINT, SIG_IGN);
-diff --git a/mimehead.c b/mimehead.c
-index 78997e0..d16270c 100644
---- a/mimehead.c
-+++ b/mimehead.c
-@@ -64,12 +64,22 @@ ha2d(char x, char y)
- Str
- decodeB(char **ww)
- {
-+ struct growbuf gb;
-+
-+ growbuf_init(&gb);
-+ decodeB_to_growbuf(&gb, ww);
-+ return growbuf_to_Str(&gb);
-+}
-+
-+void
-+decodeB_to_growbuf(struct growbuf *gb, char **ww)
-+{
- unsigned char c[4];
- char *wp = *ww;
- char d[3];
- int i, n_pad;
-- Str ap = Strnew_size(strlen(wp));
-
-+ growbuf_reserve(gb, strlen(wp) + 1);
- n_pad = 0;
- while (1) {
- for (i = 0; i < 4; i++) {
-@@ -93,39 +103,50 @@ decodeB(char **ww)
- for (i = 0; i < 4; i++) {
- c[i] = c2e(c[i]);
- if (c[i] == BAD_BASE64) {
-- *ww = wp;
-- return ap;
-+ goto last;
- }
- }
- d[0] = ((c[0] << 2) | (c[1] >> 4));
- d[1] = ((c[1] << 4) | (c[2] >> 2));
- d[2] = ((c[2] << 6) | c[3]);
- for (i = 0; i < 3 - n_pad; i++) {
-- Strcat_char(ap, d[i]);
-+ GROWBUF_ADD_CHAR(gb, d[i]);
- }
- if (n_pad || *wp == '\0' || *wp == '?')
- break;
- }
-+last:
-+ growbuf_reserve(gb, gb->length + 1);
-+ gb->ptr[gb->length] = '\0';
- *ww = wp;
-- return ap;
-+ return;
- }
-
- Str
- decodeU(char **ww)
- {
-+ struct growbuf gb;
-+
-+ growbuf_init(&gb);
-+ decodeU_to_growbuf(&gb, ww);
-+ return growbuf_to_Str(&gb);
-+}
-+
-+void
-+decodeU_to_growbuf(struct growbuf *gb, char **ww)
-+{
- unsigned char c1, c2;
- char *w = *ww;
- int n, i;
-- Str a;
-
- if (*w <= 0x20 || *w >= 0x60)
-- return Strnew_size(0);
-+ return;
- n = *w - 0x20;
-- a = Strnew_size(n);
-+ growbuf_reserve(gb, n + 1);
- for (w++, i = 2; *w != '\0' && n; n--) {
- c1 = (w[0] - 0x20) % 0x40;
- c2 = (w[1] - 0x20) % 0x40;
-- Strcat_char(a, (c1 << i) | (c2 >> (6 - i)));
-+ gb->ptr[gb->length++] = (c1 << i) | (c2 >> (6 - i));
- if (i == 6) {
- w += 2;
- i = 2;
-@@ -135,7 +156,8 @@ decodeU(char **ww)
- i += 2;
- }
- }
-- return a;
-+ gb->ptr[gb->length] = '\0';
-+ return;
- }
-
- /* RFC2047 (4.2. The "Q" encoding) */
-@@ -165,9 +187,19 @@ decodeQ(char **ww)
- Str
- decodeQP(char **ww)
- {
-+ struct growbuf gb;
-+
-+ growbuf_init(&gb);
-+ decodeQP_to_growbuf(&gb, ww);
-+ return growbuf_to_Str(&gb);
-+}
-+
-+void
-+decodeQP_to_growbuf(struct growbuf *gb, char **ww)
-+{
- char *w = *ww;
-- Str a = Strnew_size(strlen(w));
-
-+ growbuf_reserve(gb, strlen(w) + 1);
- for (; *w != '\0'; w++) {
- if (*w == '=') {
- w++;
-@@ -180,15 +212,16 @@ decodeQP(char **ww)
- else {
- if (*w == '\0' || *(w + 1) == '\0')
- break;
-- Strcat_char(a, ha2d(*w, *(w + 1)));
-+ gb->ptr[gb->length++] = ha2d(*w, *(w + 1));
- w++;
- }
- }
- else
-- Strcat_char(a, *w);
-+ gb->ptr[gb->length++] = *w;
- }
-+ gb->ptr[gb->length] = '\0';
- *ww = w;
-- return a;
-+ return;
- }
-
- #ifdef USE_M17N
-diff --git a/proto.h b/proto.h
-index 7248ee5..0d8beb5 100644
---- a/proto.h
-+++ b/proto.h
-@@ -607,9 +607,12 @@ extern char *getAnchorText(Buffer *buf, AnchorList *al, Anchor *a);
- extern Buffer *link_list_panel(Buffer *buf);
-
- extern Str decodeB(char **ww);
-+extern void decodeB_to_growbuf(struct growbuf *gb, char **ww);
- extern Str decodeQ(char **ww);
- extern Str decodeQP(char **ww);
-+extern void decodeQP_to_growbuf(struct growbuf *gb, char **ww);
- extern Str decodeU(char **ww);
-+extern void decodeU_to_growbuf(struct growbuf *gb, char **ww);
- #ifdef USE_M17N
- extern Str decodeWord(char **ow, wc_ces * charset);
- extern Str decodeMIME(Str orgstr, wc_ces * charset);
-@@ -811,5 +814,3 @@ extern void dispVer(void);
- void srand48(long);
- long lrand48(void);
- #endif
--
--#include "indep.h"