mirror of
				https://github.com/osmarks/ngircd.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	Support non-standard vsnprintf() return code
C99 states that vsnprintf() "returns the number of characters that would have been printed if the n were unlimited"; but according to the Linux manual page "glibc until 2.0.6 would return -1 when the output was truncated" -- so we have to handle both cases ...
This commit is contained in:
		| @@ -1,6 +1,6 @@ | |||||||
| /* | /* | ||||||
|  * ngIRCd -- The Next Generation IRC Daemon |  * ngIRCd -- The Next Generation IRC Daemon | ||||||
|  * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors. |  * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors. | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @@ -984,6 +984,7 @@ va_dcl | |||||||
| 	size_t len; | 	size_t len; | ||||||
| 	bool ok; | 	bool ok; | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | 	int r; | ||||||
|  |  | ||||||
| 	assert( Idx > NONE ); | 	assert( Idx > NONE ); | ||||||
| 	assert( Format != NULL ); | 	assert( Format != NULL ); | ||||||
| @@ -993,7 +994,8 @@ va_dcl | |||||||
| #else | #else | ||||||
| 	va_start( ap ); | 	va_start( ap ); | ||||||
| #endif | #endif | ||||||
| 	if (vsnprintf( buffer, COMMAND_LEN - 2, Format, ap ) >= COMMAND_LEN - 2 ) { | 	r = vsnprintf(buffer, COMMAND_LEN - 2, Format, ap); | ||||||
|  | 	if (r >= COMMAND_LEN - 2 || r == -1) { | ||||||
| 		/* | 		/* | ||||||
| 		 * The string that should be written to the socket is longer | 		 * The string that should be written to the socket is longer | ||||||
| 		 * than the allowed size of COMMAND_LEN bytes (including both | 		 * than the allowed size of COMMAND_LEN bytes (including both | ||||||
| @@ -1014,6 +1016,13 @@ va_dcl | |||||||
| 		 * an other server only routing the message!), so the only | 		 * an other server only routing the message!), so the only | ||||||
| 		 * option left is to shorten the string and to hope that the | 		 * option left is to shorten the string and to hope that the | ||||||
| 		 * result is still somewhat useful ... | 		 * result is still somewhat useful ... | ||||||
|  | 		 * | ||||||
|  | 		 * Note: | ||||||
|  | 		 * C99 states that vsnprintf() "returns the number of characters | ||||||
|  | 		 * that would have been printed if the n were unlimited"; but | ||||||
|  | 		 * according to the Linux manual page "glibc until 2.0.6 would | ||||||
|  | 		 * return -1 when the output was truncated" -- so we have to | ||||||
|  | 		 * handle both cases ... | ||||||
| 		 *                                                   -alex- | 		 *                                                   -alex- | ||||||
| 		 */ | 		 */ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -139,16 +139,35 @@ va_dcl | |||||||
| { | { | ||||||
| 	char str[5]; | 	char str[5]; | ||||||
| 	va_list ap; | 	va_list ap; | ||||||
|  | 	int r; | ||||||
|  |  | ||||||
| #ifdef PROTOTYPES | #ifdef PROTOTYPES | ||||||
| 	va_start(ap, Format); | 	va_start(ap, Format); | ||||||
| #else | #else | ||||||
| 	va_start(ap); | 	va_start(ap); | ||||||
| #endif | #endif | ||||||
| 	if (vsnprintf(str, sizeof(str), Format, ap) != Len) | 	r = vsnprintf(str, sizeof(str), Format, ap); | ||||||
| 		Panic("vsnprintf return code"); |  | ||||||
| 	va_end(ap); | 	va_end(ap); | ||||||
|  | 	if (r != Len) { | ||||||
|  | 		/* C99 states that vsnprintf() "returns the number of | ||||||
|  | 		 * characters that would have been printed if the n were | ||||||
|  | 		 * unlimited", but according to the Linux manual page "glibc | ||||||
|  | 		 * until 2.0.6 would return -1 when the output was truncated", | ||||||
|  | 		 * and other implementations (libUTIL on A/UX) even return the | ||||||
|  | 		 * number of characters processed ... so we only test our own | ||||||
|  | 		 * implementation and warn on errors otherwise :-/ */ | ||||||
|  | #ifdef HAVE_VSNPRINTF | ||||||
|  | 		fprintf(stderr, | ||||||
|  | 			"\n ** WARNING: The vsnprintf() function of this system isn't standard\n"); | ||||||
|  | 		fprintf(stderr, | ||||||
|  | 			" ** conformant and returns a WRONG result: %d (should be %d)! The test\n", | ||||||
|  | 			r, Len); | ||||||
|  | 		fprintf(stderr, | ||||||
|  | 			" ** result has been ignored but may lead to errors during execution!\n\n"); | ||||||
|  | #else | ||||||
|  | 		Panic("vsnprintf return code"); | ||||||
|  | #endif | ||||||
|  | 	} | ||||||
| 	if (str[4] != '\0') | 	if (str[4] != '\0') | ||||||
| 		Panic("vsnprintf NULL byte"); | 		Panic("vsnprintf NULL byte"); | ||||||
| 	if (strlen(str) != 4) | 	if (strlen(str) != 4) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Alexander Barton
					Alexander Barton