@@ -140,7 +140,8 @@ import .Base:
140
140
IOError, _UVError, _sizeof_uv_fs, check_open, close, eof, eventloop, fd, isopen,
141
141
bytesavailable, position, read, read!, readavailable, seek, seekend, show,
142
142
skip, stat, unsafe_read, unsafe_write, write, transcode, uv_error,
143
- setup_stdio, rawhandle, OS_HANDLE, INVALID_OS_HANDLE, windowserror, filesize
143
+ setup_stdio, rawhandle, OS_HANDLE, INVALID_OS_HANDLE, windowserror, filesize,
144
+ isexecutable, isreadable, iswritable
144
145
145
146
import . Base. RefValue
146
147
@@ -365,5 +366,85 @@ function touch(f::File)
365
366
f
366
367
end
367
368
369
+ """
370
+ isexecutable(path::String)
371
+
372
+ Return `true` if the given `path` has executable permissions.
373
+
374
+ !!! note
375
+ This permission may change before the user executes `path`,
376
+ so it is recommended to execute the file and handle the error if that fails,
377
+ rather than calling `isexecutable` first.
378
+
379
+ !!! note
380
+ Prior to Julia 1.6, this did not correctly interrogate filesystem
381
+ ACLs on Windows, therefore it would return `true` for any
382
+ file. From Julia 1.6 on, it correctly determines whether the
383
+ file is marked as executable or not.
384
+
385
+ See also [`ispath`](@ref), [`isreadable`](@ref), [`iswritable`](@ref).
386
+ """
387
+ function isexecutable (path:: String )
388
+ # We use `access()` and `X_OK` to determine if a given path is
389
+ # executable by the current user. `X_OK` comes from `unistd.h`.
390
+ X_OK = 0x01
391
+ return ccall (:jl_fs_access , Cint, (Cstring, Cint), path, X_OK) == 0
392
+ end
393
+ isexecutable (path:: AbstractString ) = isexecutable (String (path))
394
+
395
+ """
396
+ isreadable(path::String)
397
+
398
+ Return `true` if the access permissions for the given `path` permitted reading by the current user.
399
+
400
+ !!! note
401
+ This permission may change before the user calls `open`,
402
+ so it is recommended to just call `open` alone and handle the error if that fails,
403
+ rather than calling `isreadable` first.
404
+
405
+ !!! note
406
+ Currently this function does not correctly interrogate filesystem
407
+ ACLs on Windows, therefore it can return wrong results.
408
+
409
+ !!! compat "Julia 1.11"
410
+ This function requires at least Julia 1.11.
411
+
412
+ See also [`ispath`](@ref), [`isexecutable`](@ref), [`iswritable`](@ref).
413
+ """
414
+ function isreadable (path:: String )
415
+ # We use `access()` and `R_OK` to determine if a given path is
416
+ # readable by the current user. `R_OK` comes from `unistd.h`.
417
+ R_OK = 0x04
418
+ return ccall (:jl_fs_access , Cint, (Cstring, Cint), path, R_OK) == 0
419
+ end
420
+ isreadable (path:: AbstractString ) = isreadable (String (path))
421
+
422
+ """
423
+ iswritable(path::String)
424
+
425
+ Return `true` if the access permissions for the given `path` permitted writing by the current user.
426
+
427
+ !!! note
428
+ This permission may change before the user calls `open`,
429
+ so it is recommended to just call `open` alone and handle the error if that fails,
430
+ rather than calling `iswritable` first.
431
+
432
+ !!! note
433
+ Currently this function does not correctly interrogate filesystem
434
+ ACLs on Windows, therefore it can return wrong results.
435
+
436
+ !!! compat "Julia 1.11"
437
+ This function requires at least Julia 1.11.
438
+
439
+ See also [`ispath`](@ref), [`isexecutable`](@ref), [`isreadable`](@ref).
440
+ """
441
+ function iswritable (path:: String )
442
+ # We use `access()` and `W_OK` to determine if a given path is
443
+ # writeable by the current user. `W_OK` comes from `unistd.h`.
444
+ W_OK = 0x02
445
+ return ccall (:jl_fs_access , Cint, (Cstring, Cint), path, W_OK) == 0
446
+ end
447
+ iswritable (path:: AbstractString ) = iswritable (String (path))
448
+
368
449
369
450
end
0 commit comments