diff --git a/ksh.spec b/ksh.spec index cafae45..c02e520 100644 --- a/ksh.spec +++ b/ksh.spec @@ -1,7 +1,7 @@ # # spec file for package ksh # -# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed diff --git a/ksh93-dttree-crash.dif b/ksh93-dttree-crash.dif index 7bb8c52..9372bce 100644 --- a/ksh93-dttree-crash.dif +++ b/ksh93-dttree-crash.dif @@ -1,11 +1,505 @@ ---- src/lib/libast/include/cdt.h -+++ src/lib/libast/include/cdt.h 2012-12-20 11:37:28.641452879 +0000 -@@ -313,7 +313,7 @@ _END_EXTERNS_ - #define _DTCMP(dt,k1,k2,dc) \ - ((dc)->comparf ? (*(dc)->comparf)((dt), (k1), (k2), (dc)) : \ - (dc)->size > 0 ? memcmp((Void_t*)(k1), ((Void_t*)k2), (dc)->size) : \ -- strcmp((char*)(k1), ((char*)k2)) ) -+ strcmp((char*)(k1), ((char*)(k2 ? k2 : ""))) ) +--- src/lib/libast/cdt/dtcomp.c 2011-10-24 20:23:26.000000000 +0000 ++++ src/lib/libast/cdt/dtcomp.c 2012-12-20 10:29:45.005452948 +0000 +@@ -52,9 +52,3 @@ extern ssize_t dtsize(Dt_t* d) + { + return (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_STAT); + } +- +-#undef dtstat +-extern ssize_t dtstat(Dt_t* d) +-{ +- return (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_STAT); +-} +--- src/lib/libast/cdt/dtdisc.c 2011-10-04 20:58:38.000000000 +0000 ++++ src/lib/libast/cdt/dtdisc.c 2012-12-20 10:29:45.013452595 +0000 +@@ -57,7 +57,6 @@ Dtdisc_t* disc; + int type; + #endif + { +- Dtsearch_f searchf; + Dtdisc_t *old; + Dtlink_t *list; - #define _DTHSH(dt,ky,dc) ((dc)->hashf ? (*(dc)->hashf)((dt), (ky), (dc)) : \ - dtstrhash(0, (ky), (dc)->size) ) +@@ -71,8 +70,6 @@ int type; + if(!disc) /* only want to know current discipline */ + return old; + +- searchf = dt->meth->searchf; +- + if(old->eventf && (*old->eventf)(dt,DT_DISC,(Void_t*)disc,old) < 0) + return NIL(Dtdisc_t*); + +--- src/lib/libast/cdt/dthash.c 2011-12-16 05:06:27.000000000 +0000 ++++ src/lib/libast/cdt/dthash.c 2012-12-20 10:29:45.013452595 +0000 +@@ -52,11 +52,13 @@ static int htable(Dt_t* dt) + if((n = hash->tblz) > 0 && (hash->type&H_FIXED) ) + return 0; /* fixed size table */ + +- if(n == 0 && disc && disc->eventf) /* let user have input */ ++ if(disc && disc->eventf) /* let user have input */ + { if((*disc->eventf)(dt, DT_HASHSIZE, &n, disc) > 0 ) + { if(n < 0) /* fix table size */ + { hash->type |= H_FIXED; +- n = -n; ++ n = -n; /* desired table size */ ++ if(hash->tblz >= n ) /* table size is fixed now */ ++ return 0; + } + } + } +@@ -234,12 +236,13 @@ static Void_t* hstat(Dt_t* dt, Dtstat_t* + + for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t) + { for(n = 0, l = *t; l; l = l->_rght) ++ { if(n < DT_MAXSIZE) ++ st->lsize[n] += 1; + n += 1; ++ } + st->mlev = n > st->mlev ? n : st->mlev; + if(n < DT_MAXSIZE) /* if chain length is small */ +- { st->msize = n > st->msize ? n : st->msize; +- st->lsize[n] += n; +- } ++ st->msize = n > st->msize ? n : st->msize; + } + } + +@@ -310,7 +313,7 @@ int type; + hsh = _DTHSH(dt,key,disc); + + tbl = hash->htbl + (hsh & (hash->tblz-1)); +- pp = ll = NIL(Dtlink_t*); ++ pp = ll = NIL(Dtlink_t*); /* pp is the before, ll is the here */ + for(p = NIL(Dtlink_t*), l = *tbl; l; p = l, l = l->_rght) + { if(hsh == l->_hash) + { o = _DTOBJ(disc,l); k = _DTKEY(disc,o); +@@ -342,20 +345,41 @@ int type; + _dtfree(dt, ll, type); + DTRETURN(obj, _DTOBJ(disc,ll)); + } ++ else if(type & DT_INSTALL ) ++ { if(dt->meth->type&DT_BAG) ++ goto do_insert; ++ else if(!(lnk = _dtmake(dt, obj, type)) ) ++ DTRETURN(obj, NIL(Void_t*) ); ++ else /* replace old object with new one */ ++ { if(pp) /* remove old object */ ++ pp->_rght = ll->_rght; ++ else *tbl = ll->_rght; ++ o = _DTOBJ(disc,ll); ++ _dtfree(dt, ll, DT_DELETE); ++ DTANNOUNCE(dt, o, DT_DELETE); ++ ++ goto do_insert; ++ } ++ } + else + { /**/DEBUG_ASSERT(type&(DT_INSERT|DT_ATTACH|DT_APPEND|DT_RELINK)); +- if(!(dt->meth->type&DT_BAG) ) ++ if((dt->meth->type&DT_BAG) ) ++ goto do_insert; ++ else + { if(type&(DT_INSERT|DT_APPEND|DT_ATTACH) ) +- type |= DT_SEARCH; /* for announcement */ ++ type |= DT_MATCH; /* for announcement */ + else if(lnk && (type&DT_RELINK) ) ++ { /* remove a duplicate */ ++ o = _DTOBJ(disc, lnk); + _dtfree(dt, lnk, DT_DELETE); ++ DTANNOUNCE(dt, o, DT_DELETE); ++ } + DTRETURN(obj, _DTOBJ(disc,ll)); + } +- else goto do_insert; + } + } + else /* no matching object */ +- { if(!(type&(DT_INSERT|DT_APPEND|DT_ATTACH|DT_RELINK)) ) ++ { if(!(type&(DT_INSERT|DT_INSTALL|DT_APPEND|DT_ATTACH|DT_RELINK)) ) + DTRETURN(obj, NIL(Void_t*)); + + do_insert: /* inserting a new object */ +--- src/lib/libast/cdt/dtlist.c 2011-11-08 19:37:25.000000000 +0000 ++++ src/lib/libast/cdt/dtlist.c 2012-12-20 10:29:45.013452595 +0000 +@@ -142,9 +142,9 @@ int type; + } + + #if __STD_C +-static Void_t* liststat(Dt_t* dt, Dtstat_t* st) ++static Void_t* listat(Dt_t* dt, Dtstat_t* st) + #else +-static Void_t* liststat(dt, st) ++static Void_t* listat(dt, st) + Dt_t* dt; + Dtstat_t* st; + #endif +@@ -190,7 +190,7 @@ int type; + else if(type&DT_CLEAR) + DTRETURN(obj, lclear(dt)); + else if(type&DT_STAT ) +- DTRETURN(obj, liststat(dt, (Dtstat_t*)obj)); ++ DTRETURN(obj, listat(dt, (Dtstat_t*)obj)); + + h = list->here; /* save finger to last search object */ + list->here = NIL(Dtlink_t*); +@@ -206,8 +206,9 @@ int type; + { r = (Dtlink_t*)obj; + goto do_insert; + } +- else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH)) +- { if(!(r = _dtmake(dt, obj, type)) ) ++ else if(type&(DT_INSERT|DT_INSTALL|DT_APPEND|DT_ATTACH)) ++ { dt_insert: ++ if(!(r = _dtmake(dt, obj, type)) ) + DTRETURN(obj, NIL(Void_t*)); + dt->data->size += 1; + +@@ -294,7 +295,7 @@ int type; + } + r = h ? h : r; + } +- if(!r) ++ if(!r) /* not found */ + DTRETURN(obj, NIL(Void_t*)); + + if(type&(DT_DELETE|DT_DETACH|DT_REMOVE)) +--- src/lib/libast/cdt/dtopen.c 2012-01-19 09:47:26.000000000 +0000 ++++ src/lib/libast/cdt/dtopen.c 2012-12-20 10:29:45.021452290 +0000 +@@ -153,25 +153,3 @@ void _dtfree(Dt_t* dt, Dtlink_t* l, int + if(disc->link < 0) /* free holder */ + (void)(*dt->memoryf)(dt, (Void_t*)l, 0, disc); + } +- +-int dtuserlock(Dt_t* dt, unsigned int key, int type) +-{ +- if(type > 0) +- return asolock(&dt->data->user.lock, key, ASO_LOCK); +- else if(type < 0) +- return asolock(&dt->data->user.lock, key, ASO_UNLOCK); +- else return asolock(&dt->data->user.lock, key, ASO_TRYLOCK); +-} +- +-Void_t* dtuserdata(Dt_t* dt, Void_t* data, unsigned int key) +-{ +- if(key == 0) +- return dt->data->user.data; +- else if(dtuserlock(dt, key, 1) < 0 ) +- return NIL(Void_t*); +- else +- { dt->data->user.data = data; +- dtuserlock(dt, key, -1); +- return data; +- } +-} +--- src/lib/libast/cdt/dtstat.c 1970-01-01 00:00:00.000000000 +0000 ++++ src/lib/libast/cdt/dtstat.c 2012-12-20 10:29:45.021452290 +0000 +@@ -0,0 +1,54 @@ ++/*********************************************************************** ++* * ++* This software is part of the ast package * ++* Copyright (c) 1985-2012 AT&T Intellectual Property * ++* and is licensed under the * ++* Eclipse Public License, Version 1.0 * ++* by AT&T Intellectual Property * ++* * ++* A copy of the License is available at * ++* http://www.eclipse.org/org/documents/epl-v10.html * ++* (with md5 checksum b35adb5213ca9657e911e9befb180842) * ++* * ++* Information and Software Systems Research * ++* AT&T Research * ++* Florham Park NJ * ++* * ++* Glenn Fowler * ++* David Korn * ++* Phong Vo * ++* * ++***********************************************************************/ ++#include "dthdr.h" ++ ++/* Get statistics for a dictionary ++** ++** Written by Kiem-Phong Vo ++*/ ++ ++ssize_t dtstat(Dt_t* dt, Dtstat_t* dtst) ++{ ++ ssize_t sz, k, maxk; ++ char *str; ++ char *end; ++ ++ sz = (ssize_t)(*dt->meth->searchf)(dt, (Void_t*)dtst, DT_STAT); ++ ++ str = dtst->mesg; ++ end = &dtst->mesg[sizeof(dtst->mesg)] - 1; ++ str += sfsprintf(str, end - str, "Objects=%d Levels=%d(Largest:", dtst->size, dtst->mlev+1); ++ ++ /* print top 3 levels */ ++ for(k = maxk = 0; k <= dtst->mlev; ++k) ++ if(dtst->lsize[k] > dtst->lsize[maxk]) ++ maxk = k; ++ if(maxk > 0) ++ maxk -= 1; ++ for(k = 0; k < 3 && maxk <= dtst->mlev; ++k, ++maxk) ++ str += sfsprintf(str, end - str, " lev[%d]=%d", maxk, dtst->lsize[maxk] ); ++ if (str < end) ++ *str++ = ')'; ++ *str = 0; ++ ++ return sz; ++} +--- src/lib/libast/cdt/dtstrhash.c 2011-09-28 03:43:49.000000000 +0000 ++++ src/lib/libast/cdt/dtstrhash.c 2012-12-20 10:29:45.021452290 +0000 +@@ -22,40 +22,38 @@ + #include "dthdr.h" + + /* Hashing a string into an unsigned integer. +-** The basic method is to continuingly accumulate bytes and multiply +-** with some given prime. The length n of the string is added last. +-** The recurrent equation is like this: +-** h[k] = (h[k-1] + bytes)*prime for 0 <= k < n +-** h[n] = (h[n-1] + n)*prime +-** The prime is chosen to have a good distribution of 1-bits so that +-** the multiplication will distribute the bits in the accumulator well. +-** The below code accumulates 2 bytes at a time for speed. +-** +-** Written by Kiem-Phong Vo (02/28/03) ++** This is the FNV (Fowler-Noll-Vo) hash function. ++** Written by Kiem-Phong Vo (01/10/2012) + */ + + #if __STD_C + uint dtstrhash(uint h, Void_t* args, ssize_t n) + #else + uint dtstrhash(h,args,n) +-reg uint h; ++uint h; + Void_t* args; + ssize_t n; + #endif + { + unsigned char *s = (unsigned char*)args; + +- if(n <= 0) +- { for(; *s != 0; s += s[1] ? 2 : 1) +- h = (h + (s[0]<<8) + s[1])*DT_PRIME; +- n = s - (unsigned char*)args; ++#if _ast_sizeof_int == 8 /* 64-bit hash */ ++#define FNV_PRIME ((1<<40) + (1<<8) + 0xb3) ++#define FNV_OFFSET 14695981039346656037 ++#else /* 32-bit hash */ ++#define FNV_PRIME ((1<<24) + (1<<8) + 0x93) ++#define FNV_OFFSET 2166136261 ++#endif ++ h = (h == 0 || h == ~0) ? FNV_OFFSET : h; ++ if(n <= 0) /* see discipline key definition for == 0 */ ++ { for(; *s != 0; ++s ) ++ h = (h ^ s[0]) * FNV_PRIME; + } + else + { unsigned char* ends; +- for(ends = s+n-1; s < ends; s += 2) +- h = (h + (s[0]<<8) + s[1])*DT_PRIME; +- if(s <= ends) +- h = (h + (s[0]<<8))*DT_PRIME; ++ for(ends = s+n; s < ends; ++s) ++ h = (h ^ s[0]) * FNV_PRIME; + } +- return (h+n)*DT_PRIME; ++ ++ return h; + } +--- src/lib/libast/cdt/dttree.c 2011-12-16 05:06:36.000000000 +0000 ++++ src/lib/libast/cdt/dttree.c 2012-12-20 10:29:45.029525330 +0000 +@@ -545,7 +545,14 @@ int type; + } + else goto no_root; + } +- else if(type&DT_REMOVE) /* remove a particular element in the tree */ ++ else if(type&(DT_DELETE|DT_DETACH)) ++ { dt_delete: /* remove an object from the dictionary */ ++ obj = _DTOBJ(disc,root); ++ _dtfree(dt, root, type); ++ dt->data->size -= 1; ++ goto no_root; ++ } ++ else if(type&DT_REMOVE) /* remove a particular object */ + { if(_DTOBJ(disc,root) == obj) + goto dt_delete; + else +@@ -555,28 +562,32 @@ int type; + DTRETURN(obj, NIL(Void_t*)); + } + } +- else if(type&(DT_DELETE|DT_DETACH)) +- { dt_delete: /* remove an object from the dictionary */ +- obj = _DTOBJ(disc,root); +- _dtfree(dt, root, type); +- dt->data->size -= 1; +- goto no_root; +- } + else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH)) + { if(dt->meth->type&DT_OSET) +- { type |= DT_SEARCH; /* for announcement */ ++ { type |= DT_MATCH; /* for announcement */ + goto has_root; + } +- else ++ else /* if(dt->meth->type&DT_OBAG) */ + { root->_left = NIL(Dtlink_t*); + root->_rght = link._left; + link._left = root; + goto dt_insert; + } + } ++ else if(type&DT_INSTALL) ++ { /* remove old object before insert new one */ ++ o = _DTOBJ(disc, root); ++ _dtfree(dt, root, DT_DELETE); ++ DTANNOUNCE(dt, o, DT_DELETE); ++ goto dt_insert; ++ } + else if(type&DT_RELINK) /* a duplicate */ + { if(dt->meth->type&DT_OSET) ++ { /* remove object */ ++ o = _DTOBJ(disc, me); + _dtfree(dt, me, DT_DELETE); ++ DTANNOUNCE(dt, o, DT_DELETE); ++ } + else + { me->_left = NIL(Dtlink_t*); + me->_rght = link._left; +@@ -612,7 +623,7 @@ int type; + { obj = NIL(Void_t*); + goto no_root; + } +- else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH)) ++ else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH|DT_INSTALL)) + { dt_insert: + if(!(root = _dtmake(dt, obj, type)) ) + { obj = NIL(Void_t*); +@@ -638,8 +649,6 @@ dt_return: + + static int treeevent(Dt_t* dt, int event, Void_t* arg) + { +- Dtlink_t *l, *list; +- ssize_t size; + Dttree_t *tree = (Dttree_t*)dt->data; + + if(event == DT_OPEN) +--- src/lib/libast/cdt/dtuser.c 1970-01-01 00:00:00.000000000 +0000 ++++ src/lib/libast/cdt/dtuser.c 2012-12-20 10:29:45.029525330 +0000 +@@ -0,0 +1,59 @@ ++/*********************************************************************** ++* * ++* This software is part of the ast package * ++* Copyright (c) 1985-2012 AT&T Intellectual Property * ++* and is licensed under the * ++* Eclipse Public License, Version 1.0 * ++* by AT&T Intellectual Property * ++* * ++* A copy of the License is available at * ++* http://www.eclipse.org/org/documents/epl-v10.html * ++* (with md5 checksum b35adb5213ca9657e911e9befb180842) * ++* * ++* Information and Software Systems Research * ++* AT&T Research * ++* Florham Park NJ * ++* * ++* Glenn Fowler * ++* David Korn * ++* Phong Vo * ++* * ++***********************************************************************/ ++#include "dthdr.h" ++ ++/* Perform various functions on the user's behalf. ++** ++** Written by Kiem-Phong Vo (01/05/2012) ++*/ ++ ++/* managing the lock dt->data->user.lock */ ++int dtuserlock(Dt_t* dt, unsigned int key, int type) ++{ ++ if(key == 0) ++ return -1; ++ else if(type > 0) ++ return asolock(&dt->data->user.lock, key, ASO_LOCK); ++ else if(type < 0) ++ return asolock(&dt->data->user.lock, key, ASO_UNLOCK); ++ else return asolock(&dt->data->user.lock, key, ASO_TRYLOCK); ++} ++ ++/* managing the user data slot dt->data->user.data */ ++Void_t* dtuserdata(Dt_t* dt, Void_t* data, int set) ++{ ++ if(set == 0) /* just return current value */ ++ return asogetptr(&dt->data->user.data); ++ else while(1) ++ { Void_t *current = dt->data->user.data; ++ if(asocasptr(&dt->data->user.data, current, data) == current) ++ return current; ++ } ++} ++ ++/* announcing an event on the user's behalf */ ++int dtuserevent(Dt_t* dt, int flags, Void_t* data) ++{ ++ if(!dt->disc->eventf) ++ return 0; ++ else return (*dt->disc->eventf)(dt, DT_ANNOUNCE|DT_USER|flags, data, dt->disc); ++} +--- src/lib/libast/include/cdt.h 2012-12-20 11:37:28.641452879 +0000 ++++ src/lib/libast/include/cdt.h 2012-12-20 10:29:45.129453247 +0000 +@@ -164,6 +164,7 @@ struct _dtstat_s + ssize_t msize; /* max #defined elts in below arrays */ + ssize_t lsize[DT_MAXSIZE]; /* #objects by level */ + ssize_t tsize[DT_MAXSIZE]; /* #tables by level */ ++ char mesg[256]; /* digest of top level statistics */ + }; + + /* supported storage methods */ +@@ -199,7 +200,8 @@ struct _dtstat_s + #define DT_ATLEAST 0000040000 /* find the least elt >= object */ + #define DT_ATMOST 0000100000 /* find the biggest elt <= object */ + #define DT_REMOVE 0002000000 /* remove a specific object */ +-#define DT_TOANNOUNCE (DT_INSERT|DT_DELETE|DT_SEARCH|DT_NEXT|DT_PREV|DT_FIRST|DT_LAST|DT_MATCH|DT_ATTACH|DT_DETACH|DT_APPEND|DT_ATLEAST|DT_ATMOST|DT_REMOVE) ++#define DT_INSTALL 0004000000 /* install a new object */ ++#define DT_TOANNOUNCE (DT_INSERT|DT_DELETE|DT_SEARCH|DT_NEXT|DT_PREV|DT_FIRST|DT_LAST|DT_MATCH|DT_ATTACH|DT_DETACH|DT_APPEND|DT_ATLEAST|DT_ATMOST|DT_REMOVE|DT_INSTALL) + + #define DT_RELINK 0000002000 /* re-inserting (dtdisc,dtmethod...) */ + #define DT_FLATTEN 0000000040 /* flatten objects into a list */ +@@ -216,6 +218,7 @@ struct _dtstat_s + /* the actual event will be this bit */ + /* combined with the operation bit */ + #define DT_OPTIMIZE 0100000000 /* optimizing data structure */ ++#define DT_USER 0200000000 /* an announcement on user's behalf */ + + /* events for discipline and method event-handling functions */ + #define DT_OPEN 1 /* a dictionary is being opened */ +@@ -277,7 +280,8 @@ extern int dtwalk _ARG_((Dt_t*, int(*)( + extern int dtcustomize _ARG_((Dt_t*, int, int)); + extern unsigned int dtstrhash _ARG_((unsigned int, Void_t*, ssize_t)); + extern int dtuserlock _ARG_((Dt_t*, unsigned int, int)); +-extern Void_t* dtuserdata _ARG_((Dt_t*, Void_t*, unsigned int)); ++extern Void_t* dtuserdata _ARG_((Dt_t*, Void_t*, int)); ++extern int dtuserevent _ARG_((Dt_t*, int, Void_t*)); + + /* deal with upward binary compatibility (operation bit translation, etc.) */ + extern Dt_t* _dtopen _ARG_((Dtdisc_t*, Dtmethod_t*, unsigned long)); +@@ -334,6 +338,7 @@ _END_EXTERNS_ + #define dtsearch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_SEARCH) + #define dtmatch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_MATCH) + #define dtinsert(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_INSERT) ++#define dtinstall(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_INSTALL) + #define dtappend(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_APPEND) + #define dtdelete(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_DELETE) + #define dtremove(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_REMOVE) +@@ -345,7 +350,6 @@ _END_EXTERNS_ + #define dtextract(d) (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_EXTRACT) + #define dtrestore(d,l) (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(l),DT_RESTORE) + +-#define dtstat(d,s) (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(s),DT_STAT) + #define dtsize(d) (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_STAT) + + #define DT_PRIME 17109811 /* 2#00000001 00000101 00010011 00110011 */