+ pid_t retval = waitpid (pid, &status, flags);
+ if (retval == pid)
+ break;
+ else if (retval < 0)
+ {
+ if (errno != EINTR)
+ {
+ error = errno;
+ break;
+ }
+ }
+#if __GNU__
+ else if (retval == 0)
+ sleep (1);
+#endif
+ else
+ NOT_REACHED ();
+ }
+
+ bool ok = true;
+ if (error)
+ {
+ msg (SW, _("While running \"%s\", waiting for child process "
+ "failed (%s)."),
+ command, strerror (errno));
+ ok = false;
+ }
+
+ if (WIFSIGNALED (status))
+ {
+ int signum = WTERMSIG (status);
+ if (signum == SIGALRM)
+ msg (SW, _("Command \"%s\" timed out."), command);
+ else
+ msg (SW, _("Command \"%s\" terminated by signal %d."), command, signum);
+ ok = false;
+ }
+ else if (WIFEXITED (status) && WEXITSTATUS (status))
+ {
+ int exit_code = WEXITSTATUS (status);
+ const char *detail = (exit_code == EXIT_ENOENT
+ ? _("Command or shell not found")
+ : exit_code == EXIT_CANNOT_INVOKE
+ ? _("Could not invoke command or shell")
+ : NULL);
+ if (detail)
+ msg (SW, _("Command \"%s\" exited with status %d (%s)."),
+ command, exit_code, detail);
+ else
+ msg (SW, _("Command \"%s\" exited with status %d."),
+ command, exit_code);
+ ok = false;
+ }
+
+ rewind (output_file);
+ size_t length;
+ char *locale_output = fread_file (output_file, 0, &length);
+ if (!locale_output)
+ {
+ msg (SW, _("Command \"%s\" output could not be read (%s)."),
+ command, strerror (errno));
+ ok = false;
+ }
+ else if (length > 0)
+ {
+ char *output = recode_string ("UTF-8", locale_charset (),
+ locale_output, -1);
+
+ /* Drop final new-line, if any. */
+ char *end = strchr (output, '\0');
+ if (end > output && end[-1] == '\n')
+ end[-1] = '\0';
+
+ text_item_submit (text_item_create_nocopy (TEXT_ITEM_LOG, output));
+ }
+ free (locale_output);
+
+ return ok;
+}