Browse code

strerror/strerror_r->cli_strerror which is always thread safe.

git-svn: trunk@4927

Török Edvin authored on 2009/03/12 04:11:09
Showing 15 changed files
... ...
@@ -1,3 +1,8 @@
1
+Wed Mar 11 21:11:03 EET 2009 (edwin)
2
+------------------------------------
3
+ * clamav-milter/, clamd/, libclamav/, sigtool/, unit_tests/: 
4
+ strerror/strerror_r->cli_strerror which is always thread safe.
5
+
1 6
 Wed Mar 11 19:18:15 CET 2009 (acab)
2 7
 -----------------------------------
3 8
  * libclamav: changed some warning texts (bb#1456)
... ...
@@ -45,14 +45,7 @@
45 45
 #include "libclamav/others.h"
46 46
 #include "netcode.h"
47 47
 
48
-#ifdef HAVE_STRERROR_R
49
-#define strerror_print(msg) \
50
-	strerror_r(errno, er, sizeof(er)); \
51
-	logg(msg": %s\n", er);
52
-#else
53
-#define strerror_print(msg) \
54
-	logg(msg"\n");
55
-#endif
48
+#define strerror_print(msg) logg(msg": %s\n", cli_strerror(errno, er, sizeof(er)))
56 49
 
57 50
 enum {
58 51
     NON_SMTP,
... ...
@@ -610,16 +610,11 @@ int fds_poll_recv(struct fd_data *data, int timeout, int check_signals)
610 610
 #endif
611 611
 
612 612
     if (retval == -1 && errno != EINTR) {
613
-	char buff[BUFFSIZE + 1];
614
-#ifdef HAVE_STRERROR_R
615
-	strerror_r(errno, buff, BUFFSIZE);
616
-#else
617
-	buff[0] = '\0';
618
-#endif
613
+	char err[128];
619 614
 #ifdef HAVE_POLL
620
-	logg("!poll_recv_fds: poll failed: %s\n", buff);
615
+	logg("!poll_recv_fds: poll failed: %s\n", cli_strerror(errno, err, sizeof(err)));
621 616
 #else
622
-	logg("!poll_recv_fds: select failed: %s\n", buff);
617
+	logg("!poll_recv_fds: select failed: %s\n", cli_strerror(errno, err, sizeof(err)));
623 618
 #endif
624 619
     }
625 620
 
... ...
@@ -26,11 +26,6 @@
26 26
 #include "clamav-config.h"
27 27
 #endif
28 28
 
29
-#ifdef C_LINUX
30
-/* We want XSI compliant strerror_r, not GNU one.*/
31
-#define _XOPEN_SOURCE 600
32
-#endif
33
-
34 29
 #include <stdio.h>
35 30
 #include <stdlib.h>
36 31
 #include <string.h>
... ...
@@ -172,14 +167,10 @@ int conn_reply_error(const client_conn_t *conn, const char *msg)
172 172
 int conn_reply_errno(const client_conn_t *conn, const char *path,
173 173
 		     const char *msg)
174 174
 {
175
-    char buf[BUFFSIZE + sizeof(". ERROR")];
176
-#ifdef HAVE_STRERROR_R
177
-    strerror_r(errno, buf, BUFFSIZE-1);
178
-    strcat(buf, ". ERROR");
179
-#else
180
-    snprintf(buf, sizeof(buf), "%u. ERROR", errno);
181
-#endif
182
-    return conn_reply(conn, path, msg, buf);
175
+    char err[BUFFSIZE + sizeof(". ERROR")];
176
+    cli_strerror(errno, err, BUFFSIZE-1);
177
+    strcat(err, ". ERROR");
178
+    return conn_reply(conn, path, msg, err);
183 179
 }
184 180
 
185 181
 /* returns
... ...
@@ -706,6 +706,7 @@ static int in_iconv_u16(const m_area_t* in_m_area, iconv_t* iconv_struct, m_area
706 706
 	char*  input   = (char*)in_m_area->buffer + in_m_area->offset;
707 707
 	size_t outleft = out_m_area->length > 0 ? out_m_area->length : 0;
708 708
 	char* out      = (char*)out_m_area->buffer;
709
+	char err[128];
709 710
 
710 711
 	out_m_area->offset = 0;
711 712
 	if(!inleft) {
... ...
@@ -734,7 +735,7 @@ static int in_iconv_u16(const m_area_t* in_m_area, iconv_t* iconv_struct, m_area
734 734
 				/* not enough space in output buffer */
735 735
 				break;
736 736
 			}
737
-			cli_dbgmsg(MODULE_NAME "iconv error:%s\n", strerror(errno));
737
+			cli_dbgmsg(MODULE_NAME "iconv error:%s\n", cli_strerror(errno, err, sizeof(err)));
738 738
 		} else if(outleft == outleft_last) {
739 739
 			cli_dbgmsg(MODULE_NAME "iconv stall (no output)\n");
740 740
 		} else {
... ...
@@ -135,6 +135,7 @@ CLAMAV_PRIVATE {
135 135
     sha256_update;
136 136
     sha256_final;
137 137
     cli_url_canon;
138
+    cli_strerror;
138 139
   local:
139 140
     *;
140 141
 };
... ...
@@ -3744,8 +3744,9 @@ rfc1341(message *m, const char *dir)
3744 3744
 		struct stat statb;
3745 3745
 
3746 3746
 		if(stat(pdir, &statb) < 0) {
3747
+			char err[128];
3747 3748
 			cli_errmsg("Partial directory %s: %s\n", pdir,
3748
-				strerror(errno));
3749
+				cli_strerror(errno, err, sizeof(err)));
3749 3750
 			free(id);
3750 3751
 			return -1;
3751 3752
 		}
