diff mbox series

[10/10] http: fix build error on FreeBSD

Message ID deb30e12a5861410b6c3b7385fe09599ddd0394b.1728906490.git.ps@pks.im (mailing list archive)
State Superseded
Headers show
Series Platform compatibility fixes | expand

Commit Message

Patrick Steinhardt Oct. 14, 2024, 12:21 p.m. UTC
The `result` parameter passed to `http_request_reauth()` may either
point to a `struct strbuf` or a `FILE *`, where the `target` parameter
tells us which of either it actually is. To accommodate for both types
the pointer is a `void *`, which we then pass directly to functions
without doing a cast.

This is fine on most platforms, but it breaks on FreeBSD because
`fileno()` is implemented as a macro that tries to directly access the
`FILE *` structure.

Fix this issue by storing the `FILE *` in a local variable before we
pass it on to other functions.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 http.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

Comments

Taylor Blau Oct. 14, 2024, 10:14 p.m. UTC | #1
On Mon, Oct 14, 2024 at 02:21:39PM +0200, Patrick Steinhardt wrote:
> The `result` parameter passed to `http_request_reauth()` may either
> point to a `struct strbuf` or a `FILE *`, where the `target` parameter
> tells us which of either it actually is. To accommodate for both types
> the pointer is a `void *`, which we then pass directly to functions
> without doing a cast.
>
> This is fine on most platforms, but it breaks on FreeBSD because
> `fileno()` is implemented as a macro that tries to directly access the
> `FILE *` structure.

Hah. I'm sure this was another fun debugging story ;-). Reading this
made me chuckle aloud, but the fix you wrote here makes perfect sense to
me.

Thanks,
Taylor
Patrick Steinhardt Oct. 15, 2024, 11:44 a.m. UTC | #2
On Mon, Oct 14, 2024 at 06:14:04PM -0400, Taylor Blau wrote:
> On Mon, Oct 14, 2024 at 02:21:39PM +0200, Patrick Steinhardt wrote:
> > The `result` parameter passed to `http_request_reauth()` may either
> > point to a `struct strbuf` or a `FILE *`, where the `target` parameter
> > tells us which of either it actually is. To accommodate for both types
> > the pointer is a `void *`, which we then pass directly to functions
> > without doing a cast.
> >
> > This is fine on most platforms, but it breaks on FreeBSD because
> > `fileno()` is implemented as a macro that tries to directly access the
> > `FILE *` structure.
> 
> Hah. I'm sure this was another fun debugging story ;-). Reading this
> made me chuckle aloud, but the fix you wrote here makes perfect sense to
> me.

I'm sure I've either got less hair or grown more gray hair over the last
couple weeks due to all of these weird compatibility issues. Kind of
puzzling that either nobody else has hit those issues, or alternatively
that nobody seems to care. *shrug*

Patrick
diff mbox series

Patch

diff --git a/http.c b/http.c
index d59e59f66b1..72973175a85 100644
--- a/http.c
+++ b/http.c
@@ -2290,17 +2290,19 @@  static int http_request_reauth(const char *url,
 		case HTTP_REQUEST_STRBUF:
 			strbuf_reset(result);
 			break;
-		case HTTP_REQUEST_FILE:
-			if (fflush(result)) {
+		case HTTP_REQUEST_FILE: {
+			FILE *f = result;
+			if (fflush(f)) {
 				error_errno("unable to flush a file");
 				return HTTP_START_FAILED;
 			}
-			rewind(result);
-			if (ftruncate(fileno(result), 0) < 0) {
+			rewind(f);
+			if (ftruncate(fileno(f), 0) < 0) {
 				error_errno("unable to truncate a file");
 				return HTTP_START_FAILED;
 			}
 			break;
+		}
 		default:
 			BUG("Unknown http_request target");
 		}