X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Futilities%2Fhost.c;h=22d25c0eb09711e45cf5d07ce4fa84b0ac862416;hb=a208fcf0dcdcc445dd7d492e00ebdf3ce23e247f;hp=1ab7cc1d02eef6a530ddd7159a3dcf342ad159af;hpb=d7c2328e0a1902e9e090baa95c7a0b671e93d4ee;p=pspp diff --git a/src/language/utilities/host.c b/src/language/utilities/host.c index 1ab7cc1d02..22d25c0eb0 100644 --- a/src/language/utilities/host.c +++ b/src/language/utilities/host.c @@ -38,7 +38,7 @@ #include "libpspp/str.h" #include "libpspp/string-array.h" #include "libpspp/temp-file.h" -#include "output/text-item.h" +#include "output/driver.h" #include "gl/error.h" #include "gl/intprops.h" @@ -53,14 +53,11 @@ #define N_(msgid) msgid #if !HAVE_FORK +#define TIME_LIMIT_SUPPORTED 0 static bool run_commands (const struct string_array *commands, double time_limit) { - if (time_limit != DBL_MAX) - { - msg (SE, _("Time limit not supported on this platform.")); - return false; - } + assert (time_limit == DBL_MAX); for (size_t i = 0; i < commands->n; i++) { @@ -80,6 +77,7 @@ run_commands (const struct string_array *commands, double time_limit) return true; } #else +#define TIME_LIMIT_SUPPORTED 1 static bool run_command (const char *command, struct timespec timeout) { @@ -122,6 +120,11 @@ run_command (const char *command, struct timespec timeout) { /* Running in the child. */ +#if __GNU__ + /* Hurd doesn't support inheriting process timers in a way that works. */ + if (setpgid (0, 0) < 0) + error (1, errno, _("Failed to set process group.")); +#else /* Set up timeout. */ if (timeout.tv_sec < TYPE_MAXIMUM (time_t)) { @@ -140,6 +143,7 @@ run_command (const char *command, struct timespec timeout) if (setitimer (ITIMER_REAL, &it, NULL) < 0) error (1, errno, _("Failed to set timeout.")); } +#endif /* Set up file descriptors: - /dev/null for stdin @@ -174,7 +178,15 @@ run_command (const char *command, struct timespec timeout) int error = 0; for (;;) { - pid_t retval = waitpid (pid, &status, 0); +#if __GNU__ + if (timespec_cmp (current_timespec (), timeout) >= 0) + kill (-pid, SIGALRM); + + int flags = WNOHANG; +#else + int flags = 0; +#endif + pid_t retval = waitpid (pid, &status, flags); if (retval == pid) break; else if (retval < 0) @@ -185,6 +197,10 @@ run_command (const char *command, struct timespec timeout) break; } } +#if __GNU__ + else if (retval == 0) + sleep (1); +#endif else NOT_REACHED (); } @@ -243,7 +259,7 @@ run_command (const char *command, struct timespec timeout) if (end > output && end[-1] == '\n') end[-1] = '\0'; - text_item_submit (text_item_create_nocopy (TEXT_ITEM_LOG, output)); + output_log_nocopy (output); } free (locale_output); @@ -271,13 +287,13 @@ cmd_host (struct lexer *lexer, struct dataset *ds UNUSED) { if (settings_get_safer_mode ()) { - msg (SE, _("This command not allowed when the %s option is set."), "SAFER"); + lex_next_error (lexer, -1, -1, + _("This command not allowed when the %s option is set."), + "SAFER"); return CMD_FAILURE; } - if (!lex_force_match_id (lexer, "COMMAND") - || !lex_force_match (lexer, T_EQUALS) - || !lex_force_match (lexer, T_LBRACK) + if (!lex_force_match_phrase (lexer, "COMMAND=[") || !lex_force_string (lexer)) return CMD_FAILURE; @@ -296,6 +312,7 @@ cmd_host (struct lexer *lexer, struct dataset *ds UNUSED) double time_limit = DBL_MAX; if (lex_match_id (lexer, "TIMELIMIT")) { + int time_limit_start = lex_ofs (lexer) - 1; if (!lex_force_match (lexer, T_EQUALS) || !lex_force_num (lexer)) { @@ -306,6 +323,15 @@ cmd_host (struct lexer *lexer, struct dataset *ds UNUSED) double num = lex_number (lexer); lex_get (lexer); time_limit = num < 0.0 ? 0.0 : num; + + int time_limit_end = lex_ofs (lexer) - 1; + if (!TIME_LIMIT_SUPPORTED) + { + lex_ofs_error (lexer, time_limit_start, time_limit_end, + _("Time limit not supported on this platform.")); + string_array_destroy (&commands); + return false; + } } enum cmd_result result = lex_end_of_command (lexer);