fs: add the fs.mkdtemp() function.

This uses libuv's mkdtemp function to provide a way to create a
temporary folder, using a prefix as the path. The prefix is appended
six random characters. The callback function will receive the name
of the folder that was created.

Usage example:

fs.mkdtemp('/tmp/foo-', function(err, folder) {
    console.log(folder);
        // Prints: /tmp/foo-Tedi42
});

The fs.mkdtempSync version is also provided. Usage example:

console.log(fs.mkdtemp('/tmp/foo-'));
    // Prints: tmp/foo-Tedi42

This pull request also includes the relevant documentation changes
and tests.

PR-URL: https://github.com/nodejs/node/pull/5333
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Florian MARGAINE 2016-02-24 22:17:44 +01:00 коммит произвёл Benjamin Gruenbaum
Родитель e6bfe044ff
Коммит e5f8a6a2fa
4 изменённых файлов: 98 добавлений и 0 удалений

Просмотреть файл

@ -532,6 +532,30 @@ to the completion callback. `mode` defaults to `0o777`.
Synchronous mkdir(2). Returns `undefined`.
## fs.mkdtemp(prefix, callback)
Creates a unique temporary directory.
Generates six random characters to be appended behind a required
`prefix` to create a unique temporary directory.
The created folder path is passed as a string to the callback's second
parameter.
Example:
```js
fs.mkdtemp('/tmp/foo-', (err, folder) => {
console.log(folder);
// Prints: /tmp/foo-itXde2
});
```
## fs.mkdtempSync(template)
The synchronous version of [`fs.mkdtemp()`][]. Returns the created
folder path.
## fs.open(path, flags[, mode], callback)
Asynchronous file open. See open(2). `flags` can be:

Просмотреть файл

@ -2138,3 +2138,24 @@ SyncWriteStream.prototype.destroy = function() {
};
SyncWriteStream.prototype.destroySoon = SyncWriteStream.prototype.destroy;
fs.mkdtemp = function(prefix, callback) {
if (typeof callback !== 'function') {
throw new TypeError('"callback" argument must be a function');
}
if (!nullCheck(prefix, callback)) {
return;
}
var req = new FSReqWrap();
req.oncomplete = callback;
binding.mkdtemp(prefix + 'XXXXXX', req);
};
fs.mkdtempSync = function(prefix) {
nullCheck(prefix);
return binding.mkdtemp(prefix + 'XXXXXX');
};

Просмотреть файл

@ -200,6 +200,11 @@ static void After(uv_fs_t *req) {
static_cast<const uv_stat_t*>(req->ptr));
break;
case UV_FS_MKDTEMP:
argv[1] = String::NewFromUtf8(env->isolate(),
static_cast<const char*>(req->path));
break;
case UV_FS_READLINK:
argv[1] = String::NewFromUtf8(env->isolate(),
static_cast<const char*>(req->ptr));
@ -1294,6 +1299,25 @@ static void FUTimes(const FunctionCallbackInfo<Value>& args) {
}
}
static void Mkdtemp(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
if (args.Length() < 1)
return TYPE_ERROR("template is required");
if (!args[0]->IsString())
return TYPE_ERROR("template must be a string");
node::Utf8Value tmpl(env->isolate(), args[0]);
if (args[1]->IsObject()) {
ASYNC_CALL(mkdtemp, args[1], *tmpl);
} else {
SYNC_CALL(mkdtemp, *tmpl, *tmpl);
args.GetReturnValue().Set(String::NewFromUtf8(env->isolate(),
SYNC_REQ.path));
}
}
void FSInitialize(const FunctionCallbackInfo<Value>& args) {
Local<Function> stats_constructor = args[0].As<Function>();
CHECK(stats_constructor->IsFunction());
@ -1347,6 +1371,8 @@ void InitFs(Local<Object> target,
env->SetMethod(target, "utimes", UTimes);
env->SetMethod(target, "futimes", FUTimes);
env->SetMethod(target, "mkdtemp", Mkdtemp);
StatWatcher::Initialize(env, target);
// Create FunctionTemplate for FSReqWrap

Просмотреть файл

@ -0,0 +1,27 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const Buffer = require('buffer').Buffer;
common.refreshTmpDir();
const tmpFolder = fs.mkdtempSync(path.join(common.tmpDir, 'foo.'));
assert(path.basename(tmpFolder).length === 'foo.XXXXXX'.length);
assert(common.fileExists(tmpFolder));
const utf8 = fs.mkdtempSync(path.join(common.tmpDir, '\u0222abc.'));
assert.equal(Buffer.byteLength(path.basename(utf8)),
Buffer.byteLength('\u0222abc.XXXXXX'));
assert(common.fileExists(utf8));
fs.mkdtemp(
path.join(common.tmpDir, 'bar.'),
common.mustCall(function(err, folder) {
assert.ifError(err);
assert(common.fileExists(folder));
})
);