|
@@ -3173,6 +3173,12 @@ get_string_from_pipe(FILE *stream, char *buf_out, size_t count)
|
|
|
if (buf_out[len - 1] == '\n') {
|
|
|
/* Remove the trailing newline */
|
|
|
buf_out[len - 1] = '\0';
|
|
|
+ } else {
|
|
|
+ /* No newline; check whether we overflowed the buffer */
|
|
|
+ if (!feof(stream))
|
|
|
+ log_warn(LD_GENERAL,
|
|
|
+ "Line from stream was truncated: %s", buf_out);
|
|
|
+ /* TODO: What to do with this error? */
|
|
|
}
|
|
|
|
|
|
return IO_STREAM_OKAY;
|
|
@@ -3192,65 +3198,44 @@ log_from_pipe(FILE *stream, int severity, const char *executable,
|
|
|
int *child_status)
|
|
|
{
|
|
|
char buf[256];
|
|
|
+ enum stream_status r;
|
|
|
|
|
|
for (;;) {
|
|
|
- char *retval;
|
|
|
- retval = fgets(buf, sizeof(buf), stream);
|
|
|
-
|
|
|
- if (NULL == retval) {
|
|
|
- if (feof(stream)) {
|
|
|
- /* Program has closed stream (probably it exited) */
|
|
|
- /* TODO: check error */
|
|
|
- fclose(stream);
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- if (EAGAIN == errno) {
|
|
|
- /* Nothing more to read, try again next time */
|
|
|
- return 0;
|
|
|
- } else {
|
|
|
- /* There was a problem, abandon this child process */
|
|
|
- fclose(stream);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- /* We have some data, log it and keep asking for more */
|
|
|
- size_t len;
|
|
|
+ r = get_string_from_pipe(stream, buf, sizeof(buf) - 1);
|
|
|
|
|
|
- len = strlen(buf);
|
|
|
- if (buf[len - 1] == '\n') {
|
|
|
- /* Remove the trailing newline */
|
|
|
- buf[len - 1] = '\0';
|
|
|
- } else {
|
|
|
- /* No newline; check whether we overflowed the buffer */
|
|
|
- if (!feof(stream))
|
|
|
- log_warn(LD_GENERAL,
|
|
|
- "Line from port forwarding helper was truncated: %s", buf);
|
|
|
- /* TODO: What to do with this error? */
|
|
|
- }
|
|
|
+ if (r == IO_STREAM_CLOSED) {
|
|
|
+ fclose(stream);
|
|
|
+ return 1;
|
|
|
+ } else if (r == IO_STREAM_EAGAIN) {
|
|
|
+ return 0;
|
|
|
+ } else if (r == IO_STREAM_TERM) {
|
|
|
+ fclose(stream);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
|
|
|
- /* Check if buf starts with SPAWN_ERROR_MESSAGE */
|
|
|
- if (strcmpstart(buf, SPAWN_ERROR_MESSAGE) == 0) {
|
|
|
- /* Parse error message */
|
|
|
- int retval, child_state, saved_errno;
|
|
|
- retval = tor_sscanf(buf, SPAWN_ERROR_MESSAGE "%x/%x",
|
|
|
- &child_state, &saved_errno);
|
|
|
- if (retval == 2) {
|
|
|
- log_warn(LD_GENERAL,
|
|
|
- "Failed to start child process \"%s\" in state %d: %s",
|
|
|
- executable, child_state, strerror(saved_errno));
|
|
|
- if (child_status)
|
|
|
- *child_status = 1;
|
|
|
- } else {
|
|
|
- /* Failed to parse message from child process, log it as a
|
|
|
- warning */
|
|
|
- log_warn(LD_GENERAL,
|
|
|
- "Unexpected message from port forwarding helper \"%s\": %s",
|
|
|
- executable, buf);
|
|
|
- }
|
|
|
+ tor_assert(r == IO_STREAM_OKAY);
|
|
|
+
|
|
|
+ /* Check if buf starts with SPAWN_ERROR_MESSAGE */
|
|
|
+ if (strcmpstart(buf, SPAWN_ERROR_MESSAGE) == 0) {
|
|
|
+ /* Parse error message */
|
|
|
+ int retval, child_state, saved_errno;
|
|
|
+ retval = tor_sscanf(buf, SPAWN_ERROR_MESSAGE "%x/%x",
|
|
|
+ &child_state, &saved_errno);
|
|
|
+ if (retval == 2) {
|
|
|
+ log_warn(LD_GENERAL,
|
|
|
+ "Failed to start child process \"%s\" in state %d: %s",
|
|
|
+ executable, child_state, strerror(saved_errno));
|
|
|
+ if (child_status)
|
|
|
+ *child_status = 1;
|
|
|
} else {
|
|
|
- log_fn(severity, LD_GENERAL, "Port forwarding helper says: %s", buf);
|
|
|
+ /* Failed to parse message from child process, log it as a
|
|
|
+ warning */
|
|
|
+ log_warn(LD_GENERAL,
|
|
|
+ "Unexpected message from port forwarding helper \"%s\": %s",
|
|
|
+ executable, buf);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ log_fn(severity, LD_GENERAL, "Port forwarding helper says: %s", buf);
|
|
|
}
|
|
|
}
|
|
|
|