soyuka
soyuka

Reputation: 9105

What's the most portable way to test if a directory is writable in nodejs?

A friend asked me this question and I gave de-facto two options.

First way, testing the file permissions:

//adapted from https://stackoverflow.com/questions/11775884/nodejs-file-permissions#answer-11781404
var fs = require('fs')

function canWrite(directory) {
 var stat = fs.statSync(directory)

 // 2 is the octal value for chmod -w-
 return !!( 2 & (stat.mode & parseInt('777', 8)).toString(8)[0] ) //first char is the owner
}

What if the user (process.uid) was not the file system owner (stat.uid) neither in it's group (process.gid vs stat.gid)? It will still get the 644 permissions and writing will not be possible.

How may we actually know (with nodejs) that the current user belongs to the file system group (stat.gid)? Easy in bash but to be portable it'd be a mess with nodejs.

Second way, lazy:

var fs = require('fs')
var canWrite = true

try {
  fs.writeFileSync('./test')
  fs.unlinkSync('./test')
} catch(e) {
  canWrite = false
}

if(canWrite) {
 //go for it
}

Lazy solution of couse, but it should do the job. This could also block the kernel buffer. On the other side, fs.Stat is usually cached by operating systems.

Neither of these solution is perfect.

How would you do? Is there something I'm missing?

Upvotes: 14

Views: 7239

Answers (1)

Maroshii
Maroshii

Reputation: 4027

What about:

var fs = require('fs');

fs.access(__dirname, fs.constants.W_OK, function(err) {
  if(err){
    console.error("can't write");
    process.exit(1);
  }

  console.log("can write");
  process.exit(0);
});

Docs here

fs.constants.W_OK : File can be written by the calling process.

If you run the above with sudo you may get different outputs depending on user permissions.

Upvotes: 26

Related Questions