/*
* 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, StringValueCStr(argv[0]));
#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);
#else
if (status == -1)
last_status_set(0x7f << 8, 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(StringValueCStr(cmd));
last_status_set((status & 0xff) << 8, 0);
#else
volatile VALUE prog = 0;
int pid;
struct rb_exec_arg earg;
RETSIGTYPE (*chfunc)(int);
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];
}
proc_prepare_args(&earg, argc, argv, prog);
chfunc = signal(SIGCHLD, SIG_DFL);
retry:
pid = fork();
if (pid == 0) {
/* child process */
rb_thread_atfork();
rb_protect(proc_exec_args, (VALUE)&earg, NULL);
_exit(127);
}
if (pid < 0) {
if (errno == EAGAIN) {
rb_thread_sleep(1);
goto retry;
}
}
else {
rb_syswait(pid);
}
signal(SIGCHLD, chfunc);
if (pid < 0) rb_sys_fail(0);
status = NUM2INT(rb_last_status);
#endif
if (status == EXIT_SUCCESS) return Qtrue;
return Qfalse;
}