4 #include "sys/cygwin.h"
7 #include "shared_info.h"
14 typedef const _device *KR_device_t;
20 exists_internal (const device&)
26 exists (const device&)
31 /* Check existence of POSIX devices backed by real NT devices. */
33 exists_ntdev (const device& dev)
35 WCHAR wpath[MAX_PATH];
37 OBJECT_ATTRIBUTES attr;
41 sys_mbstowcs (wpath, MAX_PATH, dev.native ());
42 RtlInitUnicodeString (&upath, wpath);
43 InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
44 /* Except for the serial IO devices, the native paths are
45 direct device paths, not symlinks, so every status code
46 except for "NOT_FOUND" means the device exists. */
47 status = NtOpenSymbolicLinkObject (&h, SYMBOLIC_LINK_QUERY, &attr);
50 case STATUS_OBJECT_NAME_NOT_FOUND:
51 case STATUS_OBJECT_PATH_NOT_FOUND:
61 /* Don't list via readdir but allow as a direct reference. */
63 exists_ntdev_silent (const device& dev)
65 return exists_ntdev (dev) ? -1 : false;
69 exists_console (const device& dev)
71 fh_devices devn = *const_cast<device *> (&dev);
77 return cygheap && cygheap->ctty && cygheap->ctty->is_console ()
78 && fhandler_console::exists ();
80 if (dev.get_minor () < MAX_CONS_DEV)
82 unsigned long bitmask = fhandler_console::console_unit (CONS_LIST_USED);
83 return !!(bitmask & (1UL << dev.get_minor ()));
90 exists_pty (const device& dev)
92 /* Only existing slave ptys. */
93 return cygwin_shared->tty.connect (dev.get_minor ()) != -1;
96 const _device dev_cygdrive_storage =
97 {"/cygdrive", {FH_CYGDRIVE}, "", exists};
99 const _device dev_fs_storage =
100 {"", {FH_FS}, "", exists};
102 const _device dev_dev_disk_storage =
103 {"", {FH_DEV_DISK}, "", exists};
105 const _device dev_proc_storage =
106 {"", {FH_PROC}, "", exists};
108 const _device dev_procnet_storage =
109 {"", {FH_PROCNET}, "", exists};
111 const _device dev_procsys_storage =
112 {"", {FH_PROCSYS}, "", exists};
114 const _device dev_procsysvipc_storage =
115 {"", {FH_PROCSYSVIPC}, "", exists};
117 const _device dev_netdrive_storage =
118 {"", {FH_NETDRIVE}, "", exists};
120 const _device dev_registry_storage =
121 {"", {FH_REGISTRY}, "", exists_internal};
123 const _device dev_piper_storage =
124 {"", {FH_PIPER}, "", exists_internal};
126 const _device dev_pipew_storage =
127 {"", {FH_PIPEW}, "", exists_internal};
129 const _device dev_signalfd_storage =
130 {"", {FH_SIGNALFD}, "", exists_internal};
132 const _device dev_timerfd_storage =
133 {"", {FH_TIMERFD}, "", exists_internal};
135 const _device dev_mqueue_storage =
136 {"", {FH_MQUEUE}, "", exists_internal};
138 const _device dev_socket_storage =
139 {"", {FH_SOCKET}, "", exists_internal};
141 const _device dev_af_inet_storage =
142 {"", {FH_INET}, "", exists_internal};
144 const _device dev_af_unix_storage =
145 {"", {FH_UNIX}, "", exists_internal};
147 const _device dev_af_local_storage =
148 {"", {FH_LOCAL}, "", exists_internal};
150 const _device dev_bad_storage =
151 {"", {FH_NADA}, "", exists_internal};
153 const _device dev_error_storage =
154 {"", {FH_ERROR}, "", exists_internal};
156 #define BRACK(x) {devn: x}
159 /* Internal devices below are prefixed with a ":". This moves them out of
160 the POSIX namespace. */
162 "/dev", BRACK(FH_DEV), "", exists, S_IFDIR
163 "/dev/disk", BRACK(FH_DEV_DISK), "", exists, S_IFDIR
164 "/dev/tty", BRACK(FH_TTY), "/dev/tty", exists, S_IFCHR
165 "/dev/pty%(0-127)d", BRACK(FHDEV(DEV_PTYS_MAJOR, {$1})), "/dev/pty{$1}", exists_pty, S_IFCHR, =ptys_dev
166 ":ptym%(0-127)d", BRACK(FHDEV(DEV_PTYM_MAJOR, {$1})), "/dev/ptym{$1}", exists_internal, S_IFCHR, =ptym_dev
167 "/dev/cons%(0-127)d", BRACK(FHDEV(DEV_CONS_MAJOR, {$1})), "/dev/cons{$1}", exists_console, S_IFCHR, =cons_dev
168 "/dev/console", BRACK(FH_CONSOLE), "/dev/console", exists_console, S_IFCHR, =console_dev
169 "/dev/ptmx", BRACK(FH_PTMX), "/dev/ptmx", exists, S_IFCHR
170 "/dev/windows", BRACK(FH_WINDOWS), "\\Device\\Null", exists_ntdev, S_IFCHR
171 "/dev/mixer", BRACK(FH_OSS_MIXER), "\\Device\\Null", exists_ntdev, S_IFCHR
172 "/dev/dsp", BRACK(FH_OSS_DSP), "\\Device\\Null", exists_ntdev, S_IFCHR
173 "/dev/conin", BRACK(FH_CONIN), "/dev/conin", exists_console, S_IFCHR
174 "/dev/conout", BRACK(FH_CONOUT), "/dev/conout", exists_console, S_IFCHR
175 "/dev/null", BRACK(FH_NULL), "\\Device\\Null", exists_ntdev, S_IFCHR
176 "/dev/zero", BRACK(FH_ZERO), "\\Device\\Null", exists_ntdev, S_IFCHR
177 "/dev/full", BRACK(FH_FULL), "\\Device\\Null", exists_ntdev, S_IFCHR
178 "/dev/random", BRACK(FH_RANDOM), "\\Device\\Null", exists_ntdev, S_IFCHR
179 "/dev/urandom", BRACK(FH_URANDOM), "\\Device\\Null", exists_ntdev, S_IFCHR, =urandom_dev
180 "/dev/clipboard", BRACK(FH_CLIPBOARD), "\\Device\\Null", exists_ntdev, S_IFCHR
181 "/dev/com%(1-16)d", BRACK(FHDEV(DEV_SERIAL_MAJOR, {$1 - 1})), "\\??\\COM{$1}", exists_ntdev_silent, S_IFCHR
182 "/dev/ttyS%(0-127)d", BRACK(FHDEV(DEV_SERIAL_MAJOR, {$1})), "\\??\\COM{$1 + 1}", exists_ntdev, S_IFCHR
183 ":pipe", BRACK(FH_PIPE), "/dev/pipe", exists_internal, S_IFCHR
184 ":fifo", BRACK(FH_FIFO), "/dev/fifo", exists_internal, S_IFCHR
185 "/dev/st%(0-127)d", BRACK(FHDEV(DEV_TAPE_MAJOR, {$1})), "\\Device\\Tape{$1}", exists_ntdev, S_IFCHR
186 "/dev/nst%(0-127)d", BRACK(FHDEV(DEV_TAPE_MAJOR, {$1 + 128})), "\\Device\\Tape{$1}", exists_ntdev, S_IFCHR
187 "/dev/fd%(0-15)d", BRACK(FHDEV(DEV_FLOPPY_MAJOR, {$1})), "\\Device\\Floppy{$1}", exists_ntdev, S_IFBLK
188 "/dev/scd%(0-15)d", BRACK(FHDEV(DEV_CDROM_MAJOR, {$1})), "\\Device\\CdRom{$1}", exists_ntdev, S_IFBLK
189 "/dev/sr%(0-15)d", BRACK(FHDEV(DEV_CDROM_MAJOR, {$1})), "\\Device\\CdRom{$1}", exists_ntdev, S_IFBLK
190 "/dev/fd", BRACK(FH_DEV_FD), "/proc/self/fd", exists, S_IFLNK
191 "/dev/stdin", BRACK(FH_DEV_FD), "/proc/self/fd/0", exists, S_IFLNK
192 "/dev/stdout", BRACK(FH_DEV_FD), "/proc/self/fd/1", exists, S_IFLNK
193 "/dev/stderr", BRACK(FH_DEV_FD), "/proc/self/fd/2", exists, S_IFLNK
194 %other {return NULL;}
198 const _device *dev_storage_end = dev_storage
199 + (sizeof dev_storage / sizeof dev_storage[0]);
201 /* Convert disk/partition to major/minor */
203 conv_dp_to_mm (int drive, int part, _major_t &major, _minor_t &minor)
207 major = DEV_SD_HIGHPART_START + drive / 5;
209 minor = (part - 16) + 48 * drive;
212 if (drive < ('q' - 'a')) /* /dev/sda -to- /dev/sdp */
213 major = DEV_SD_MAJOR;
214 else if (drive < 32) /* /dev/sdq -to- /dev/sdaf */
216 major = DEV_SD1_MAJOR;
219 else if (drive < 48) /* /dev/sdag -to- /dev/sdav */
221 major = DEV_SD2_MAJOR;
224 else if (drive < 64) /* /dev/sdaw -to- /dev/sdbl */
226 major = DEV_SD3_MAJOR;
229 else if (drive < 80) /* /dev/sdbm -to- /dev/sdcb */
231 major = DEV_SD4_MAJOR;
234 else if (drive < 96) /* /dev/sdcc -to- /dev/sdcr */
236 major = DEV_SD5_MAJOR;
239 else if (drive < 112) /* /dev/sdcs -to- /dev/sddh */
241 major = DEV_SD6_MAJOR;
244 /* NOTE: This will cause multiple /dev/sddx entries in
245 /proc/partitions if there are more than 128 devices */
246 else /* /dev/sddi -to- /dev/sddx */
248 major = DEV_SD7_MAJOR;
251 minor = part + (drive * 16);
254 #define DISK_PREFIX "/dev/sd"
255 #define DP_LEN (sizeof (DISK_PREFIX) - 1)
257 static const char *hd_pattern = "\\Device\\Harddisk%u\\Partition%u";
260 device::parse (const char *s)
262 size_t len = strlen (s);
263 const _device *dev = KR_find_keyword (s, len);
267 /* /dev/sd* devices have 8192 entries, given that we support 128 disks
268 with up to 64 partitions. Handling them with shilka raises the size
269 of devices.o from ~250K to ~2 Megs. So we handle them here manually
270 to save this space. */
271 int drive = 0, part = 0;
272 const char *pos = s + DP_LEN;
274 /* Generic check for /dev/sd[a-z] prefix */
275 if (len <= DP_LEN || strncmp (s, DISK_PREFIX, DP_LEN)
276 || pos[0] < 'a' || pos[0] > 'z')
280 if (pos[0] == 'd' && pos[1] >= 'a' && pos[1] <= 'x')
282 drive = 104 + (pos[1] - 'a');
285 /* /dev/sd[a-c][a-z]? */
286 else if (pos[0] <= 'c' && pos[1] >= 'a' && pos[1] <= 'z')
288 drive = 26 + (pos[0] - 'a') * 26 + (pos[1] - 'a');
292 drive = (pos[0] - 'a');
293 /* Check next position in string for partition number. */
295 /* No partition number, equivalent to Windows partition 0. */
298 /* First digit must not be 0. */
299 else if (pos[0] < '1' || pos[0] > '9')
302 part = (pos[0] - '0');
303 else if (pos[1] < '0' || pos[1] > '9' || pos[2] != '\0')
307 part = (pos[0] - '0') * 10 + (pos[1] - '0');
311 char buf[sizeof *hd_pattern + 32];
312 __small_sprintf (buf, hd_pattern, drive, part);
314 if (exists_ntdev (*this))
317 conv_dp_to_mm (drive, part, d.major, d.minor);
319 exists_func = exists_ntdev;
321 lives_in_dev = dev_on_fs = false;
334 /* nothing to do... yet */
338 device::parse (_major_t major, _minor_t minor)
340 dev_t devn = FHDEV (major, minor);
344 for (const _device *devidx = dev_storage; devidx < dev_storage_end; devidx++)
345 if (devidx->d.devn == devn)
352 d.devn = FHDEV (major, minor);
356 device::parse (dev_t dev)
358 parse (_major (dev), _minor (dev));
362 device::parsedisk (int drive, int part)
364 char buf[sizeof ("/dev/sddx63")], *bp;
366 conv_dp_to_mm (drive, part, d.major, d.minor);
367 bp = stpcpy (buf, "/dev/sd");
371 *bp++ = drive / 26 + 'a';
379 *bp++ = part / 10 + '0';