/* * call-seq: * io.getpass(prompt=nil) -> string * * See IO#getpass. */ static VALUE io_getpass(int argc, VALUE *argv, VALUE io) { VALUE str; rb_check_arity(argc, 0, 1); prompt(argc, argv, io); str = str_chomp(rb_funcallv(io, id_gets, 0, 0)); puts_call(io); return str; }
/* * call-seq: * io.getpass(prompt=nil) -> string * * Reads and returns a line without echo back. * Prints +prompt+ unless it is +nil+. * * You must require 'io/console' to use this method. */ static VALUE console_getpass(int argc, VALUE *argv, VALUE io) { VALUE str, wio; rb_check_arity(argc, 0, 1); wio = rb_io_get_write_io(io); if (wio == io && io == rb_stdin) wio = rb_stderr; prompt(argc, argv, wio); str = rb_ensure(getpass_call, io, puts_call, wio); return str_chomp(str); }
/** * pm_execute * @params * int should_wait - Indicates if this execute should be inline or asynchronous * const char* command - The command to run * const char* cd - Run in this directory unless it's a NULL pointer * int nice - Special nice level * const char** env - Environment variables to run in the shell * @output pid_t pid - output pid of the new process **/ pid_t pm_execute(int should_wait, const char* command, const char *cd, int nice, const char** env) { // Setup execution char **command_argv = {0}; int command_argc = 0; int running_script = 0; if (expand_command((const char*)str_chomp(command), &command_argc, &command_argv, &running_script)) ; command_argv[command_argc] = 0; // Now actually RUN it! pid_t pid; if (should_wait) pid = vfork(); else pid = fork(); switch (pid) { case -1: return -1; case 0: { pm_setup_signal_handlers(); if (cd != NULL && cd[0] != '\0') chdir(cd); else chdir("/tmp"); if (execve((const char*)command_argv[0], command_argv, (char* const*) env) < 0) { printf("execve failed because: %s\n", strerror(errno)); exit(-1); } } default: // In parent process if (nice != INT_MAX && setpriority(PRIO_PROCESS, pid, nice) < 0) ; return pid; } }
/** * pm_execute * @params * int should_wait - Indicates if this execute should be inline or asynchronous * const char* command - The command to run * const char* cd - Run in this directory unless it's a NULL pointer * int nice - Special nice level * const char** env - Environment variables to run in the shell * @output pid_t pid - output pid of the new process **/ pid_t pm_execute( int should_wait, const char* command, const char *cd, int nice, const char** env, int *child_stdin, const char* p_stdout, const char *p_stderr ) { // Setup execution char **command_argv = {0}; int command_argc = 0; int running_script = 0; int countdown = 200; // If there is nothing here, don't run anything :) if (strlen(command) == 0) return -1; char* chomped_string = str_chomp(command); char* safe_chomped_string = str_safe_quote(chomped_string); if (expand_command((const char*)safe_chomped_string, &command_argc, &command_argv, &running_script, env)) ; command_argv[command_argc] = 0; // Now actually RUN it! pid_t pid; #if USE_PIPES int child_fd[2]; if ( pipe(child_fd) < 0 ) {// Create a pipe to the child (do we need this? I doubt it) perror("pipe failed"); } // Setup the stdin so the parent can communicate! (*child_stdin) = child_fd[0]; #endif // Let's name it so we can get to it later int child_dev_null; #if DEBUG if ((child_dev_null = open("debug.log", O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) { syslog(LOG_ERR, "babysitter (fatal): Could not open debug.log: errno: %d\n", errno); }; #else if ((child_dev_null = open("/dev/null", O_RDWR)) < 0) { syslog(LOG_ERR, "babysitter (fatal): Could not open /dev/null: errno: %d\n", errno); }; #endif // Setup fork pm_setup_fork(); if (should_wait) pid = vfork(); else pid = fork(); switch (pid) { case -1: return -1; case 0: { // Child process pm_setup_child(); if (cd != NULL && cd[0] != '\0') safe_chdir(cd); else safe_chdir("/tmp"); int child_stdout, child_stderr; // Set everything to dev/null first child_stdout = child_stderr = child_dev_null; // If we've passed in a stdout filename, then open it if(p_stdout) if ((child_stdout = open(p_stdout, O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) { perror("child stdout"); child_stdout = child_dev_null; } // If we've been passed a stderr filename, then open that if(p_stderr) if ((child_stderr = open(p_stderr, O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) { perror("child stderr"); child_stderr = child_dev_null; } // Parent doesn't write anything to the child, so just close this right away // REDIRECT TO DEV/NULL // Replace the stdout/stderr with the child_write fd #if USE_PIPES if (dup2(child_fd[0], STDIN_FILENO) < 0) FATAL_ERROR("could not dup STDIN_FILENO", -1); close(child_fd[1]); // We are using a different stdout #endif #if DEBUG #else // Setup the different stdout/stderr if (dup2(child_stdout, STDOUT_FILENO) < 0) FATAL_ERROR("could not dup STDOUT_FILENO", -1); if (dup2(child_stderr, STDERR_FILENO) < 0) FATAL_ERROR("could not dup STDERR_FILENO", -1); if (child_stdout != child_dev_null) close(child_stdout); if (child_stderr != child_dev_null) close(child_stderr); #endif if (execve((const char*)command_argv[0], command_argv, (char* const*) env) < 0) { perror("execve"); exit(-1); } } default: // In parent process // set the stdout back close(child_dev_null); // Child write never gets used outside the child #if USE_PIPES if (dup2(child_fd[1], STDOUT_FILENO) < 0) perror("dup2"); close(child_fd[0]); #endif if (nice != INT_MAX && setpriority(PRIO_PROCESS, pid, nice) < 0) ; if (running_script) { while (countdown > 0) { if (kill(pid, 0) != 0) break; usleep(100); countdown--; } struct stat buffer; if (stat(command_argv[0], &buffer) != 0) { printf("file doesn't exist when it should because: %s\n", strerror(errno)); } if( unlink( command_argv[0] ) != 0 ) perror( "Error deleting file" ); } // These are free'd later, anyway // if (chomped_string) free(chomped_string); // if (safe_chomped_string) free(safe_chomped_string); return pid; } }
static int ipkg_conf_parse_file(ipkg_conf_t *conf, const char *filename, pkg_src_list_t *pkg_src_list, nv_pair_list_t *tmp_dest_nv_pair_list, char **lists_dir) { int err; ipkg_option_t * options; FILE *file = fopen(filename, "r"); regex_t valid_line_re, comment_re; #define regmatch_size 12 regmatch_t regmatch[regmatch_size]; if (ipkg_init_options_array(conf, &options)<0) return ENOMEM; if (file == NULL) { fprintf(stderr, "%s: failed to open %s: %s\n", __FUNCTION__, filename, strerror(errno)); free(options); return errno; } ipkg_message(conf, IPKG_NOTICE, "loading conf file %s\n", filename); err = xregcomp(&comment_re, "^[[:space:]]*(#.*|[[:space:]]*)$", REG_EXTENDED); if (err) { free(options); return err; } err = xregcomp(&valid_line_re, "^[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))([[:space:]]+([^[:space:]]+))?[[:space:]]*$", REG_EXTENDED); if (err) { free(options); return err; } while(1) { int line_num = 0; char *line; char *type, *name, *value, *extra; line = file_read_line_alloc(file); line_num++; if (line == NULL) { break; } str_chomp(line); if (regexec(&comment_re, line, 0, 0, 0) == 0) { goto NEXT_LINE; } if (regexec(&valid_line_re, line, regmatch_size, regmatch, 0) == REG_NOMATCH) { str_chomp(line); fprintf(stderr, "%s:%d: Ignoring invalid line: `%s'\n", filename, line_num, line); goto NEXT_LINE; } /* This has to be so ugly to deal with optional quotation marks */ if (regmatch[2].rm_so > 0) { type = strndup(line + regmatch[2].rm_so, regmatch[2].rm_eo - regmatch[2].rm_so); } else { type = strndup(line + regmatch[3].rm_so, regmatch[3].rm_eo - regmatch[3].rm_so); } if (regmatch[5].rm_so > 0) { name = strndup(line + regmatch[5].rm_so, regmatch[5].rm_eo - regmatch[5].rm_so); } else { name = strndup(line + regmatch[6].rm_so, regmatch[6].rm_eo - regmatch[6].rm_so); } if (regmatch[8].rm_so > 0) { value = strndup(line + regmatch[8].rm_so, regmatch[8].rm_eo - regmatch[8].rm_so); } else { value = strndup(line + regmatch[9].rm_so, regmatch[9].rm_eo - regmatch[9].rm_so); } extra = NULL; if (regmatch[11].rm_so > 0) { extra = strndup (line + regmatch[11].rm_so, regmatch[11].rm_eo - regmatch[11].rm_so); } /* We use the tmp_dest_nv_pair_list below instead of conf->pkg_dest_list because we might encounter an offline_root option later and that would invalidate the directories we would have computed in pkg_dest_list_init. (We do a similar thing with tmp_src_nv_pair_list for sake of symmetry.) */ if (strcmp(type, "option") == 0) { ipkg_conf_set_option(options, name, value); } else if (strcmp(type, "src") == 0) { if (!nv_pair_list_find(pkg_src_list, name)) { pkg_src_list_append (pkg_src_list, name, value, extra, 0); } else { ipkg_message(conf, IPKG_ERROR, "ERROR: duplicate src declaration. Skipping:\n\t src %s %s\n", name, value); } } else if (strcmp(type, "src/gz") == 0) { if (!nv_pair_list_find(pkg_src_list, name)) { pkg_src_list_append (pkg_src_list, name, value, extra, 1); } else { ipkg_message(conf, IPKG_ERROR, "ERROR: duplicate src declaration. Skipping:\n\t src %s %s\n", name, value); } } else if (strcmp(type, "dest") == 0) { nv_pair_list_append(tmp_dest_nv_pair_list, name, value); } else if (strcmp(type, "lists_dir") == 0) { *lists_dir = realloc(*lists_dir,strlen(value)+1); if (*lists_dir == NULL) { ipkg_message(conf, IPKG_ERROR, "ERROR: Not enough memory\n"); free(options); return EINVAL; } sprintf (*lists_dir,"%s",value); } else if (strcmp(type, "arch") == 0) { ipkg_message(conf, IPKG_INFO, "supported arch %s priority (%s)\n", name, value); if (!value) { ipkg_message(conf, IPKG_NOTICE, "defaulting architecture %s priority to 10\n", name); value = strdup("10"); } nv_pair_list_append(&conf->arch_list, strdup(name), strdup(value)); } else { fprintf(stderr, "WARNING: Ignoring unknown configuration " "parameter: %s %s %s\n", type, name, value); free(options); return EINVAL; } free(type); free(name); free(value); if (extra) free (extra); NEXT_LINE: free(line); } free(options); regfree(&comment_re); regfree(&valid_line_re); fclose(file); return 0; }