⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 time.c

📁 它通过提供glibc兼容使得应用程序移植到较小的c 库时相当得容易. 它能够应用到带虚拟存储的Linux和uClinux上.在大多数带MMU部件的平台上为使它更加紧凑,它也能够编译成共享库.uClib
💻 C
📖 第 1 页 / 共 4 页
字号:
static char *read_TZ_file(char *buf){	int fd;	ssize_t r;	size_t todo;	char *p = NULL;	if ((fd = open(_PATH_TZ, O_RDONLY)) >= 0) {		todo = TZ_BUFLEN;		p = buf;		do {			if ((r = read(fd, p, todo)) < 0) {				goto ERROR;			}			if (r == 0) {				break;			}			p += r;			todo -= r;		} while (todo);		if ((p > buf) && (p[-1] == '\n')) {	/* Must end with newline. */			p[-1] = 0;			p = buf;#ifdef __TIME_TZ_FILE_ONCE			++TZ_file_read;#endif /* __TIME_TZ_FILE_ONCE */		} else {		ERROR:			p = NULL;		}		close(fd);	}	return p;}#endif /* __TIME_TZ_FILE */void tzset(void){	register const char *e;	register char *s;	long off;	short *p;	rule_struct new_rules[2];	int n, count, f;	char c;#ifdef __TIME_TZ_FILE	char buf[TZ_BUFLEN];#endif /* __TIME_TZ_FILE */#ifdef __TIME_TZ_OPT_SPEED	static char oldval[TZ_BUFLEN]; /* BSS-zero'd. */#endif /* __TIME_TZ_OPT_SPEED */	TZLOCK;	e = getenv(TZ);				/* TZ env var always takes precedence. */#ifdef __TIME_TZ_FILE_ONCE	/* Put this inside the lock to prevent the possiblity of two different	 * timezones being used in a threaded app. */	if (e != NULL) {		TZ_file_read = 0;		/* Reset if the TZ env var is set. */	} else if (TZ_file_read > 0) {		goto FAST_DONE;	}#endif /* __TIME_TZ_FILE_ONCE */	/* Warning!!!  Since uClibc doesn't do lib locking, the following is	 * potentially unsafe in a multi-threaded program since it is remotely	 * possible that another thread could call setenv() for TZ and overwrite	 * the string being parsed.  So, don't do that... */	if ((!e						/* TZ env var not set... */#ifdef __TIME_TZ_FILE		 && !(e = read_TZ_file(buf)) /* and no file or invalid file */#endif /* __TIME_TZ_FILE */		 ) || !*e) {			/* or set to empty string. */	ILLEGAL:					/* TODO: Clean up the following... */#ifdef __TIME_TZ_OPT_SPEED		*oldval = 0;			/* Set oldval tonnn empty string. */#endif /* __TIME_TZ_OPT_SPEED */		s = _time_tzinfo[0].tzname;		*s = 'U';		*++s = 'T';		*++s = 'C';		*++s =		*_time_tzinfo[1].tzname = 0;		_time_tzinfo[0].gmt_offset = 0;		goto DONE;	}	if (*e == ':') {			/* Ignore leading ':'. */		++e;	}#ifdef __TIME_TZ_OPT_SPEED	if (strcmp(e, oldval) == 0) { /* Same string as last time... */		goto FAST_DONE;			/* So nothing to do. */	}	/* Make a copy of the TZ env string.  It won't be nul-terminated if	 * it is too long, but it that case it will be illegal and will be reset	 * to the empty string anyway. */	strncpy(oldval, e, TZ_BUFLEN);#endif /* __TIME_TZ_OPT_SPEED */		count = 0;	new_rules[1].tzname[0] = 0; LOOP:	/* Get std or dst name. */	c = 0;	if (*e == '<') {		++e;		c = '>';	}	s = new_rules[count].tzname;	n = 0;	while (*e		   && isascii(*e)		/* SUSv3 requires char in portable char set. */		   && (isalpha(*e)			   || (c && (isalnum(*e) || (*e == '+') || (*e == '-'))))		   ) {		*s++ = *e++;		if (++n > TZNAME_MAX) {			goto ILLEGAL;		}	}	*s = 0;	if ((n < 3)					/* Check for minimum length. */		|| (c && (*e++ != c))	/* Match any quoting '<'. */		) {		goto ILLEGAL;	}	/* Get offset */	s = (char *) e;	if ((*e != '-') && (*e != '+')) {		if (count && !isdigit(*e)) {			off -= 3600;		/* Default to 1 hour ahead of std. */			goto SKIP_OFFSET;		}		--e;	}	++e;	if (!(e = getoffset(e, &off))) {		goto ILLEGAL;	}	if (*s == '-') {		off = -off;				/* Save off in case needed for dst default. */	} SKIP_OFFSET:	new_rules[count].gmt_offset = off;	if (!count) {		if (*e) {			++count;			goto LOOP;		}	} else {					/* OK, we have dst, so get some rules. */		count = 0;		if (!*e) {				/* No rules so default to US rules. */			e = DEFAULT_RULES;		}		do {			if (*e++ != ',') {				goto ILLEGAL;			}			n = 365;			s = (char *) RULE;			if ((c = *e++) == 'M') {				n = 12;			} else if (c == 'J') {				s += 8;			} else {				--e;				c = 0;				s += 6;			}			*(p = &new_rules[count].rule_type) = c;			if (c != 'M') {				p -= 2;			}			do {				++s;				if (!(e = getnumber(e, &f))					|| (((unsigned int)(f - s[1])) > n)					|| (*s && (*e++ != *s))					) {					goto ILLEGAL;				}				*--p = f;			} while ((n = *(s += 2)) > 0);			off = 2 * 60 * 60;	/* Default to 2:00:00 */			if (*e == '/') {				++e;				if (!(e = getoffset(e, &off))) {					goto ILLEGAL;				}			}			new_rules[count].dst_offset = off;		} while (++count < 2);		if (*e) {			goto ILLEGAL;		}	}	memcpy(_time_tzinfo, new_rules, sizeof(new_rules)); DONE:	tzname[0] = _time_tzinfo[0].tzname;	tzname[1] = _time_tzinfo[1].tzname;	daylight = !!_time_tzinfo[1].tzname[0];	timezone = _time_tzinfo[0].gmt_offset; FAST_DONE:	TZUNLOCK;}#endif/**********************************************************************//*  #ifdef L_utime *//* utime is a syscall in both linux and elks. *//*  int utime(const char *path, const struct utimbuf *times) *//*  #endif *//**********************************************************************//* Non-SUSv3 *//**********************************************************************/#ifdef L_utimes#ifndef __BCC__#error The uClibc version of utimes is in sysdeps/linux/common.#endif#include <utime.h>#include <sys/time.h>int utimes(const char *filename, register const struct timeval *tvp){	register struct utimbuf *p = NULL;	struct utimbuf utb;	if (tvp) {		p = &utb;		p->actime = tvp[0].tv_sec;		p->modtime = tvp[1].tv_sec;	}	return utime(filename, p);}#endif/**********************************************************************/#ifdef L__time_t2tmstatic const uint16_t vals[] = {	60, 60, 24, 7 /* special */, 36524, 1461, 365, 0};static const unsigned char days[] = {	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, /* non-leap */	    29,};/* Notes: * If time_t is 32 bits, then no overflow is possible. * It time_t is > 32 bits, this needs to be adjusted to deal with overflow. *//* Note: offset is the correction in _days_ to *timer! */struct tm *_time_t2tm(const time_t *__restrict timer,					  int offset, struct tm *__restrict result){	register int *p;	time_t t1, t, v;	int wday=0;					/* Note: wday can be uninitialized. */	{		register const uint16_t *vp;		t = *timer;		p = (int *) result;		p[7] = 0;		vp = vals;		do {			if ((v = *vp) == 7) {				/* Overflow checking, assuming time_t is long int... */#if (LONG_MAX > INT_MAX) && (LONG_MAX > 2147483647L)#if (INT_MAX == 2147483647L) && (LONG_MAX == 9223372036854775807L)				/* Valid range for t is [-784223472856L, 784223421720L].				 * Outside of this range, the tm_year field will overflow. */				if (((unsigned long)(t + offset- -784223472856L))					> (784223421720L - -784223472856L)					) {					return NULL;				}#else#error overflow conditions unknown#endif#endif				/* We have days since the epoch, so caluclate the weekday. */#if defined(__BCC__) && TIME_T_IS_UNSIGNED				wday = (t + 4) % (*vp);	/* t is unsigned */#else				wday = ((int)((t % (*vp)) + 11)) % ((int)(*vp)); /* help bcc */#endif				/* Set divisor to days in 400 years.  Be kind to bcc... */				v = ((time_t)(vp[1])) << 2;				++v;				/* Change to days since 1/1/1601 so that for 32 bit time_t				 * values, we'll have t >= 0.  This should be changed for				 * archs with larger time_t types. 				 * Also, correct for offset since a multiple of 7. */				/* TODO: Does this still work on archs with time_t > 32 bits? */				t += (135140L - 366) + offset; /* 146097 - (365*30 + 7) -366 */			}#if defined(__BCC__) && TIME_T_IS_UNSIGNED			t -= ((t1 = t / v) * v);#else			if ((t -= ((t1 = t / v) * v)) < 0) {				t += v;				--t1;			}#endif			if ((*vp == 7) && (t == v-1)) {				--t;			/* Correct for 400th year leap case */				++p[4];			/* Stash the extra day... */			}#if defined(__BCC__) && 0			*p = t1;			if (v <= 60) {				*p = t;				t = t1;			}			++p;#else			if (v <= 60) {				*p++ = t;				t = t1;			} else {				*p++ = t1;			}#endif		} while (*++vp);	}	if (p[-1] == 4) {		--p[-1];		t = 365;	}	*p += ((int) t);			/* result[7] .. tm_yday */	p -= 2;						/* at result[5] */#if (LONG_MAX > INT_MAX) && (LONG_MAX > 2147483647L)	/* Protect against overflow.  TODO: Unecessary if int arith wraps? */	*p = ((((p[-2]<<2) + p[-1])*25 + p[0])<< 2) + (p[1] - 299); /* tm_year */#else	*p = ((((p[-2]<<2) + p[-1])*25 + p[0])<< 2) + p[1] - 299; /* tm_year */#endif	p[1] = wday;				/* result[6] .. tm_wday */	{		register const unsigned char *d = days;		wday = 1900 + *p;		if (__isleap(wday)) {			d += 11;		}		wday = p[2] + 1;		/* result[7] .. tm_yday */		*--p = 0;				/* at result[4] .. tm_mon */		while (wday > *d) {			wday -= *d;			if (*d == 29) {				d -= 11;		/* Backup to non-leap Feb. */			}			++d;			++*p;				/* Increment tm_mon. */		}		p[-1] = wday;			/* result[3] .. tm_mday */	}	/* TODO -- should this be 0? */	p[4] = 0;					/* result[8] .. tm_isdst */	return result;}#endif/**********************************************************************/#ifdef L___time_tmstruct tm __time_tm;	/* Global shared by gmtime() and localtime(). */#endif/**********************************************************************/#ifdef L__time_mktimestatic const unsigned char vals[] = {	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, /* non-leap */	    29,};time_t _time_mktime(struct tm *timeptr, int store_on_success){#ifdef __BCC__	long days, secs;#else	long long secs;#endif	time_t t;	struct tm x;	/* 0:sec  1:min  2:hour  3:mday  4:mon  5:year  6:wday  7:yday  8:isdst */	register int *p = (int *) &x;	register const unsigned char *s;	int d;	tzset();	memcpy(p, timeptr, sizeof(struct tm));	d = 400;	p[5] = (p[5] - ((p[6] = p[5]/d) * d)) + (p[7] = p[4]/12);	if ((p[4] -= 12 * p[7]) < 0) {		p[4] += 12;		--p[5];	}	s = vals;	d = (p[5] += 1900);			/* Correct year.  Now between 1900 and 2300. */	if (__isleap(d)) {		s += 11;	}		p[7] = 0;	d = p[4];	while (d) {		p[7] += *s;		if (*s == 29) {			s -= 11;			/* Backup to non-leap Feb. */		}		++s;		--d;	}#ifdef __BCC__	d = p[5] - 1;	days = -719163L + ((long)d)*365 + ((d/4) - (d/100) + (d/400) + p[3] + p[7]);	secs = p[0] + 60*( p[1] + 60*((long)(p[2])) )		+ _time_tzinfo[timeptr->tm_isdst > 0].gmt_offset;	if (secs < 0) {		secs += 120009600L;		days -= 1389;	}	if ( ((unsigned long)(days + secs/86400L)) > 49710L) {		return -1;	}	secs += (days * 86400L);#else	TZLOCK;	d = p[5] - 1;	d = -719163L + d*365 + (d/4) - (d/100) + (d/400);	secs = p[0]		+ _time_tzinfo[timeptr->tm_isdst > 0].gmt_offset		+ 60*( p[1]			   + 60*(p[2]					 + 24*(((146073L * ((long long)(p[6])) + d)							+ p[3]) + p[7])));	TZUNLOCK;	if (((unsigned long long)(secs - LONG_MIN))		> (((unsigned long long)LONG_MAX) - LONG_MIN)		) {		return -1;	}#endif	t = secs;	localtime_r(&t, (struct tm *)p);	if (t < 0) {	    return -1;	}	if (store_on_success) {		memcpy(timeptr, p, sizeof(struct tm));	}	return t;}#endif/**********************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -