]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/ipc.cc
Throughout, update copyrights to reflect dates which correspond to main-branch
[newlib-cygwin.git] / winsup / cygwin / ipc.cc
CommitLineData
f449bfef
RC
1/* ipc.cc: Single unix specification IPC interface for Cygwin
2
bc837d22 3 Copyright 2001, 2002, 2003, 2008, 2010 Red Hat, Inc.
f449bfef
RC
4
5 Originally written by Robert Collins <robert.collins@hotmail.com>
10bada05 6 Updated to 64 bit key_t by Charles Wilson <cygwin@cwilson.fastmail.fm>
f449bfef
RC
7
8 This file is part of Cygwin.
9
10 This software is a copyrighted work licensed under the terms of the
11 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12 details. */
13
14#include "winsup.h"
f449bfef
RC
15#include <sys/stat.h>
16
f449bfef 17/* Notes: we return a valid key even if id's low order 8 bits are 0. */
10bada05 18extern "C" key_t
f0227ea3 19ftok (const char *path, int id)
f449bfef 20{
194d9eb3 21 struct __stat64 statbuf;
10bada05 22 key_t tmp;
194d9eb3 23 if (stat64 (path, &statbuf))
f449bfef
RC
24 {
25 /* stat set the appropriate errno for us */
26 return (key_t) -1;
27 }
2402700d 28
627ef695 29 /* Since Cygwin 1.5
10bada05
CV
30 dev_t is 32bits for cygwin
31 ino_t is 64bits for cygwin
32 and we need 8 bits for the id.
33 thus key_t needs 104 bits total -- but we only have 64 (long long)
34 We will have to alias; leaving open the possibility that the same
35 key will be returned for multiple files. This possibility exists
36 also on Linux; the question is, how to minimize this possibility.
df04ae29 37
10bada05
CV
38 How to solve? Well, based on C. Vinschen's research, the nFileIndex*
39 words vary as follows, on a partition with > 110,000 files
40 nFileIndexHigh: 564 values between 0x00010000 -- 0xffff0000
41 nFileIndexLow : 103812 values between 0x00000000 -- 0x0003ffff
df04ae29 42 R. Collins suggests that these may represent a tree path,
10bada05
CV
43 and that it would require ~2.9M files to force the tree depth
44 to increase and reveal more bit usage.
df04ae29 45
10bada05 46 Implementation details: dev_t is 32bits, but is formed by
df04ae29 47 device(32bits) << 16 | unit(32bits)
10bada05
CV
48 But device is ACTUALLY == status & FH_DEVMASK, where FH_DEVMASK
49 is 0x00000fff --> 12 bits
df04ae29
CF
50
51 As it happens, the maximum number of devices is actually
10bada05
CV
52 FH_NDEV, not FH_DEVMASK, where FH_NDEV is currently 0x0000001d.
53 However, FH_NDEV grows as new device types are added. So
54 currently the device number needs 5 bits, but later? Let's
55 take a cue from Linux, and use the lower 8 bits (instead of the
56 lower 12 or 16) for the device (major?) number.
df04ae29 57
10bada05
CV
58 Similarly, while 'units' is an int (32bits), it is unclear
59 how many of these are significant. For most devices, it seems that
60 'units' is equivalent to 'minor'. For FH_TAPE, it's obvious that
61 only 8 bits are important. However, for FH_SOCKET...it might be
62 as high as 16 significant bits.
df04ae29 63
10bada05
CV
64 Let's assume that we only need 8 bits from device (major) and
65 only 8 bits from unit (minor). (On linux, only 8 bits of minor
66 are used, and none from major).
67 ---> so, we only need 0x00ff00ff (16 bits) of dev_t
df04ae29 68
10bada05 69 ---> we MUST have all 8 bits of id.
df04ae29 70
10bada05
CV
71 ---> So, we only have 64 - 8 - 16 = 40 bits for ino_t. But, we
72 need 0xffff0000 for nFileIndexHigh and 0x0003ffff for nFileIndexLow
73 minimum, or 16 + 18 = 34 bits. Lucky us - we have 6 more bits
74 to distribute.
df04ae29 75
10bada05
CV
76 For lack of a better idea, we'll allocate 2 of the extra bits to
77 nFileIndexHigh and 4 to nFileIndexLow. */
f449bfef 78
10bada05
CV
79 /* get 8 bits from dev_t (major), put into 0xff00000000000000L */
80 tmp = (((key_t) statbuf.st_dev) & 0x0000000000ff0000LL) << 40;
81 /* get 8 bits from dev_t (minor), put into 0x00ff000000000000L */
82 tmp |= (((key_t) statbuf.st_dev) & 0x00000000000000ffLL) << 48;
83 /* get upper 16+2 bits from nFileInfoHigh, put into 0x0000ffffc0000000L
84 shift down first, then mask, to avoid sign extension on rightshift */
85 tmp |= (((key_t) statbuf.st_ino) & 0xffffc00000000000LL) >> 16;
86 /* get lower 18+4 bits from nFileInfoLow, put into 0x000000003fffff00L */
87 tmp |= (((key_t) statbuf.st_ino) & 0x00000000003fffffLL) << 8;
88 /* use all 8 bits of id, and put into 0x00000000000000ffL */
89 tmp |= (id & 0x00ff);
90 return tmp;
f449bfef 91}
This page took 0.323466 seconds and 5 git commands to generate.