maybe_flush_or_die: move a too-loose Windows specific error
check to compat
Commit b2f5e268 (Windows: Work around an oddity when a pipe with no reader
is written to) introduced a check for EINVAL after fflush() to fight
spurious "Invalid argument" errors on Windows when a pipe was broken. But
this check may hide real errors on systems that do not have the this odd
behavior. Introduce an fflush wrapper in compat/mingw.* so that the treatment
is only applied on Windows.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
			
			
				maint
			
			
		
							parent
							
								
									bafc478f16
								
							
						
					
					
						commit
						84adb64154
					
				|  | @ -335,6 +335,28 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream) | |||
| 	return freopen(filename, otype, stream); | ||||
| } | ||||
|  | ||||
| #undef fflush | ||||
| int mingw_fflush(FILE *stream) | ||||
| { | ||||
| 	int ret = fflush(stream); | ||||
|  | ||||
| 	/* | ||||
| 	 * write() is used behind the scenes of stdio output functions. | ||||
| 	 * Since git code does not check for errors after each stdio write | ||||
| 	 * operation, it can happen that write() is called by a later | ||||
| 	 * stdio function even if an earlier write() call failed. In the | ||||
| 	 * case of a pipe whose readable end was closed, only the first | ||||
| 	 * call to write() reports EPIPE on Windows. Subsequent write() | ||||
| 	 * calls report EINVAL. It is impossible to notice whether this | ||||
| 	 * fflush invocation triggered such a case, therefore, we have to | ||||
| 	 * catch all EINVAL errors whole-sale. | ||||
| 	 */ | ||||
| 	if (ret && errno == EINVAL) | ||||
| 		errno = EPIPE; | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC. | ||||
|  * Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch. | ||||
|  |  | |||
|  | @ -185,6 +185,9 @@ FILE *mingw_fopen (const char *filename, const char *otype); | |||
| FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream); | ||||
| #define freopen mingw_freopen | ||||
|  | ||||
| int mingw_fflush(FILE *stream); | ||||
| #define fflush mingw_fflush | ||||
|  | ||||
| char *mingw_getcwd(char *pointer, int len); | ||||
| #define getcwd mingw_getcwd | ||||
|  | ||||
|  |  | |||
|  | @ -34,12 +34,7 @@ void maybe_flush_or_die(FILE *f, const char *desc) | |||
| 			return; | ||||
| 	} | ||||
| 	if (fflush(f)) { | ||||
| 		/* | ||||
| 		 * On Windows, EPIPE is returned only by the first write() | ||||
| 		 * after the reading end has closed its handle; subsequent | ||||
| 		 * write()s return EINVAL. | ||||
| 		 */ | ||||
| 		if (errno == EPIPE || errno == EINVAL) | ||||
| 		if (errno == EPIPE) | ||||
| 			exit(0); | ||||
| 		die_errno("write failure on '%s'", desc); | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Johannes Sixt
						Johannes Sixt