? 64bit_keyt.patch Index: winsup/cygwin/cygwin.din =================================================================== RCS file: /cvs/src/src/winsup/cygwin/cygwin.din,v retrieving revision 1.87 diff -u -r1.87 cygwin.din --- winsup/cygwin/cygwin.din 9 May 2003 22:11:25 -0000 1.87 +++ winsup/cygwin/cygwin.din 14 May 2003 06:21:37 -0000 @@ -508,6 +508,8 @@ _ftello64 = ftello64 ftime _ftime = ftime +ftok +_ftok = ftok ftruncate _ftruncate = ftruncate _ftruncate64 = ftruncate64 Index: winsup/cygwin/ipc.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/ipc.cc,v retrieving revision 1.8 diff -u -r1.8 ipc.cc --- winsup/cygwin/ipc.cc 12 May 2003 11:06:26 -0000 1.8 +++ winsup/cygwin/ipc.cc 14 May 2003 06:21:38 -0000 @@ -17,23 +17,116 @@ extern "C" { +/* + * we don't do 'fat' 64-32 bit here, because ftok has not as + * yet been an official part of cygwin -- so there's no need + * to allow for 'old' binaries. However, we provide the old + * implementation here as well, ifdef'ed out. + */ +#ifdef __CYGWIN_USE_BIG_TYPES__ + /* Notes: we return a valid key even if id's low order 8 bits are 0. */ key_t ftok (const char *path, int id) { struct __stat64 statbuf; + key_t tmp; if (stat64 (path, &statbuf)) { /* stat set the appropriate errno for us */ return (key_t) -1; } - /* dev_t is short for cygwin - * ino_t is long for cygwin + /* + * When __CYGWIN_USE_BIG_TYPES__, + * dev_t is 32bits for cygwin + * ino_t is 64bits for cygwin * and we need 8 bits for the id. - * thus key_t is long long. + * thus key_t needs 104 bits total -- but we only have 64 (long long) + * We will have to alias; leaving open the possibility that the same + * key will be returned for multiple files. This possibility exists + * also on Linux; the question is, how to minimize this possibility. + * + * How to solve? Well, based on C. Vinshen's research, the nFileIndex* + * words vary as follows, on a partition with > 110,000 files + * nFileIndexHigh: 564 values between 0x00010000 -- 0xffff0000 + * nFileIndexLow : 103812 values between 0x00000000 -- 0x0003ffff + * R. Collins suggests that these may represent a tree path, + * and that it would require ~2.9M files to force the tree depth + * to increase and reveal more bit usage. + * + * Implementation details: dev_t is 32bits, but is formed by + * device(32bits) << 16 | unit(32bits) + * But device is ACTUALLY == status & FH_DEVMASK, where FH_DEVMASK + * is 0x00000fff --> 12 bits + * + * As it happens, the maximum number of devices is actually + * FH_NDEV, not FH_DEVMASK, where FH_NDEV is currently 0x0000001d. + * However, FH_NDEV grows as new device types are added. So + * currently the device number needs 5 bits, but later? Let's + * take a cue from Linux, and use the lower 8 bits (instead of the + * lower 12 or 16) for the device (major?) number. + * + * Similarly, while 'units' is an int (32bits), it is unclear + * how many of these are significant. For most devices, it seems that + * 'units' is equivalent to 'minor'. For FH_TAPE, it's obvious that + * only 8 bits are important. However, for FH_SOCKET...it might be + * as high as 16 significant bits. + * + * Let's assume that we only need 8 bits from device (major) and + * only 8 bits from unit (minor). (On linux, only 8 bits of minor + * are used, and none from major). + * ---> so, we only need 0x00ff00ff (16 bits) of dev_t + * + * ---> we MUST have all 8 bits of id. + * + * ---> So, we only have 64 - 8 - 16 = 40 bits for ino_t. But, we + * need 0xffff0000 for nFileIndexHigh and 0x0003ffff for nFileIndexLow + * minimum, or 16 + 18 = 34 bits. Lucky us - we have 6 more bits + * to distribute. + * + * For lack of a better idea, we'll allocate 2 of the extra bits to + * nFileIndexHigh and 4 to nFileIndexLow. + */ + // get 8 bits from dev_t (major), put into 0xff00000000000000L + tmp = (((key_t) statbuf.st_dev) & 0x0000000000ff0000L) << 40; + // get 8 bits from dev_t (minor), put into 0x00ff000000000000L + tmp |= (((key_t) statbuf.st_dev) & 0x00000000000000ffL) << 48; + // get upper 16+2 bits from nFileInfoHigh, put into 0x0000ffffc0000000L + // shift down first, then mask, to avoid sign extension on rightshift + tmp |= (((key_t) statbuf.st_ino) >> 16) & 0x0000ffffc0000000L; + // get lower 18+4 bits from nFileInfoLow, put into 0x000000003fffff00L + tmp |= (((key_t) statbuf.st_ino) & 0x00000000003fffffL) << 8; + // use all 8 bits of id, and put into 0x00000000000000ffL + tmp |= (id & 0x00ff); + return tmp; +} + +#else /* __CYGWIN_USE_BIG_TYPES__ */ + +key_t +ftok (const char *path, int id) +{ + struct __stat32 statbuf; + if (stat (path, &statbuf)) + { + /* stat set the appropriate errno for us */ + return (key_t) -1; + } + + /* + * When !__CYGWIN_USE_BIG_TYPES__, + * dev_t is short for cygwin + * ino_t is long for cygwin + * and we need 8 bits for the id. (16 + 32 + 8 == 56) + * This must all fit into 32 bits. For backwards compatibility + * with old cygipc, we use its hash. */ - return ((long long) statbuf.st_dev << (5*8)) | (statbuf.st_ino << (8) ) | (id & 0x00ff); + return ((statbuf.st_ino & 0x0000ffff) | + ((st.st_dev & 0x000000ff) << 16) | + ((id & 0x000000ff) << 24)); } + +#endif /* __CYGWIN_USE_BIG_TYPES__ */ } Index: winsup/cygwin/include/cygwin/types.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/include/cygwin/types.h,v retrieving revision 1.20 diff -u -r1.20 types.h --- winsup/cygwin/include/cygwin/types.h 11 May 2003 12:50:18 -0000 1.20 +++ winsup/cygwin/include/cygwin/types.h 14 May 2003 06:21:38 -0000 @@ -101,7 +101,13 @@ #ifndef __key_t_defined #define __key_t_defined -typedef long key_t; +typedef long __key32_t; +typedef long long __key64_t; +#ifdef __CYGWIN_USE_BIG_TYPES__ +typedef __key64_t key_t; +#else +typedef __key32_t key_t; +#endif #endif /* __key_t_defined */ #ifndef __BIT_TYPES_DEFINED Index: winsup/cygwin/include/cygwin/version.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/include/cygwin/version.h,v retrieving revision 1.117 diff -u -r1.117 version.h --- winsup/cygwin/include/cygwin/version.h 9 May 2003 22:11:25 -0000 1.117 +++ winsup/cygwin/include/cygwin/version.h 14 May 2003 06:21:40 -0000 @@ -205,12 +205,13 @@ underscore. No problems with backward compatibility since no official release has been made so far. This change removes exported symbols like fopen64, which might confuse configure. + 86: Export ftok */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 85 +#define CYGWIN_VERSION_API_MINOR 86 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible