Re: psql client does not handle WSAEWOULDBLOCK on Windows
От | Tom Lane |
---|---|
Тема | Re: psql client does not handle WSAEWOULDBLOCK on Windows |
Дата | |
Msg-id | 1768846.1759691684@sss.pgh.pa.us обсуждение исходный текст |
Ответ на | Re: psql client does not handle WSAEWOULDBLOCK on Windows (Tom Lane <tgl@sss.pgh.pa.us>) |
Список | pgsql-hackers |
I wrote: > Michael Paquier <michael@paquier.xyz> writes: >> Also, what about pqsecure_raw_write() in pqsecure_open_gss()? >> Shouldn't the same check apply? > Yeah, I think we pretty much need to use SOCK_ERRNO, SOCK_ERRNO_SET, > and SOCK_STRERROR (if relevant) throughout fe-secure-gssapi.c. Since nothing seems to be happening here, I took another look and decided that the required changes are really pretty straightforward. fe-secure-gssapi.c doesn't contain any strerror calls, and its touches of errno all appear to relate to socket errors, so we can just change them all. As attached. > Like you, I'm not really in a position to test this on Windows ... I'm still not, but it's straightforward enough that I'm willing to push on my own authority. I'll just put this up for long enough to make sure that the cfbot is happy with it --- though I think it's not building with GSSAPI on Windows, so that may prove little. regards, tom lane From 36f3ee942ef12801e52ce3fc82204455345939a6 Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Sun, 5 Oct 2025 15:05:38 -0400 Subject: [PATCH v2] Use SOCK_ERRNO[_SET] in fe-secure-gssapi.c. On Windows, this code did not handle error conditions correctly at all, since it looked at "errno" which is not used for socket-related errors on that platform. This resulted, for example, in failure to connect to a PostgreSQL server with GSSAPI enabled. We have a convention for dealing with this within libpq, which is to use SOCK_ERRNO and SOCK_ERRNO_SET rather than touching errno directly; but the GSSAPI code is a relative latecomer and did not get that memo. (The equivalent backend code continues to use errno, because the backend does this differently. Maybe libpq's approach should be rethought someday.) Author: Ning Wu <ning94803@gmail.com> Co-authored-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/CAFGqpvg-pRw=cdsUpKYfwY6D3d-m9tw8WMcAEE7HHWfm-oYWvw@mail.gmail.com Backpatch-through: 13 --- src/interfaces/libpq/fe-secure-gssapi.c | 27 ++++++++++++++----------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/interfaces/libpq/fe-secure-gssapi.c b/src/interfaces/libpq/fe-secure-gssapi.c index bc9e1ce06fa..843b31e175f 100644 --- a/src/interfaces/libpq/fe-secure-gssapi.c +++ b/src/interfaces/libpq/fe-secure-gssapi.c @@ -121,7 +121,7 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t len) { appendPQExpBufferStr(&conn->errorMessage, "GSSAPI caller failed to retransmit all data needing to be retried\n"); - errno = EINVAL; + SOCK_ERRNO_SET(EINVAL); return -1; } @@ -199,14 +199,14 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t len) if (major != GSS_S_COMPLETE) { pg_GSS_error(libpq_gettext("GSSAPI wrap error"), conn, major, minor); - errno = EIO; /* for lack of a better idea */ + SOCK_ERRNO_SET(EIO); /* for lack of a better idea */ goto cleanup; } if (conf_state == 0) { libpq_append_conn_error(conn, "outgoing GSSAPI message would not use confidentiality"); - errno = EIO; /* for lack of a better idea */ + SOCK_ERRNO_SET(EIO); /* for lack of a better idea */ goto cleanup; } @@ -215,7 +215,7 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t len) libpq_append_conn_error(conn, "client tried to send oversize GSSAPI packet (%zu > %zu)", (size_t) output.length, PQ_GSS_MAX_PACKET_SIZE - sizeof(uint32)); - errno = EIO; /* for lack of a better idea */ + SOCK_ERRNO_SET(EIO); /* for lack of a better idea */ goto cleanup; } @@ -341,7 +341,7 @@ pg_GSS_read(PGconn *conn, void *ptr, size_t len) /* If we still haven't got the length, return to the caller */ if (PqGSSRecvLength < sizeof(uint32)) { - errno = EWOULDBLOCK; + SOCK_ERRNO_SET(EWOULDBLOCK); return -1; } } @@ -354,7 +354,7 @@ pg_GSS_read(PGconn *conn, void *ptr, size_t len) libpq_append_conn_error(conn, "oversize GSSAPI packet sent by the server (%zu > %zu)", (size_t) input.length, PQ_GSS_MAX_PACKET_SIZE - sizeof(uint32)); - errno = EIO; /* for lack of a better idea */ + SOCK_ERRNO_SET(EIO); /* for lack of a better idea */ return -1; } @@ -373,7 +373,7 @@ pg_GSS_read(PGconn *conn, void *ptr, size_t len) /* If we don't yet have the whole packet, return to the caller */ if (PqGSSRecvLength - sizeof(uint32) < input.length) { - errno = EWOULDBLOCK; + SOCK_ERRNO_SET(EWOULDBLOCK); return -1; } @@ -393,7 +393,7 @@ pg_GSS_read(PGconn *conn, void *ptr, size_t len) pg_GSS_error(libpq_gettext("GSSAPI unwrap error"), conn, major, minor); ret = -1; - errno = EIO; /* for lack of a better idea */ + SOCK_ERRNO_SET(EIO); /* for lack of a better idea */ goto cleanup; } @@ -401,7 +401,7 @@ pg_GSS_read(PGconn *conn, void *ptr, size_t len) { libpq_append_conn_error(conn, "incoming GSSAPI message did not use confidentiality"); ret = -1; - errno = EIO; /* for lack of a better idea */ + SOCK_ERRNO_SET(EIO); /* for lack of a better idea */ goto cleanup; } @@ -437,7 +437,8 @@ gss_read(PGconn *conn, void *recv_buffer, size_t length, ssize_t *ret) *ret = pqsecure_raw_read(conn, recv_buffer, length); if (*ret < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) + if (SOCK_ERRNO == EAGAIN || SOCK_ERRNO == EWOULDBLOCK || + SOCK_ERRNO == EINTR) return PGRES_POLLING_READING; else return PGRES_POLLING_FAILED; @@ -457,7 +458,8 @@ gss_read(PGconn *conn, void *recv_buffer, size_t length, ssize_t *ret) *ret = pqsecure_raw_read(conn, recv_buffer, length); if (*ret < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) + if (SOCK_ERRNO == EAGAIN || SOCK_ERRNO == EWOULDBLOCK || + SOCK_ERRNO == EINTR) return PGRES_POLLING_READING; else return PGRES_POLLING_FAILED; @@ -520,7 +522,8 @@ pqsecure_open_gss(PGconn *conn) ret = pqsecure_raw_write(conn, PqGSSSendBuffer + PqGSSSendNext, amount); if (ret < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) + if (SOCK_ERRNO == EAGAIN || SOCK_ERRNO == EWOULDBLOCK || + SOCK_ERRNO == EINTR) return PGRES_POLLING_WRITING; else return PGRES_POLLING_FAILED; -- 2.43.7
В списке pgsql-hackers по дате отправления: