Merge "Add recvmmsg and sendmmsg syscalls."
diff --git a/libc/Android.mk b/libc/Android.mk
index 852db73..d4ccefb 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -317,10 +317,12 @@
libc_upstream_openbsd_src_files := \
upstream-openbsd/lib/libc/gen/exec.c \
- upstream-openbsd/lib/libc/gen/ftok.c \
upstream-openbsd/lib/libc/gen/fnmatch.c \
- upstream-openbsd/lib/libc/gen/toupper_.c \
+ upstream-openbsd/lib/libc/gen/ftok.c \
+ upstream-openbsd/lib/libc/gen/getprogname.c \
+ upstream-openbsd/lib/libc/gen/setprogname.c \
upstream-openbsd/lib/libc/gen/tolower_.c \
+ upstream-openbsd/lib/libc/gen/toupper_.c \
upstream-openbsd/lib/libc/string/strstr.c \
upstream-openbsd/lib/libc/string/strsep.c \
upstream-openbsd/lib/libc/string/wcslcpy.c \
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 9c04059..9595170 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -153,6 +153,10 @@
extern lldiv_t lldiv(long long, long long);
+/* BSD compatibility. */
+extern const char* getprogname(void);
+extern void setprogname(const char*);
+
#if 1 /* MISSING FROM BIONIC - ENABLED FOR STLPort and libstdc++-v3 */
/* make STLPort happy */
extern int mblen(const char *, size_t);
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index e2599b4..6e7eaa9 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -74,9 +74,9 @@
#define WILDABBR " "
#endif /* !defined WILDABBR */
-static char wildabbr[] = WILDABBR;
+static char wildabbr[] = WILDABBR;
-static const char gmt[] = "GMT";
+static const char gmt[] = "GMT";
/*
** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
@@ -89,7 +89,7 @@
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
#endif /* !defined TZDEFDST */
-struct ttinfo { /* time type information */
+struct ttinfo { /* time type information */
int_fast32_t tt_gmtoff; /* UT offset in seconds */
int tt_isdst; /* used to set tm_isdst */
int tt_abbrind; /* abbreviation list index */
@@ -97,7 +97,7 @@
int tt_ttisgmt; /* TRUE if transition is UT */
};
-struct lsinfo { /* leap second information */
+struct lsinfo { /* leap second information */
time_t ls_trans; /* transition time */
int_fast64_t ls_corr; /* correction to apply */
};
@@ -112,32 +112,32 @@
#endif /* !defined TZNAME_MAX */
struct state {
- int leapcnt;
- int timecnt;
- int typecnt;
- int charcnt;
- int goback;
- int goahead;
- time_t ats[TZ_MAX_TIMES];
- unsigned char types[TZ_MAX_TIMES];
- struct ttinfo ttis[TZ_MAX_TYPES];
- char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
- (2 * (MY_TZNAME_MAX + 1)))];
- struct lsinfo lsis[TZ_MAX_LEAPS];
- int defaulttype; /* for early times or if no transitions */
+ int leapcnt;
+ int timecnt;
+ int typecnt;
+ int charcnt;
+ int goback;
+ int goahead;
+ time_t ats[TZ_MAX_TIMES];
+ unsigned char types[TZ_MAX_TIMES];
+ struct ttinfo ttis[TZ_MAX_TYPES];
+ char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
+ (2 * (MY_TZNAME_MAX + 1)))];
+ struct lsinfo lsis[TZ_MAX_LEAPS];
+ int defaulttype; /* for early times or if no transitions */
};
struct rule {
- int r_type; /* type of rule--see below */
- int r_day; /* day number of rule */
- int r_week; /* week number of rule */
- int r_mon; /* month number of rule */
- int_fast32_t r_time; /* transition time of rule */
+ int r_type; /* type of rule--see below */
+ int r_day; /* day number of rule */
+ int r_week; /* week number of rule */
+ int r_mon; /* month number of rule */
+ int_fast32_t r_time; /* transition time of rule */
};
-#define JULIAN_DAY 0 /* Jn - Julian day */
-#define DAY_OF_YEAR 1 /* n - day of year */
-#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
+#define JULIAN_DAY 0 /* Jn - Julian day */
+#define DAY_OF_YEAR 1 /* n - day of year */
+#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
/*
** Prototypes for static functions.
@@ -147,7 +147,7 @@
static int __bionic_open_tzdata(const char*, int*);
static int_fast32_t detzcode(const char * codep);
-static time_t detzcode64(const char * codep);
+static int_fast64_t detzcode64(const char * codep);
static int differ_by_repeat(time_t t1, time_t t0);
static const char * getzname(const char * strp) ATTRIBUTE_PURE;
static const char * getqzname(const char * strp, const int delim)
@@ -165,6 +165,7 @@
static int increment_overflow(int * number, int delta);
static int leaps_thru_end_of(int y) ATTRIBUTE_PURE;
static int increment_overflow32(int_fast32_t * number, int delta);
+static int increment_overflow_time(time_t *t, int_fast32_t delta);
static int normalize_overflow32(int_fast32_t * tensptr,
int * unitsptr, int base);
static int normalize_overflow(int * tensptr, int * unitsptr,
@@ -186,18 +187,18 @@
const struct state * sp, struct tm * tmp);
static int tmcomp(const struct tm * atmp,
const struct tm * btmp);
-static time_t transtime(time_t janfirst, int year,
- const struct rule * rulep, int_fast32_t offset)
+static int_fast32_t transtime(int year, const struct rule * rulep,
+ int_fast32_t offset)
ATTRIBUTE_PURE;
-static int typesequiv(const struct state * sp, int a, int b);
+static int typesequiv(const struct state * sp, int a, int b);
static int tzload(const char * name, struct state * sp,
int doextend);
static int tzparse(const char * name, struct state * sp,
int lastditch);
#ifdef ALL_STATE
-static struct state * lclptr;
-static struct state * gmtptr;
+static struct state * lclptr;
+static struct state * gmtptr;
#endif /* defined ALL_STATE */
#ifndef ALL_STATE
@@ -211,11 +212,11 @@
#define TZ_STRLEN_MAX 255
#endif /* !defined TZ_STRLEN_MAX */
-static char lcl_TZname[TZ_STRLEN_MAX + 1];
-static int lcl_is_set;
-static int gmt_is_set;
+static char lcl_TZname[TZ_STRLEN_MAX + 1];
+static int lcl_is_set;
+static int gmt_is_set;
-char * tzname[2] = {
+char * tzname[2] = {
wildabbr,
wildabbr
};
@@ -231,43 +232,43 @@
static struct tm tmGlobal;
#ifdef USG_COMPAT
-long timezone = 0;
-int daylight = 0;
+long timezone = 0;
+int daylight = 0;
#endif /* defined USG_COMPAT */
#ifdef ALTZONE
-long altzone = 0;
+long altzone = 0;
#endif /* defined ALTZONE */
static int_fast32_t
detzcode(const char *const codep)
{
- register int_fast32_t result;
- register int i;
+ register int_fast32_t result;
+ register int i;
- result = (codep[0] & 0x80) ? -1 : 0;
- for (i = 0; i < 4; ++i)
- result = (result << 8) | (codep[i] & 0xff);
- return result;
+ result = (codep[0] & 0x80) ? -1 : 0;
+ for (i = 0; i < 4; ++i)
+ result = (result << 8) | (codep[i] & 0xff);
+ return result;
}
-static time_t
+static int_fast64_t
detzcode64(const char *const codep)
{
- register time_t result;
- register int i;
+ register int_fast64_t result;
+ register int i;
- result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0;
- for (i = 0; i < 8; ++i)
- result = result * 256 + (codep[i] & 0xff);
- return result;
+ result = (codep[0] & 0x80) ? -1 : 0;
+ for (i = 0; i < 8; ++i)
+ result = (result << 8) | (codep[i] & 0xff);
+ return result;
}
static void
settzname(void)
{
- register struct state * const sp = lclptr;
- register int i;
+ register struct state * const sp = lclptr;
+ register int i;
tzname[0] = wildabbr;
tzname[1] = wildabbr;
@@ -333,10 +334,10 @@
static int
differ_by_repeat(const time_t t1, const time_t t0)
{
- if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
- return 0;
+ if (TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
+ return 0;
#if __LP64__ // 32-bit Android only has a signed 32-bit time_t; 64-bit Android is fixed.
- return t1 - t0 == SECSPERREPEAT;
+ return t1 - t0 == SECSPERREPEAT;
#endif
}
@@ -344,26 +345,26 @@
tzload(register const char* name, register struct state* const sp,
register const int doextend)
{
- register const char * p;
- register int i;
- register int fid;
- register int stored;
- register int nread;
+ register const char * p;
+ register int i;
+ register int fid;
+ register int stored;
+ register int nread;
typedef union {
- struct tzhead tzhead;
- char buf[2 * sizeof(struct tzhead) +
- 2 * sizeof *sp +
- 4 * TZ_MAX_TIMES];
+ struct tzhead tzhead;
+ char buf[2 * sizeof(struct tzhead) +
+ 2 * sizeof *sp +
+ 4 * TZ_MAX_TIMES];
} u_t;
#ifdef ALL_STATE
- register u_t * up;
+ register u_t * up;
up = (u_t *) calloc(1, sizeof *up);
if (up == NULL)
return -1;
#else /* !defined ALL_STATE */
- u_t u;
- register u_t * const up = &u;
+ u_t u;
+ register u_t * const up = &u;
#endif /* !defined ALL_STATE */
sp->goback = sp->goahead = FALSE;
@@ -371,15 +372,15 @@
goto oops;
int toread;
fid = __bionic_open_tzdata(name, &toread);
- if (fid < 0) {
- return -1;
- }
+ if (fid < 0)
+ goto oops;
nread = read(fid, up->buf, toread);
if (close(fid) < 0 || nread <= 0)
goto oops;
for (stored = 4; stored <= 8; stored *= 2) {
- int ttisstdcnt;
- int ttisgmtcnt;
+ int ttisstdcnt;
+ int ttisgmtcnt;
+ int timecnt;
ttisstdcnt = (int) detzcode(up->tzhead.tzh_ttisstdcnt);
ttisgmtcnt = (int) detzcode(up->tzhead.tzh_ttisgmtcnt);
@@ -396,24 +397,45 @@
(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
goto oops;
if (nread - (p - up->buf) <
- sp->timecnt * stored + /* ats */
- sp->timecnt + /* types */
- sp->typecnt * 6 + /* ttinfos */
- sp->charcnt + /* chars */
- sp->leapcnt * (stored + 4) + /* lsinfos */
- ttisstdcnt + /* ttisstds */
- ttisgmtcnt) /* ttisgmts */
+ sp->timecnt * stored + /* ats */
+ sp->timecnt + /* types */
+ sp->typecnt * 6 + /* ttinfos */
+ sp->charcnt + /* chars */
+ sp->leapcnt * (stored + 4) + /* lsinfos */
+ ttisstdcnt + /* ttisstds */
+ ttisgmtcnt) /* ttisgmts */
goto oops;
+ timecnt = 0;
for (i = 0; i < sp->timecnt; ++i) {
- sp->ats[i] = (stored == 4) ?
- detzcode(p) : detzcode64(p);
+ int_fast64_t at
+ = stored == 4 ? detzcode(p) : detzcode64(p);
+ sp->types[i] = ((TYPE_SIGNED(time_t)
+ ? time_t_min <= at
+ : 0 <= at)
+ && at <= time_t_max);
+ if (sp->types[i]) {
+ if (i && !timecnt && at != time_t_min) {
+ /*
+ ** Keep the earlier record, but tweak
+ ** it so that it starts with the
+ ** minimum time_t value.
+ */
+ sp->types[i - 1] = 1;
+ sp->ats[timecnt++] = time_t_min;
+ }
+ sp->ats[timecnt++] = at;
+ }
p += stored;
}
+ timecnt = 0;
for (i = 0; i < sp->timecnt; ++i) {
- sp->types[i] = (unsigned char) *p++;
- if (sp->types[i] >= sp->typecnt)
+ unsigned char typ = *p++;
+ if (sp->typecnt <= typ)
goto oops;
+ if (sp->types[i])
+ sp->types[timecnt++] = typ;
}
+ sp->timecnt = timecnt;
for (i = 0; i < sp->typecnt; ++i) {
register struct ttinfo * ttisp;
@@ -468,44 +490,6 @@
}
}
/*
- ** Out-of-sort ats should mean we're running on a
- ** signed time_t system but using a data file with
- ** unsigned values (or vice versa).
- */
- for (i = 0; i < sp->timecnt; ++i)
- if ((i < sp->timecnt - 1 &&
- sp->ats[i] > sp->ats[i + 1]) ||
- (i == sp->timecnt - 1 && !TYPE_SIGNED(time_t) &&
- sp->ats[i] >
- ((stored == 4) ? INT32_MAX : INT64_MAX))) {
- if (TYPE_SIGNED(time_t)) {
- /*
- ** Ignore the end (easy).
- */
- sp->timecnt = i + 1;
- } else {
- /*
- ** Ignore the beginning (harder).
- */
- register int j;
-
- /*
- ** Keep the record right before the
- ** epoch boundary,
- ** but tweak it so that it starts
- ** right with the epoch
- ** (thanks to Doug Bailey).
- */
- sp->ats[i] = 0;
- for (j = 0; j + i < sp->timecnt; ++j) {
- sp->ats[j] = sp->ats[j + i];
- sp->types[j] = sp->types[j + i];
- }
- sp->timecnt = j;
- }
- break;
- }
- /*
** If this is an old file, we're done.
*/
if (up->tzhead.tzh_version[0] == '\0')
@@ -514,16 +498,16 @@
for (i = 0; i < nread; ++i)
up->buf[i] = p[i];
/*
- ** If this is a narrow time_t system, we're done.
+ ** If this is a signed narrow time_t system, we're done.
*/
- if (stored >= (int) sizeof(time_t))
+ if (TYPE_SIGNED(time_t) && stored >= (int) sizeof(time_t))
break;
}
if (doextend && nread > 2 &&
up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
sp->typecnt + 2 <= TZ_MAX_TYPES) {
- struct state ts;
- register int result;
+ struct state ts;
+ register int result;
up->buf[nread - 1] = '\0';
result = tzparse(&up->buf[1], &ts, FALSE);
@@ -618,31 +602,31 @@
static int
typesequiv(const struct state *const sp, const int a, const int b)
{
- register int result;
+ register int result;
- if (sp == NULL ||
- a < 0 || a >= sp->typecnt ||
- b < 0 || b >= sp->typecnt)
- result = FALSE;
- else {
- register const struct ttinfo * ap = &sp->ttis[a];
- register const struct ttinfo * bp = &sp->ttis[b];
- result = ap->tt_gmtoff == bp->tt_gmtoff &&
- ap->tt_isdst == bp->tt_isdst &&
- ap->tt_ttisstd == bp->tt_ttisstd &&
- ap->tt_ttisgmt == bp->tt_ttisgmt &&
- strcmp(&sp->chars[ap->tt_abbrind],
- &sp->chars[bp->tt_abbrind]) == 0;
- }
- return result;
+ if (sp == NULL ||
+ a < 0 || a >= sp->typecnt ||
+ b < 0 || b >= sp->typecnt)
+ result = FALSE;
+ else {
+ register const struct ttinfo * ap = &sp->ttis[a];
+ register const struct ttinfo * bp = &sp->ttis[b];
+ result = ap->tt_gmtoff == bp->tt_gmtoff &&
+ ap->tt_isdst == bp->tt_isdst &&
+ ap->tt_ttisstd == bp->tt_ttisstd &&
+ ap->tt_ttisgmt == bp->tt_ttisgmt &&
+ strcmp(&sp->chars[ap->tt_abbrind],
+ &sp->chars[bp->tt_abbrind]) == 0;
+ }
+ return result;
}
-static const int mon_lengths[2][MONSPERYEAR] = {
+static const int mon_lengths[2][MONSPERYEAR] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
-static const int year_lengths[2] = {
+static const int year_lengths[2] = {
DAYSPERNYEAR, DAYSPERLYEAR
};
@@ -675,7 +659,7 @@
static const char *
getqzname(register const char *strp, const int delim)
{
- register int c;
+ register int c;
while ((c = *strp) != '\0' && c != delim)
++strp;
@@ -692,8 +676,8 @@
static const char *
getnum(register const char * strp, int * const nump, const int min, const int max)
{
- register char c;
- register int num;
+ register char c;
+ register int num;
if (strp == NULL || !is_digit(c = *strp))
return NULL;
@@ -761,7 +745,7 @@
static const char *
getoffset(register const char *strp, int_fast32_t *const offsetp)
{
- register int neg = 0;
+ register int neg = 0;
if (*strp == '-') {
neg = 1;
@@ -830,19 +814,18 @@
}
/*
-** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
-** year, a rule, and the offset from UT at the time that rule takes effect,
-** calculate the Epoch-relative time that rule takes effect.
+** Given a year, a rule, and the offset from UT at the time that rule takes
+** effect, calculate the year-relative time that rule takes effect.
*/
-static time_t
-transtime(const time_t janfirst, const int year,
- register const struct rule *const rulep, const int_fast32_t offset)
+static int_fast32_t
+transtime(const int year, register const struct rule *const rulep,
+ const int_fast32_t offset)
{
- register int leapyear;
- register time_t value;
- register int i;
- int d, m1, yy0, yy1, yy2, dow;
+ register int leapyear;
+ register int_fast32_t value;
+ register int i;
+ int d, m1, yy0, yy1, yy2, dow;
INITIALIZE(value);
leapyear = isleap(year);
@@ -856,7 +839,7 @@
** add SECSPERDAY times the day number-1 to the time of
** January 1, midnight, to get the day.
*/
- value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
+ value = (rulep->r_day - 1) * SECSPERDAY;
if (leapyear && rulep->r_day >= 60)
value += SECSPERDAY;
break;
@@ -867,16 +850,13 @@
** Just add SECSPERDAY times the day number to the time of
** January 1, midnight, to get the day.
*/
- value = janfirst + rulep->r_day * SECSPERDAY;
+ value = rulep->r_day * SECSPERDAY;
break;
case MONTH_NTH_DAY_OF_WEEK:
/*
** Mm.n.d - nth "dth day" of month m.
*/
- value = janfirst;
- for (i = 0; i < rulep->r_mon - 1; ++i)
- value += mon_lengths[leapyear][i] * SECSPERDAY;
/*
** Use Zeller's Congruence to get day-of-week of first day of
@@ -909,13 +889,15 @@
/*
** "d" is the day-of-month (zero-origin) of the day we want.
*/
- value += d * SECSPERDAY;
+ value = d * SECSPERDAY;
+ for (i = 0; i < rulep->r_mon - 1; ++i)
+ value += mon_lengths[leapyear][i] * SECSPERDAY;
break;
}
/*
- ** "value" is the Epoch-relative time of 00:00:00 UT on the day in
- ** question. To get the Epoch-relative time of the specified local
+ ** "value" is the year-relative time of 00:00:00 UT on the day in
+ ** question. To get the year-relative time of the specified local
** time on that day, add the transition time and the current offset
** from UT.
*/
@@ -931,17 +913,15 @@
tzparse(const char * name, register struct state * const sp,
const int lastditch)
{
- const char * stdname;
- const char * dstname;
- size_t stdlen;
- size_t dstlen;
- int_fast32_t stdoffset;
- int_fast32_t dstoffset;
- register time_t * atp;
- register unsigned char * typep;
- register char * cp;
- register int load_result;
- static struct ttinfo zttinfo;
+ const char * stdname;
+ const char * dstname;
+ size_t stdlen;
+ size_t dstlen;
+ int_fast32_t stdoffset;
+ int_fast32_t dstoffset;
+ register char * cp;
+ register int load_result;
+ static struct ttinfo zttinfo;
INITIALIZE(dstname);
stdname = name;
@@ -994,13 +974,12 @@
if (*name == '\0' && load_result != 0)
name = TZDEFRULESTRING;
if (*name == ',' || *name == ';') {
- struct rule start;
- struct rule end;
- register int year;
- register int yearlim;
- register time_t janfirst;
- time_t starttime;
- time_t endtime;
+ struct rule start;
+ struct rule end;
+ register int year;
+ register int yearlim;
+ register int timecnt;
+ time_t janfirst;
++name;
if ((name = getrule(name, &start)) == NULL)
@@ -1022,46 +1001,47 @@
sp->ttis[1].tt_gmtoff = -stdoffset;
sp->ttis[1].tt_isdst = 0;
sp->ttis[1].tt_abbrind = 0;
- atp = sp->ats;
- typep = sp->types;
+ timecnt = 0;
janfirst = 0;
yearlim = EPOCH_YEAR + YEARSPERREPEAT;
for (year = EPOCH_YEAR; year < yearlim; year++) {
- int_fast32_t yearsecs;
-
- starttime = transtime(janfirst, year, &start,
- stdoffset);
- endtime = transtime(janfirst, year, &end,
- dstoffset);
+ int_fast32_t
+ starttime = transtime(year, &start, stdoffset),
+ endtime = transtime(year, &end, dstoffset);
+ int_fast32_t
yearsecs = (year_lengths[isleap(year)]
* SECSPERDAY);
- if (starttime > endtime
+ int reversed = endtime < starttime;
+ if (reversed) {
+ int_fast32_t swap = starttime;
+ starttime = endtime;
+ endtime = swap;
+ }
+ if (reversed
|| (starttime < endtime
&& (endtime - starttime
< (yearsecs
+ (stdoffset - dstoffset))))) {
- if (&sp->ats[TZ_MAX_TIMES - 2] < atp)
+ if (TZ_MAX_TIMES - 2 < timecnt)
break;
yearlim = year + YEARSPERREPEAT + 1;
- if (starttime > endtime) {
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- } else {
- *atp++ = starttime;
- *typep++ = 0; /* DST begins */
- *atp++ = endtime;
- *typep++ = 1; /* DST ends */
+ sp->ats[timecnt] = janfirst;
+ if (increment_overflow_time
+ (&sp->ats[timecnt], starttime))
+ break;
+ sp->types[timecnt++] = reversed;
+ sp->ats[timecnt] = janfirst;
+ if (increment_overflow_time
+ (&sp->ats[timecnt], endtime))
+ break;
+ sp->types[timecnt++] = !reversed;
}
- }
- if (time_t_max - janfirst < yearsecs)
+ if (increment_overflow_time(&janfirst, yearsecs))
break;
- janfirst += yearsecs;
}
- sp->timecnt = atp - sp->ats;
- if (!sp->timecnt)
- sp->typecnt = 1; /* Perpetual DST. */
+ sp->timecnt = timecnt;
+ if (!timecnt)
+ sp->typecnt = 1; /* Perpetual DST. */
} else {
register int_fast32_t theirstdoffset;
register int_fast32_t theirdstoffset;
@@ -1212,7 +1192,7 @@
static void
tzset_locked(void)
{
- register const char * name = NULL;
+ register const char * name = NULL;
name = getenv("TZ");
@@ -1281,10 +1261,10 @@
localsub(const time_t * const timep, const int_fast32_t offset,
struct tm * const tmp, const struct state * sp) // android-changed: added sp.
{
- register const struct ttinfo * ttisp;
- register int i;
- register struct tm * result;
- const time_t t = *timep;
+ register const struct ttinfo * ttisp;
+ register int i;
+ register struct tm * result;
+ const time_t t = *timep;
// BEGIN android-changed: support user-supplied sp.
if (sp == NULL) {
@@ -1298,8 +1278,8 @@
if ((sp->goback && t < sp->ats[0]) ||
(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
time_t newt = t;
- register time_t seconds;
- register time_t years;
+ register time_t seconds;
+ register time_t years;
if (t < sp->ats[0])
seconds = sp->ats[0] - t;
@@ -1330,8 +1310,8 @@
if (sp->timecnt == 0 || t < sp->ats[0]) {
i = sp->defaulttype;
} else {
- register int lo = 1;
- register int hi = sp->timecnt;
+ register int lo = 1;
+ register int hi = sp->timecnt;
while (lo < hi) {
register int mid = (lo + hi) >> 1;
@@ -1371,7 +1351,7 @@
struct tm *
localtime_r(const time_t * const timep, struct tm * tmp)
{
- struct tm* result;
+ struct tm* result;
_tzLock();
tzset_locked();
@@ -1389,7 +1369,7 @@
gmtsub(const time_t * const timep, const int_fast32_t offset,
struct tm *const tmp, const struct state * sp) // android-changed: added sp.
{
- register struct tm * result;
+ register struct tm * result;
(void) sp; // android-added: unused.
@@ -1437,7 +1417,7 @@
struct tm *
gmtime_r(const time_t * const timep, struct tm * tmp)
{
- struct tm* result;
+ struct tm* result;
_tzLock();
result = gmtsub(timep, 0L, tmp, NULL); // android-changed: extra parameter.
@@ -1463,15 +1443,15 @@
register const struct state *const sp,
register struct tm *const tmp)
{
- register const struct lsinfo * lp;
- register time_t tdays;
- register int idays; /* unsigned would be so 2003 */
- register int_fast64_t rem;
- int y;
- register const int * ip;
- register int_fast64_t corr;
- register int hit;
- register int i;
+ register const struct lsinfo * lp;
+ register time_t tdays;
+ register int idays; /* unsigned would be so 2003 */
+ register int_fast64_t rem;
+ int y;
+ register const int * ip;
+ register int_fast64_t corr;
+ register int hit;
+ register int i;
corr = 0;
hit = 0;
@@ -1631,61 +1611,77 @@
static int
increment_overflow(int *const ip, int j)
{
- register int const i = *ip;
+ register int const i = *ip;
- /*
- ** If i >= 0 there can only be overflow if i + j > INT_MAX
- ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
- ** If i < 0 there can only be overflow if i + j < INT_MIN
- ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
- */
- if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
- return TRUE;
- *ip += j;
- return FALSE;
+ /*
+ ** If i >= 0 there can only be overflow if i + j > INT_MAX
+ ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
+ ** If i < 0 there can only be overflow if i + j < INT_MIN
+ ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
+ */
+ if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
+ return TRUE;
+ *ip += j;
+ return FALSE;
}
static int
increment_overflow32(int_fast32_t *const lp, int const m)
{
- register int_fast32_t const l = *lp;
+ register int_fast32_t const l = *lp;
- if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
- return TRUE;
- *lp += m;
- return FALSE;
+ if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
+ return TRUE;
+ *lp += m;
+ return FALSE;
+}
+
+static int
+increment_overflow_time(time_t *tp, int_fast32_t j)
+{
+ /*
+ ** This is like
+ ** 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
+ ** except that it does the right thing even if *tp + j would overflow.
+ */
+ if (! (j < 0
+ ? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
+ : *tp <= time_t_max - j))
+ return TRUE;
+ *tp += j;
+ return FALSE;
}
static int
normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
{
- register int tensdelta;
+ register int tensdelta;
- tensdelta = (*unitsptr >= 0) ?
- (*unitsptr / base) :
- (-1 - (-1 - *unitsptr) / base);
- *unitsptr -= tensdelta * base;
- return increment_overflow(tensptr, tensdelta);
+ tensdelta = (*unitsptr >= 0) ?
+ (*unitsptr / base) :
+ (-1 - (-1 - *unitsptr) / base);
+ *unitsptr -= tensdelta * base;
+ return increment_overflow(tensptr, tensdelta);
}
static int
normalize_overflow32(int_fast32_t *const tensptr, int *const unitsptr,
- const int base)
+ const int base)
{
- register int tensdelta;
+ register int tensdelta;
- tensdelta = (*unitsptr >= 0) ?
- (*unitsptr / base) :
- (-1 - (-1 - *unitsptr) / base);
- *unitsptr -= tensdelta * base;
- return increment_overflow32(tensptr, tensdelta);
+ tensdelta = (*unitsptr >= 0) ?
+ (*unitsptr / base) :
+ (-1 - (-1 - *unitsptr) / base);
+ *unitsptr -= tensdelta * base;
+ return increment_overflow32(tensptr, tensdelta);
}
static int
tmcomp(register const struct tm * const atmp,
register const struct tm * const btmp)
{
- register int result;
+ register int result;
if (atmp->tm_year != btmp->tm_year)
return atmp->tm_year < btmp->tm_year ? -1 : 1;
@@ -1704,16 +1700,16 @@
int * const okayp,
const int do_norm_secs, const struct state * sp) // android-changed: added sp
{
- register int dir;
- register int i, j;
- register int saved_seconds;
- register int_fast32_t li;
- register time_t lo;
- register time_t hi;
- int_fast32_t y;
- time_t newt;
- time_t t;
- struct tm yourtm, mytm;
+ register int dir;
+ register int i, j;
+ register int saved_seconds;
+ register int_fast32_t li;
+ register time_t lo;
+ register time_t hi;
+ int_fast32_t y;
+ time_t newt;
+ time_t t;
+ struct tm yourtm, mytm;
*okayp = FALSE;
yourtm = *tmp;
@@ -1884,7 +1880,7 @@
const int_fast32_t offset,
int *const okayp, const struct state* sp) // android-changed: added sp.
{
- time_t t;
+ time_t t;
/*
** First try without normalization of seconds
@@ -1900,11 +1896,11 @@
struct tm * (* const funcp) (const time_t *, int_fast32_t, struct tm *, const struct state *), // android-changed: added sp.
const int_fast32_t offset, const struct state * sp) // android-changed: added sp.
{
- register time_t t;
- register int samei, otheri;
- register int sameind, otherind;
- register int i;
- register int nseen;
+ register time_t t;
+ register int samei, otheri;
+ register int sameind, otherind;
+ register int i;
+ register int nseen;
int seen[TZ_MAX_TYPES];
int types[TZ_MAX_TYPES];
int okay;
@@ -1997,7 +1993,7 @@
time_t
timegm(struct tm * const tmp)
{
- time_t result;
+ time_t result;
if (tmp != NULL)
tmp->tm_isdst = 0;
@@ -2020,7 +2016,7 @@
long
gtime(struct tm * const tmp)
{
- const time_t t = mktime(tmp);
+ const time_t t = mktime(tmp);
if (t == WRONG)
return -1;
@@ -2046,9 +2042,9 @@
static int_fast64_t
leapcorr(time_t * timep)
{
- register struct state * sp;
- register struct lsinfo * lp;
- register int i;
+ register struct state * sp;
+ register struct lsinfo * lp;
+ register int i;
sp = lclptr;
i = sp->leapcnt;
@@ -2070,8 +2066,8 @@
time_t
posix2time(time_t t)
{
- time_t x;
- time_t y;
+ time_t x;
+ time_t y;
tzset();
/*
@@ -2168,26 +2164,40 @@
}
off_t specific_zone_offset = -1;
+ ssize_t index_size = ntohl(header.data_offset) - ntohl(header.index_offset);
+ char* index = malloc(index_size);
+ if (TEMP_FAILURE_RETRY(read(fd, index, index_size)) != index_size) {
+ fprintf(stderr, "%s: could not read index of \"%s\": %s\n",
+ __FUNCTION__, path, (bytes_read == -1) ? strerror(errno) : "short read");
+ free(index);
+ close(fd);
+ return -1;
+ }
static const size_t NAME_LENGTH = 40;
- unsigned char buf[NAME_LENGTH + 3 * sizeof(int32_t)];
+ struct index_entry_t {
+ char buf[NAME_LENGTH];
+ int32_t start;
+ int32_t length;
+ int32_t raw_gmt_offset;
+ };
- size_t id_count = (ntohl(header.data_offset) - ntohl(header.index_offset)) / sizeof(buf);
+ size_t id_count = (ntohl(header.data_offset) - ntohl(header.index_offset)) / sizeof(struct index_entry_t);
+ struct index_entry_t* entry = (struct index_entry_t*) index;
for (size_t i = 0; i < id_count; ++i) {
- if (TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf))) != (ssize_t) sizeof(buf)) {
- break;
- }
-
char this_id[NAME_LENGTH + 1];
- memcpy(this_id, buf, NAME_LENGTH);
+ memcpy(this_id, entry->buf, NAME_LENGTH);
this_id[NAME_LENGTH] = '\0';
if (strcmp(this_id, olson_id) == 0) {
- specific_zone_offset = to_int(buf + NAME_LENGTH) + ntohl(header.data_offset);
- *data_size = to_int(buf + NAME_LENGTH + sizeof(int32_t));
+ specific_zone_offset = ntohl(entry->start) + ntohl(header.data_offset);
+ *data_size = ntohl(entry->length);
break;
}
+
+ ++entry;
}
+ free(index);
if (specific_zone_offset == -1) {
XLOG(("%s: couldn't find zone \"%s\"\n", __FUNCTION__, olson_id));
diff --git a/libc/tzcode/private.h b/libc/tzcode/private.h
index 3a19305..4eb0ab6 100644
--- a/libc/tzcode/private.h
+++ b/libc/tzcode/private.h
@@ -34,6 +34,10 @@
#define HAVE_INCOMPATIBLE_CTIME_R 0
#endif /* !defined INCOMPATIBLE_CTIME_R */
+#ifndef HAVE_LINK
+#define HAVE_LINK 1
+#endif /* !defined HAVE_LINK */
+
#ifndef HAVE_SETTIMEOFDAY
#define HAVE_SETTIMEOFDAY 3
#endif /* !defined HAVE_SETTIMEOFDAY */
diff --git a/libc/tzcode/tzfile.h b/libc/tzcode/tzfile.h
index a2955dd..529650d 100644
--- a/libc/tzcode/tzfile.h
+++ b/libc/tzcode/tzfile.h
@@ -101,16 +101,8 @@
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
-#ifndef NOSOLAR
+/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
-#endif /* !defined NOSOLAR */
-#ifdef NOSOLAR
-/*
-** Must be at least 14 for Europe/Riga as of Jan 12 1995,
-** as noted by Earl Chew.
-*/
-#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
-#endif /* !defined NOSOLAR */
#endif /* !defined TZ_MAX_TYPES */
#ifndef TZ_MAX_CHARS
diff --git a/libc/upstream-openbsd/lib/libc/gen/getprogname.c b/libc/upstream-openbsd/lib/libc/gen/getprogname.c
new file mode 100644
index 0000000..1cf498c88
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/gen/getprogname.c
@@ -0,0 +1,24 @@
+/* $OpenBSD: getprogname.c,v 1.2 2013/05/31 21:19:01 tedu Exp $ */
+/*
+ * Copyright (c) 2013 Antoine Jacoutot <ajacoutot@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+extern const char *__progname;
+
+const char *
+getprogname(void)
+{
+ return (__progname);
+}
diff --git a/libc/upstream-openbsd/lib/libc/gen/setprogname.c b/libc/upstream-openbsd/lib/libc/gen/setprogname.c
new file mode 100644
index 0000000..18b2ce0
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/gen/setprogname.c
@@ -0,0 +1,32 @@
+/* $OpenBSD: setprogname.c,v 1.3 2013/06/01 01:43:43 tedu Exp $ */
+/*
+ * Copyright (c) 2013 Antoine Jacoutot <ajacoutot@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+
+extern const char *__progname;
+
+void
+setprogname(const char *progname)
+{
+ const char *tmpn;
+
+ tmpn = strrchr(progname, '/');
+ if (tmpn == NULL)
+ __progname = progname;
+ else
+ __progname = tmpn + 1;
+}
diff --git a/libm/amd64/fenv.c b/libm/amd64/fenv.c
index b2c017b..b058de2 100755
--- a/libm/amd64/fenv.c
+++ b/libm/amd64/fenv.c
@@ -42,7 +42,7 @@
* x87 fpu registers are 16bit wide. The upper bits, 31-16, are marked as
* RESERVED.
*/
-fenv_t __fe_dfl_env = {
+const fenv_t __fe_dfl_env = {
{
0xffff0000 | __INITIAL_NPXCW__, /* Control word register */
0xffff0000, /* Status word register */
diff --git a/libm/include/amd64/machine/fenv.h b/libm/include/amd64/machine/fenv.h
index f22a931..79a4120 100644
--- a/libm/include/amd64/machine/fenv.h
+++ b/libm/include/amd64/machine/fenv.h
@@ -97,7 +97,7 @@
* A floating-point control mode is a system variable whose value may be set by
* the user to affect the subsequent behavior of floating-point arithmetic.
*/
-typedef __uint_32 fexcept_t;
+typedef __uint32_t fexcept_t;
__END_DECLS