Tcl Source Code

View Ticket
Login
Ticket UUID: bc7925fc5038e49d114fb6bc0d6d8366f9be2f67
Title: Inconsistencies in long path handling in Tcl 8.6 and 9
Type: Bug Created on: 2025-12-18 11:10:06
Submitter: apnadkarni Assigned to: nobody
Subsystem: - New Builtin Commands Severity: Minor
Priority: 5 Medium Last modified: 2025-12-18 11:15:49
Status: Open Closed by: nobody
Resolution: None Closed on:
Version:
Description:

(I'm working on adding support for long paths as available in newer Windows versions. The bugs below are only tangentially related as the new support does not use the \\?\ prefix.)

Tcl 9 (and 8.6) support for long file paths (> MAX_PATH characters) on Windows is inconsistent and unusable from applications. Consider

% set longPath [file join [pwd] {*}[lrepeat 4 [string repeat X 254]]]; string length $longPath
1044
% file mkdir $longPath
% file isdirectory $longPath
1

All that works, but leads to inconsistent behaviour like you can create the directory but not change to it

% cd $longPath
couldn't change working directory to "C:/src/tcltk/wip/tcl/win/XXX.....XX": file name too long

Or the directory exists but not its parent!

% file isdirectory [file join $longPath ..]
0
% file exists [file join $longPath ..]
0

Or discrepancies with commands like glob

% glob $longPath/*
couldn't read directory "C:/src/tcltk/wip/tcl/win/XXXX...XX/*": no such file or directory
% glob $longPath/../*

The first case should not be returning an error. The second case should be returning the leaf component.

The basic issue is that Tcl tries to handle Windows MAX_PATH limitations by prefixing \\?\ to file paths whose lengths exceed MAX_PATH. That causes the Win32 API's to bypass their normal processing of paths and pass it directly to the NT Object manager which accepts paths up to 32K (or thereabouts). The problem is that

  • semantics of the NT Object manager are different from the Win32 "normal" or portable path syntax (leading to the bugs with the parent directories like above)
  • Tcl does not do this "helpful" preprocessing for all code paths.
  • Not all Win32 API's that Tcl calls may support this "pass-through" syntax

The result is the inconsistent and confusing behavior as logged in the c.l.t. thread and Tk ticket.

My opinion is that Tcl should not try to fix up deficiencies in a system API (Win32 in this case) unless it can do a reasonably thorough job. It is better to raise an error than present a logically inconsistent interface to the user as illustrated in the above commands.

User Comments:
apnadkarni added on 2025-12-18 11:15:49:

As a point of clarification, the apn-win-longpaths branch adds support for paths longer than MAX_PATH on systems that are configured to allow longer paths via Group Policy or registry settings. On such systems, relevant Win32 API's natively support longer file paths and the branch merely ensures Tcl itself does not limit path lengths through the use of static arrays.

In particular, it will not help on systems where long path support has not been enabled. On these systems the issues listed in the ticket will continue to exist.