diff options
Diffstat (limited to '')
-rw-r--r-- | debian/patches/240_win64gc.patch | 1235 |
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" |