#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"
#define N_(msgid) msgid
\f
#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++)
{
return true;
}
#else
+#define TIME_LIMIT_SUPPORTED 1
static bool
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))
{
if (setitimer (ITIMER_REAL, &it, NULL) < 0)
error (1, errno, _("Failed to set timeout."));
}
+#endif
/* Set up file descriptors:
- /dev/null for stdin
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)
break;
}
}
+#if __GNU__
+ else if (retval == 0)
+ sleep (1);
+#endif
else
NOT_REACHED ();
}
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);
{
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;
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))
{
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);