Skip to content

Instantly share code, notes, and snippets.

@Kami
Created November 18, 2010 01:20
static int CallGetPwUidNam(eio_req *req) {
struct getpw_request *greq = (struct getpw_request *)req->data;
size_t bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
if (bufsize == -1) {
bufsize = 1024;
}
greq->buffer = (char *)malloc(bufsize);
if (!greq->buffer) {
req->result = ENOMEM;
return 0;
}
if (greq->uid) {
req->result = getpwuid_r((uid_t)greq->uid, &(greq->pwd), greq->buffer,
bufsize, &(greq->result));
}
else if (greq->name) {
req->result = getpwnam_r((char *)greq->name, &(greq->pwd), greq->buffer,
bufsize, &(greq->result));
}
return 0;
}
static int AfterCallGetPwUidNam(eio_req *req) {
ev_unref(EV_DEFAULT_UC);
struct getpw_request *greq = (struct getpw_request *)req->data;
HandleScope scope;
Local<Value> argv[2];
if (req->result != 0) {
argv[0] = ErrnoException(req->result, ((greq->uid) ? "getpwuid" : "getpwnam"),
strerror(req->result));
argv[1] = Local<Value>::New(Null());
}
else if (!greq->result) {
argv[0] = Local<Value>::New(Null());
argv[1] = Local<Value>::New(Null());
}
else {
Local<Object> pwd_object = Object::New();
pwd_object->Set(String::NewSymbol("pw_name"), String::New(greq->pwd.pw_name));
pwd_object->Set(String::NewSymbol("pw_uid"), Integer::New(greq->pwd.pw_uid));
pwd_object->Set(String::NewSymbol("pw_gid"), Integer::New(greq->pwd.pw_gid));
pwd_object->Set(String::NewSymbol("pw_dir"), String::New(greq->pwd.pw_dir));
pwd_object->Set(String::NewSymbol("pw_shell"), String::New(greq->pwd.pw_shell));
argv[0] = Local<Value>::New(Null());
argv[1] = pwd_object;
}
TryCatch try_catch;
greq->cb->Call(v8::Context::GetCurrent()->Global(), 2, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
if (greq->buffer) free(greq->buffer);
if (greq->name) free(greq->name);
greq->cb.Dispose();
free(greq);
return 0;
}
static Handle<Value> GetPwUid(const Arguments& args) {
HandleScope scope;
if (args.Length() < 2) {
return ThrowException(Exception::Error(
String::New("getpwuid requires 2 arguments")));
}
if (!args[0]->IsNumber()) {
return ThrowException(Exception::Error(
String::New("First argument must be a number")));
}
if (!args[1]->IsFunction()) {
return ThrowException(Exception::Error(
String::New("Second argument must be a function")));
}
uid_t uid = (uid_t)args[0]->Int32Value();
Local<Function> cb = Local<Function>::Cast(args[1]);
struct getpw_request *greq = (struct getpw_request *)
calloc(1, sizeof(struct getpw_request));
if (!greq) {
V8::LowMemoryNotification();
return ThrowException(Exception::Error(
String::New("Could not allocate enough memory")));
}
greq->uid = uid;
greq->cb = Persistent<Function>::New(cb);
eio_custom(CallGetPwUidNam, EIO_PRI_DEFAULT, AfterCallGetPwUidNam, greq);
ev_ref(EV_DEFAULT_UC);
return Undefined();
}
static Handle<Value> GetPwNam(const Arguments& args) {
HandleScope scope;
if (args.Length() < 2) {
return ThrowException(Exception::Error(
String::New("getpwnam requires 2 argument")));
}
if (!args[0]->IsString()) {
return ThrowException(Exception::Error(
String::New("First argument must be a string")));
}
if (!args[1]->IsFunction()) {
return ThrowException(Exception::Error(
String::New("Second argument must be a function")));
}
String::Utf8Value name(args[0]->ToString());
Local<Function> cb = Local<Function>::Cast(args[1]);
struct getpw_request *greq = (struct getpw_request *)
calloc(1, sizeof(struct getpw_request));
if (!greq) {
V8::LowMemoryNotification();
return ThrowException(Exception::Error(
String::New("Could not allocate enough memory")));
}
greq->name = (char*)malloc(name.length() + 1);
if (!greq->name) {
V8::LowMemoryNotification();
return ThrowException(Exception::Error(
String::New("Could not allocate enough memory")));
}
strcpy(greq->name, *name);
greq->cb = Persistent<Function>::New(cb);
eio_custom(CallGetPwUidNam, EIO_PRI_DEFAULT, AfterCallGetPwUidNam, greq);
ev_ref(EV_DEFAULT_UC);
return Undefined();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment