/*
* call-seq:
* system(cmd [, arg, ...]) => true or false
*
* Executes _cmd_ in a subshell, returning +true+ if
* the command was found and ran successfully, +false+
* otherwise. An error status is available in <code>$?</code>. The
* arguments are processed in the same way as for
* <code>Kernel::exec</code>.
*
* system("echo *")
* system("echo", "*")
*
* <em>produces:</em>
*
* config.h main.rb
* *
*/
static VALUE
rb_f_system(argc, argv)
int argc;
VALUE *argv;
{
int status;
#if defined(__EMX__)
VALUE cmd;
fflush(stdout);
fflush(stderr);
if (argc == 0) {
rb_last_status = Qnil;
rb_raise(rb_eArgError, "wrong number of arguments");
}
if (TYPE(argv[0]) == T_ARRAY) {
if (RARRAY(argv[0])->len != 2) {
rb_raise(rb_eArgError, "wrong first argument");
}
argv[0] = RARRAY(argv[0])->ptr[0];
}
cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
SafeStringValue(cmd);
status = do_spawn(RSTRING(cmd)->ptr);
last_status_set(status, 0);
#elif defined(__human68k__) || defined(__DJGPP__) || defined(_WIN32)
volatile VALUE prog = 0;
fflush(stdout);
fflush(stderr);
if (argc == 0) {
rb_last_status = Qnil;
rb_raise(rb_eArgError, "wrong number of arguments");
}
if (TYPE(argv[0]) == T_ARRAY) {
if (RARRAY(argv[0])->len != 2) {
rb_raise(rb_eArgError, "wrong first argument");
}
prog = RARRAY(argv[0])->ptr[0];
argv[0] = RARRAY(argv[0])->ptr[1];
}
if (argc == 1 && prog == 0) {
#if defined(_WIN32)
SafeStringValue(argv[0]);
status = do_spawn(P_WAIT, RSTRING(argv[0])->ptr);
#else
status = proc_spawn(argv[0]);
#endif
}
else {
status = proc_spawn_n(argc, argv, prog);
}
#if !defined(_WIN32)
last_status_set(status == -1 ? 127 : status, 0);
#endif
#elif defined(__VMS)
VALUE cmd;
if (argc == 0) {
rb_last_status = Qnil;
rb_raise(rb_eArgError, "wrong number of arguments");
}
if (TYPE(argv[0]) == T_ARRAY) {
if (RARRAY(argv[0])->len != 2) {
rb_raise(rb_eArgError, "wrong first argument");
}
argv[0] = RARRAY(argv[0])->ptr[0];
}
cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
SafeStringValue(cmd);
status = system(RSTRING(cmd)->ptr);
last_status_set((status & 0xff) << 8, 0);
#else
volatile VALUE prog = 0;
int pid;
int i;
fflush(stdout);
fflush(stderr);
if (argc == 0) {
rb_last_status = Qnil;
rb_raise(rb_eArgError, "wrong number of arguments");
}
if (TYPE(argv[0]) == T_ARRAY) {
if (RARRAY(argv[0])->len != 2) {
rb_raise(rb_eArgError, "wrong first argument");
}
prog = RARRAY(argv[0])->ptr[0];
argv[0] = RARRAY(argv[0])->ptr[1];
}
if (prog) {
SafeStringValue(prog);
}
for (i = 0; i < argc; i++) {
SafeStringValue(argv[i]);
}
retry:
switch (pid = fork()) {
case 0:
if (argc == 1 && prog == 0) {
rb_proc_exec(RSTRING(argv[0])->ptr);
}
else {
proc_exec_n(argc, argv, prog);
}
_exit(127);
break; /* not reached */
case -1:
if (errno == EAGAIN) {
rb_thread_sleep(1);
goto retry;
}
rb_sys_fail(0);
break;
default:
rb_syswait(pid);
}
status = NUM2INT(rb_last_status);
#endif
if (status == EXIT_SUCCESS) return Qtrue;
return Qfalse;
}