... ...
@@ -4566,6 +4567,7 @@ nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostnam
4566 4566
 	struct timeval timeout;	/* When we should time out */
4567 4567
 	int numfd;		/* Highest fdset fd plus 1 */
4568 4568
 	long flags;
4569
+	char err[128];
4569 4570
 
4570 4571
 	gettimeofday(&timeout, 0);	/* store when we started to connect */
4571 4572
 
... ...
@@ -4576,9 +4578,9 @@ nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostnam
4576 4576
 	flags = fcntl(sock, F_GETFL, 0);
4577 4577
 
4578 4578
 	if(flags == -1L)
4579
-		cli_dbgmsg("getfl: %s\n", strerror(errno));
4579
+		cli_dbgmsg("getfl: %s\n", cli_strerror(errno, err, sizeof(err)));
4580 4580
 	else if(fcntl(sock, F_SETFL, (long)(flags | O_NONBLOCK)) < 0)
4581
-		cli_dbgmsg("setfl: %s\n", strerror(errno));
4581
+		cli_dbgmsg("setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
4582 4582
 #else
4583 4583
 	flags = -1L;
4584 4584
 #endif
... ...
@@ -4587,17 +4589,17 @@ nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostnam
4587 4587
 			case EALREADY:
4588 4588
 			case EINPROGRESS:
4589 4589
 				cli_dbgmsg("%s: connect: %s\n", hostname,
4590
-					strerror(errno));
4590
+					cli_strerror(errno, err, sizeof(err)));
4591 4591
 				break; /* wait for connection */
4592 4592
 			case EISCONN:
4593 4593
 				return 0; /* connected */
4594 4594
 			default:
4595 4595
 				cli_dbgmsg("%s: connect: %s\n",
4596
-					hostname, strerror(errno));
4596
+					hostname, cli_strerror(errno, err, sizeof(err)));
4597 4597
 #ifdef	F_SETFL
4598 4598
 				if(flags != -1L)
4599 4599
 					if(fcntl(sock, F_SETFL, flags))
4600
-						cli_dbgmsg("f_setfl: %s\n", strerror(errno));
4600
+						cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
4601 4601
 #endif
4602 4602
 				return -1; /* failed */
4603 4603
 		}
... ...
@@ -4605,7 +4607,7 @@ nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostnam
4605 4605
 #ifdef	F_SETFL
4606 4606
 		if(flags != -1L)
4607 4607
 			if(fcntl(sock, F_SETFL, flags))
4608
-				cli_dbgmsg("f_setfl: %s\n", strerror(errno));
4608
+				cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
4609 4609
 #endif
