Added posix fsync and fdatasync to fs module
authorAndrew Johnston <apjohnsto@gmail.com>
Mon, 22 Mar 2010 07:25:24 +0000 (07:25 +0000)
committerRyan Dahl <ry@tinyclouds.org>
Sat, 15 May 2010 01:42:22 +0000 (18:42 -0700)
lib/fs.js
src/node_file.cc
test/simple/test-fs-fsync.js [new file with mode: 0644]
wscript

index fcb89d2..833300d 100644 (file)
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -187,6 +187,22 @@ fs.rmdirSync = function (path) {
   return binding.rmdir(path);
 };
 
+fs.fdatasync = function (fd, callback) {
+  binding.fdatasync(fd, callback || noop);
+};
+
+fs.fdatasyncSync = function (fd) {
+  return binding.fdatasync(fd);
+};
+
+fs.fsync = function (fd, callback) {
+  binding.fsync(fd, callback || noop);
+};
+
+fs.fsyncSync = function (fd) {
+  return binding.fsync(fd);
+};
+
 fs.mkdir = function (path, mode, callback) {
   binding.mkdir(path, mode, callback || noop);
 };
index a576b5c..1aee4b9 100644 (file)
@@ -54,6 +54,8 @@ static int After(eio_req *req) {
       case EIO_RMDIR:
       case EIO_MKDIR:
       case EIO_FTRUNCATE:
+      case EIO_FSYNC:
+      case EIO_FDATASYNC:
       case EIO_LINK:
       case EIO_SYMLINK:
       case EIO_CHMOD:
@@ -330,6 +332,46 @@ static Handle<Value> Truncate(const Arguments& args) {
   }
 }
 
+static Handle<Value> Fdatasync(const Arguments& args) {
+  HandleScope scope;
+
+  if (args.Length() < 1 || !args[0]->IsInt32()) {
+    return THROW_BAD_ARGS;
+  }
+
+  int fd = args[0]->Int32Value();
+
+  if (args[1]->IsFunction()) {
+    ASYNC_CALL(fdatasync, args[1], fd)
+  } else {
+#if HAVE_FDATASYNC
+    int ret = fdatasync(fd);
+#else
+    int ret = fsync(fd);
+#endif
+    if (ret != 0) return ThrowException(ErrnoException(errno));
+    return Undefined();
+  }
+}
+
+static Handle<Value> Fsync(const Arguments& args) {
+  HandleScope scope;
+
+  if (args.Length() < 1 || !args[0]->IsInt32()) {
+    return THROW_BAD_ARGS;
+  }
+
+  int fd = args[0]->Int32Value();
+
+  if (args[1]->IsFunction()) {
+    ASYNC_CALL(fsync, args[1], fd)
+  } else {
+    int ret = fsync(fd);
+    if (ret != 0) return ThrowException(ErrnoException(errno));
+    return Undefined();
+  }
+}
+
 static Handle<Value> Unlink(const Arguments& args) {
   HandleScope scope;
 
@@ -756,6 +798,8 @@ void File::Initialize(Handle<Object> target) {
   NODE_SET_METHOD(target, "close", Close);
   NODE_SET_METHOD(target, "open", Open);
   NODE_SET_METHOD(target, "read", Read);
+  NODE_SET_METHOD(target, "fdatasync", Fdatasync);
+  NODE_SET_METHOD(target, "fsync", Fsync);
   NODE_SET_METHOD(target, "rename", Rename);
   NODE_SET_METHOD(target, "truncate", Truncate);
   NODE_SET_METHOD(target, "rmdir", RMDir);
diff --git a/test/simple/test-fs-fsync.js b/test/simple/test-fs-fsync.js
new file mode 100644 (file)
index 0000000..3014743
--- /dev/null
@@ -0,0 +1,37 @@
+require("../common");
+
+var path = require('path');
+var fs = require('fs');
+var successes = 0;
+
+var file = path.join(fixturesDir, "a.js");
+
+error("open " + file);
+
+fs.open(file, "a", 0777, function (err, fd) {
+  error("fd " + fd);
+  if (err) throw err;
+
+  fs.fdatasyncSync(fd);
+  error("fdatasync SYNC: ok");
+  successes++;
+
+  fs.fsyncSync(fd);
+  error("fsync SYNC: ok");
+  successes++;
+
+  fs.fdatasync(fd, function (err) {
+    if (err) throw err;
+    error("fdatasync ASYNC: ok");
+    successes++;
+    fs.fsync(fd, function(err) {
+      if (err) throw err;
+      error("fsync ASYNC: ok");
+      successes++;
+    });
+  });
+});
+
+process.addListener("exit", function () {
+  assert.equal(4, successes);
+});
diff --git a/wscript b/wscript
index 0083b88..63d072c 100644 (file)
--- a/wscript
+++ b/wscript
@@ -133,6 +133,22 @@ def configure(conf):
   conf.env.append_value('CCFLAGS',  '-D_FILE_OFFSET_BITS=64')
   conf.env.append_value('CXXFLAGS', '-D_FILE_OFFSET_BITS=64')
 
+  ## needed for node_file.cc fdatasync
+  ## Strangely on OSX 10.6 the g++ doesn't see fdatasync but gcc does?
+  code =  """
+    #include <unistd.h>
+    int main(void)
+    {
+       int fd = 0;
+       fdatasync (fd);
+       return 0;
+    }
+  """
+  if conf.check_cxx(msg="Checking for fdatasync(2) with c++", fragment=code):
+    conf.env.append_value('CXXFLAGS', '-DHAVE_FDATASYNC=1')
+  else:
+    conf.env.append_value('CXXFLAGS', '-DHAVE_FDATASYNC=0')
+
   # platform
   platform_def = '-DPLATFORM=' + sys.platform
   conf.env.append_value('CCFLAGS', platform_def)