/* * 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; }