4610 4610
 		return connect_error(sock, hostname);
4611 4611
 	}
... ...
@@ -4647,7 +4649,7 @@ nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostnam
4647 4647
 		n = select(numfd, 0, &fds, 0, &waittime);
4648 4648
 		if(n < 0) {
4649 4649
 			cli_dbgmsg("%s: select attempt %d %s\n",
4650
-				hostname, select_failures, strerror(errno));
4650
+				hostname, select_failures, cli_strerror(errno, err, sizeof(err)));
4651 4651
 			if(--select_failures >= 0)
4652 4652
 				continue; /* not timed-out, try again */
4653 4653
 			break; /* failed */
... ...
@@ -4659,7 +4661,7 @@ nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostnam
4659 4659
 #ifdef	F_SETFL
4660 4660
 			if(flags != -1L)
4661 4661
 				if(fcntl(sock, F_SETFL, flags))
4662
-					cli_dbgmsg("f_setfl: %s\n", strerror(errno));
4662
+					cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
4663 4663
 #endif
4664 4664
 			return connect_error(sock, hostname);
4665 4665
 		}
... ...
@@ -4674,7 +4676,7 @@ nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostnam
4674 4674
 #ifdef	F_SETFL
4675 4675
 	if(flags != -1L)
4676 4676
 		if(fcntl(sock, F_SETFL, flags))
4677
-			cli_dbgmsg("f_setfl: %s\n", strerror(errno));
4677
+			cli_dbgmsg("f_setfl: %s\n", cli_strerror(errno, err, sizeof(err)));
4678 4678
 #endif
4679 4679
 	return -1; /* failed */
4680 4680
 }
