Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Implement RFE [b42b208ba4]: file attributes -readonly (and -archive, -hidden, -system) on Cygwin. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
56569781637c73c6c22a8cff1b175861 |
User & Date: | jan.nijtmans 2014-03-26 14:38:07 |
Context
2014-03-27
| ||
16:27 | New test iortrans-4.8.1 exposes segfault bug [721ec69271]. check-in: 994f93910e user: dgp tags: trunk | |
2014-03-26
| ||
14:38 | Implement RFE [b42b208ba4]: file attributes -readonly (and -archive, -hidden, -system) on Cygwin. check-in: 5656978163 user: jan.nijtmans tags: trunk | |
14:34 | Only write back file attributes if any of them really changed. Closed-Leaf check-in: f6fc8ce920 user: jan.nijtmans tags: rfe-b42b208ba4 | |
2014-03-21
| ||
17:11 | Added comments raising questions about possible updates to channel drivers on Windows. check-in: 5134ecb54a user: dgp tags: trunk | |
Changes
Changes to unix/tclUnixFCmd.c.
︙ | ︙ | |||
87 88 89 90 91 92 93 | static int SetOwnerAttribute(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); static int SetPermissionsAttribute(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); static int GetModeFromPermString(Tcl_Interp *interp, const char *modeStringPtr, mode_t *modePtr); | | | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | static int SetOwnerAttribute(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); static int SetPermissionsAttribute(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); static int GetModeFromPermString(Tcl_Interp *interp, const char *modeStringPtr, mode_t *modePtr); #if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__) static int GetUnixFileAttributes(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr); static int SetUnixFileAttributes(Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); #endif /* * Prototype for the TraverseUnixTree callback function. */ |
︙ | ︙ | |||
120 121 122 123 124 125 126 | */ extern TclFileAttrProcs tclpFileAttrProcs[]; extern const char *const tclpFileAttrStrings[]; #else /* !DJGPP */ enum { | > > > > > > > | | > > > > > > > > > > | | > > > > > > > > > | | > > > | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | */ extern TclFileAttrProcs tclpFileAttrProcs[]; extern const char *const tclpFileAttrStrings[]; #else /* !DJGPP */ enum { #if defined(__CYGWIN__) UNIX_ARCHIVE_ATTRIBUTE, #endif UNIX_GROUP_ATTRIBUTE, #if defined(__CYGWIN__) UNIX_HIDDEN_ATTRIBUTE, #endif UNIX_OWNER_ATTRIBUTE, UNIX_PERMISSIONS_ATTRIBUTE, #if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__) UNIX_READONLY_ATTRIBUTE, #endif #if defined(__CYGWIN__) UNIX_SYSTEM_ATTRIBUTE, #endif #ifdef MAC_OSX_TCL MACOSX_CREATOR_ATTRIBUTE, MACOSX_TYPE_ATTRIBUTE, MACOSX_HIDDEN_ATTRIBUTE, MACOSX_RSRCLENGTH_ATTRIBUTE, #endif UNIX_INVALID_ATTRIBUTE /* lint - last enum value needs no trailing , */ }; MODULE_SCOPE const char *const tclpFileAttrStrings[]; const char *const tclpFileAttrStrings[] = { #if defined(__CYGWIN__) "-archive", #endif "-group", #if defined(__CYGWIN__) "-hidden", #endif "-owner", "-permissions", #if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__) "-readonly", #endif #if defined(__CYGWIN__) "-system", #endif #ifdef MAC_OSX_TCL "-creator", "-type", "-hidden", "-rsrclength", #endif NULL }; MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[]; const TclFileAttrProcs tclpFileAttrProcs[] = { #if defined(__CYGWIN__) {GetUnixFileAttributes, SetUnixFileAttributes}, #endif {GetGroupAttribute, SetGroupAttribute}, #if defined(__CYGWIN__) {GetUnixFileAttributes, SetUnixFileAttributes}, #endif {GetOwnerAttribute, SetOwnerAttribute}, {GetPermissionsAttribute, SetPermissionsAttribute}, #if defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) || defined(__CYGWIN__) {GetUnixFileAttributes, SetUnixFileAttributes}, #endif #if defined(__CYGWIN__) {GetUnixFileAttributes, SetUnixFileAttributes}, #endif #ifdef MAC_OSX_TCL {TclMacOSXGetFileAttribute, TclMacOSXSetFileAttribute}, {TclMacOSXGetFileAttribute, TclMacOSXSetFileAttribute}, {TclMacOSXGetFileAttribute, TclMacOSXSetFileAttribute}, {TclMacOSXGetFileAttribute, TclMacOSXSetFileAttribute}, #endif |
︙ | ︙ | |||
2242 2243 2244 2245 2246 2247 2248 | * an existing writable directory; we've no recovery mechanism if it * isn't. */ return TCL_TEMPORARY_FILE_DIRECTORY; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 | * an existing writable directory; we've no recovery mechanism if it * isn't. */ return TCL_TEMPORARY_FILE_DIRECTORY; } #if defined(__CYGWIN__) static void StatError( Tcl_Interp *interp, /* The interp that has the error */ Tcl_Obj *fileName) /* The name of the file which caused the * error. */ { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf("could not read \"%s\": %s", TclGetString(fileName), Tcl_PosixError(interp))); } static WCHAR * winPathFromObj( Tcl_Obj *fileName) { int size; const char *native = Tcl_FSGetNativePath(fileName); WCHAR *winPath; size = cygwin_conv_path(1, native, NULL, 0); winPath = ckalloc(size); cygwin_conv_path(1, native, winPath, size); return winPath; } static const int attributeArray[] = { 0x20, 0, 2, 0, 0, 1, 4}; /* *---------------------------------------------------------------------- * * GetUnixFileAttributes * * Gets the readonly attribute of a file. * * Results: * Standard TCL result. Returns a new Tcl_Obj in attributePtrPtr if there * is no error. The object will have ref count 0. * * Side effects: * A new object is allocated. * *---------------------------------------------------------------------- */ static int GetUnixFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file (UTF-8). */ Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */ { int fileAttributes; WCHAR *winPath = winPathFromObj(fileName); fileAttributes = GetFileAttributesW(winPath); ckfree(winPath); if (fileAttributes == -1) { StatError(interp, fileName); return TCL_ERROR; } *attributePtrPtr = Tcl_NewIntObj((fileAttributes&attributeArray[objIndex])!=0); return TCL_OK; } /* *--------------------------------------------------------------------------- * * SetUnixFileAttributes * * Sets the readonly attribute of a file. * * Results: * Standard TCL result. * * Side effects: * The readonly attribute of the file is changed. * *--------------------------------------------------------------------------- */ static int SetUnixFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file (UTF-8). */ Tcl_Obj *attributePtr) /* The attribute to set. */ { int yesNo, fileAttributes, old; WCHAR *winPath; if (Tcl_GetBooleanFromObj(interp, attributePtr, &yesNo) != TCL_OK) { return TCL_ERROR; } winPath = winPathFromObj(fileName); fileAttributes = old = GetFileAttributesW(winPath); if (fileAttributes == -1) { ckfree(winPath); StatError(interp, fileName); return TCL_ERROR; } if (yesNo) { fileAttributes |= attributeArray[objIndex]; } else { fileAttributes &= ~attributeArray[objIndex]; } if ((fileAttributes != old) && !SetFileAttributesW(winPath, fileAttributes)) { ckfree(winPath); StatError(interp, fileName); return TCL_ERROR; } ckfree(winPath); return TCL_OK; } #elif defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE) /* *---------------------------------------------------------------------- * * GetUnixFileAttributes * * Gets the readonly attribute (user immutable flag) of a file. * * Results: * Standard TCL result. Returns a new Tcl_Obj in attributePtrPtr if there * is no error. The object will have ref count 0. * * Side effects: * A new object is allocated. * *---------------------------------------------------------------------- */ static int GetUnixFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file (UTF-8). */ Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */ { Tcl_StatBuf statBuf; int result; |
︙ | ︙ | |||
2289 2290 2291 2292 2293 2294 2295 | return TCL_OK; } /* *--------------------------------------------------------------------------- * | | | | 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 | return TCL_OK; } /* *--------------------------------------------------------------------------- * * SetUnixFileAttributes * * Sets the readonly attribute (user immutable flag) of a file. * * Results: * Standard TCL result. * * Side effects: * The readonly attribute of the file is changed. * *--------------------------------------------------------------------------- */ static int SetUnixFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file (UTF-8). */ Tcl_Obj *attributePtr) /* The attribute to set. */ { Tcl_StatBuf statBuf; int result, readonly; |
︙ | ︙ |
Changes to unix/tclUnixPort.h.
︙ | ︙ | |||
89 90 91 92 93 94 95 96 97 98 99 100 101 102 | __declspec(dllimport) extern __stdcall int GetModuleFileNameW(void *, const char *, int); __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int, const char *, int, const char *, int, const char *, const char *); __declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int, const char *, int, WCHAR *, int); __declspec(dllimport) extern __stdcall void OutputDebugStringW(const WCHAR *); __declspec(dllimport) extern __stdcall int IsDebuggerPresent(); __declspec(dllimport) extern int cygwin_conv_path(int, const void *, void *, int); __declspec(dllimport) extern int cygwin_conv_path_list(int, const void *, void *, int); # define USE_PUTENV 1 # define USE_PUTENV_FOR_UNSET 1 /* On Cygwin, the environment is imported from the Cygwin DLL. */ #ifndef __x86_64__ | > > > | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | __declspec(dllimport) extern __stdcall int GetModuleFileNameW(void *, const char *, int); __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int, const char *, int, const char *, int, const char *, const char *); __declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int, const char *, int, WCHAR *, int); __declspec(dllimport) extern __stdcall void OutputDebugStringW(const WCHAR *); __declspec(dllimport) extern __stdcall int IsDebuggerPresent(); __declspec(dllimport) extern __stdcall int GetLastError(); __declspec(dllimport) extern __stdcall int GetFileAttributesW(const WCHAR *); __declspec(dllimport) extern __stdcall int SetFileAttributesW(const WCHAR *, int); __declspec(dllimport) extern int cygwin_conv_path(int, const void *, void *, int); __declspec(dllimport) extern int cygwin_conv_path_list(int, const void *, void *, int); # define USE_PUTENV 1 # define USE_PUTENV_FOR_UNSET 1 /* On Cygwin, the environment is imported from the Cygwin DLL. */ #ifndef __x86_64__ |
︙ | ︙ |
Changes to win/tclWinFCmd.c.
︙ | ︙ | |||
1821 1822 1823 1824 1825 1826 1827 | static int SetWinFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file. */ Tcl_Obj *attributePtr) /* The new value of the attribute. */ { | | | > | | 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 | static int SetWinFileAttributes( Tcl_Interp *interp, /* The interp we are using for errors. */ int objIndex, /* The index of the attribute. */ Tcl_Obj *fileName, /* The name of the file. */ Tcl_Obj *attributePtr) /* The new value of the attribute. */ { DWORD fileAttributes, old; int yesNo, result; const TCHAR *nativeName; nativeName = Tcl_FSGetNativePath(fileName); fileAttributes = old = GetFileAttributes(nativeName); if (fileAttributes == 0xffffffff) { StatError(interp, fileName); return TCL_ERROR; } result = Tcl_GetBooleanFromObj(interp, attributePtr, &yesNo); if (result != TCL_OK) { return result; } if (yesNo) { fileAttributes |= (attributeArray[objIndex]); } else { fileAttributes &= ~(attributeArray[objIndex]); } if ((fileAttributes != old) && !SetFileAttributes(nativeName, fileAttributes)) { StatError(interp, fileName); return TCL_ERROR; } return result; } |
︙ | ︙ |