Handle up to 63 partitions per drive

Revamp device parsing code.  Introducing support for more partitions
into the shilka-generated parser has the unfortunate side-effect of
raising the size of the DLL by almost 2 Megs.  Therefore we split out
the handling for /dev/sdXY devices into a tiny bit of hand-written
code.

While at it, remove some unused cruft from devices.* and generally
clean up the device class to provide access methods instead of direct
access to members.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2016-06-23 16:56:41 +02:00
parent bceb8ebebb
commit b2867a68b9
21 changed files with 5268 additions and 40170 deletions

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,7 @@ typedef unsigned short _minor_t;
#include <sys/stat.h> #include <sys/stat.h>
#include <dirent.h> #include <dirent.h>
#include "cygheap_malloc.h"
#define MAX_CONSOLES 63 #define MAX_CONSOLES 63
enum fh_devices enum fh_devices
@ -93,6 +94,8 @@ enum fh_devices
DEV_SD5_MAJOR = 69, DEV_SD5_MAJOR = 69,
DEV_SD6_MAJOR = 70, DEV_SD6_MAJOR = 70,
DEV_SD7_MAJOR = 71, DEV_SD7_MAJOR = 71,
DEV_SD_HIGHPART_START = 259, /* partition # > 15 */
DEV_SD_HIGHPART_END = 284,
FH_SD = FHDEV (DEV_SD_MAJOR, 0), FH_SD = FHDEV (DEV_SD_MAJOR, 0),
FH_SD1 = FHDEV (DEV_SD1_MAJOR, 0), FH_SD1 = FHDEV (DEV_SD1_MAJOR, 0),
FH_SD2 = FHDEV (DEV_SD2_MAJOR, 0), FH_SD2 = FHDEV (DEV_SD2_MAJOR, 0),
@ -253,14 +256,21 @@ enum fh_devices
FH_ERROR = FHDEV (255, 255) /* Set by fh constructor when error detected */ FH_ERROR = FHDEV (255, 255) /* Set by fh constructor when error detected */
}; };
struct device /* struct _device is required to allow the code in devices.cc autogenerated
from devices.in continuing to work, even with a proper class device.
We need to keep up with this as long as we use shilka to build a device
table.
Do not add members to device. Always add it to _device. */
class device;
struct _device
{ {
const char *name; const char *_name;
union __cygwin_dev union __cygwin_dev
{ {
dev_t devn; dev_t devn;
DWORD devn_dword;
int devn_int;
fh_devices devn_fh_devices; fh_devices devn_fh_devices;
struct struct
{ {
@ -268,16 +278,58 @@ struct device
_major_t major; _major_t major;
}; };
} d; } d;
const char *native; const char *_native;
int (*exists_func) (const device&); int (*exists_func) (const device&);
__mode_t mode; __mode_t _mode;
bool lives_in_dev:4; bool lives_in_dev;
bool dev_on_fs:4; bool dev_on_fs;
static const device *lookup (const char *, unsigned int = UINT32_MAX); bool name_allocated;
bool native_allocated;
};
class device : private _device
{
void parsedisk (int, int);
void name (const char *n, bool a)
{
_name = (!(name_allocated = a)) ? n : cstrdup (n);
}
void native (const char *n, bool a)
{
_native = (!(native_allocated = a)) ? n : cstrdup (n);
}
public:
device () { memset (this, 0, sizeof *this); }
device (int drive, int part)
{
memset (this, 0, sizeof *this);
parsedisk (drive, part);
}
~device ()
{
if (name_allocated)
cfree ((void *) _name);
if (native_allocated)
cfree ((void *) _native);
}
const char *name () const { return _name; }
const char *native () const { return _native; }
__mode_t mode () const { return _mode; }
void mode (__mode_t m) { _mode = m; }
void name (const char *n) { name (n, false); }
void native (const char *n) { native (n, false); }
void dup ()
{
name (_name, name_allocated);
native (_native, native_allocated);
}
void parse (const char *); void parse (const char *);
void parse (_major_t major, _minor_t minor); void parse (_major_t major, _minor_t minor);
void parse (dev_t dev); void parse (dev_t dev);
void parsedisk (int, int);
inline bool setunit (unsigned n) inline bool setunit (unsigned n)
{ {
d.minor = n; d.minor = n;
@ -308,8 +360,21 @@ struct device
dev_t get_device () const {return d.devn;} dev_t get_device () const {return d.devn;}
inline operator fh_devices () {return d.devn_fh_devices;} inline operator fh_devices () {return d.devn_fh_devices;}
inline operator bool () {return !!d.devn_int;} inline operator bool () {return !!d.devn;}
inline operator dev_t& () {return d.devn;} inline operator dev_t& () {return d.devn;}
device &operator = (_device _d)
{
memcpy (this, &_d, sizeof _d);
dev_on_fs = name_allocated = native_allocated = false;
return *this;
}
device &operator = (device &_d)
{
memcpy (this, &_d, sizeof _d);
name (_d.name (), _d.name_allocated);
native (_d.native (), _d.native_allocated);
return *this;
}
fh_devices operator = (fh_devices n) {return d.devn_fh_devices = n;} fh_devices operator = (fh_devices n) {return d.devn_fh_devices = n;}
inline void setfs (bool x) {dev_on_fs = x;} inline void setfs (bool x) {dev_on_fs = x;}
inline bool isfs () const {return dev_on_fs || d.devn == FH_FS;} inline bool isfs () const {return dev_on_fs || d.devn == FH_FS;}
@ -318,45 +383,45 @@ struct device
inline int exists () const {return exists_func (*this);} inline int exists () const {return exists_func (*this);}
unsigned char type () const unsigned char type () const
{ {
if (S_ISBLK (mode)) if (S_ISBLK (_mode))
return DT_BLK; return DT_BLK;
return mode >> 12; return _mode >> 12;
} }
}; };
extern const device dev_storage[]; extern const _device dev_storage[];
extern const device *dev_storage_end; extern const _device *dev_storage_end;
extern const device *console_dev; extern const _device *console_dev;
extern const device *ptmx_dev; extern const _device *ptmx_dev;
extern const device *ptys_dev; extern const _device *ptys_dev;
extern const device *urandom_dev; extern const _device *urandom_dev;
extern const device dev_dgram_storage; extern const _device dev_dgram_storage;
#define dgram_dev (&dev_dgram_storage) #define dgram_dev ((device *) &dev_dgram_storage)
extern const device dev_stream_storage; extern const _device dev_stream_storage;
#define stream_dev (&dev_stream_storage) #define stream_dev ((device *) &dev_stream_storage)
extern const device dev_tcp_storage; extern const _device dev_tcp_storage;
#define tcp_dev (&dev_tcp_storage) #define tcp_dev ((device *) &dev_tcp_storage)
extern const device dev_udp_storage; extern const _device dev_udp_storage;
#define udp_dev (&dev_udp_storage) #define udp_dev ((device *) &dev_udp_storage)
extern const device dev_piper_storage; extern const _device dev_piper_storage;
#define piper_dev (&dev_piper_storage) #define piper_dev ((device *) &dev_piper_storage)
extern const device dev_pipew_storage; extern const _device dev_pipew_storage;
#define pipew_dev (&dev_pipew_storage) #define pipew_dev ((device *) &dev_pipew_storage)
extern const device dev_proc_storage; extern const _device dev_proc_storage;
#define proc_dev (&dev_proc_storage) #define proc_dev ((device *) &dev_proc_storage)
extern const device dev_dev_storage; extern const _device dev_dev_storage;
#define dev_dev (&dev_dev_storage) #define dev_dev ((device *) &dev_dev_storage)
extern const device dev_netdrive_storage; extern const _device dev_netdrive_storage;
#define netdrive_dev (&dev_netdrive_storage) #define netdrive_dev ((device *) &dev_netdrive_storage)
extern const device dev_cygdrive_storage; extern const _device dev_cygdrive_storage;
#define cygdrive_dev (&dev_cygdrive_storage) #define cygdrive_dev ((device *) &dev_cygdrive_storage)
extern const device dev_fh_storage; extern const _device dev_fh_storage;
#define fh_dev (&dev_fh_storage) #define fh_dev ((device *) &dev_fh_storage)
extern const device dev_fs_storage; extern const _device dev_fs_storage;
#define fs_dev (&dev_fs_storage) #define fs_dev ((device *) &dev_fs_storage)
#define isproc_dev(devn) \ #define isproc_dev(devn) \
(devn >= FH_PROC_MIN_MINOR && devn <= FH_PROC_MAX_MINOR) (devn >= FH_PROC_MIN_MINOR && devn <= FH_PROC_MAX_MINOR)

View File

@ -9,7 +9,7 @@
#include "fhandler.h" #include "fhandler.h"
#include "ntdll.h" #include "ntdll.h"
typedef const device *KR_device_t; typedef const _device *KR_device_t;
} }
%type KR_device_t %type KR_device_t
%local { %local {
@ -36,7 +36,7 @@ exists_ntdev (const device& dev)
HANDLE h; HANDLE h;
NTSTATUS status; NTSTATUS status;
sys_mbstowcs (wpath, MAX_PATH, dev.native); sys_mbstowcs (wpath, MAX_PATH, dev.native ());
RtlInitUnicodeString (&upath, wpath); RtlInitUnicodeString (&upath, wpath);
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL); InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
/* Except for the serial IO devices, the native paths are /* Except for the serial IO devices, the native paths are
@ -86,55 +86,55 @@ exists_pty (const device& dev)
return cygwin_shared->tty.connect (dev.get_minor ()) != -1; return cygwin_shared->tty.connect (dev.get_minor ()) != -1;
} }
const device dev_cygdrive_storage = const _device dev_cygdrive_storage =
{"/cygdrive", {FH_CYGDRIVE}, "", exists}; {"/cygdrive", {FH_CYGDRIVE}, "", exists};
const device dev_fs_storage = const _device dev_fs_storage =
{"", {FH_FS}, "", exists}; {"", {FH_FS}, "", exists};
const device dev_proc_storage = const _device dev_proc_storage =
{"", {FH_PROC}, "", exists}; {"", {FH_PROC}, "", exists};
const device dev_procnet_storage = const _device dev_procnet_storage =
{"", {FH_PROCNET}, "", exists}; {"", {FH_PROCNET}, "", exists};
const device dev_procsys_storage = const _device dev_procsys_storage =
{"", {FH_PROCSYS}, "", exists}; {"", {FH_PROCSYS}, "", exists};
const device dev_procsysvipc_storage = const _device dev_procsysvipc_storage =
{"", {FH_PROCSYSVIPC}, "", exists}; {"", {FH_PROCSYSVIPC}, "", exists};
const device dev_netdrive_storage = const _device dev_netdrive_storage =
{"", {FH_NETDRIVE}, "", exists}; {"", {FH_NETDRIVE}, "", exists};
const device dev_registry_storage = const _device dev_registry_storage =
{"", {FH_REGISTRY}, "", exists_internal}; {"", {FH_REGISTRY}, "", exists_internal};
const device dev_piper_storage = const _device dev_piper_storage =
{"", {FH_PIPER}, "", exists_internal}; {"", {FH_PIPER}, "", exists_internal};
const device dev_pipew_storage = const _device dev_pipew_storage =
{"", {FH_PIPEW}, "", exists_internal}; {"", {FH_PIPEW}, "", exists_internal};
const device dev_tcp_storage = const _device dev_tcp_storage =
{"", {FH_TCP}, "", exists_internal}; {"", {FH_TCP}, "", exists_internal};
const device dev_udp_storage = const _device dev_udp_storage =
{"", {FH_UDP}, "", exists_internal}; {"", {FH_UDP}, "", exists_internal};
const device dev_stream_storage = const _device dev_stream_storage =
{"", {FH_STREAM}, "", exists_internal}; {"", {FH_STREAM}, "", exists_internal};
const device dev_dgram_storage = const _device dev_dgram_storage =
{"", {FH_DGRAM}, "", exists_internal}; {"", {FH_DGRAM}, "", exists_internal};
const device dev_bad_storage = const _device dev_bad_storage =
{"", {FH_NADA}, "", exists_internal}; {"", {FH_NADA}, "", exists_internal};
const device dev_error_storage = const _device dev_error_storage =
{"", {FH_ERROR}, "", exists_internal}; {"", {FH_ERROR}, "", exists_internal};
#define BRACK(x) {devn_int: x} #define BRACK(x) {devn: x}
%storage_here %storage_here
} }
/* Internal devices below are prefixed with a ":". This moves them out of /* Internal devices below are prefixed with a ":". This moves them out of
@ -166,31 +166,140 @@ const device dev_error_storage =
"/dev/fd%(0-15)d", BRACK(FHDEV(DEV_FLOPPY_MAJOR, {$1})), "\\Device\\Floppy{$1}", exists_ntdev, S_IFBLK "/dev/fd%(0-15)d", BRACK(FHDEV(DEV_FLOPPY_MAJOR, {$1})), "\\Device\\Floppy{$1}", exists_ntdev, S_IFBLK
"/dev/scd%(0-15)d", BRACK(FHDEV(DEV_CDROM_MAJOR, {$1})), "\\Device\\CdRom{$1}", exists_ntdev, S_IFBLK "/dev/scd%(0-15)d", BRACK(FHDEV(DEV_CDROM_MAJOR, {$1})), "\\Device\\CdRom{$1}", exists_ntdev, S_IFBLK
"/dev/sr%(0-15)d", BRACK(FHDEV(DEV_CDROM_MAJOR, {$1})), "\\Device\\CdRom{$1}", exists_ntdev, S_IFBLK "/dev/sr%(0-15)d", BRACK(FHDEV(DEV_CDROM_MAJOR, {$1})), "\\Device\\CdRom{$1}", exists_ntdev, S_IFBLK
"/dev/sd%{a-z}s", BRACK(FH_SD{uc $1}), "\\Device\\Harddisk{ord($1) - ord('a')}\\Partition0", exists_ntdev, S_IFBLK
"/dev/sda%{a-z}s", BRACK(FH_SDA{uc $1}), "\\Device\\Harddisk{26 + ord($1) - ord('a')}\\Partition0", exists_ntdev, S_IFBLK
"/dev/sdb%{a-z}s", BRACK(FH_SDB{uc $1}), "\\Device\\Harddisk{52 + ord($1) - ord('a')}\\Partition0", exists_ntdev, S_IFBLK
"/dev/sdc%{a-z}s", BRACK(FH_SDC{uc $1}), "\\Device\\Harddisk{78 + ord($1) - ord('a')}\\Partition0", exists_ntdev, S_IFBLK
"/dev/sdd%{a-x}s", BRACK(FH_SDD{uc $1}), "\\Device\\Harddisk{104 + ord($1) - ord('a')}\\Partition0", exists_ntdev, S_IFBLK
"/dev/sd%{a-z}s%(1-15)d", BRACK(FH_SD{uc $1} | {$2}), "\\Device\\Harddisk{ord($1) - ord('a')}\\Partition{$2 % 16}", exists_ntdev, S_IFBLK
"/dev/sda%{a-z}s%(1-15)d", BRACK(FH_SDA{uc $1} | {$2}), "\\Device\\Harddisk{26 + ord($1) - ord('a')}\\Partition{$2 % 16}", exists_ntdev, S_IFBLK
"/dev/sdb%{a-z}s%(1-15)d", BRACK(FH_SDB{uc $1} | {$2}), "\\Device\\Harddisk{52 + ord($1) - ord('a')}\\Partition{$2 % 16}", exists_ntdev, S_IFBLK
"/dev/sdc%{a-z}s%(1-15)d", BRACK(FH_SDC{uc $1} | {$2}), "\\Device\\Harddisk{78 + ord($1) - ord('a')}\\Partition{$2 % 16}", exists_ntdev, S_IFBLK
"/dev/sdd%{a-x}s%(1-15)d", BRACK(FH_SDD{uc $1} | {$2}), "\\Device\\Harddisk{104 + ord($1) - ord('a')}\\Partition{$2 % 16}", exists_ntdev, S_IFBLK
"/dev/kmsg", BRACK(FH_KMSG), "\\Device\\MailSlot\\cygwin\\dev\\kmsg", exists_ntdev, S_IFCHR "/dev/kmsg", BRACK(FH_KMSG), "\\Device\\MailSlot\\cygwin\\dev\\kmsg", exists_ntdev, S_IFCHR
%other {return NULL;} %other {return NULL;}
%% %%
#undef BRACK #undef BRACK
const device *dev_storage_end = dev_storage + (sizeof dev_storage / sizeof dev_storage[0]); const _device *dev_storage_end = dev_storage
+ (sizeof dev_storage / sizeof dev_storage[0]);
/* Convert disk/partition to major/minor */
static void
conv_dp_to_mm (int drive, int part, _major_t &major, _minor_t &minor)
{
if (part >= 16)
{
major = DEV_SD_HIGHPART_START + drive / 5;
drive %= 5;
minor = (part - 16) + 48 * drive;
return;
}
if (drive < ('q' - 'a')) /* /dev/sda -to- /dev/sdp */
major = DEV_SD_MAJOR;
else if (drive < 32) /* /dev/sdq -to- /dev/sdaf */
{
major = DEV_SD1_MAJOR;
drive -= 'q' - 'a';
}
else if (drive < 48) /* /dev/sdag -to- /dev/sdav */
{
major = DEV_SD2_MAJOR;
drive -= 32;
}
else if (drive < 64) /* /dev/sdaw -to- /dev/sdbl */
{
major = DEV_SD3_MAJOR;
drive -= 48;
}
else if (drive < 80) /* /dev/sdbm -to- /dev/sdcb */
{
major = DEV_SD4_MAJOR;
drive -= 64;
}
else if (drive < 96) /* /dev/sdcc -to- /dev/sdcr */
{
major = DEV_SD5_MAJOR;
drive -= 80;
}
else if (drive < 112) /* /dev/sdcs -to- /dev/sddh */
{
major = DEV_SD6_MAJOR;
drive -= 96;
}
/* NOTE: This will cause multiple /dev/sddx entries in
/proc/partitions if there are more than 128 devices */
else /* /dev/sddi -to- /dev/sddx */
{
major = DEV_SD7_MAJOR;
drive -= 112;
}
minor = part + (drive * 16);
}
#define DISK_PREFIX "/dev/sd"
#define DP_LEN (sizeof (DISK_PREFIX) - 1)
static const char *hd_pattern = "\\Device\\Harddisk%u\\Partition%u";
void void
device::parse (const char *s) device::parse (const char *s)
{ {
size_t len = strlen (s); size_t len = strlen (s);
const device *dev = KR_find_keyword (s, len); const _device *dev = KR_find_keyword (s, len);
if (!dev) if (!dev)
*this = *fs_dev; {
/* /dev/sd* devices have 8192 entries, given that we support 128 disks
with up to 64 partitions. Handling them with shilka raises the size
of devices.o from ~250K to ~2 Megs. So we handle them here manually
to save this space. */
int drive = 0, part = 0;
const char *pos = s + DP_LEN;
/* Generic check for /dev/sd[a-z] prefix */
if (len <= DP_LEN || strncmp (s, DISK_PREFIX, DP_LEN)
|| pos[0] < 'a' || pos[0] > 'z')
goto no_disk;
/* /dev/sdd[a-x]? */
if (pos[0] == 'd' && pos[1] >= 'a' && pos[1] <= 'x')
{
drive = 104 + (pos[1] - 'a');
++pos;
}
/* /dev/sd[a-c][a-z]? */
else if (pos[0] <= 'c' && pos[1] >= 'a' && pos[1] <= 'z')
{
drive = 26 + (pos[0] - 'a') * 26 + (pos[1] - 'a');
++pos;
}
else
drive = (pos[0] - 'a');
/* Check next position in string for partition number. */
++pos;
/* No partition number, equivalent to Windows partition 0. */
if (!pos[0])
;
/* First digit must not be 0. */
else if (pos[0] < '1' || pos[0] > '9')
goto no_disk;
else if (!pos[1])
part = (pos[0] - '0');
else if (pos[1] < '0' || pos[1] > '9' || pos[2] != '\0')
goto no_disk;
else
{
part = (pos[0] - '0') * 10 + (pos[1] - '0');
if (part > 63)
goto no_disk;
}
char buf[sizeof *hd_pattern + 32];
__small_sprintf (buf, hd_pattern, drive, part);
native (buf, false);
if (exists_ntdev (*this))
{
name (s, true);
conv_dp_to_mm (drive, part, d.major, d.minor);
native (buf, true);
exists_func = exists_ntdev;
_mode = S_IFBLK;
lives_in_dev = dev_on_fs = false;
return;
}
no_disk:
*this = *fs_dev;
}
else else
*this = *dev; *this = *dev;
} }
@ -208,7 +317,7 @@ device::parse (_major_t major, _minor_t minor)
d.devn = 0; d.devn = 0;
for (const device *devidx = dev_storage; devidx < dev_storage_end; devidx++) for (const _device *devidx = dev_storage; devidx < dev_storage_end; devidx++)
if (devidx->d.devn == devn) if (devidx->d.devn == devn)
{ {
*this = *devidx; *this = *devidx;
@ -228,45 +337,26 @@ device::parse (dev_t dev)
void void
device::parsedisk (int drive, int part) device::parsedisk (int drive, int part)
{ {
int base; char buf[sizeof ("/dev/sddx63")], *bp;
if (drive < ('q' - 'a')) /* /dev/sda -to- /dev/sdp */
base = DEV_SD_MAJOR; conv_dp_to_mm (drive, part, d.major, d.minor);
else if (drive < 32) /* /dev/sdq -to- /dev/sdaf */ bp = stpcpy (buf, "/dev/sd");
if (drive >= 26)
{ {
base = DEV_SD1_MAJOR; drive -= 26;
drive -= 'q' - 'a'; *bp++ = drive / 26 + 'a';
drive %= 26;
} }
else if (drive < 48) /* /dev/sdag -to- /dev/sdav */ *bp++ = drive + 'a';
if (part)
{ {
base = DEV_SD2_MAJOR; if (part >= 10)
drive -= 32; {
*bp++ = part / 10 + '0';
part %= 10;
}
*bp++ = part + '0';
} }
else if (drive < 64) /* /dev/sdaw -to- /dev/sdbl */ *bp = '\0';
{ name (buf, true);
base = DEV_SD3_MAJOR;
drive -= 48;
}
else if (drive < 80) /* /dev/sdbm -to- /dev/sdcb */
{
base = DEV_SD4_MAJOR;
drive -= 64;
}
else if (drive < 96) /* /dev/sdcc -to- /dev/sdcr */
{
base = DEV_SD5_MAJOR;
drive -= 80;
}
else if (drive < 112) /* /dev/sdcs -to- /dev/sddh */
{
base = DEV_SD6_MAJOR;
drive -= 96;
}
/* NOTE: This will cause multiple /dev/sddx entries in
/proc/partitions if there are more than 128 devices */
else /* /dev/sddi -to- /dev/sddx */
{
base = DEV_SD7_MAJOR;
drive -= 112;
}
parse (base, part + (drive * 16));
} }

View File

@ -282,7 +282,7 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
CONSOLE_SCREEN_BUFFER_INFO buf; CONSOLE_SCREEN_BUFFER_INFO buf;
DCB dcb; DCB dcb;
unsigned bin = O_BINARY; unsigned bin = O_BINARY;
device dev = {}; device dev;
first_fd_for_open = 0; first_fd_for_open = 0;
@ -451,7 +451,7 @@ build_fh_dev (const device& dev, const char *unix_name)
if (unix_name) if (unix_name)
pc.set_posix (unix_name); pc.set_posix (unix_name);
else else
pc.set_posix (dev.name); pc.set_posix (dev.name ());
return build_fh_pc (pc); return build_fh_pc (pc);
} }
@ -476,13 +476,8 @@ fh_alloc (path_conv& pc)
case DEV_FLOPPY_MAJOR: case DEV_FLOPPY_MAJOR:
case DEV_CDROM_MAJOR: case DEV_CDROM_MAJOR:
case DEV_SD_MAJOR: case DEV_SD_MAJOR:
case DEV_SD1_MAJOR: case DEV_SD1_MAJOR ... DEV_SD7_MAJOR:
case DEV_SD2_MAJOR: case DEV_SD_HIGHPART_START ... DEV_SD_HIGHPART_END:
case DEV_SD3_MAJOR:
case DEV_SD4_MAJOR:
case DEV_SD5_MAJOR:
case DEV_SD6_MAJOR:
case DEV_SD7_MAJOR:
fh = cnew (fhandler_dev_floppy); fh = cnew (fhandler_dev_floppy);
break; break;
case DEV_TAPE_MAJOR: case DEV_TAPE_MAJOR:
@ -646,14 +641,14 @@ build_fh_pc (path_conv& pc)
debug_printf ("found an archetype for %s(%d/%d) io_handle %p", fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor (), debug_printf ("found an archetype for %s(%d/%d) io_handle %p", fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor (),
fh->archetype->get_io_handle ()); fh->archetype->get_io_handle ());
if (!fh->get_name ()) if (!fh->get_name ())
fh->set_name (fh->archetype->dev ().name); fh->set_name (fh->archetype->dev ().name ());
} }
else if (cygwin_finished_initializing && !pc.isopen ()) else if (cygwin_finished_initializing && !pc.isopen ())
fh->set_name (pc); fh->set_name (pc);
else else
{ {
if (!fh->get_name ()) if (!fh->get_name ())
fh->set_name (fh->dev ().native); fh->set_name (fh->dev ().native ());
fh->archetype = fh->clone (); fh->archetype = fh->clone ();
debug_printf ("created an archetype (%p) for %s(%d/%d)", fh->archetype, fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor ()); debug_printf ("created an archetype (%p) for %s(%d/%d)", fh->archetype, fh->get_name (), fh->dev ().get_major (), fh->dev ().get_minor ());
fh->archetype->archetype = NULL; fh->archetype->archetype = NULL;

View File

@ -159,8 +159,8 @@ char *fhandler_base::get_proc_fd_name (char *buf)
{ {
if (get_name ()) if (get_name ())
return strcpy (buf, get_name ()); return strcpy (buf, get_name ());
if (dev ().name) if (dev ().name ())
return strcpy (buf, dev ().name); return strcpy (buf, dev ().name ());
return strcpy (buf, ""); return strcpy (buf, "");
} }

View File

@ -425,7 +425,7 @@ public:
virtual select_record *select_except (select_stuff *); virtual select_record *select_except (select_stuff *);
virtual const char *get_native_name () virtual const char *get_native_name ()
{ {
return dev ().native; return dev ().native ();
} }
virtual bg_check_types bg_check (int) {return bg_ok;} virtual bg_check_types bg_check (int) {return bg_ok;}
void clear_readahead () void clear_readahead ()
@ -1059,8 +1059,9 @@ class fhandler_disk_file: public fhandler_base
class fhandler_dev: public fhandler_disk_file class fhandler_dev: public fhandler_disk_file
{ {
const struct device *devidx; const struct _device *devidx;
bool dir_exists; bool dir_exists;
int drive, part;
public: public:
fhandler_dev (); fhandler_dev ();
int open (int flags, mode_t mode); int open (int flags, mode_t mode);
@ -1569,7 +1570,7 @@ class fhandler_pty_slave: public fhandler_pty_common
void fixup_after_exec (); void fixup_after_exec ();
select_record *select_read (select_stuff *); select_record *select_read (select_stuff *);
virtual char const *ttyname () { return pc.dev.name; } virtual char const *ttyname () { return pc.dev.name (); }
int __reg2 fstat (struct stat *buf); int __reg2 fstat (struct stat *buf);
int __reg3 facl (int, int, struct acl *); int __reg3 facl (int, int, struct acl *);
int __reg1 fchmod (mode_t mode); int __reg1 fchmod (mode_t mode);

View File

@ -25,8 +25,8 @@ details. */
static int static int
device_cmp (const void *a, const void *b) device_cmp (const void *a, const void *b)
{ {
return strcmp (((const device *) a)->name, return strcmp (((const device *) a)->name (),
((const device *) b)->name + dev_prefix_len); ((const device *) b)->name () + dev_prefix_len);
} }
fhandler_dev::fhandler_dev () : fhandler_dev::fhandler_dev () :
@ -147,6 +147,7 @@ fhandler_dev::opendir (int fd)
set_close_on_exec (true); set_close_on_exec (true);
dir->__fh = this; dir->__fh = this;
dir_exists = false; dir_exists = false;
drive = part = 0;
} }
devidx = dir_exists ? NULL : dev_storage_scan_start; devidx = dir_exists ? NULL : dev_storage_scan_start;
@ -161,11 +162,13 @@ free_dir:
return NULL; return NULL;
} }
static const WCHAR *hd_pattern = L"\\Device\\Harddisk%u\\Partition%u";
int int
fhandler_dev::readdir (DIR *dir, dirent *de) fhandler_dev::readdir (DIR *dir, dirent *de)
{ {
int ret; int ret;
const device *curdev; const _device *curdev;
device dev; device dev;
if (!devidx) if (!devidx)
@ -175,7 +178,7 @@ fhandler_dev::readdir (DIR *dir, dirent *de)
/* Avoid to print devices for which users have created files under /* Avoid to print devices for which users have created files under
/dev already, for instance by using the old script from Igor /dev already, for instance by using the old script from Igor
Peshansky. */ Peshansky. */
dev.name = de->d_name; dev.name (de->d_name);
if (!bsearch (&dev, dev_storage_scan_start, dev_storage_size, if (!bsearch (&dev, dev_storage_scan_start, dev_storage_size,
sizeof dev, device_cmp)) sizeof dev, device_cmp))
break; break;
@ -192,25 +195,63 @@ fhandler_dev::readdir (DIR *dir, dirent *de)
/* If exists returns < 0 it means that the device can be used by a /* If exists returns < 0 it means that the device can be used by a
program but its use is deprecated and, so, it is not returned program but its use is deprecated and, so, it is not returned
by readdir((). */ by readdir((). */
if (curdev->exists () <= 0) device *cdev = (device *) curdev;
if (cdev->exists () <= 0)
continue; continue;
++dir->__d_position; ++dir->__d_position;
strcpy (de->d_name, curdev->name + dev_prefix_len); strcpy (de->d_name, cdev->name () + dev_prefix_len);
if (curdev->get_major () == DEV_TTY_MAJOR if (cdev->get_major () == DEV_TTY_MAJOR
&& (curdev->is_device (FH_CONIN) && (cdev->is_device (FH_CONIN)
|| curdev->is_device (FH_CONOUT) || cdev->is_device (FH_CONOUT)
|| curdev->is_device (FH_CONSOLE))) || cdev->is_device (FH_CONSOLE)))
{ {
/* Make sure conin, conout, and console have the same inode number /* Make sure conin, conout, and console have the same inode number
as the current consX. */ as the current consX. */
de->d_ino = myself->ctty; de->d_ino = myself->ctty;
} }
else else
de->d_ino = curdev->get_device (); de->d_ino = cdev->get_device ();
de->d_type = curdev->type (); de->d_type = cdev->type ();
ret = 0; ret = 0;
break; break;
} }
/* Last but not least, scan for existing disks/partitions. */
if (ret)
{
UNICODE_STRING upath;
WCHAR buf[(sizeof *hd_pattern + 32) / sizeof (wchar_t)];
OBJECT_ATTRIBUTES attr;
FILE_BASIC_INFORMATION fbi;
NTSTATUS status;
InitializeObjectAttributes (&attr, &upath, 0, NULL, NULL);
while (drive < 128)
{
while (part < 64)
{
USHORT len = __small_swprintf (buf, hd_pattern, drive, part);
RtlInitCountedUnicodeString (&upath, buf, len * sizeof (WCHAR));
status = NtQueryAttributesFile (&attr, &fbi);
debug_printf ("%S %y", &upath, status);
if (status != STATUS_OBJECT_NAME_NOT_FOUND
&& status != STATUS_OBJECT_PATH_NOT_FOUND)
{
device dev (drive, part);
strcpy (de->d_name, dev.name () + 5);
de->d_ino = dev.get_device ();
de->d_type = DT_BLK;
++part;
ret = 0;
goto out;
}
if (part == 0)
break;
++part;
}
part = 0;
++drive;
}
}
out: out:
debug_printf ("returning %d", ret); debug_printf ("returning %d", ret);

View File

@ -513,7 +513,7 @@ fhandler_base::fstat_helper (struct stat *buf)
else else
{ {
buf->st_dev = buf->st_rdev = dev (); buf->st_dev = buf->st_rdev = dev ();
buf->st_mode = dev ().mode; buf->st_mode = dev ().mode ();
buf->st_size = 0; buf->st_size = 0;
} }
} }
@ -532,7 +532,7 @@ fhandler_base::fstat_helper (struct stat *buf)
else if (is_fs_special ()) else if (is_fs_special ())
{ {
buf->st_dev = buf->st_rdev = dev (); buf->st_dev = buf->st_rdev = dev ();
buf->st_mode = dev ().mode; buf->st_mode = dev ().mode ();
buf->st_size = 0; buf->st_size = 0;
} }
else else
@ -2091,7 +2091,7 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
else if (fpath.is_fs_special ()) else if (fpath.is_fs_special ())
{ {
fname->Length -= 4 * sizeof (WCHAR); fname->Length -= 4 * sizeof (WCHAR);
de->d_type = S_ISCHR (fpath.dev.mode) ? DT_CHR : DT_BLK; de->d_type = S_ISCHR (fpath.dev.mode ()) ? DT_CHR : DT_BLK;
} }
} }
} }

