diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-03-05 07:59:38 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-03-05 07:59:38 +0400 |
commit | b8315afeed0bc4ec1c9d9f7772957d372807b8b2 (patch) | |
tree | b36366cb423ab513c0d0c3fc1f57ce1ebd773eef /source/blender | |
parent | e39f05e5faa63027026e0ec4cd8c085113d01596 (diff) |
patch [#34103] fileops_file_is_writable.patch, fileops_file_is_writable_2.patch
from Lawrence D'Oliveiro (ldo)
More efficient implementation of BLI_file_is_writable using access(2) instead of actually opening file.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenlib/intern/fileops.c | 43 |
1 files changed, 20 insertions, 23 deletions
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index e8afead4999..3f8b21103b8 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -155,34 +155,31 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r) return mem; } - -/* return 1 when file can be written */ +/** + * Returns true if the file with the specified name can be written. + * This implementation uses access(2), which makes the check according + * to the real UID and GID of the process, not its effective UID and GID. + * This shouldn't matter for Blender, which is not going to run privileged + * anyway. + */ bool BLI_file_is_writable(const char *filename) { - int file; - - /* first try to open without creating */ - file = BLI_open(filename, O_BINARY | O_RDWR, 0666); - - if (file < 0) { - /* now try to open and create. a test without actually - * creating a file would be nice, but how? */ - file = BLI_open(filename, O_BINARY | O_RDWR | O_CREAT, 0666); - - if (file < 0) { - return false; - } - else { - /* success, delete the file we create */ - close(file); - BLI_delete(filename, false, false); - return true; - } + bool writable; + if (access(filename, W_OK) == 0) { + /* file exists and I can write to it */ + writable = true; + } + else if (errno != ENOENT) { + /* most likely file or containing directory cannot be accessed */ + writable = false; } else { - close(file); - return true; + /* file doesn't exist -- check I can create it in parent directory */ + char parent[FILE_MAX]; + BLI_split_dirfile(filename, parent, NULL, sizeof parent, 0); + writable = access(parent, X_OK | W_OK) == 0; } + return writable; } /** |