Skip to content

Commit 2269d7d

Browse files
raltMylesBorins
authored andcommitted
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: #5333 Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Trevor Norris <[email protected]>
1 parent 5824522 commit 2269d7d

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

‎doc/api/fs.md‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,30 @@ added: v0.1.21
851851

852852
Synchronous mkdir(2). Returns `undefined`.
853853

854+
## fs.mkdtemp(prefix, callback)
855+
856+
Creates a unique temporary directory.
857+
858+
Generates six random characters to be appended behind a required
859+
`prefix` to create a unique temporary directory.
860+
861+
The created folder path is passed as a string to the callback's second
862+
parameter.
863+
864+
Example:
865+
866+
```js
867+
fs.mkdtemp('/tmp/foo-', (err, folder) =>{
868+
console.log(folder);
869+
// Prints: /tmp/foo-itXde2
870+
});
871+
```
872+
873+
## fs.mkdtempSync(template)
874+
875+
The synchronous version of [`fs.mkdtemp()`][]. Returns the created
876+
folder path.
877+
854878
## fs.open(path, flags[, mode], callback)
855879
<!-- YAML
856880
added: v0.0.2

‎lib/fs.js‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,3 +1990,24 @@ SyncWriteStream.prototype.destroy = function(){
19901990
};
19911991

19921992
SyncWriteStream.prototype.destroySoon=SyncWriteStream.prototype.destroy;
1993+
1994+
fs.mkdtemp=function(prefix,callback){
1995+
if(typeofcallback!=='function'){
1996+
thrownewTypeError('"callback" argument must be a function');
1997+
}
1998+
1999+
if(!nullCheck(prefix,callback)){
2000+
return;
2001+
}
2002+
2003+
varreq=newFSReqWrap();
2004+
req.oncomplete=callback;
2005+
2006+
binding.mkdtemp(prefix+'XXXXXX',req);
2007+
};
2008+
2009+
fs.mkdtempSync=function(prefix){
2010+
nullCheck(prefix);
2011+
2012+
returnbinding.mkdtemp(prefix+'XXXXXX');
2013+
};

‎src/node_file.cc‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,11 @@ static void After(uv_fs_t *req){
200200
static_cast<constuv_stat_t*>(req->ptr));
201201
break;
202202

203+
case UV_FS_MKDTEMP:
204+
argv[1] = String::NewFromUtf8(env->isolate(),
205+
static_cast<constchar*>(req->path));
206+
break;
207+
203208
case UV_FS_READLINK:
204209
argv[1] = String::NewFromUtf8(env->isolate(),
205210
static_cast<constchar*>(req->ptr));
@@ -1264,6 +1269,25 @@ static void FUTimes(const FunctionCallbackInfo<Value>& args){
12641269
}
12651270
}
12661271

1272+
staticvoidMkdtemp(const FunctionCallbackInfo<Value>& args){
1273+
Environment* env = Environment::GetCurrent(args);
1274+
1275+
if (args.Length() < 1)
1276+
returnTYPE_ERROR("template is required");
1277+
if (!args[0]->IsString())
1278+
returnTYPE_ERROR("template must be a string");
1279+
1280+
node::Utf8Value tmpl(env->isolate(), args[0]);
1281+
1282+
if (args[1]->IsObject()){
1283+
ASYNC_CALL(mkdtemp, args[1], *tmpl);
1284+
} else{
1285+
SYNC_CALL(mkdtemp, *tmpl, *tmpl);
1286+
args.GetReturnValue().Set(String::NewFromUtf8(env->isolate(),
1287+
SYNC_REQ.path));
1288+
}
1289+
}
1290+
12671291
voidFSInitialize(const FunctionCallbackInfo<Value>& args){
12681292
Local<Function> stats_constructor = args[0].As<Function>();
12691293
CHECK(stats_constructor->IsFunction());
@@ -1317,6 +1341,8 @@ void InitFs(Local<Object> target,
13171341
env->SetMethod(target, "utimes", UTimes);
13181342
env->SetMethod(target, "futimes", FUTimes);
13191343

1344+
env->SetMethod(target, "mkdtemp", Mkdtemp);
1345+
13201346
StatWatcher::Initialize(env, target);
13211347

13221348
// Create FunctionTemplate for FSReqWrap

‎test/parallel/test-fs-mkdtemp.js‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
constassert=require('assert');
5+
constfs=require('fs');
6+
constpath=require('path');
7+
constBuffer=require('buffer').Buffer;
8+
9+
common.refreshTmpDir();
10+
11+
consttmpFolder=fs.mkdtempSync(path.join(common.tmpDir,'foo.'));
12+
13+
assert(path.basename(tmpFolder).length==='foo.XXXXXX'.length);
14+
assert(common.fileExists(tmpFolder));
15+
16+
constutf8=fs.mkdtempSync(path.join(common.tmpDir,'\u0222abc.'));
17+
assert.equal(Buffer.byteLength(path.basename(utf8)),
18+
Buffer.byteLength('\u0222abc.XXXXXX'));
19+
assert(common.fileExists(utf8));
20+
21+
fs.mkdtemp(
22+
path.join(common.tmpDir,'bar.'),
23+
common.mustCall(function(err,folder){
24+
assert.ifError(err);
25+
assert(common.fileExists(folder));
26+
})
27+
);

0 commit comments

Comments
(0)