Skip to content

Instantly share code, notes, and snippets.

@rentzsch
Created June 13, 2010 06:09
Show Gist options
  • Save rentzsch/436395 to your computer and use it in GitHub Desktop.
Save rentzsch/436395 to your computer and use it in GitHub Desktop.
From ac458ba1774287c7e98d03bb95ef553a932bec73 Mon Sep 17 00:00:00 2001
From: rentzsch <[email protected]>
Date: Sun, 13 Jun 2010 01:08:14 -0500
Subject: [PATCH] NEW API: fs.seek()
---
doc/api.markdown | 4 +++
lib/fs.js | 4 +++
src/node_file.cc | 49 ++++++++++++++++++++++++++++++++++++++++++
test/fixtures/helloworld.txt | 1 +
test/simple/test-fs-seek.js | 24 ++++++++++++++++++++
5 files changed, 82 insertions(+), 0 deletions(-)
create mode 100644 test/fixtures/helloworld.txt
create mode 100644 test/simple/test-fs-seek.js
diff --git a/doc/api.markdown b/doc/api.markdown
index 97a49d3..88f4c85 100644
--- a/doc/api.markdown
+++ b/doc/api.markdown
@@ -1429,6 +1429,10 @@ The callback is given the two arguments, `(err, bytesRead)`.
Synchronous version of `fs.read`. Returns the number of `bytesRead`.
+### fs.seek(fd, offset, whence='SEEK_SET')
+
+See lseek(2). Returns the resulting offset location as measured in bytes from the beginning of the file.
+
### fs.readFile(filename, [encoding,] callback)
Asynchronously reads the entire contents of a file. Example:
diff --git a/lib/fs.js b/lib/fs.js
index 3ab3f72..666aded 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -360,6 +360,10 @@ fs.chownSync = function(path, uid, gid) {
return binding.chown(path, uid, gid);
};
+fs.seek = function(fd, offset, whence) {
+ return binding.seek(fd, offset, whence);
+};
+
function writeAll (fd, data, encoding, callback) {
fs.write(fd, data, 0, encoding, function (writeErr, written) {
if (writeErr) {
diff --git a/src/node_file.cc b/src/node_file.cc
index dde2740..211df88 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -682,6 +682,54 @@ static Handle<Value> Chown(const Arguments& args) {
}
}
+
+/* fs.seek(fd, offset, whence='SEEK_SET');
+ * Wrapper for lseek(2)
+ */
+static Handle<Value> Seek(const Arguments& args) {
+ HandleScope scope;
+
+ if (args.Length() < 2) {
+ return ThrowException(Exception::TypeError(String::New(
+ "Bad argument: Requires at least two arguments (fd, offset)")));
+ }
+
+ if (!args[0]->IsInt32()) {
+ return ThrowException(Exception::TypeError(String::New(
+ "Bad argument: First argument isn't a Number representing a file descriptor")));
+ }
+
+ if (!args[1]->IsNumber()) {
+ return ThrowException(Exception::TypeError(String::New(
+ "Bad argument: Second argument isn't a Number representing an offset")));
+ }
+
+ int whence = SEEK_SET;
+
+ if (args.Length() >= 3) {
+ String::Utf8Value whenceStr(args[2]->ToString());
+
+ if (strcasecmp(*whenceStr, "SEEK_SET")) {
+ whence = SEEK_SET;
+ } else if (strcasecmp(*whenceStr, "SEEK_CUR")) {
+ whence = SEEK_CUR;
+ } else if (strcasecmp(*whenceStr, "SEEK_END")) {
+ whence = SEEK_END;
+ } else {
+ return ThrowException(Exception::TypeError(String::New(
+ "Bad argument: unknown third argument (whence). I know 'SEEK_SET', 'SEEK_CUR' and 'SEEK_END'")));
+ }
+ }
+
+ int lseekResult = lseek(args[0]->Int32Value(), args[1]->IntegerValue(), whence);
+ if (-1 == lseekResult) {
+ return ThrowException(ErrnoException(errno));
+ }
+
+ Local<Number> lseekResultObj = Number::New(lseekResult);
+ return scope.Close(lseekResultObj);
+}
+
void File::Initialize(Handle<Object> target) {
HandleScope scope;
@@ -707,6 +755,7 @@ void File::Initialize(Handle<Object> target) {
NODE_SET_METHOD(target, "chmod", Chmod);
NODE_SET_METHOD(target, "chown", Chown);
+ NODE_SET_METHOD(target, "seek", Seek);
errno_symbol = NODE_PSYMBOL("errno");
encoding_symbol = NODE_PSYMBOL("node:encoding");
diff --git a/test/fixtures/helloworld.txt b/test/fixtures/helloworld.txt
new file mode 100644
index 0000000..3b18e51
--- /dev/null
+++ b/test/fixtures/helloworld.txt
@@ -0,0 +1 @@
+hello world
diff --git a/test/simple/test-fs-seek.js b/test/simple/test-fs-seek.js
new file mode 100644
index 0000000..40a9ad8
--- /dev/null
+++ b/test/simple/test-fs-seek.js
@@ -0,0 +1,24 @@
+require('../common');
+
+var sys = require('sys'),
+ fs = require('fs'),
+ path = require('path'),
+ Buffer = require('buffer').Buffer;
+
+var dirPath = path.dirname(__filename),
+ fixturesDirPath = path.join(dirPath, '../fixtures'),
+ helloworldFilePath = path.join(fixturesDirPath, 'helloworld.txt');
+
+var buf = new Buffer(5),
+ fd;
+
+fd = fs.openSync(helloworldFilePath, 'r', 0666);
+fs.readSync(fd, buf, 0, 5);
+fs.closeSync(fd);
+assert.equal('hello', buf.toString());
+
+fd = fs.openSync(helloworldFilePath, 'r', 0666);
+fs.seek(fd, 6);
+fs.readSync(fd, buf, 0, 5);
+fs.closeSync(fd);
+assert.equal('world', buf.toString());
--
1.7.0.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment