Browse code

- sigio 64 bits bug workarround enabled for linux kernels <2.6.5.

Andrei Pelinescu-Onciul authored on 30/05/2006 20:40:23
Showing 3 changed files
... ...
@@ -66,7 +66,7 @@ MAIN_NAME=ser
66 66
 VERSION = 0
67 67
 PATCHLEVEL = 10
68 68
 SUBLEVEL =   99
69
-EXTRAVERSION = -dev40
69
+EXTRAVERSION = -dev41
70 70
 
71 71
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
72 72
 			$(SUBLEVEL) )
... ...
@@ -1195,7 +1195,7 @@ ifeq ($(OS), linux)
1195 1195
 	# check for >= 2.2.0
1196 1196
 	ifeq ($(shell [ $(OSREL_N) -ge 2002000 ] && echo has_sigio), has_sigio)
1197 1197
 		ifeq ($(NO_SIGIO),)
1198
-			DEFS+=-DHAVE_SIGIO_RT
1198
+			DEFS+=-DHAVE_SIGIO_RT -DSIGINFO64_WORKARROUND
1199 1199
 		endif
1200 1200
 	endif
1201 1201
 	ifeq ($(NO_SELECT),)
... ...
@@ -87,6 +87,8 @@ char* poll_method_str[POLL_END]={ "none", "poll", "epoll_lt", "epoll_et",
87 87
 								  "sigio_rt", "select", "kqueue",  "/dev/poll"
88 88
 								};
89 89
 
90
+int _os_ver=0; /* os version number */
91
+
90 92
 #ifdef HAVE_SIGIO_RT
91 93
 static int _sigio_init=0;
92 94
 static int _sigio_crt_rtsig;
... ...
@@ -334,10 +336,10 @@ static unsigned int get_sys_version(int* major, int* minor, int* minor2)
334 336
 char* check_poll_method(enum poll_types poll_method)
