Browse code

replace getc() with getc_unlocked() when available. This avoids a function call on systems that have getc_unlocked() implemented as a macro.

git-svn: trunk@3611

Török Edvin authored on 2008/02/12 01:48:14
Showing 2 changed files
... ...
@@ -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;