Open groundwater opened 10 years ago
So, I have thought about using ffi for this, but given how stable syscalls are, I think it's worth wrapping them at the C layer.
I do think it's worth using a library like nan or node addon layer to abstract away the v8-specifics.
My biggest question here is organization. I think any organization is fine, as long as it's clear and easy to find modules. I don't mind a little manual work either, e.g. if a data type is defined in one module, but consumed in another, if it keeps things simple.
I think the todos are:
Any suggestions or example for item (1) are appreciated.
cc/ @jwerle
I really prefer NAL over NAN. NAN has a lot of magic I don't like, and NAL just feels like C :].
If we use NAL or NAN I think it is worth creating some common interface on top of it that will yield some sort of paradigm for adopters to use. Much like how commonjs became what is today from its acceptance/adoption.
How are you thinking about defining how users interface with syscalls ?
Right now there structure is defined:
+-----------+
| hardware |
+-----------+
| kernel |
+-----------+
| init/root | <--- this piece is node-os
+-----------+
| userland |
+-----------+
What do we want to expose after init/root ? I assume this is where low level bindings will occur, right before userland.
I have to say, In terms of abstraction layers. Isn't the node team planning to release its own abstraction layer @ 1.0 If so I would suggest waiting for that time. Stabilizing nodeos around 1.0 and using the provided abstraction layer. The closer to core the project stays, the more maintainable it should be imo.
@jwerle yea NAN is just macros, and its definitely a leaky abstraction, and only for those wanting to target all node versions.
syscalls are just exposed in node modules. If your app needs to call ioctl for example, it needs to require the sys-ioctl
(or whatever we call it) module and use our defined api.
I do this already in a very janky fashion, see src-reboot for an example.
@jwerle it doesn't really make sense to talk about exposing syscalls after init. They are exposed as a node module that can be included in any node process. The modules are hosted on npm, and can be included by processes run as root, such as init, or any other user process.
@miketheprogrammer if NAL is going to merge into 1.0, it's relatively easy to keep those things in lock-step. I'll consult lord-master @tjfontaine on the matter.
all this talk of syscalls and node gives me visions of Go, in any event node-addon-layer will be included in v1.0 and it will also be a module that works against v0.8~v0.12
I guess node-addon-layer is the winner.
Sounds great. I would love to contribute in any way that I can. Let the mad science run free. On Mar 3, 2014 8:38 PM, "Jacob Groundwater" notifications@github.com wrote:
I guess node-addon-layer is the winner.
Reply to this email directly or view it on GitHubhttps://github.com/NodeOS/NodeOS/issues/21#issuecomment-36583122 .
I pulled this from the syscall Wikipedia page where they break system calls down into one of 5 categories. This seems like a good starting point.
If this doesn't break down naturally into small modules, I would consider a mega-monster module. It would be easier to manage that mega module from a build/test/integrate point of view.
@groundwater I think that is a good starting point too
@groundwater I would consider each of the 5 categories their own mega monster module. A self contained unit of functionality, even if they have cross dependencies it would be nice for them to be logically seperate.
Agreed. On Mar 4, 2014 7:15 AM, "Michael Hernandez" notifications@github.com wrote:
@groundwater https://github.com/groundwater I would consider each of the 5 categories their own mega monster module. A self contained unit of functionality, even if they have cross dependencies it would be nice for them to be logically seperate.
Reply to this email directly or view it on GitHubhttps://github.com/NodeOS/NodeOS/issues/21#issuecomment-36634290 .
Update, for simple argument passing, we can map integers and strings between JS-C++ pretty easily.
For syscalls requiring more complex data structures, we're going to use node buffers. The buffer can be written to directly from JavaScript, and the C++ side can extract the buffer point.
The JS side
var b = new Buffer(x);
var ret = ioctl(fd, SIOCGIFNAME, b);
if (ret) {
// b is a buffer containing a valid c-struct
success(b);
} else {
fail();
}
The C++ side
static Handle<Value> Ioctl(const Arguments& args) {
HandleScope scope;
// no error checking here sucka
// don't pass in bad data
int sfd = Handle<Number>::Cast(args[0])->Value();
int com = Handle<Number>::Cast(args[1])->Value();
// this should be a buffer
Local<Object> buffer = args[2]->ToObject();
// extract the pointer to the head of the buffer
// if we did things right, this should point to our struct
void* req = buffer->GetIndexedPropertiesExternalArrayData();
// this is the syscall
int res = ioctl(sfd, com, req);
// bubble the return back to JS land
return scope.Close(Integer::New(res));
}
I'm kind of just jotting notes down, I'll fill in the details soon.
Thanks to @tjfontaine for some pointers on a better way to write this
#include <sys/ioctl.h>
#include <v8.h>
#include <node.h>
using namespace v8;
using namespace node;
namespace NodeOS
{
static Handle<Value> Ioctl(const Arguments& args) {
HandleScope scope;
// error checks
if (!args[0]->IsInteger())
return ThrowException(Exception::TypeError(String::New("Argument 0 Must be an Integer")));
if (!args[1]->IsInteger())
return ThrowException(Exception::TypeError(String::New("Argument 1 Must be an Integer")));
if (!Buffer::HasInstance(args[2]))
return ThrowException(Exception::TypeError(String::New("Argument 2 Must be a Buffer")));
// convert arguments
int sfd = args[0]->IntegerValue();
int com = args[1]->InteverValue();
void* req = Buffer::Data(args[2]);
// syscall
int res = ioctl(sfd, com, req);
// return value
return scope.Close(Integer::New(res));
}
}
@groundwater I was thinking about implementing a ioctl module along these lines and found your code here. Are you planning on publishing a standalone ioctl module? Thanks!
Hey @santigimeno I'm looking at moving all my syscall stuff through ffi.
If you wanted to run with an ioctl module, I'm all for it. Maybe I can even leverage it. If you wanted to discuss the idea too, I have a few lessons learned I can share.
Point me to a repo if you start something, I'll try to contribute.
@groundwater here's my initial work: https://github.com/santigimeno/node-ioctl. There are some examples here: https://github.com/santigimeno/node-ioctl/tree/master/examples
@santigimeno sorry I didn't reply to this earlier. This is awesome.
I want to start a collection of these on http://npkg.org, where we can list done, and wanted modules. See #31.
This is a really good idea! Someone please grab charge of this
As part of this project, I would like to complete a Linux and/or POSIX system call interface in node. This should take the form of many small modules, rather than one big module providing everything.
The lowest levels should not do much more than wrap native syscalls, mapping arguments between the Javascript and C types.
I have kind of started this, but I think it's worth forking out as its own ongoing project.
cc @aulvi