From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id 3D20D3858D3C; Tue, 21 Nov 2023 18:41:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3D20D3858D3C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1700592062; bh=QMVqJzz+vQTJ5l5Zd1s2ZBLPZD9bjSjPfOY5f+tiytg=; h=From:To:Subject:Date:From; b=V+ZeqhvFlHy6ch4/gEAHEWuRDNzPDkDWOmBhloK7zMLfaiDbhHetIaCiqFfP45QCP x/JelOHaXp2TzHPb8lVxQdvpocsEgE4e6z6GwCRWLOpSjPqkqPPNzTovoDHr4DNMki 8QwiaahpiC6+3SI5iQnIQRmWYU+FqIkR/U25xD9Q= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/main] Cygwin: /dev/disk: Append '#N' if the same name appears more than once X-Act-Checkin: newlib-cygwin X-Git-Author: Christian Franke X-Git-Refname: refs/heads/main X-Git-Oldrev: 3cacedbbac5b2ab651fddcad1d5ce2acd1979b93 X-Git-Newrev: 3ef4bb186196b23f7a349a0614294b7ee1e0c4dc Message-Id: <20231121184102.3D20D3858D3C@sourceware.org> Date: Tue, 21 Nov 2023 18:41:02 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D3ef4bb18619= 6b23f7a349a0614294b7ee1e0c4dc commit 3ef4bb186196b23f7a349a0614294b7ee1e0c4dc Author: Christian Franke AuthorDate: Tue Nov 21 19:28:02 2023 +0100 Commit: Corinna Vinschen CommitDate: Tue Nov 21 19:40:37 2023 +0100 Cygwin: /dev/disk: Append '#N' if the same name appears more than once =20 No longer drop ranges of identical link names. Append '#0, #1, ...' to each name instead. Enhance charset allowed in label names. No longer ignore null volume serial numbers. =20 Signed-off-by: Christian Franke Diff: --- winsup/cygwin/fhandler/dev_disk.cc | 54 +++++++++++++++++++++++-----------= ---- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/winsup/cygwin/fhandler/dev_disk.cc b/winsup/cygwin/fhandler/de= v_disk.cc index c5d72816f0c5..29af9de95a0e 100644 --- a/winsup/cygwin/fhandler/dev_disk.cc +++ b/winsup/cygwin/fhandler/dev_disk.cc @@ -64,10 +64,11 @@ sanitize_label_string (WCHAR *s) /* Linux does not skip leading spaces. */ return sanitize_string (s, L'\0', L' ', L'_', [] (WCHAR c) -> bool { - /* Labels may contain characters not allowed in filenames. - Linux replaces spaces with \x20 which is not an option here. */ - return !((0 <=3D c && c <=3D L' ') || c =3D=3D L':' || c =3D=3D L'/'= || c =3D=3D L'\\' - || c =3D=3D L'"'); + /* Labels may contain characters not allowed in filenames. Also + replace '#' to avoid that duplicate markers introduce new + duplicates. Linux replaces spaces with \x20 which is not an + option here. */ + return !(c =3D=3D L'/' || c =3D=3D L'\\' || c =3D=3D L'#'); } ); } @@ -304,8 +305,7 @@ partition_to_label_or_uuid(bool uuid, const UNICODE_STR= ING *drive_uname, const NTFS_VOLUME_DATA_BUFFER *nvdb =3D reinterpret_cast(ioctl_buf); if (uuid && DeviceIoControl (volhdl, FSCTL_GET_NTFS_VOLUME_DATA, nullptr= , 0, - ioctl_buf, NT_MAX_PATH, &bytes_read, nullptr) - && nvdb->VolumeSerialNumber.QuadPart) + ioctl_buf, NT_MAX_PATH, &bytes_read, nullptr)) { /* Print without any separator as on Linux. */ __small_sprintf (name, "%016X", nvdb->VolumeSerialNumber.QuadPart); @@ -327,13 +327,9 @@ partition_to_label_or_uuid(bool uuid, const UNICODE_ST= RING *drive_uname, FILE_FS_VOLUME_INFORMATION *ffvi =3D reinterpret_cast(ioctl_buf); if (uuid) - { - if (!ffvi->VolumeSerialNumber) - return false; - /* Print with separator as on Linux. */ - __small_sprintf (name, "%04x-%04x", ffvi->VolumeSerialNumber >> 16, - ffvi->VolumeSerialNumber & 0xffff); - } + /* Print with separator as on Linux. */ + __small_sprintf (name, "%04x-%04x", ffvi->VolumeSerialNumber >> 16, + ffvi->VolumeSerialNumber & 0xffff); else { /* Label is not null terminated. */ @@ -361,6 +357,20 @@ by_id_compare_name (const void *a, const void *b) return strcmp (ap->name, bp->name); } =20 +static int +by_id_compare_name_drive_part (const void *a, const void *b) +{ + const by_id_entry *ap =3D reinterpret_cast(a); + const by_id_entry *bp =3D reinterpret_cast(b); + int cmp =3D strcmp (ap->name, bp->name); + if (cmp) + return cmp; + cmp =3D ap->drive - bp->drive; + if (cmp) + return cmp; + return ap->part - bp->part; +} + static by_id_entry * by_id_realloc (by_id_entry *p, size_t n) { @@ -610,8 +620,9 @@ get_by_id_table (by_id_entry * &table, fhandler_dev_dis= k::dev_disk_location loc) if (!table) return (errno_set ? -1 : 0); =20 - /* Sort by name and remove duplicates. */ - qsort (table, table_size, sizeof (*table), by_id_compare_name); + /* Sort by {name, drive, part} to ensure stable sort order. */ + qsort (table, table_size, sizeof (*table), by_id_compare_name_drive_part= ); + /* Mark duplicate names. */ for (unsigned i =3D 0; i < table_size; i++) { unsigned j =3D i + 1; @@ -619,12 +630,13 @@ get_by_id_table (by_id_entry * &table, fhandler_dev_d= isk::dev_disk_location loc) j++; if (j =3D=3D i + 1) continue; - /* Duplicate(s) found, remove all entries with this name. */ - debug_printf ("removing duplicates %d-%d: '%s'", i, j - 1, table[i].= name); - if (j < table_size) - memmove (table + i, table + j, (table_size - j) * sizeof (*table)); - table_size -=3D j - i; - i--; + /* Duplicate(s) found, append "#N" to all entries. This never + introduces new duplicates because '#' never occurs in the + original names. */ + debug_printf ("mark duplicates %u-%u of '%s'", i, j - 1, table[i].na= me); + size_t len =3D strlen (table[i].name); + for (unsigned k =3D i; k < j; k++) + __small_sprintf (table[k].name + len, "#%u", k - i); } =20 debug_printf ("table_size: %d", table_size);