Determine if a directory or file is writable

Ultimately what I would like to do is determine if a directory or file is writable by the current user. Looking at the Filesystem commands there is uperm(), gperm(), and operm() which at first blush look like exactly what I need. However to determine if uperm() is me I need to know my user ID so that I can compare it with the owner ID of the file. Likewise with gperm() I would need to know if one of my groups match the group of the file system object.

I haven’t been able to find a function in Julia that returns the user’s ID…nor anything about the groups the user belongs to. I would like functions that work in both Linux and Windows so I would prefer something in Julia (or a package) rather than executing external commands.

I would like to do this before I start doing some expensive operations so that I know I can save the results. And yes, with the behavior of this application it is entirely possible the user pointed me at a directory/file they do not have write access to. So it is a situation I need to handle.

Alternate solutions for testing the directory I’ve come up with, is first I could try to create an empty file in the directory, if that works, then I have write access. Or, and I like this better, I believe I could just touch() the directory, if that works, we should be good to go from a directory standpoint.

The file solution is trickier. I could use touch() or even just try to open the file for write access. But both of those would update the last modified time. And I don’t want to update the last modified time before I actually have the data to modify the file with.

Anyone have any suggestions?

A very hacky (and not very portable) solution is getting the user id with something like

parse(Int, chomp(read(`id -u`, String)))

and then comparing it to the relevant parts from stat(directory) etc.

id can also deliver groups in a format you can parse. There is probably a neater solution, using the getuid etc functions from C would be more elegant.

1 Like

Thank you, that pushed me down some other pathes. :slight_smile: I think in the end I’m going to go for a solution that works “most” of the time. I’ll do a touch() on the directory if that works, then I’ll assume I have write access to the files inside. The chances of that assumption being wrong should be low enough to not be a big deal. :slight_smile:

Another solution that occurs to me is

is_writable(path) = success(`test -w $(path)`)

which should work on Linux, don’t know about OS X.

It would be great if at least a package could expose getuid & friends.

1 Like

Oh, I like that. :slight_smile:

If you want to call getuid, you can just do ccall(:getuid, Cint, ()).

However, neither this nor any of the above solutions will work on Windows, where checking write permissions seems incredibly complicated if you don’t want to try writing to the file.

1 Like

To be fair, a lot of things can complicate the issue on Linux too (eg SELinux).

Perhaps a try ... catch block would work best, aiming to actually perform whatever task is needed, catching an IOError for the “permission denied” code, and rethrowing everything else. Exceptions are relatively costly, but not in the context of filesystem access.

3 Likes