/* execute a system call and return stream from STDOUT */ void f_system(union argument *arg) { struct value val, result; struct udvt_entry *errno_var; char *output; int output_len, ierr; /* Retrieve parameters from top of stack */ pop(&val); /* Make sure parameters are of the correct type */ if (val.type != STRING) int_error(NO_CARET, "non-string argument to system()"); FPRINTF((stderr," f_system input = \"%s\"\n", val.v.string_val)); ierr = do_system_func(val.v.string_val, &output); if ((errno_var = add_udv_by_name("ERRNO"))) { errno_var->udv_undef = FALSE; Ginteger(&errno_var->udv_value, ierr); } output_len = strlen(output); /* chomp result */ if ( output_len > 0 && output[output_len-1] == '\n' ) output[output_len-1] = NUL; FPRINTF((stderr," f_system result = \"%s\"\n", output)); push(Gstring(&result, output)); gpfree_string(&result); /* free output */ gpfree_string(&val); /* free command string */ }
/* substitute output from ` ` * *strp points to the input string. (*strp)[current] is expected to * be the initial back tic. Characters through the following back tic * are replaced by the output of the command. extend_input_line() * is called to extend *strp array if needed. */ static void substitute(char **strp, size_t *str_lenp, int current) { char *last; char c; char *str, *pgm, *rest = NULL; char *output; size_t pgm_len, rest_len = 0; int output_pos; /* forgive missing closing backquote at end of line */ str = *strp + current; last = str; while (*++last) { if (*last == '`') break; } pgm_len = last - str; pgm = gp_alloc(pgm_len, "command string"); safe_strncpy(pgm, str + 1, pgm_len); /* omit ` to leave room for NUL */ /* save rest of line, if any */ if (*last) { last++; /* advance past ` */ rest_len = strlen(last) + 1; if (rest_len > 1) { rest = gp_alloc(rest_len, "input line copy"); strcpy(rest, last); } } /* do system call */ (void) do_system_func(pgm, &output); free(pgm); /* now replace ` ` with output */ output_pos = 0; while ((c = output[output_pos++])) { if (c != '\n' && c != '\r') (*strp)[current++] = c; if (current == *str_lenp) extend_input_line(); } (*strp)[current] = 0; free(output); /* tack on rest of line to output */ if (rest) { while (current + rest_len > *str_lenp) extend_input_line(); strcpy(*strp + current, rest); free(rest); } screen_ok = FALSE; }