335 337
 {
336 338
 	char* ret;
337
-	unsigned int os_ver;
338 339
 
339 340
 	ret=0;
340
-	os_ver=get_sys_version(0,0,0);	
341
+	if (_os_ver==0) 
342
+		_os_ver=get_sys_version(0,0,0);
341 343
 	switch(poll_method){
342 344
 		case POLL_NONE:
343 345
 			break;
... ...
@@ -356,7 +358,7 @@ char* check_poll_method(enum poll_types poll_method)
356 358
 			ret="epoll not supported, try re-compiling with -DHAVE_EPOLL";
357 359
 #else
358 360
 			/* only on 2.6 + */
359
-			if (os_ver<0x020542) /* if ver < 2.5.66 */
361
+			if (_os_ver<0x020542) /* if ver < 2.5.66 */
360 362
 			 	ret="epoll not supported on kernels < 2.6";
361 363
 #endif
362 364
 			break;
... ...
@@ -366,7 +368,7 @@ char* check_poll_method(enum poll_types poll_method)
366 368
 				" -DHAVE_SIGIO_RT";
367 369
 #else
368 370
 			/* only on 2.2 +  ?? */
369
-			if (os_ver<0x020200) /* if ver < 2.2.0 */
371
+			if (_os_ver<0x020200) /* if ver < 2.2.0 */
370 372
 			 	ret="epoll not supported on kernels < 2.2 (?)";
371 373
 #endif
372 374
 			break;
... ...
@@ -376,13 +378,13 @@ char* check_poll_method(enum poll_types poll_method)
376 378
 #else
377 379
 		/* only in FreeBSD 4.1, NETBSD 2.0, OpenBSD 2.9, Darwin */
378 380
 	#ifdef __OS_freebsd
379
-			if (os_ver<0x0401) /* if ver < 4.1 */
381
+			if (_os_ver<0x0401) /* if ver < 4.1 */
380 382
 				ret="kqueue not supported on FreeBSD < 4.1";
381 383
 	#elif defined (__OS_netbsd)
382
-			if (os_ver<0x020000) /* if ver < 2.0 */
384
+			if (_os_ver<0x020000) /* if ver < 2.0 */
383 385
 				ret="kqueue not supported on NetBSD < 2.0";
384 386
 	#elif defined (__OS_openbsd)
385
-			if (os_ver<0x0209) /* if ver < 2.9 ? */
387
+			if (_os_ver<0x0209) /* if ver < 2.9 ? */
386 388
 				ret="kqueue not supported on OpenBSD < 2.9 (?)";
387 389
 	#endif /* assume that the rest support kqueue ifdef HAVE_KQUEUE */
388 390
 #endif
... ...
@@ -394,7 +396,7 @@ char* check_poll_method(enum poll_types poll_method)
394 396
 #else
395 397
 	/* only in Solaris >= 7.0 (?) */
396 398
 	#ifdef __OS_solaris
397
-		if (os_ver<0x0507) /* ver < 5.7 */
399
+		if (_os_ver<0x0507) /* ver < 5.7 */
398 400
 			ret="/dev/poll not supported on Solaris < 7.0 (SunOS 5.7)";
399 401
 	#endif
400 402
 #endif
... ...
@@ -411,12 +413,12 @@ char* check_poll_method(enum poll_types poll_method)
411 413
 enum poll_types choose_poll_method()
412 414
 {
413 415
 	enum poll_types poll_method;
414
-	unsigned int os_ver;
415 416
 
416
-	os_ver=get_sys_version(0,0,0);	
417
+	if (_os_ver==0)
418
+		_os_ver=get_sys_version(0,0,0);	
417 419
 	poll_method=0;
418 420
 #ifdef HAVE_EPOLL
419
-	if (os_ver>=0x020542) /* if ver >= 2.5.66 */
421
+	if (_os_ver>=0x020542) /* if ver >= 2.5.66 */
420 422
 		poll_method=POLL_EPOLL_LT; /* or POLL_EPOLL_ET */
421 423
 		
422 424
 #endif
... ...
@@ -424,11 +426,11 @@ enum poll_types choose_poll_method()
424 426
 	if (poll_method==0)
425 427
 		/* only in FreeBSD 4.1, NETBSD 2.0, OpenBSD 2.9, Darwin */
426 428
 	#ifdef __OS_freebsd
427
-		if (os_ver>=0x0401) /* if ver >= 4.1 */
429
+		if (_os_ver>=0x0401) /* if ver >= 4.1 */
428 430
 	#elif defined (__OS_netbsd)
429
-		if (os_ver>=0x020000) /* if ver >= 2.0 */
431
+		if (_os_ver>=0x020000) /* if ver >= 2.0 */
430 432
 	#elif defined (__OS_openbsd)
431
-		if (os_ver>=0x0209) /* if ver >= 2.9 (?) */
433
+		if (_os_ver>=0x0209) /* if ver >= 2.9 (?) */
432 434
 	#endif /* assume that the rest support kqueue ifdef HAVE_KQUEUE */
433 435
 			poll_method=POLL_KQUEUE;
434 436
 #endif
... ...
@@ -436,13 +438,13 @@ enum poll_types choose_poll_method()
436 438
 	#ifdef __OS_solaris
437 439
 	if (poll_method==0)
438 440
 		/* only in Solaris >= 7.0 (?) */
439
-		if (os_ver>=0x0507) /* if ver >=SunOS 5.7 */
441
+		if (_os_ver>=0x0507) /* if ver >=SunOS 5.7 */
440 442
 			poll_method=POLL_DEVPOLL;
441 443
 	#endif
442 444
 #endif
443 445
 #ifdef  HAVE_SIGIO_RT
444 446
 		if (poll_method==0) 
445
-			if (os_ver>=0x020200) /* if ver >= 2.2.0 */
447
+			if (_os_ver>=0x020200) /* if ver >= 2.2.0 */
446 448
 				poll_method=POLL_SIGIO_RT;
447 449
 #endif
448 450
 		if (poll_method==0) poll_method=POLL_POLL;
... ...
@@ -488,6 +490,7 @@ int init_io_wait(io_wait_h* h, int max_fd, enum poll_types poll_method)
488 490
 {
489 491
 	char * poll_err;
490 492
 	
493
+	if (_os_ver==0) _os_ver=get_sys_version(0,0,0);
491 494
 	memset(h, 0, sizeof(*h));
492 495
 	h->max_fd_no=max_fd;
493 496
 #ifdef HAVE_EPOLL
... ...
@@ -48,6 +48,7 @@
48 48
  *  2005-06-13  created by andrei
49 49
  *  2005-06-26  added kqueue (andrei)
50 50
  *  2005-07-01  added /dev/poll (andrei)
51
+ *  2006-05-30  sigio 64 bit workarround enabled for kernels < 2.6.5 (andrei)
51 52
  */
52 53
 
53 54
 
... ...
@@ -93,6 +94,9 @@
93 94
 #endif
94 95
 
95 96
 
97
+extern int _os_ver; /* os version number, needed to select bugs workarrounds */
98
+
99
+
96 100
 #if 0
97 101
 enum fd_types; /* this should be defined from the including file,
98 102
 				  see tcp_main.c for an example, 
... ...
@@ -823,13 +827,14 @@ again:
823 827
 	if (n!=SIGIO){
824 828
 #ifdef SIGINFO64_WORKARROUND
825 829
 		/* on linux siginfo.si_band is defined as long in userspace
826
-		 * and as int kernel (< 2.6.5) => on 64 bits things will break!
830
+		 * and as int in kernel (< 2.6.5) => on 64 bits things will break!
827 831
 		 * (si_band will include si_fd, and si_fd will contain
828
-		 *  garbage)
832
+		 *  garbage).
829 833
 		 *  see /usr/src/linux/include/asm-generic/siginfo.h and
830 834
 		 *      /usr/include/bits/siginfo.h
835
+		 *  On newer kernels this is fixed (si_band is long in the kernel too).
831 836
 		 * -- andrei */
832
-		if (sizeof(siginfo.si_band)>sizeof(int)){
837
+		if  ((_os_ver<0x020605) && (sizeof(siginfo.si_band)>sizeof(int))){
833 838
 			sigio_band=*((int*)&siginfo.si_band);
834 839
 			sigio_fd=*(((int*)&siginfo.si_band)+1);
835 840
 		}else