View File

@ -159,8 +159,9 @@ fhandler_dev_floppy::lock_partition (DWORD to_write)
/* The simple case. We have only a single partition open anyway. /* The simple case. We have only a single partition open anyway.
Try to lock the partition so that a subsequent write succeeds. Try to lock the partition so that a subsequent write succeeds.
If there's some file handle open on one of the affected partitions, If there's some file handle open on one of the affected partitions,
this fails, but that's how it works on Vista and later... */ this fails, but that's how it works on Vista and later...
if (get_minor () % 16 != 0) Only DEV_SD7_MAJOR and less can point to partition 0. */
if (get_major () <= DEV_SD7_MAJOR && get_minor () % 16 != 0)
{ {
if (!DeviceIoControl (get_handle (), FSCTL_LOCK_VOLUME, if (!DeviceIoControl (get_handle (), FSCTL_LOCK_VOLUME,
NULL, 0, NULL, 0, &bytes_read, NULL)) NULL, 0, NULL, 0, &bytes_read, NULL))

View File

@ -1334,7 +1334,6 @@ format_proc_partitions (void *, char *&destbuf)
DWORD bytes_read; DWORD bytes_read;
DWORD part_cnt = 0; DWORD part_cnt = 0;
unsigned long long size; unsigned long long size;
device dev;
restart = FALSE; restart = FALSE;
/* ... and check for a "Harddisk[0-9]*" entry. */ /* ... and check for a "Harddisk[0-9]*" entry. */
@ -1385,10 +1384,10 @@ format_proc_partitions (void *, char *&destbuf)
"IOCTL_DISK_GET_PARTITION_INFO{_EX}) %E", &upath); "IOCTL_DISK_GET_PARTITION_INFO{_EX}) %E", &upath);
size = 0; size = 0;
} }
dev.parsedisk (drive_num, 0); device dev (drive_num, 0);
bufptr += __small_sprintf (bufptr, "%5d %5d %9U %s\n", bufptr += __small_sprintf (bufptr, "%5d %5d %9U %s\n",
dev.get_major (), dev.get_minor (), dev.get_major (), dev.get_minor (),
size >> 10, dev.name + 5); size >> 10, dev.name () + 5);
/* Fetch drive layout info to get size of all partitions on the disk. */ /* Fetch drive layout info to get size of all partitions on the disk. */
if (DeviceIoControl (devhdl, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, if (DeviceIoControl (devhdl, IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
NULL, 0, ioctl_buf, NT_MAX_PATH, &bytes_read, NULL)) NULL, 0, ioctl_buf, NT_MAX_PATH, &bytes_read, NULL))
@ -1410,7 +1409,7 @@ format_proc_partitions (void *, char *&destbuf)
"IOCTL_DISK_GET_DRIVE_LAYOUT{_EX}): %E", &upath); "IOCTL_DISK_GET_DRIVE_LAYOUT{_EX}): %E", &upath);
/* Loop over partitions. */ /* Loop over partitions. */
if (pix || pi) if (pix || pi)
for (DWORD i = 0; i < part_cnt; ++i) for (DWORD i = 0; i < part_cnt && i < 64; ++i)
{ {
DWORD part_num; DWORD part_num;
@ -1431,11 +1430,11 @@ format_proc_partitions (void *, char *&destbuf)
Just skip. */ Just skip. */
if (part_num == 0) if (part_num == 0)
continue; continue;
dev.parsedisk (drive_num, part_num); device dev (drive_num, part_num);
bufptr += __small_sprintf (bufptr, "%5d %5d %9U %s", bufptr += __small_sprintf (bufptr, "%5d %5d %9U %s",
dev.get_major (), dev.get_minor (), dev.get_major (), dev.get_minor (),
size >> 10, dev.name + 5); size >> 10, dev.name () + 5);
/* Check if the partition is mounted in Windows and, if so, /* Check if the partition is mounted in Windows and, if so,
print the mount point list. */ print the mount point list. */
__small_swprintf (fpath, __small_swprintf (fpath,
@ -1445,7 +1444,7 @@ format_proc_partitions (void *, char *&destbuf)
&& GetVolumePathNamesForVolumeNameW (gpath, mp_buf, && GetVolumePathNamesForVolumeNameW (gpath, mp_buf,
NT_MAX_PATH, &len)) NT_MAX_PATH, &len))
{ {
len = strlen (dev.name + 5); len = strlen (dev.name () + 5);
while (len++ < 6) while (len++ < 6)
*bufptr++ = ' '; *bufptr++ = ' ';
for (PWCHAR p = mp_buf; *p; p = wcschr (p, L'\0') + 1) for (PWCHAR p = mp_buf; *p; p = wcschr (p, L'\0') + 1)

View File

@ -461,8 +461,8 @@ format_process_ctty (void *data, char *&destbuf)
} }
device d; device d;
d.parse (p->ctty); d.parse (p->ctty);
destbuf = (char *) crealloc_abort (destbuf, strlen (d.name) + 2); destbuf = (char *) crealloc_abort (destbuf, strlen (d.name ()) + 2);
return __small_sprintf (destbuf, "%s\n", d.name); return __small_sprintf (destbuf, "%s\n", d.name ());
} }
static off_t static off_t

