-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0015-keep-buffer-like-temp-file-in-memory.patch
195 lines (181 loc) · 5.25 KB
/
0015-keep-buffer-like-temp-file-in-memory.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
From 3776d7d28624f0761edc5f8d4956af2c62cf1dc1 Mon Sep 17 00:00:00 2001
From: Julius Plenz <[email protected]>
Date: Wed, 5 Oct 2011 18:27:17 +0200
Subject: [PATCH 15/19] keep buffer-like temp file in memory
When searching the header or body for strings and the `thorough_search'
option is set, a temp file was created, parsed, and then unlinked again.
This is now done in memory using glibc's open_memstream() and
fmemopen() if they are available.
This is a bit hackish, but might increase performance greatly. YMMV.
Signed-off-by: Julius Plenz <[email protected]>
---
configure.ac | 2 ++
handler.c | 29 +++++++++++++++++++++++++++++
pattern.c | 38 ++++++++++++++++++++++++++++++++++++++
3 files changed, 69 insertions(+), 0 deletions(-)
diff --git a/configure.ac b/configure.ac
index 5a8c7f0..91964c1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1289,6 +1289,8 @@ if test $mutt_cv_langinfo_yesexpr = yes; then
AC_DEFINE(HAVE_LANGINFO_YESEXPR,1,[ Define if you have <langinfo.h> and nl_langinfo(YESEXPR). ])
fi
+AC_CHECK_FUNCS(fmemopen open_memstream)
+
dnl Documentation tools
have_openjade="no"
AC_PATH_PROG([OSPCAT], [ospcat], [none])
diff --git a/handler.c b/handler.c
index a45fbab..13162a1 100644
--- a/handler.c
+++ b/handler.c
@@ -1525,6 +1525,11 @@ int mutt_body_handler (BODY *b, STATE *s)
char type[STRING];
int rc = 0;
+#ifdef HAVE_FMEMOPEN
+ char *temp;
+ size_t tempsize;
+#endif
+
int oflags = s->flags;
/* first determine which handler to use to process this part */
@@ -1644,6 +1649,14 @@ int mutt_body_handler (BODY *b, STATE *s)
{
/* decode to a tempfile, saving the original destination */
fp = s->fpout;
+#ifdef HAVE_FMEMOPEN
+ if ((s->fpout = open_memstream(&temp, &tempsize)) == NULL)
+ {
+ mutt_error _("Unable to open memory stream!");
+ dprint (1, (debugfile, "Can't open memory stream.\n"));
+ goto bail;
+ }
+#else
mutt_mktemp (tempfile, sizeof (tempfile));
if ((s->fpout = safe_fopen (tempfile, "w")) == NULL)
{
@@ -1651,6 +1664,7 @@ int mutt_body_handler (BODY *b, STATE *s)
dprint (1, (debugfile, "Can't open %s.\n", tempfile));
goto bail;
}
+#endif
/* decoding the attachment changes the size and offset, so save a copy
* of the "real" values now, and restore them after processing
*/
@@ -1679,8 +1693,19 @@ int mutt_body_handler (BODY *b, STATE *s)
/* restore final destination and substitute the tempfile for input */
s->fpout = fp;
fp = s->fpin;
+#ifdef HAVE_FMEMOPEN
+ if(tempsize)
+ s->fpin = fmemopen(temp, tempsize, "r");
+ else /* fmemopen cannot handle zero-length buffers */
+ s->fpin = safe_fopen ("/dev/null", "r");
+ if(s->fpin == NULL) {
+ mutt_perror("failed to re-open memstream!");
+ return (-1);
+ }
+#else
s->fpin = fopen (tempfile, "r");
unlink (tempfile);
+#endif
/* restore the prefix */
s->prefix = savePrefix;
@@ -1706,6 +1731,10 @@ int mutt_body_handler (BODY *b, STATE *s)
/* restore the original source stream */
safe_fclose (&s->fpin);
+#ifdef HAVE_FMEMOPEN
+ if(tempsize)
+ FREE(&temp);
+#endif
s->fpin = fp;
}
}
diff --git a/pattern.c b/pattern.c
index dbd73bd..d9ccfbc 100644
--- a/pattern.c
+++ b/pattern.c
@@ -154,6 +154,10 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
HEADER *h = ctx->hdrs[msgno];
char *buf;
size_t blen;
+#ifdef HAVE_FMEMOPEN
+ char *temp;
+ size_t tempsize;
+#endif
if ((msg = mx_open_message (ctx, msgno)) != NULL)
{
@@ -163,12 +167,20 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
memset (&s, 0, sizeof (s));
s.fpin = msg->fp;
s.flags = M_CHARCONV;
+#ifdef HAVE_FMEMOPEN
+ if((s.fpout = open_memstream(&temp, &tempsize)) == NULL)
+ {
+ mutt_perror ("Error opening memstream");
+ return (0);
+ }
+#else
mutt_mktemp (tempfile, sizeof (tempfile));
if ((s.fpout = safe_fopen (tempfile, "w+")) == NULL)
{
mutt_perror (tempfile);
return (0);
}
+#endif
if (pat->op != M_BODY)
mutt_copy_header (msg->fp, h, s.fpout, CH_FROM | CH_DECODE, NULL);
@@ -184,7 +196,11 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
if (s.fpout)
{
safe_fclose (&s.fpout);
+#ifdef HAVE_FMEMOPEN
+ FREE(&temp);
+#else
unlink (tempfile);
+#endif
}
return (0);
}
@@ -193,11 +209,28 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
mutt_body_handler (h->content, &s);
}
+#ifdef HAVE_FMEMOPEN
+ fclose(s.fpout);
+ lng = tempsize;
+
+ if(tempsize) {
+ if ((fp = fmemopen(temp, tempsize, "r")) == NULL) {
+ mutt_perror ("Error re-opening memstream");
+ return (0);
+ }
+ } else { /* fmemopen cannot handle empty buffers */
+ if ((fp = safe_fopen ("/dev/null", "r")) == NULL) {
+ mutt_perror ("Error opening /dev/null");
+ return (0);
+ }
+ }
+#else
fp = s.fpout;
fflush (fp);
fseek (fp, 0, 0);
fstat (fileno (fp), &st);
lng = (long) st.st_size;
+#endif
}
else
{
@@ -244,7 +277,12 @@ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
if (option (OPTTHOROUGHSRC))
{
safe_fclose (&fp);
+#ifdef HAVE_FMEMOPEN
+ if(tempsize)
+ FREE (&temp);
+#else
unlink (tempfile);
+#endif
}
}
--
1.7.7.3