git-svn: trunk@3611
Török Edvin authored on 2008/02/12 01:48:14... | ... |
@@ -1,3 +1,9 @@ |
1 |
+Mon Feb 11 18:33:22 EET 2008 (edwin) |
|
2 |
+------------------------------------ |
|
3 |
+ * libclamav/mbox.c: replace getc() with getc_unlocked() when available. This |
|
4 |
+ avoids a function call on systems that have getc_unlocked() |
|
5 |
+ implemented as a macro. |
|
6 |
+ |
|
1 | 7 |
Mon Feb 11 15:46:39 CET 2008 (tk) |
2 | 8 |
--------------------------------- |
3 | 9 |
* libclamav/server-th.c: add missing mutex sync for progexit (bb#461) |
... | ... |
@@ -218,6 +218,19 @@ typedef struct mbox_ctx { |
218 | 218 |
unsigned int files; /* number of files extracted */ |
219 | 219 |
} mbox_ctx; |
220 | 220 |
|
221 |
+/* if supported by the system, use the optimized |
|
222 |
+ * version of getc, that doesn't do locking, |
|
223 |
+ * and is possibly implemented entirely as a macro */ |
|
224 |
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L |
|
225 |
+#define GETC(fp) getc_unlocked(fp) |
|
226 |
+#define LOCKFILE(fp) flockfile(fp) |
|
227 |
+#define UNLOCKFILE(fp) funlockfile(fp) |
|
228 |
+#else |
|
229 |
+#define GETC(fp) getc(fp) |
|
230 |
+#define LOCKFILE(fp) |
|
231 |
+#define UNLOCKFILE(fp) |
|
232 |
+#endif |
|
233 |
+ |
|
221 | 234 |
static int cli_parse_mbox(const char *dir, int desc, cli_ctx *ctx); |
222 | 235 |
static message *parseEmailFile(FILE *fin, const table_t *rfc821Table, const char *firstLine, const char *dir); |
223 | 236 |
static message *parseEmailHeaders(message *m, const table_t *rfc821Table); |
... | ... |
@@ -1394,6 +1407,9 @@ cli_parse_mbox(const char *dir, int desc, cli_ctx *ctx) |
1394 | 1394 |
while((fgets(buffer, sizeof(buffer) - 1, fd) != NULL) && |
1395 | 1395 |
(strchr("\r\n", buffer[0]) == NULL)) |
1396 | 1396 |
; |
1397 |
+ LOCKFILE(fd); |
|
1398 |
+ /* getline_from_mbox could be using unlocked_stdio(3), |
|
1399 |
+ * so lock file here */ |
|
1397 | 1400 |
/* |
1398 | 1401 |
* Ignore any blank lines at the top of the message |
1399 | 1402 |
*/ |
... | ... |
@@ -1404,6 +1420,7 @@ cli_parse_mbox(const char *dir, int desc, cli_ctx *ctx) |
1404 | 1404 |
buffer[sizeof(buffer) - 1] = '\0'; |
1405 | 1405 |
|
1406 | 1406 |
body = parseEmailFile(fd, rfc821, buffer, dir); |
1407 |
+ UNLOCKFILE(fd); |
|
1407 | 1408 |
fclose(fd); |
1408 | 1409 |
} |
1409 | 1410 |
|
... | ... |
@@ -1628,7 +1645,7 @@ parseEmailFile(FILE *fin, const table_t *rfc821, const char *firstLine, const ch |
1628 | 1628 |
|
1629 | 1629 |
assert(fullline != NULL); |
1630 | 1630 |
|
1631 |
- lookahead = getc(fin); |
|
1631 |
+ lookahead = GETC(fin); |
|
1632 | 1632 |
if(lookahead != EOF) { |
1633 | 1633 |
ungetc(lookahead, fin); |
1634 | 1634 |
|
... | ... |
@@ -4752,8 +4769,9 @@ getline_from_mbox(char *buffer, size_t len, FILE *fin) |
4752 | 4752 |
{ |
4753 | 4753 |
char *ret; |
4754 | 4754 |
|
4755 |
- if(feof(fin)) |
|
4756 |
- return NULL; |
|
4755 |
+/* we check for eof from the result of GETC() |
|
4756 |
+ * if(feof(fin)) |
|
4757 |
+ return NULL;*/ |
|
4757 | 4758 |
|
4758 | 4759 |
if((len == 0) || (buffer == NULL)) { |
4759 | 4760 |
cli_errmsg("Invalid call to getline_from_mbox(). Refer to http://www.clamav.net/bugs\n"); |
... | ... |
@@ -4763,10 +4781,7 @@ getline_from_mbox(char *buffer, size_t len, FILE *fin) |
4763 | 4763 |
ret = buffer; |
4764 | 4764 |
|
4765 | 4765 |
do { |
4766 |
- int c = getc(fin); |
|
4767 |
- |
|
4768 |
- if(ferror(fin)) |
|
4769 |
- return NULL; |
|
4766 |
+ int c = GETC(fin); |
|
4770 | 4767 |
|
4771 | 4768 |
switch(c) { |
4772 | 4769 |
default: |
... | ... |
@@ -4774,15 +4789,19 @@ getline_from_mbox(char *buffer, size_t len, FILE *fin) |
4774 | 4774 |
continue; |
4775 | 4775 |
case '\n': |
4776 | 4776 |
*buffer++ = '\n'; |
4777 |
- c = getc(fin); |
|
4777 |
+ c = GETC(fin); |
|
4778 | 4778 |
if((c != '\r') && !feof(fin)) |
4779 | 4779 |
ungetc(c, fin); |
4780 | 4780 |
break; |
4781 | 4781 |
case EOF: |
4782 |
+ if(ret == buffer || ferror(fin)) { |
|
4783 |
+ /* EOF on first char, or error */ |
|
4784 |
+ return NULL; |
|
4785 |
+ } |
|
4782 | 4786 |
break; |
4783 | 4787 |
case '\r': |
4784 | 4788 |
*buffer++ = '\n'; |
4785 |
- c = getc(fin); |
|
4789 |
+ c = GETC(fin); |
|
4786 | 4790 |
if((c != '\n') && !feof(fin)) |
4787 | 4791 |
ungetc(c, fin); |
4788 | 4792 |
break; |