View File

@ -54,7 +54,7 @@ chop $storage[$#storage];
chop $storage[$#storage]; chop $storage[$#storage];
$storage[$#storage] .= "\n"; $storage[$#storage] .= "\n";
splice(@lines, $storage_ix, 1, splice(@lines, $storage_ix, 1,
"const _RDATA device dev_storage[] =\n", "{\n", "const _RDATA _device dev_storage[] =\n", "{\n",
@storage, "};\n\n", @storage, "};\n\n",
sort {$a cmp $b} values %pointers); sort {$a cmp $b} values %pointers);
open(SHILKA, '>', $shilka); open(SHILKA, '>', $shilka);
@ -128,7 +128,7 @@ sub generate {
$rest = "$fh, $rest" if $rest =~ /^"/o; $rest = "$fh, $rest" if $rest =~ /^"/o;
$rest = fixup($rest, $vars); $rest = fixup($rest, $vars);
if ($rest =~ /^(.*), =(\S*_dev)\b\s*(.*)$/) { if ($rest =~ /^(.*), =(\S*_dev)\b\s*(.*)$/) {
$pointers{$2} ||= "const device *$2 = $storage_loc;\n"; $pointers{$2} ||= "const _device *$2 = $storage_loc;\n";
$rest = $1 . $3; $rest = $1 . $3;
} }
push(@storage, " {\"$dev\", " . $rest . "},\n"); push(@storage, " {\"$dev\", " . $rest . "},\n");

View File

@ -528,7 +528,8 @@ mmap_record::alloc_fh ()
of the correct type to be sure to call the method of the of the correct type to be sure to call the method of the
correct class. */ correct class. */
device fdev; device fdev;
fdev.name = fdev.native = ""; fdev.name ("");
fdev.native ("");
fdev.parse (get_device ()); fdev.parse (get_device ());
fhandler_base *fh = build_fh_dev (fdev); fhandler_base *fh = build_fh_dev (fdev);
if (fh) if (fh)

View File

@ -78,7 +78,7 @@ win32_device_name (const char *src_path, char *win32_path, device& dev)
dev.parse (src_path); dev.parse (src_path);
if (dev == FH_FS || dev == FH_DEV) if (dev == FH_FS || dev == FH_DEV)
return false; return false;
strcpy (win32_path, dev.native); strcpy (win32_path, dev.native ());
return true; return true;
} }

View File

@ -603,7 +603,7 @@ fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
if (fixup) if (fixup)
((fhandler_socket *) fd)->init_fixup_before (); ((fhandler_socket *) fd)->init_fixup_before ();
fd->set_flags (O_RDWR | O_BINARY); fd->set_flags (O_RDWR | O_BINARY);
debug_printf ("fd %d, name '%s', soc %p", (int) fd, dev->name, soc); debug_printf ("fd %d, name '%s', soc %p", (int) fd, dev->name (), soc);
/* Raise default buffer sizes (instead of WinSock default 8K). /* Raise default buffer sizes (instead of WinSock default 8K).

View File

@ -687,7 +687,6 @@ path_conv::check (const char *src, unsigned opt,
path = NULL; path = NULL;
} }
close_conv_handle (); close_conv_handle ();
memset (&dev, 0, sizeof (dev));
fs.clear (); fs.clear ();
if (posix_path) if (posix_path)
{ {
@ -944,7 +943,7 @@ path_conv::check (const char *src, unsigned opt,
} }
dev.parse (sym.major, sym.minor); dev.parse (sym.major, sym.minor);
dev.setfs (1); dev.setfs (1);
dev.mode = sym.mode; dev.mode (sym.mode);
fileattr = sym.fileattr; fileattr = sym.fileattr;
goto out; goto out;
} }

View File

@ -239,7 +239,7 @@ class path_conv
path_flags (0), suffix (NULL), posix_path (NULL), error (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0),
dev (in_dev) dev (in_dev)
{ {
set_path (in_dev.native); set_path (in_dev.native ());
} }
path_conv (int, const char *src, unsigned opt = PC_SYM_FOLLOW, path_conv (int, const char *src, unsigned opt = PC_SYM_FOLLOW,
@ -322,6 +322,10 @@ class path_conv
{ {
free_strings (); free_strings ();
memcpy (this, &pc, sizeof pc); memcpy (this, &pc, sizeof pc);
/* The device info might contain pointers to allocated strings, in
contrast to statically allocated strings. Calling device::dup()
will duplicate the string if the source was allocated. */
dev.dup ();
path = cstrdup (in_path); path = cstrdup (in_path);
conv_handle.dup (pc.conv_handle); conv_handle.dup (pc.conv_handle);
posix_path = cstrdup(pc.posix_path); posix_path = cstrdup(pc.posix_path);

View File

@ -449,7 +449,7 @@ _pinfo::_ctty (char *buf)
{ {
device d; device d;
d.parse (ctty); d.parse (ctty);
__small_sprintf (buf, "ctty %s", d.name); __small_sprintf (buf, "ctty %s", d.name ());
} }
return buf; return buf;
} }

