@matheusbsbs / matheus-bagliano / commits / a111eb7808
Fork 0

run-command: handle short writes and EINTR in die_child

If start_command fails after forking and before exec finishes, there is not much use in noticing an I/O error on top of that. finish_command will notice that the child exited with nonzero status anyway. So as noted in v1.7.0.3~20^2 (run-command.c: fix build warnings on Ubuntu, 2010-01-30) and v1.7.5-rc0~29^2 (2011-03-16), it is safe to ignore errors from write in this codepath. Even so, the result from write contains useful information: it tells us if the write was cancelled by a signal (EINTR) or was only partially completed (e.g., when writing to an almost-full pipe). Let's use write_in_full to loop until the desired number of bytes have been written (still ignoring errors if that fails). As a happy side effect, the assignment to a dummy variable to appease gcc -D_FORTIFY_SOURCE is no longer needed. xwrite and write_in_full check the return value from write(2). Noticed with gcc -Wunused-but-set-variable. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Nieder committed Apr 20, 2011 at 05:40 UTC a111eb7808bfdb90286e54b9ccdaea4f3bec3102
1 file changed +9 -6
run-command.c
+9 -6
@@ -67,21 +67,24 @@ static int child_notifier = -1;
67
68 static void notify_parent(void)
69 {
70 - ssize_t unused;
71 - unused = write(child_notifier, "", 1);
70 + /*
71 + * execvp failed. If possible, we'd like to let start_command
72 + * know, so failures like ENOENT can be handled right away; but
73 + * otherwise, finish_command will still report the error.
74 + */
75 + xwrite(child_notifier, "", 1);
76 }
77
78 static NORETURN void die_child(const char *err, va_list params)
79 {
80 char msg[4096];
77 - ssize_t unused;
81 int len = vsnprintf(msg, sizeof(msg), err, params);
82 if (len > sizeof(msg))
83 len = sizeof(msg);
84
82 - unused = write(child_err, "fatal: ", 7);
83 - unused = write(child_err, msg, len);
84 - unused = write(child_err, "\n", 1);
85 + write_in_full(child_err, "fatal: ", 7);
86 + write_in_full(child_err, msg, len);
87 + write_in_full(child_err, "\n", 1);
88 exit(128);
89 }
90 #endif