... ...
@@ -4682,6 +4684,7 @@ nonblock_connect(SOCKET sock, const struct sockaddr_in *sin, const char *hostnam
4682 4682
 static int
4683 4683
 connect_error(SOCKET sock, const char *hostname)
4684 4684
 {
4685
+        char err[128];
4685 4686
 #ifdef	SO_ERROR
4686 4687
 	int optval;
4687 4688
 	socklen_t optlen = sizeof(optval);
... ...
@@ -4689,7 +4692,7 @@ connect_error(SOCKET sock, const char *hostname)
4689 4689
 	getsockopt(sock, SOL_SOCKET, SO_ERROR, &optval, &optlen);
4690 4690
 
4691 4691
 	if(optval) {
4692
-		cli_dbgmsg("%s: %s\n", hostname, strerror(optval));
4692
+		cli_dbgmsg("%s: %s\n", hostname, cli_strerror(optval, err, sizeof(err)));
4693 4693
 		return -1;
4694 4694
 	}
4695 4695
 #endif
... ...
@@ -668,7 +668,8 @@ int cli_gentempfd(const char *dir, char **name, int *fd)
668 668
      * errors
669 669
      */
670 670
    if(*fd == -1) {
671
-	cli_errmsg("cli_gentempfd: Can't create temporary file %s: %s\n", *name, strerror(errno));
671
+        char err[128];
672
+	cli_errmsg("cli_gentempfd: Can't create temporary file %s: %s\n", *name, cli_strerror(errno, err, sizeof(err)));
672 673
 	free(*name);
673 674
 	return CL_ECREAT;
674 675
     }
... ...
@@ -682,7 +683,8 @@ int cli_gentempfd(const char *dir, char **name, int *fd)
682 682
 int cli_unlink(const char *pathname)
683 683
 {
684 684
 	if (unlink(pathname)==-1) {
685
-	    cli_warnmsg("cli_unlink: failure - %s\n", strerror(errno));
685
+	    char err[128];
686
+	    cli_warnmsg("cli_unlink: failure - %s\n", cli_strerror(errno, err, sizeof(err)));
686 687
 	    return 1;
687 688
 	}
688 689
 	return 0;
... ...
@@ -705,10 +707,11 @@ cli_rmdirs(const char *name)
705 705
 	    char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
706 706
 	} result;
707 707
 #endif
708
+	char err[128];
708 709
 
709 710
 
710 711
     if(stat(name, &statb) < 0) {
711
-	cli_warnmsg("cli_rmdirs: Can't locate %s: %s\n", name, strerror(errno));
712
+	cli_warnmsg("cli_rmdirs: Can't locate %s: %s\n", name, cli_strerror(errno, err, sizeof(err)));
712 713
 	return -1;
713 714
     }
714 715
 
... ...
@@ -753,7 +756,7 @@ cli_rmdirs(const char *name)
753 753
     closedir(dd);
754 754
 
755 755
     if(rmdir(name) < 0) {
756
-	cli_errmsg("cli_rmdirs: Can't remove temporary directory %s: %s\n", name, strerror(errno));
756
+	cli_errmsg("cli_rmdirs: Can't remove temporary directory %s: %s\n", name, cli_strerror(errno, err, sizeof(err)));
757 757
 	return -1;
758 758
     }
759 759
 
... ...
@@ -772,6 +775,7 @@ int cli_rmdirs(const char *dirname)
772 772
 #endif
773 773
 	struct stat maind, statbuf;
774 774
 	char *path;
775
+	char err[128];
775 776
 
776 777
 
777 778
     chmod(dirname, 0700);
... ...
@@ -779,7 +783,7 @@ int cli_rmdirs(const char *dirname)
779 779
 	while(stat(dirname, &maind) != -1) {
780 780
 	    if(!rmdir(dirname)) break;
781 781
 	    if(errno != ENOTEMPTY && errno != EEXIST && errno != EBADF) {
782
-		cli_errmsg("cli_rmdirs: Can't remove temporary directory %s: %s\n", dirname, strerror(errno));
782
+		cli_errmsg("cli_rmdirs: Can't remove temporary directory %s: %s\n", dirname, cli_strerror(errno, err, sizeof(err)));
783 783
 		closedir(dd);
784 784
 		return -1;
785 785
 	    }
... ...
@@ -437,4 +437,5 @@ typedef int (*cli_ftw_cb)(struct stat *stat_buf, char *filename, const char *pat
437 437
  */
438 438
 int cli_ftw(char *base, int flags, int maxdepth, cli_ftw_cb callback, struct cli_ftw_cbdata *data);
439 439
 
440
+const char *cli_strerror(int errnum, char* buf, size_t len);
440 441
 #endif
... ...
@@ -76,7 +76,9 @@
76 76
 # ifndef HAVE_CTIME_R
77 77
 static pthread_mutex_t cli_ctime_mutex = PTHREAD_MUTEX_INITIALIZER;
78 78
 # endif
79
-
79
+#ifndef HAVE_STRERROR_R
80
+static pthread_mutex_t cli_strerror_mutex = PTHREAD_MUTEX_INITIALIZER;
81
+#endif
80 82
 #endif
81 83
 uint8_t cli_debug_flag = 0;
82 84
 
... ...
@@ -296,10 +298,11 @@ int cli_readn(int fd, void *buff, unsigned int count)
296 296
                         return (count - todo);
297 297
                 }
298 298
                 if (retval < 0) {
299
+			char err[128];
299 300
 			if (errno == EINTR) {
300 301
 				continue;
301 302
 			}
302
-			cli_errmsg("cli_readn: read error: %s\n", strerror(errno));
303
+			cli_errmsg("cli_readn: read error: %s\n", cli_strerror(errno, err, sizeof(err)));
303 304
                         return -1;
304 305
                 }
305 306
                 todo -= retval;
... ...
@@ -326,10 +329,11 @@ int cli_writen(int fd, const void *buff, unsigned int count)
326 326
         do {
327 327
                 retval = write(fd, current, todo);
328 328
                 if (retval < 0) {
329
+			char err[128];
329 330
 			if (errno == EINTR) {
330 331
 				continue;
331 332
 			}
332
-			cli_errmsg("cli_writen: write error: %s\n", strerror(errno));
333
+			cli_errmsg("cli_writen: write error: %s\n", cli_strerror(errno, err, sizeof(err)));
333 334
                         return -1;
334 335
                 }
335 336
                 todo -= retval;
... ...
@@ -679,3 +683,25 @@ static int cli_ftw_dir(const char *dirname, int flags, int maxdepth, cli_ftw_cb
679 679
     }
680 680
     return ret;
681 681
 }
682
+
683
+/* strerror_r is not available everywhere, (and when it is there are two variants,
684
+ * the XSI, and the GNU one, so provide a wrapper to make sure correct one is
685
+ * used */
686
+const char* cli_strerror(int errnum, char *buf, size_t len)
687
+{
688
+#ifdef HAVE_STRERROR_R
689
+    if (strerror_r(errnum, buf, len) == -1)
690
+	return "strerror_r failed";
691
+    return buf;
692
+#else
693
+    {
694
+	char *err;
695
+	pthread_mutex_lock(&cli_strerror_mutex);
696
+	err = strerror(errnum);
697
+	strncpy(buf, err, len);
698
+	pthread_mutex_unlock(&cli_strerror_mutex);
699
+	return buf;
700
+    }
701
+#endif
702
+}
703
+
... ...
@@ -399,7 +399,8 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
399 399
 		snprintf(fullname, sizeof(fullname), "%s/pdf%02u", dir, files);
400 400
 		fout = open(fullname, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
401 401
 		if(fout < 0) {
402
-			cli_errmsg("cli_pdf: can't create temporary file %s: %s\n", fullname, strerror(errno));
402
+			char err[128];
403
+			cli_errmsg("cli_pdf: can't create temporary file %s: %s\n", fullname, cli_strerror(errno, err, sizeof(err)));
403 404
 			rc = CL_ETMPFILE;
404 405
 			break;
405 406
 		}
... ...
@@ -161,7 +161,8 @@ static int cli_scandir(const char *dirname, cli_ctx *ctx, cli_file_t container)
161 161
 				if(container == CL_TYPE_MAIL) {
162 162
 				    fd = open(fname, O_RDONLY|O_BINARY);
163 163
 				    if(fd == -1) {
164
-					    cli_warnmsg("Cannot open file %s: %s, mode: %x\n", fname, strerror(errno), statbuf.st_mode);
164
+					    char err[128];
165
+					    cli_warnmsg("Cannot open file %s: %s, mode: %x\n", fname, cli_strerror(errno, err, sizeof(err)), statbuf.st_mode);
165 166
 					    free(fname);
166 167
 					    continue;
167 168
 				    }
... ...
@@ -185,10 +185,11 @@ cli_untar(const char *dir, int desc, unsigned int posix, cli_ctx *ctx)
185 185
 			fout = open(fullname, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
186 186
 
187 187
 			if(fout < 0) {
188
-				cli_errmsg("cli_untar: Can't create temporary file %s: %s\n", fullname, strerror(errno));
188
+				char err[128];
189
+				cli_errmsg("cli_untar: Can't create temporary file %s: %s\n", fullname, cli_strerror(errno, err, sizeof(err)));
189 190
 				return CL_ETMPFILE;
190 191
 			}
191
-			
192
+
192 193
 			cli_dbgmsg("cli_untar: extracting to %s\n", fullname);
193 194
 
194 195
 			in_block = 1;
... ...
@@ -53,7 +53,7 @@ host_triplet = @host@
53 53
 target_triplet = @target@
54 54
 bin_PROGRAMS = sigtool$(EXEEXT)
55 55
 subdir = sigtool
56
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
56
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in COPYING
57 57
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
58 58
 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \
59 59
 	$(top_srcdir)/m4/argz.m4 $(top_srcdir)/m4/fdpassing.m4 \
... ...
@@ -115,11 +115,7 @@ static void conn_teardown(void)
115 115
 
116 116
 #define NONEXISTENT "/nonexistent\vfilename"
117 117
 
118
-#ifdef HAVE_STRERROR_R
119 118
 #define NONEXISTENT_REPLY NONEXISTENT": lstat() failed: No such file or directory. ERROR"
120
-#else
121
-#define NONEXISTENT_REPLY NONEXISTENT": lstat() failed: 2. ERROR"
122
-#endif
123 119
 
124 120
 #define ACCDENIED BUILDDIR"/accdenied"
125 121
 #define ACCDENIED_REPLY ACCDENIED": Access denied. ERROR"