View File

@ -100,7 +100,7 @@ quotactl (int cmd, const char *special, int id, caddr_t addr)
set_errno (ENOENT); set_errno (ENOENT);
return -1; return -1;
} }
if (!S_ISBLK (pc.dev.mode)) if (!S_ISBLK (pc.dev.mode ()))
{ {
set_errno (ENOTBLK); set_errno (ENOTBLK);
return -1; return -1;

View File

@ -1646,7 +1646,7 @@ umask (mode_t mask)
int int
chmod_device (path_conv& pc, mode_t mode) chmod_device (path_conv& pc, mode_t mode)
{ {
return mknod_worker (pc.get_win32 (), pc.dev.mode & S_IFMT, mode, pc.dev.get_major (), pc.dev.get_minor ()); return mknod_worker (pc.get_win32 (), pc.dev.mode () & S_IFMT, mode, pc.dev.get_major (), pc.dev.get_minor ());
} }
#define FILTERED_MODE(m) ((m) & (S_ISUID | S_ISGID | S_ISVTX \ #define FILTERED_MODE(m) ((m) & (S_ISUID | S_ISGID | S_ISVTX \
@ -2769,7 +2769,7 @@ ctermid (char *str)
{ {
device d; device d;
d.parse (myself->ctty); d.parse (myself->ctty);
strcpy (str, d.name); strcpy (str, d.name ());
} }
return str; return str;
} }

View File

@ -277,5 +277,5 @@ tty_min::ttyname ()
{ {
device d; device d;
d.parse (ntty); d.parse (ntty);
return d.name; return d.name ();
} }