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 334
 char* check_poll_method(enum poll_types poll_method)
335 335
 {
336 336
 	char* ret;
337
-	unsigned int os_ver;
338 337
 
339 338
 	ret=0;
340
-	os_ver=get_sys_version(0,0,0);	
339
+	if (_os_ver==0) 
340
+		_os_ver=get_sys_version(0,0,0);
341 341
 	switch(poll_method){
342 342
 		case POLL_NONE:
343 343
 			break;
... ...
@@ -356,7 +358,7 @@ char* check_poll_method(enum poll_types poll_method)
356 356
 			ret="epoll not supported, try re-compiling with -DHAVE_EPOLL";
357 357
 #else
358 358
 			/* only on 2.6 + */
359
-			if (os_ver<0x020542) /* if ver < 2.5.66 */
359
+			if (_os_ver<0x020542) /* if ver < 2.5.66 */
360 360
 			 	ret="epoll not supported on kernels < 2.6";
361 361
 #endif
362 362
 			break;
... ...
@@ -366,7 +368,7 @@ char* check_poll_method(enum poll_types poll_method)
366 366
 				" -DHAVE_SIGIO_RT";
367 367
 #else
368 368
 			/* only on 2.2 +  ?? */
369
-			if (os_ver<0x020200) /* if ver < 2.2.0 */
369
+			if (_os_ver<0x020200) /* if ver < 2.2.0 */
370 370
 			 	ret="epoll not supported on kernels < 2.2 (?)";
371 371
 #endif
372 372
 			break;
... ...
@@ -376,13 +378,13 @@ char* check_poll_method(enum poll_types poll_method)
376 376
 #else
377 377
 		/* only in FreeBSD 4.1, NETBSD 2.0, OpenBSD 2.9, Darwin */
378 378
 	#ifdef __OS_freebsd
379
-			if (os_ver<0x0401) /* if ver < 4.1 */
379
+			if (_os_ver<0x0401) /* if ver < 4.1 */
380 380
 				ret="kqueue not supported on FreeBSD < 4.1";
381 381
 	#elif defined (__OS_netbsd)
382
-			if (os_ver<0x020000) /* if ver < 2.0 */
382
+			if (_os_ver<0x020000) /* if ver < 2.0 */
383 383
 				ret="kqueue not supported on NetBSD < 2.0";
384 384
 	#elif defined (__OS_openbsd)
385
-			if (os_ver<0x0209) /* if ver < 2.9 ? */
385
+			if (_os_ver<0x0209) /* if ver < 2.9 ? */
386 386
 				ret="kqueue not supported on OpenBSD < 2.9 (?)";
387 387
 	#endif /* assume that the rest support kqueue ifdef HAVE_KQUEUE */
388 388
 #endif
... ...
@@ -394,7 +396,7 @@ char* check_poll_method(enum poll_types poll_method)
394 394
 #else
395 395
 	/* only in Solaris >= 7.0 (?) */
396 396
 	#ifdef __OS_solaris
397
-		if (os_ver<0x0507) /* ver < 5.7 */
397
+		if (_os_ver<0x0507) /* ver < 5.7 */
398 398
 			ret="/dev/poll not supported on Solaris < 7.0 (SunOS 5.7)";
399 399
 	#endif
400 400
 #endif
... ...
@@ -411,12 +413,12 @@ char* check_poll_method(enum poll_types poll_method)
411 411
 enum poll_types choose_poll_method()
412 412
 {
413 413
 	enum poll_types poll_method;
414
-	unsigned int os_ver;
415 414
 
416
-	os_ver=get_sys_version(0,0,0);	
415
+	if (_os_ver==0)
416
+		_os_ver=get_sys_version(0,0,0);	
417 417
 	poll_method=0;
418 418
 #ifdef HAVE_EPOLL
419
-	if (os_ver>=0x020542) /* if ver >= 2.5.66 */
419
+	if (_os_ver>=0x020542) /* if ver >= 2.5.66 */
420 420
 		poll_method=POLL_EPOLL_LT; /* or POLL_EPOLL_ET */
421 421
 		
422 422
 #endif
... ...
@@ -424,11 +426,11 @@ enum poll_types choose_poll_method()
424 424
 	if (poll_method==0)
425 425
 		/* only in FreeBSD 4.1, NETBSD 2.0, OpenBSD 2.9, Darwin */
426 426
 	#ifdef __OS_freebsd
427
-		if (os_ver>=0x0401) /* if ver >= 4.1 */
427
+		if (_os_ver>=0x0401) /* if ver >= 4.1 */
428 428
 	#elif defined (__OS_netbsd)
429
-		if (os_ver>=0x020000) /* if ver >= 2.0 */
429
+		if (_os_ver>=0x020000) /* if ver >= 2.0 */
430 430
 	#elif defined (__OS_openbsd)
431
-		if (os_ver>=0x0209) /* if ver >= 2.9 (?) */
431
+		if (_os_ver>=0x0209) /* if ver >= 2.9 (?) */
432 432
 	#endif /* assume that the rest support kqueue ifdef HAVE_KQUEUE */
433 433
 			poll_method=POLL_KQUEUE;
434 434
 #endif
... ...
@@ -436,13 +438,13 @@ enum poll_types choose_poll_method()
436 436
 	#ifdef __OS_solaris
437 437
 	if (poll_method==0)
438 438
 		/* only in Solaris >= 7.0 (?) */
439
-		if (os_ver>=0x0507) /* if ver >=SunOS 5.7 */
439
+		if (_os_ver>=0x0507) /* if ver >=SunOS 5.7 */
440 440
 			poll_method=POLL_DEVPOLL;
441 441
 	#endif
442 442
 #endif
443 443
 #ifdef  HAVE_SIGIO_RT
444 444
 		if (poll_method==0) 
445
-			if (os_ver>=0x020200) /* if ver >= 2.2.0 */
445
+			if (_os_ver>=0x020200) /* if ver >= 2.2.0 */
446 446
 				poll_method=POLL_SIGIO_RT;
447 447
 #endif
448 448
 		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 488
 {
489 489
 	char * poll_err;
490 490
 	
491
+	if (_os_ver==0) _os_ver=get_sys_version(0,0,0);
491 492
 	memset(h, 0, sizeof(*h));
492 493
 	h->max_fd_no=max_fd;
493 494
 #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 93
 #endif
94 94
 
95 95
 
96
+extern int _os_ver; /* os version number, needed to select bugs workarrounds */
97
+
98
+
96 99
 #if 0
97 100
 enum fd_types; /* this should be defined from the including file,
98 101
 				  see tcp_main.c for an example, 
... ...
@@ -823,13 +827,14 @@ again:
823 823
 	if (n!=SIGIO){
824 824
 #ifdef SIGINFO64_WORKARROUND
825 825
 		/* 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!
826
+		 * and as int in kernel (< 2.6.5) => on 64 bits things will break!
827 827
 		 * (si_band will include si_fd, and si_fd will contain
828
-		 *  garbage)
828
+		 *  garbage).
829 829
 		 *  see /usr/src/linux/include/asm-generic/siginfo.h and
830 830
 		 *      /usr/include/bits/siginfo.h
831
+		 *  On newer kernels this is fixed (si_band is long in the kernel too).
831 832
 		 * -- andrei */
832
-		if (sizeof(siginfo.si_band)>sizeof(int)){
833
+		if  ((_os_ver<0x020605) && (sizeof(siginfo.si_band)>sizeof(int))){
833 834
 			sigio_band=*((int*)&siginfo.si_band);
834 835
 			sigio_fd=*(((int*)&siginfo.si_band)+1);
835 836
 		}else