int Action_exec(Action *action, Profile *prof) { int rc = 0; debug("ACTION: command=%s, pid_file=%s, restart=%d, depends=%s", bdata(prof->command), bdata(prof->pid_file), prof->restart, bdata(action->depends)); pid_t pid = fork(); check(pid >= 0, "Fork failed, WTF. How can fork fail?"); if(pid == 0) { rc = Unixy_drop_priv(action->profile_dir); if(rc != 0) { log_err("Not fatal, but we couldn't drop priv for %s", bdata(action->name)); } redirect_output("run.log"); rc = execle(bdata(prof->command), bdata(prof->command), NULL, environ); check(rc != -1, "Failed to exec command: %s", bdata(prof->command)); } else { int status = 0; debug("WAITING FOR CHILD."); pid = waitpid(pid, &status, 0); } debug("Command ran and exited successfully, now looking for the PID file."); return 0; error: return -1; }
int main(int argc, char **argv) { if (argc < 2) { (void) fprintf(stderr, "Usage: %s <command> ...\n", argv[0]); exit(1); } rotate_logs(); redirect_output(); dump_privs(); dump_args(argc, argv); /* print the header for the output from the program we exec (pre-flush) */ (void) puts("=== OUTPUT ==="); /* flush before next cmd takes over */ (void) fflush(stdout); (void) fflush(stderr); exec_next(argc, argv); /* if we got here, we failed */ (void) fprintf(stderr, "FATAL: execvp() failed.\n"); exit(1); }
int main(int argc, char **argv) { time_t now; char time_buffer[32]; if (argc < 2) { (void) fprintf(stderr, "Usage: %s <command> ...\n", argv[0]); exit(1); } rotate_logs(); redirect_output(); disable_cores(); dump_privs(); dump_args(argc, argv); /* get the current time for the log */ time(&now); cftime(time_buffer, "%Y-%m-%dT%H:%M:%SZ", &now); /* print the header for the output from the program we exec (pre-flush) */ (void) printf("=== OUTPUT (%s) ===\n", time_buffer); /* flush before next cmd takes over */ (void) fflush(stdout); (void) fflush(stderr); exec_next(argc, argv); /* if we got here, we failed */ (void) fprintf(stderr, "FATAL: execvp() failed.\n"); exit(1); }
static void check_redirect_output (void) { if (redirect_request == RR_REQUESTED) { redirect_request = RR_DONE; redirect_output (); } }
/* Executes a simple command that is not a builtin function, redirecting input * and output as appropriate. As with all exec_XXX() functions, assumes that * the parent has forked if necessary. Does not return. * * @simple = CMD to be executed */ void exec_simple(CMD* simple) { if (simple->fromFile && redirect_input(simple) < 0) _exit(EXIT_FAILURE); if (simple->toFile && redirect_output(simple) < 0) _exit(EXIT_FAILURE); assert(simple && simple->type == SIMPLE); execvp(simple->argv[0], &simple->argv[0]); _exit_error(EXIT_FAILURE); // execvp only returns on an error }
/* Executes a subcommand, redirecting input and output as appropriate. As with * all exec_XXX() functions, assumes that the parent has forked if necessary. * Does not return. * * @subcmd = CMD to be executed */ void exec_subcmd(CMD* subcmd) { if (subcmd->fromFile && redirect_input(subcmd) < 0) _exit(EXIT_FAILURE); if (subcmd->toFile && redirect_output(subcmd) < 0) _exit(EXIT_FAILURE); // Subcommands don't wait for backgrounded processes. They will be // reparented to init and be reaped accordingly int ret_val = process(subcmd->left); _exit(ret_val); // Any error messages will be produced during process }
/* command with output */ static int _cmd_w_out(sock_t sn, action_t a, flag_t f, const void * param, size_t size, FILE * out) { int sock, ret = -1; if ((sock = __open_socket(sn)) >= 0) { if (send_xmldb_cmd(sock, a, f, param, size) >= 0) { redirect_output(sock, out ? out : stdout); ret = 0; } close(sock); } return ret; }
int Action_exec(Action *action, Profile *prof) { int rc = 0; char *procer_run_log = NULL; bstring pidfile_env = bformat("PROCER_PIDFILE=%s", bdata(prof->pid_file)); putenv(bdata(pidfile_env)); bstring action_env = bformat("PROCER_ACTION=%s", bdata(action->name)); putenv(bdata(action_env)); debug("ACTION: command=%s, pid_file=%s, restart=%d, depends=%s", bdata(prof->command), bdata(prof->pid_file), prof->restart, bdata(action->depends)); pid_t pid = fork(); check(pid >= 0, "Fork failed, WTF. How can fork fail?"); if(pid == 0) { rc = Unixy_drop_priv(action->profile_dir); if(rc != 0) { log_err("Not fatal, but we couldn't drop priv for %s", bdata(action->name)); } if( (procer_run_log = getenv("PROCER_RUN_LOG")) == NULL) procer_run_log = "run.log"; redirect_output(procer_run_log); rc = execle(bdatae(prof->command, ""), bdatae(prof->command, ""), NULL, environ); check(rc != -1, "Failed to exec command: %s", bdata(prof->command)); } else { int status = 0; debug("WAITING FOR CHILD."); pid = waitpid(pid, &status, 0); } debug("Command ran and exited successfully, now looking for the PID file."); return 0; error: return -1; }
/* Executes a builtin command, redirecting input and output as appropriate. * and output as appropriate. As with all exec_XXX() functions, assumes that * the parent has forked if necessary, but unlike the others, returns the status * of the command executed. * * @simple = CMD to be executed * * Returns: Status of command executed */ int exec_builtin(CMD* simple) { // Keep track of old stdin, stdout, stderr for after execution of built-in int old_stdin = dup(0); int old_stdout = dup(1); int old_stderr = dup(2); // Failures for built-in commands to redirect should not cause the command // to abort, but it should set ? appropriately int redirect_status = 0; if (simple->fromFile && redirect_input(simple) < 0) redirect_status = errno; if (simple->toFile && redirect_output(simple) < 0) { int fd_devnull = open("/dev/null", O_WRONLY); dup2(fd_devnull, 1); if (ISREDERR(simple->toType)) dup2(fd_devnull, 2); close(fd_devnull); redirect_status = errno; } char* cmd_name = simple->argv[0]; int builtin_status = 0; if (!strcmp(cmd_name, "cd")) { builtin_status = cd(simple->argc, simple->argv); } else if (!strcmp(cmd_name, "pushd")) { builtin_status = pushd(simple->argc, simple->argv); } else if (!strcmp(cmd_name, "popd")) { builtin_status = popd(simple->argc, simple->argv); } else { builtin_status = 1; } dup2(old_stdin, 0); close(old_stdin); dup2(old_stdout, 1); close(old_stdout); dup2(old_stderr, 2); close(old_stderr); return builtin_status ? builtin_status : redirect_status; }
int main(int argc, char *argv[]) { puts("start"); /* int spawnl( int mode, const char * path, const char * arg0, const char * arg1..., const char * argn, NULL ); */ if(signal(SIGINT, sig_handler) == SIG_ERR) printf("Parent: Unable to create handler for SIGINT\n"); /* pid1 = spawnl(P_NOWAIT, "Proces1", "Proces1", NULL); pid2 = spawnl(P_NOWAIT, "Proces2", "Proces2", NULL); pid3 = spawnl(P_NOWAIT, "Proces3", "Proces3", NULL); pid4 = spawnl(P_NOWAIT, "Proces4", "Proces4", NULL); pid5 = spawnl(P_NOWAIT, "Proces5", "Proces5", NULL); pid6 = spawnl(P_NOWAIT, "Proces6", "Proces6", NULL); */ //trzeba pouruchamiac procesy i przekierowac ich wyjscia //niestety nie da sie tego zrobic spawnem, trzeba forkowac if( (pid1 = fork()) == 0) { redirect_output("p1.txt"); execl("Proces1", "Proces1", NULL); } else if( (pid2 = fork()) == 0) { redirect_output("p2.txt"); execl("Proces2", "Proces2", NULL); } else if( (pid3 = fork()) == 0) { redirect_output("p3.txt"); execl("Proces3", "Proces3", NULL); } else if( (pid4 = fork()) == 0) { redirect_output("p4.txt"); execl("Proces4", "Proces4", NULL); } else if( (pid5 = fork()) == 0) { redirect_output("p5.txt"); execl("Proces5", "Proces5", NULL); } else if( (pid6 = fork()) == 0) { redirect_output("p6.txt"); execl("Proces6", "Proces6", NULL); } puts("------------ nacisnij ctrl-c by zakonczyc wszystko"); while(1) { sleep(1); } return EXIT_SUCCESS; }
int lrgdb_patch_buffer(int fd, unsigned long flags, const char * buffer, FILE * out) { if (send_xmldb_cmd(fd, RGDB_PATCH_BUFF, flags, buffer, strlen(buffer)+1) < 0) return -1; if (out) redirect_output(fd, out); return 0; }
int lrgdb_ephp(int fd, unsigned long flags, const char * phpfile, FILE * out) { if (send_xmldb_cmd(fd, RGDB_EPHP, flags, phpfile, strlen(phpfile)+1) < 0) return -1; if (out) redirect_output(fd, out); return 0; }
int lrgdb_patch(int fd, unsigned long flags, const char * tempfile, FILE * out) { if (send_xmldb_cmd(fd, RGDB_PATCH, flags, tempfile, strlen(tempfile)+1) < 0) return -1; if (out) redirect_output(fd, out); return 0; }
/* * Do the command */ int do_command(char **args, int in, int out, int pipe, int block) { char *input_filename, *output_filename; // Check for redirected input int input = redirect_input(args, &input_filename); switch(input) { case -1: printf("Syntax error!\n"); return -1; break; case 0: break; case 1: printf("Redirecting input from: %s\n", input_filename); break; } // check for append int append = check_append(args, &output_filename); // Check for redirected output int output = redirect_output(args, &output_filename); switch(append) { case -1: printf("Syntax error!\n"); return -1; break; case 0: break; case 1: printf("Redirecting and appending output to: %s\n", output_filename); break; } switch(output) { case -1: printf("Syntax error!\n"); return -1; break; case 0: break; case 1: printf("Redirecting output to: %s\n", output_filename); break; } int result; pid_t child_id; // Fork the child process child_id = fork(); // Check for errors in fork() switch(child_id) { case EAGAIN: perror("Error EAGAIN: "); return child_id; case ENOMEM: perror("Error ENOMEM: "); return child_id; } if(child_id == 0) { // Set up redirection in the child process if(out != 1) { dup2(out, 1); close(out); } if(in != 0) { dup2(in, 0); close(in); } if(input) freopen(input_filename, "r", stdin); if(output) freopen(output_filename, "w+", stdout); if(append) freopen(output_filename, "a", stdout); result = execvp(args[0], args); exit(1); }else { return child_id; } return result; }
/* Initialize the server - return fd of the listening socket or -1 on error */ int server_init (int debugging, int foreground) { struct sockaddr_un sock_name; int server_sock; int pid; logit ("Starting MOC Server"); pid = check_pid_file (); if (pid && valid_pid(pid)) { fprintf (stderr, "\nIt seems that the server is already running" " with pid %d.\n", pid); fprintf (stderr, "If it is not true, remove the pid file (%s)" " and try again.\n", create_file_name(PID_FILE)); fatal ("Exiting!"); } if (foreground) log_init_stream (stdout, "stdout"); else { FILE *logfp; logfp = NULL; if (debugging) { logfp = fopen (SERVER_LOG, "a"); if (!logfp) fatal ("Can't open server log file: %s", strerror (errno)); } log_init_stream (logfp, SERVER_LOG); } if (pipe(wake_up_pipe) < 0) fatal ("pipe() failed: %s", strerror(errno)); unlink (socket_name()); /* Create a socket */ if ((server_sock = socket (PF_LOCAL, SOCK_STREAM, 0)) == -1) fatal ("Can't create socket: %s", strerror(errno)); sock_name.sun_family = AF_LOCAL; strcpy (sock_name.sun_path, socket_name()); /* Bind to socket */ if (bind(server_sock, (struct sockaddr *)&sock_name, SUN_LEN(&sock_name)) == -1) fatal ("Can't bind() to the socket: %s", strerror(errno)); if (listen(server_sock, 1) == -1) fatal ("listen() failed: %s", strerror(errno)); audio_initialize (); tags_cache_init (&tags_cache, options_get_int("TagsCacheSize")); tags_cache_load (&tags_cache, create_file_name("cache")); clients_init (); server_tid = pthread_self (); thread_signal (SIGTERM, sig_exit); thread_signal (SIGINT, foreground ? sig_exit : SIG_IGN); thread_signal (SIGHUP, SIG_IGN); thread_signal (SIGQUIT, sig_exit); thread_signal (SIGPIPE, SIG_IGN); write_pid_file (); if (!foreground) { setsid (); redirect_output (stdin); redirect_output (stdout); redirect_output (stderr); } return server_sock; }
/* Initialize the server - return fd of the listening socket or -1 on error */ void server_init (int debugging, int foreground) { struct sockaddr_un sock_name; pid_t pid; logit ("Starting MOC Server"); assert (server_sock == -1); pid = check_pid_file (); if (pid && valid_pid(pid)) { fprintf (stderr, "\nIt seems that the server is already running" " with pid %d.\n", pid); fprintf (stderr, "If it is not true, remove the pid file (%s)" " and try again.\n", create_file_name(PID_FILE)); fatal ("Exiting!"); } if (foreground) log_init_stream (stdout, "stdout"); else { FILE *logfp; logfp = NULL; if (debugging) { logfp = fopen (SERVER_LOG, "a"); if (!logfp) fatal ("Can't open server log file: %s", xstrerror (errno)); } log_init_stream (logfp, SERVER_LOG); } if (pipe(wake_up_pipe) < 0) fatal ("pipe() failed: %s", xstrerror (errno)); unlink (socket_name()); /* Create a socket. * For reasons why AF_UNIX is the correct constant to use in both * cases, see the commentary the SVN log for commit r9999. */ server_sock = socket (AF_UNIX, SOCK_STREAM, 0); if (server_sock == -1) fatal ("Can't create socket: %s", xstrerror (errno)); sock_name.sun_family = AF_UNIX; strcpy (sock_name.sun_path, socket_name()); /* Bind to socket */ if (bind(server_sock, (struct sockaddr *)&sock_name, SUN_LEN(&sock_name)) == -1) fatal ("Can't bind() to the socket: %s", xstrerror (errno)); if (listen(server_sock, 1) == -1) fatal ("listen() failed: %s", xstrerror (errno)); /* Log stack sizes so stack overflows can be debugged. */ log_process_stack_size (); log_pthread_stack_size (); clients_init (); audio_initialize (); tags_cache = tags_cache_new (options_get_int("TagsCacheSize")); tags_cache_load (tags_cache, create_file_name("cache")); server_tid = pthread_self (); xsignal (SIGTERM, sig_exit); xsignal (SIGINT, foreground ? sig_exit : SIG_IGN); xsignal (SIGHUP, SIG_IGN); xsignal (SIGQUIT, sig_exit); xsignal (SIGPIPE, SIG_IGN); xsignal (SIGCHLD, sig_chld); write_pid_file (); if (!foreground) { setsid (); redirect_output (stdin); redirect_output (stdout); redirect_output (stderr); } return; }
/* * The main shell function */ main() { int i; char **args; int result; int block; int output; int input; char *output_filename; char *input_filename; // Set up the signal handler sigset(SIGCHLD, sig_handler); // Loop forever while(1) { // Print out the prompt and get the input printf("->"); args = my_getline(); // No input, continue if(args[0] == NULL) continue; // Check for internal shell commands, such as exit if(internal_command(args)) continue; // Check for tilde (~) tilde(args); // Check for an ampersand block = (ampersand(args) == 0); // Check for redirected input input = redirect_input(args, &input_filename); switch(input) { case -1: printf("Syntax error!\n"); continue; break; case 0: break; case 1: if (DEBUG) printf("Redirecting input from: %s\n", input_filename); break; } // Check for redirected output output = redirect_output(args, &output_filename); switch(output) { case -1: printf("Syntax error!\n"); continue; break; case 0: break; case 1: if (DEBUG) printf("Redirecting (Overriding) output to: %s\n", output_filename); break; case 2: if (DEBUG) printf("Redirecting (Appending) output to: %s\n", output_filename); break; } // Do the command do_command(args, block, input, input_filename, output, output_filename); for (i = 0; args[i] != NULL; i++) free(args[i]); } }
int Errors::check_output() { if (output_is_redirected()) { redirect_output(false); return 1; } else return 0; }
/* * The main shell function */ main() { int i; char **args; int result; int block; int output; int input; char *output_filename; char *input_filename; // Set up the signal handler sigset(SIGCHLD, sig_handler); // Setup the signal handler struct sigaction sa; // Setup the SIGPROCMASK sigset_t blockmask; // Make sure the signal handlers are setup if(sigprocmask(SIG_BLOCK, &blockmask, NULL) == -1) { perror("Failed to setup signal handler."); return 1; } // Loop forever while(1) { // Print out the prompt and get the input printf("->"); args = getline(); // No input, continue if(args[0] == NULL) continue; // Check for internal shell commands, such as exit if(internal_command(args)) continue; // Check for an ampersand block = (ampersand(args) == 0); // Check for redirected input input = redirect_input(args, &input_filename); switch(input) { case -1: printf("Syntax error!\n"); continue; break; case 0: break; case 1: printf("Redirecting input from: %s\n", input_filename); break; } // Check for redirected output output = redirect_output(args, &output_filename); switch(output) { case -1: printf("Syntax error!\n"); continue; break; case 0: break; case 1: printf("Redirecting output to: %s\n", output_filename); break; case 2: printf("Appending output to: %s\n", output_filename); break; } // Do the command do_command(args, block, input, input_filename, output, output_filename, sigaction, blockmask, 0, 0); } }
int main (int argc, char* argv[]) { // Create our single-loop for this single-thread application EV_P; pthread_attr_t attr; int thread_status; struct evn_server* server; char socket_address[256]; EV_A = ev_default_loop(0); // Set default options, then parse new arguments to update the settings dummy_settings_set_presets(&dummy_settings); argp_parse (&argp, argc, argv, 0, 0, &dummy_settings); // TODO separate worker settings from daemon settings // (i.e. redirect) if (true == redirect) { redirect_output(); } if (0) { struct ev_periodic every_few_seconds; // To be sure that we aren't actually blocking ev_periodic_init(&every_few_seconds, test_process_is_not_blocked, 0, 1, 0); ev_periodic_start(EV_A_ &every_few_seconds); } // Set the priority of this whole process higher (requires root) setpriority(PRIO_PROCESS, 0, -13); // -15 // initialize the values of the struct that we will be giving to the new thread thread_control.dummy_settings = &dummy_settings; thread_control.buffer_head = 0; thread_control.buffer_count = 0; thread_control.EV_A = ev_loop_new(EVFLAG_AUTO); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); // Initialize the thread that will manage the DUMMY_WORKER thread_status = pthread_create(&dummy_worker_pthread, &attr, dummy_worker_thread, (void *)(&thread_control)); if (0 != thread_status) { fprintf(stderr, "thread creation failed with errno %d (%s)\n", thread_status, strerror(thread_status)); exit(EXIT_FAILURE); } pthread_attr_destroy(&attr); // Create unix socket in non-blocking fashion snprintf(socket_address, sizeof(socket_address), DUMMYD_SOCK, (int)getuid()); unlink(socket_address); server = evn_server_create(EV_A_ server_on_connection); server->on_connection = server_on_connection; evn_server_listen(server, 0, socket_address); // Run our loop, until we recieve the QUIT, TERM or INT signals, or an 'x' over the socket. puts("[Daemon] Looping.\n"); ev_loop(EV_A_ 0); // Cleanup if `unloop` is ever called clean_shutdown(EV_A_ 0); return 0; }
static void test_grid() { /* An empty grid behaves the same as a control so test here. */ test_control<gui2::tgrid>(); /* Test the child part here. */ gui2::tgrid grid(2 ,2); grid.set_id("0"); gui2::tgrid* g = new gui2::tgrid(2, 2); add_widget(grid, g, "1", 0, 0); add_widget(grid, new gui2::tlabel(), "2", 1, 0); add_widget(grid, new gui2::tlabel(), "3", 0, 1); add_widget(grid, new gui2::tlabel(), "4", 1, 1); add_widget(*g, new gui2::tlabel(), "5", 0, 0); add_widget(*g, new gui2::tlabel(), "6", 1, 0); add_widget(*g, new gui2::tlabel(), "7", 0, 1); add_widget(*g, new gui2::tlabel(), "8", 1, 1); { std::stringstream sstr; lg::tredirect_output_setter redirect_output(sstr); gui2::iterator::titerator<gui2::iterator::policy::order::ttop_down< true , true , true> > iterator(grid); while(iterator.next()) { /* DO NOTHING */ } BOOST_CHECK_EQUAL(top_down_t_t_t_result(), sstr.str()); } { std::stringstream sstr; lg::tredirect_output_setter redirect_output(sstr); gui2::iterator::titerator<gui2::iterator::policy::order::ttop_down< true , true , true> > iterator(grid); for( ; !iterator.at_end(); ++iterator) { /* DO NOTHING */ } BOOST_CHECK_EQUAL(top_down_t_t_t_result(), sstr.str()); } { std::stringstream sstr; lg::tredirect_output_setter redirect_output(sstr); gui2::iterator::titerator<gui2::iterator::policy::order::tbottom_up< true , true , true> > iterator(grid); while(iterator.next()) { /* DO NOTHING */ } BOOST_CHECK_EQUAL(bottom_up_t_t_t_result(), sstr.str()); } { std::stringstream sstr; lg::tredirect_output_setter redirect_output(sstr); gui2::iterator::titerator<gui2::iterator::policy::order::tbottom_up< true , true , true> > iterator(grid); for( ; !iterator.at_end(); ++iterator) { /* DO NOTHING */ } BOOST_CHECK_EQUAL(bottom_up_t_t_t_result(), sstr.str()); } }
int lrgdb_get(int fd, unsigned long flags, const char * node, FILE * out) { if (send_xmldb_cmd(fd, RGDB_GET, flags, node, strlen(node)+1) < 0) return -1; if (out) redirect_output(fd, out); return 0; }
int main(int argc, char *argv[]) { int rc; gamut_opts opts; signal(SIGPIPE, SIG_IGN); memset(&opts, 0, sizeof(opts)); /* Use line buffering for stdout */ setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ); rc = parse_opts(argc, argv, &opts); if(rc < 0) { s_log(G_EMERG, "Error parsing options.\n"); exit(EXIT_FAILURE); } else if(!rc) { usage(argv[0]); exit(EXIT_FAILURE); } /* * In this order, perform these steps (if necessary) * 1. Redirect to a log file * 2. Restore benchmark data from a file * 3. Run the benchmarks * 4. Save the new benchmark data * 5. Quit after benchmarks * 6. Run calibration (if no benchmark data) * 7. Run a trace file and exit * 8. Accept commands from stdin */ /* * 1. Redirect to a log file */ if(redirect_stdout) { redirect_output(); } /* * 2. Restore benchmark data from a file */ if(load_benchmarks) { s_log(G_NOTICE, "Loading benchmark data ... "); load_benchmark_data(); s_log(G_NOTICE, "done.\n"); } /* * 3. Run the benchmarks */ if(run_benchmarks) { s_log(G_NOTICE, "Running %u calibration trials.\n", DEF_BMARK_TRIALS); benchmark_delays(DEF_BMARK_TRIALS); } /* * 4. Save the new benchmark data */ if(save_benchmarks) { s_log(G_NOTICE, "Saving benchmark data ... "); save_benchmark_data(); s_log(G_NOTICE, "done.\n"); /* * 5. Quit after benchmarks */ if(quit_benchmarks) exit(EXIT_SUCCESS); } /* * 6. Run calibration (if no benchmark data is available yet) */ if(!load_benchmarks && !run_benchmarks) { s_log(G_NOTICE, "Calibrating node attributes ... "); benchmark_delays(1); s_log(G_NOTICE, "done.\n"); } init_opts(&opts); start_reaper(&opts); start_input(&opts); execute_gamut(&opts); stop_input(&opts); killall_workers(&opts); stop_reaper(&opts); return 0; }
PRIntn prmain(PRIntn argc, char **argv) { void *stackBasePtr; gpsee_interpreter_t *jsi; /* Handle describing a GPSEE/JavaScript Interpreter */ gpsee_realm_t *realm; /* Interpreter's primordial realm */ JSContext *cx; /* A context in realm */ const char *scriptCode = NULL; /* String with JavaScript program in it */ const char *scriptFilename = NULL; /* Filename with JavaScript program in it */ char * const *script_argv; /* Becomes arguments array in JS program */ char * const *script_environ = NULL; /* Environment to pass to script */ char *flags = malloc(8); /* Flags found on command line */ int noRunScript = 0; /* !0 = compile but do not run */ int fiArg = 0; int skipSheBang = 0; int exitCode; int verbosity; /* Verbosity to use before flags are processed */ #ifdef GPSEE_DEBUGGER JSDContext *jsdc; #endif #if defined(__SURELYNX__) permanent_pool = apr_initRuntime(); #endif gpsee_setVerbosity(isatty(STDERR_FILENO) ? GSR_PREPROGRAM_TTY_VERBOSITY : GSR_PREPROGRAM_NOTTY_VERBOSITY); gpsee_openlog(gpsee_basename(argv[0])); /* Print usage and exit if no arguments were given */ if (argc < 2) usage(argv[0]); flags[0] = (char)0; fiArg = findFileToInterpret(argc, argv); if (fiArg == 0) /* Not a script file interpreter (shebang) */ { int c; char *flag_p = flags; while ((c = getopt(argc, argv, whenSureLynx("D:r:","") "v:c:hHnf:F:aCRxSUWdeJz")) != -1) { switch(c) { #if defined(__SURELYNX__) case 'D': redirect_output(permanent_pool, optarg); break; case 'r': /* handled by cfg_openfile() */ break; #endif case 'c': scriptCode = optarg; break; case 'h': usage(argv[0]); break; case 'H': moreHelp(argv[0]); break; case 'n': noRunScript = 1; break; case 'F': skipSheBang = 1; case 'f': scriptFilename = optarg; break; case 'a': case 'C': case 'd': case 'e': case 'J': case 'S': case 'R': case 'U': case 'W': case 'x': case 'z': { char *flags_storage = realloc(flags, (flag_p - flags) + 1 + 1); if (flags_storage != flags) { flag_p = (flag_p - flags) + flags_storage; flags = flags_storage; } *flag_p++ = c; *flag_p = '\0'; } break; case '?': { char buf[32]; snprintf(buf, sizeof(buf), "Invalid option: %c\n", optopt); fatal(buf); } case ':': { char buf[32]; snprintf(buf, sizeof(buf), "Missing parameter to option '%c'\n", optopt); fatal(buf); } } } /* getopt wend */ /* Create the script's argument vector with the script name as arguments[0] */ { char **nc_script_argv = malloc(sizeof(argv[0]) * (2 + (argc - optind))); nc_script_argv[0] = (char *)scriptFilename; memcpy(nc_script_argv + 1, argv + optind, sizeof(argv[0]) * ((1 + argc) - optind)); script_argv = nc_script_argv; } *flag_p = (char)0; } else { scriptFilename = argv[fiArg]; if (fiArg == 2) { if (argv[1][0] != '-') fatal("Invalid syntax for file-interpreter flags! (Must begin with '-')"); flags = realloc(flags, strlen(argv[1]) + 1); strcpy(flags, argv[1] + 1); } /* This is a file interpreter; script_argv is correct at offset fiArg. */ script_argv = argv + fiArg; } if (strchr(flags, 'a')) { #if defined(GPSEE_DARWIN_SYSTEM) script_environ = (char * const *)_NSGetEnviron(); #else extern char **environ; script_environ = (char * const *)environ; #endif } loadRuntimeConfig(scriptFilename, flags, argc, argv); if (strchr(flags, 'U') || (cfg_bool_value(cfg, "gpsee_force_no_utf8_c_strings") == cfg_true) || getenv("GPSEE_NO_UTF8_C_STRINGS")) { JS_DestroyRuntime(JS_NewRuntime(1024)); putenv((char *)"GPSEE_NO_UTF8_C_STRINGS=1"); } jsi = gpsee_createInterpreter(); realm = jsi->realm; cx = jsi->cx; #if defined(GPSEE_DEBUGGER) jsdc = gpsee_initDebugger(cx, realm, DEBUGGER_JS); #endif gpsee_setThreadStackLimit(cx, &stackBasePtr, strtol(cfg_default_value(cfg, "gpsee_thread_stack_limit_bytes", "0x80000"), NULL, 0)); processFlags(cx, flags, &verbosity); free(flags); #if defined(__SURELYNX__) sl_set_debugLevel(gpsee_verbosity(0)); /* enableTerminalLogs(permanent_pool, gpsee_verbosity(0) > 0, NULL); */ #else if (verbosity < GSR_MIN_TTY_VERBOSITY && isatty(STDERR_FILENO)) verbosity = GSR_MIN_TTY_VERBOSITY; #endif if (gpsee_verbosity(0) < verbosity) gpsee_setVerbosity(verbosity); /* Run JavaScript specified with -c */ if (scriptCode) { jsval v; if (JS_EvaluateScript(cx, realm->globalObject, scriptCode, strlen(scriptCode), "command_line", 1, &v) == JS_FALSE) { v = JSVAL_NULL; goto out; } v = JSVAL_NULL; } if ((argv[0][0] == '/') #if defined(SYSTEM_GSR) && (strcmp(argv[0], SYSTEM_GSR) != 0) #endif && cfg_bool_value(cfg, "no_gsr_preload_script") != cfg_true) { char preloadScriptFilename[FILENAME_MAX]; char mydir[FILENAME_MAX]; int i; jsi->grt->exitType = et_unknown; i = snprintf(preloadScriptFilename, sizeof(preloadScriptFilename), "%s/.%s_preload", gpsee_dirname(argv[0], mydir, sizeof(mydir)), gpsee_basename(argv[0])); if ((i == 0) || (i == (sizeof(preloadScriptFilename) -1))) gpsee_log(cx, GLOG_EMERG, PRODUCT_SHORTNAME ": Unable to create preload script filename!"); else errno = 0; if (access(preloadScriptFilename, F_OK) == 0) { jsval v; JSScript *script; JSObject *scrobj; if (!gpsee_compileScript(cx, preloadScriptFilename, NULL, NULL, &script, realm->globalObject, &scrobj)) { jsi->grt->exitType = et_compileFailure; gpsee_log(cx, GLOG_EMERG, PRODUCT_SHORTNAME ": Unable to compile preload script '%s'", preloadScriptFilename); goto out; } if (!script || !scrobj) goto out; if (!noRunScript) { JS_AddNamedObjectRoot(cx, &scrobj, "preload_scrobj"); jsi->grt->exitType = et_execFailure; if (JS_ExecuteScript(cx, realm->globalObject, script, &v) == JS_TRUE) jsi->grt->exitType = et_finished; else jsi->grt->exitType = et_exception; JS_RemoveObjectRoot(cx, &scrobj); v = JSVAL_NULL; } } if (jsi->grt->exitType & et_errorMask) goto out; } /* Setup for main-script running -- cancel preprogram verbosity and use our own error reporting system in gsr that does not use error reporter */ gpsee_setVerbosity(verbosity); JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT); if (!scriptFilename) { if (!scriptCode) /* Command-line options did not include code to run */ usage(argv[0]); if (jsi->grt->exitType == et_unknown) jsi->grt->exitType = et_finished; } else { FILE *scriptFile = openScriptFile(cx, scriptFilename, skipSheBang || (fiArg != 0)); if (!scriptFile) { gpsee_log(cx, GLOG_NOTICE, PRODUCT_SHORTNAME ": Unable to open' script '%s'! (%m)", scriptFilename); jsi->grt->exitType = et_compileFailure; goto out; } processInlineFlags(cx, scriptFile, &verbosity); gpsee_setVerbosity(verbosity); /* Just compile and exit? */ if (noRunScript) { JSScript *script; JSObject *scrobj; if (!gpsee_compileScript(cx, scriptFilename, scriptFile, NULL, &script, realm->globalObject, &scrobj)) { jsi->grt->exitType = et_exception; gpsee_reportUncaughtException(cx, JSVAL_NULL, (gpsee_verbosity(0) >= GSR_FORCE_STACK_DUMP_VERBOSITY) || ((gpsee_verbosity(0) >= GPSEE_ERROR_OUTPUT_VERBOSITY) && isatty(STDERR_FILENO))); } else { jsi->grt->exitType = et_finished; } } else /* noRunScript is false; run the program */ { jsi->grt->exitType = et_execFailure; if (gpsee_runProgramModule(cx, scriptFilename, NULL, scriptFile, script_argv, script_environ) == JS_TRUE) { jsi->grt->exitType = et_finished; } else { int code; code = gpsee_getExceptionExitCode(cx); if (code >= 0) /** e.g. throw 6 */ { jsi->grt->exitType = et_requested; jsi->grt->exitCode = code; } else { if (JS_IsExceptionPending(cx)) { jsi->grt->exitType = et_exception; gpsee_reportUncaughtException(cx, JSVAL_NULL, (gpsee_verbosity(0) >= GSR_FORCE_STACK_DUMP_VERBOSITY) || ((gpsee_verbosity(0) >= GPSEE_ERROR_OUTPUT_VERBOSITY) && isatty(STDERR_FILENO))); } } } } fclose(scriptFile); goto out; } out: #ifdef GPSEE_DEBUGGER gpsee_finiDebugger(jsdc); #endif if (jsi->grt->exitType & et_successMask) { exitCode = jsi->grt->exitCode; } else { const char *reason; exitCode = 1; switch(jsi->grt->exitType) { case et_successMask: case et_errorMask: case et_requested: case et_finished: case et_dummy: default: GPSEE_NOT_REACHED("impossible"); reason = NULL; /* quell compiler warning below */ break; case et_execFailure: reason = "execFailure - probable native module error, returning JS_FALSE without setting exception"; break; case et_compileFailure: reason = "script could not be compiled"; break; case et_unknown: reason = "unknown - probable native module error, returning JS_FALSE without setting exception"; break; case et_exception: reason = NULL; break; } if (reason) { gpsee_log(cx, GLOG_NOTICE, "Unexpected interpreter shutdown: %s (%m)", reason); if (gpsee_verbosity(0) == 0) { /* not gpsee_ */ fprintf(stderr, "*** Unexpected interpreter shutdown: %s", reason); if (errno) fprintf(stderr, " (%s)\n", strerror(errno)); else fputs("\n", stderr); } } } gpsee_destroyInterpreter(jsi); JS_ShutDown(); return exitCode; }