Author: [email protected]
Date: Mon Mar 30 23:51:25 2009
New Revision: 1644
Modified:
branches/bleeding_edge/include/v8.h
branches/bleeding_edge/src/d8-posix.cc
branches/bleeding_edge/src/d8-windows.cc
branches/bleeding_edge/src/d8.cc
branches/bleeding_edge/src/d8.h
Log:
Add os.chdir and os.setenv to d8. Move system() to os.system().
Protect os.chdir, os.setenv, os.system against string conversion
failures. Add comment about the issue to include/v8.h.
Review URL: http://codereview.chromium.org/57005
Modified: branches/bleeding_edge/include/v8.h
==============================================================================
--- branches/bleeding_edge/include/v8.h (original)
+++ branches/bleeding_edge/include/v8.h Mon Mar 30 23:51:25 2009
@@ -883,7 +883,10 @@
/**
* Converts an object to a utf8-encoded character array. Useful if
- * you want to print the object.
+ * you want to print the object. If conversion to a string fails
+ * (eg. due to an exception in the toString() method of the object)
+ * then the length() method returns 0 and the * operator returns
+ * NULL.
*/
class V8EXPORT Utf8Value {
public:
@@ -903,6 +906,9 @@
/**
* Converts an object to an ascii string.
* Useful if you want to print the object.
+ * If conversion to a string fails (eg. due to an exception in the
toString()
+ * method of the object) then the length() method returns 0 and the *
operator
+ * returns NULL.
*/
class V8EXPORT AsciiValue {
public:
@@ -921,6 +927,9 @@
/**
* Converts an object to a two-byte string.
+ * If conversion to a string fails (eg. due to an exception in the
toString()
+ * method of the object) then the length() method returns 0 and the *
operator
+ * returns NULL.
*/
class V8EXPORT Value {
public:
Modified: branches/bleeding_edge/src/d8-posix.cc
==============================================================================
--- branches/bleeding_edge/src/d8-posix.cc (original)
+++ branches/bleeding_edge/src/d8-posix.cc Mon Mar 30 23:51:25 2009
@@ -184,9 +184,18 @@
// scope.
class ExecArgs {
public:
- ExecArgs(Handle<Value> arg0, Handle<Array> command_args) {
+ ExecArgs() {
+ exec_args_[0] = NULL;
+ }
+ bool Init(Handle<Value> arg0, Handle<Array> command_args) {
String::Utf8Value prog(arg0);
- int len = prog.length() + 1;
+ if (*prog == NULL) {
+ const char* message =
+ "os.system(): String conversion of program name failed";
+ ThrowException(String::New(message));
+ return false;
+ }
+ int len = prog.length() + 3;
char* c_arg = new char[len];
snprintf(c_arg, len, "%s", *prog);
exec_args_[0] = c_arg;
@@ -194,12 +203,20 @@
for (unsigned j = 0; j < command_args->Length(); i++, j++) {
Handle<Value> arg(command_args->Get(Integer::New(j)));
String::Utf8Value utf8_arg(arg);
+ if (*utf8_arg == NULL) {
+ exec_args_[i] = NULL; // Consistent state for destructor.
+ const char* message =
+ "os.system(): String conversion of argument failed.";
+ ThrowException(String::New(message));
+ return false;
+ }
int len = utf8_arg.length() + 1;
char* c_arg = new char[len];
snprintf(c_arg, len, "%s", *utf8_arg);
exec_args_[i] = c_arg;
}
exec_args_[i] = NULL;
+ return true;
}
~ExecArgs() {
for (unsigned i = 0; i < kMaxArgs; i++) {
@@ -454,7 +471,10 @@
struct timeval start_time;
gettimeofday(&start_time, NULL);
- ExecArgs exec_args(args[0], command_args);
+ ExecArgs exec_args;
+ if (!exec_args.Init(args[0], command_args)) {
+ return v8::Undefined();
+ }
int exec_error_fds[2];
int stdout_fds[2];
@@ -498,6 +518,23 @@
}
return scope.Close(accumulator);
+}
+
+
+Handle<Value> Shell::ChangeDirectory(const Arguments& args) {
+ if (args.Length() != 1) {
+ const char* message = "chdir() takes one argument";
+ return ThrowException(String::New(message));
+ }
+ String::Utf8Value directory(args[0]);
+ if (*directory == NULL) {
+ const char* message = "os.chdir(): String conversion of argument
failed.";
+ return ThrowException(String::New(message));
+ }
+ if (chdir(*directory) != 0) {
+ return ThrowException(String::New(strerror(errno)));
+ }
+ return v8::Undefined();
}
Modified: branches/bleeding_edge/src/d8-windows.cc
==============================================================================
--- branches/bleeding_edge/src/d8-windows.cc (original)
+++ branches/bleeding_edge/src/d8-windows.cc Mon Mar 30 23:51:25 2009
@@ -42,4 +42,11 @@
}
+Handle<Value> Shell::ChangeDirectory(const Arguments& args) {
+ Handle<String> error_message =
+ String::New("chdir() is not yet supported on your OS");
+ return ThrowException(error_message);
+}
+
+
} // namespace v8
Modified: branches/bleeding_edge/src/d8.cc
==============================================================================
--- branches/bleeding_edge/src/d8.cc (original)
+++ branches/bleeding_edge/src/d8.cc Mon Mar 30 23:51:25 2009
@@ -163,6 +163,28 @@
}
+Handle<Value> Shell::SetEnvironment(const Arguments& args) {
+ if (args.Length() != 2) {
+ const char* message = "setenv() takes two arguments";
+ return ThrowException(String::New(message));
+ }
+ String::Utf8Value var(args[0]);
+ String::Utf8Value value(args[1]);
+ if (*var == NULL) {
+ const char* message =
+ "os.setenv(): String conversion of variable name failed.";
+ return ThrowException(String::New(message));
+ }
+ if (*value == NULL) {
+ const char* message =
+ "os.setenv(): String conversion of variable contents failed.";
+ return ThrowException(String::New(message));
+ }
+ setenv(*var, *value, 1);
+ return v8::Undefined();
+}
+
+
Handle<Value> Shell::Load(const Arguments& args) {
for (int i = 0; i < args.Length(); i++) {
HandleScope handle_scope;
@@ -342,7 +364,12 @@
global_template->Set(String::New("load"), FunctionTemplate::New(Load));
global_template->Set(String::New("quit"), FunctionTemplate::New(Quit));
global_template->Set(String::New("version"),
FunctionTemplate::New(Version));
- global_template->Set(String::New("system"),
FunctionTemplate::New(System));
+
+ Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
+ os_templ->Set(String::New("system"), FunctionTemplate::New(System));
+ os_templ->Set(String::New("chdir"),
FunctionTemplate::New(ChangeDirectory));
+ os_templ->Set(String::New("setenv"),
FunctionTemplate::New(SetEnvironment));
+ global_template->Set(String::New("os"), os_templ);
utility_context_ = Context::New(NULL, global_template);
utility_context_->SetSecurityToken(Undefined());
Modified: branches/bleeding_edge/src/d8.h
==============================================================================
--- branches/bleeding_edge/src/d8.h (original)
+++ branches/bleeding_edge/src/d8.h Mon Mar 30 23:51:25 2009
@@ -130,9 +130,12 @@
static Handle<Value> Quit(const Arguments& args);
static Handle<Value> Version(const Arguments& args);
static Handle<Value> Load(const Arguments& args);
- // system("program_name", ["arg1", "arg2", ...], timeout1, timeout2)
will run
- // the command, passing the arguments to the program. The standard
output of
- // the program will be picked up and returned as a multiline string. If
+ // The OS object on the global object contains methods for performing
+ // operating system calls:
+ //
+ // os.system("program_name", ["arg1", "arg2", ...], timeout1, timeout2)
will
+ // run the command, passing the arguments to the program. The standard
output
+ // of the program will be picked up and returned as a multiline string.
If
// timeout1 is present then it should be a number. -1 indicates no
timeout
// and a positive number is used as a timeout in milliseconds that
limits the
// time spent waiting between receiving output characters from the
program.
@@ -140,7 +143,16 @@
// milliseconds on the total running time of the program. Exceptions are
// thrown on timeouts or other errors or if the exit status of the
program
// indicates an error.
+ //
+ // os.chdir(dir) changes directory to the given directory. Throws an
+ // exception/ on error.
+ //
+ // os.setenv(variable, value) sets an environment variable. Repeated
calls to
+ // this method leak memory due to the API of setenv in the standard C
library.
+ static Handle<Value> OSObject(const Arguments& args);
static Handle<Value> System(const Arguments& args);
+ static Handle<Value> ChangeDirectory(const Arguments& args);
+ static Handle<Value> SetEnvironment(const Arguments& args);
static Handle<Context> utility_context() { return utility_context_; }
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---