- The daylight-savings time flag was blowing up date->time conversion
when it wasn't relevant. - Error returns from mktime() were not being caught.
This commit is contained in:
		
							parent
							
								
									1a2d8690ce
								
							
						
					
					
						commit
						a304e9b7f9
					
				|  | @ -104,7 +104,7 @@ | |||
|   fixnum) ; lo secs | ||||
| 
 | ||||
| 
 | ||||
| (define-foreign %date->time/errno (date2time (fixnum sec) | ||||
| (define-foreign %date->time/error (date2time (fixnum sec) | ||||
| 					     (fixnum min) | ||||
| 					     (fixnum hour) | ||||
| 					     (fixnum month-day) | ||||
|  | @ -113,29 +113,32 @@ | |||
| 					     (desc   tz-name)	; #f or string | ||||
| 					     (desc   tz-secs)	; #f or int | ||||
| 					     (bool   summer?)) | ||||
|   desc	  ; errno or #f | ||||
|   desc	  ; errno, -1, or #f | ||||
|   fixnum  ; hi secs | ||||
|   fixnum) ; lo secs | ||||
| 
 | ||||
| (define (time . args) ; optional arg [date] | ||||
|   (let lp () | ||||
|     (receive (err hi-secs lo-secs) | ||||
| 	(if (null? args) | ||||
| 	    (%time/errno)		; Fast path for (time). | ||||
| 	    (let ((date (check-arg date? (car args) time))) | ||||
| 	      (%date->time/errno (date:seconds   date) | ||||
| 				 (date:minute    date) | ||||
| 				 (date:hour      date) | ||||
| 				 (date:month-day date) | ||||
| 				 (date:month     date) | ||||
| 				 (date:year      date) | ||||
| 				 (date:tz-name   date) ; #f or string | ||||
| 				 (date:tz-secs   date) ; #f or int | ||||
| 				 (date:summer?   date)))) | ||||
| 	(if (pair? args) | ||||
| 	    (if (null? (cdr args)) | ||||
| 		(let ((date (check-arg date? (car args) time))) | ||||
| 		  (%date->time/error (date:seconds   date) | ||||
| 				     (date:minute    date) | ||||
| 				     (date:hour      date) | ||||
| 				     (date:month-day date) | ||||
| 				     (date:month     date) | ||||
| 				     (date:year      date) | ||||
| 				     (date:tz-name   date) ; #f or string | ||||
| 				     (date:tz-secs   date) ; #f or int | ||||
| 				     (date:summer?   date))) | ||||
| 		(error "Too many arguments to TIME procedure" args)) | ||||
| 	    (%time/errno))	; Fast path for (time). | ||||
| 
 | ||||
|       (cond ((not err) (compose-8/24 hi-secs lo-secs))	; Win. | ||||
| 	    ((= errno/intr err) (lp))			; Retry. | ||||
| 	    (else (apply errno-error err time args)))))); Lose. | ||||
|       (cond ((not err) (compose-8/24 hi-secs lo-secs))	               ; Win. | ||||
| 	    ((= errno/intr err) (lp))			               ; Retry. | ||||
| 	    ((= -1 err) (error "Error converting date to time." args)) ; Lose. | ||||
| 	    (else (apply errno-error err time args))))))               ; Lose. | ||||
| 
 | ||||
| 
 | ||||
| ;;; Date | ||||
|  |  | |||
							
								
								
									
										32
									
								
								scsh/time1.c
								
								
								
								
							
							
						
						
									
										32
									
								
								scsh/time1.c
								
								
								
								
							|  | @ -190,6 +190,18 @@ scheme_value time2date(int hi_secs, int lo_secs, scheme_value zone, | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Oops
 | ||||
| ** There's a fundamental problem with the Posix mktime() function used below | ||||
| ** -- it's error return value (-1) is also a valid return value, for date | ||||
| **     11:59:00 UTC, 12/31/1969 | ||||
| ** | ||||
| ** 1. We choose to err on the paranoid side. If mktime() returns -1, it is | ||||
| **    considered an error. | ||||
| ** 2. If we return an error, we try to return a useful errno value, if we can. | ||||
| ** | ||||
| ** Who designed this interface? | ||||
| */ | ||||
| 
 | ||||
| scheme_value date2time(int sec, int min, int hour, | ||||
| 		       int mday, int month, int year, | ||||
| 		       scheme_value tz_name, scheme_value tz_secs, | ||||
|  | @ -198,7 +210,6 @@ scheme_value date2time(int sec, int min, int hour, | |||
| { | ||||
|     time_t t; | ||||
|     struct tm d; | ||||
|     int error = 0; | ||||
| 
 | ||||
|     d.tm_sec  = sec;	d.tm_min  = min;	d.tm_hour  = hour; | ||||
|     d.tm_mday = mday;	d.tm_mon  = month;	d.tm_year  = year; | ||||
|  | @ -208,9 +219,11 @@ scheme_value date2time(int sec, int min, int hour, | |||
| 	char **oldenv = environ;			/* Set TZ to UTC     */ | ||||
| 	environ = utc_env;				/* time temporarily. */ | ||||
| 	tzset(); /* NetBSD, SunOS POSIX-noncompliance requires this. */ | ||||
| 	errno = 0;	/* A -1 ret value from mktime() might be legal; */ | ||||
| 	t = mktime(&d); /*   hack errno to disambiguate. Ugh.           */ | ||||
| 	if( t == -1 && errno ) error = errno; | ||||
| 	d.tm_isdst = 0; /* FreeBSD, at least, needs this or it sulks. */ | ||||
| 	errno = 0; | ||||
| 	t = mktime(&d); | ||||
| 	/* t == -1 => you probably have an error. */ | ||||
| 	if( t == -1 ) return ENTER_FIXNUM(errno ? errno : -1); | ||||
| 	t -= EXTRACT_FIXNUM(tz_secs); | ||||
| 	environ = oldenv; | ||||
| 	} | ||||
|  | @ -220,20 +233,19 @@ scheme_value date2time(int sec, int min, int hour, | |||
| 	char **oldenv = make_newenv(tz_name, newenv); | ||||
| 	if( !oldenv ) return ENTER_FIXNUM(errno); | ||||
| 	tzset(); /* NetBSD, SunOS POSIX-noncompliance requires this. */ | ||||
| 	errno = 0;	/* A -1 ret value from mktime() might be legal; */ | ||||
| 	t = mktime(&d); /*   hack errno to disambiguate. Ugh.           */ | ||||
| 	if( t == -1 && errno ) error = errno; | ||||
| 	errno = 0; | ||||
| 	t = mktime(&d); | ||||
| 	if( t == -1 ) return ENTER_FIXNUM(errno ? errno : -1); | ||||
| 	revert_env(oldenv); | ||||
| 	} | ||||
| 
 | ||||
|     else {				/* Local time */ | ||||
| 	tzset(); /* NetBSD, SunOS POSIX-noncompliance requires this. */ | ||||
| 	errno = 0; | ||||
| 	t = mktime(&d); | ||||
| 	if( t == -1 && errno ) error = errno; | ||||
| 	if( t == -1) return ENTER_FIXNUM(errno ? errno : -1); | ||||
| 	} | ||||
| 
 | ||||
|     if( error ) return ENTER_FIXNUM(error); | ||||
| 
 | ||||
|     *hi_secs = hi8(t); | ||||
|     *lo_secs = lo24(t); | ||||
|     return SCHFALSE; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 shivers
						shivers