[PATCH v2 13/23] nscd: Introduce __nscd_read_from_socket client function
Florian Weimer
fweimer@redhat.com
Fri Mar 20 20:42:28 GMT 2026
---
nscd/nscd-client.h | 20 ++++++++++++++++-
nscd/nscd_helper.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h
index c507933acb..10284e8ef2 100644
--- a/nscd/nscd-client.h
+++ b/nscd/nscd-client.h
@@ -366,11 +366,29 @@ struct mapped_database
__libc_rwlock_define (, lock);
};
-/* Open socket connection to nscd server. */
+/* Open socket connection to nscd server, send the request, and read
+ the start of the response (update to RESPONSELEN bytes). If the
+ procided response buffer is exceeded, the socket is left open, so
+ that more data can be read. */
extern int __nscd_open_socket (const char *key, size_t keylen,
request_type type, void *response,
size_t responselen) attribute_hidden;
+/* Open a socket to nscd, send the request, and read the full
+ response. *RESPONSE is grown as necessary.
+
+ A non-negative return value indicates the number of response bytes
+ stored at RESPONSE->data. The response includes only the struct
+ *_response_header and the data that follows it, not struct
+ datahead.
+
+ On error, return a negative errno code. */
+struct scratch_buffer;
+ssize_t __nscd_read_from_socket (const char *key, size_t keylen,
+ request_type type,
+ struct scratch_buffer *response)
+ attribute_hidden;
+
/* Acquire reference to the mapping for DB (see <nscd-dbtype.h>). On
success, return a pointer to the mapping descriptor, and lock the
mapping.
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c
index 9bd0e7818e..ed2d8d09da 100644
--- a/nscd/nscd_helper.c
+++ b/nscd/nscd_helper.c
@@ -37,6 +37,7 @@
#include <kernel-features.h>
#include <nss.h>
#include <struct___timespec64.h>
+#include <scratch_buffer.h>
#include "nscd-client.h"
#include "nscd-dbtype.h"
@@ -612,3 +613,55 @@ __nscd_open_socket (const char *key, size_t keylen, request_type type,
return -1;
}
+
+ssize_t
+__nscd_read_from_socket (const char *key, size_t keylen, request_type type,
+ struct scratch_buffer *response)
+{
+ if (keylen > MAXKEYLEN)
+ return -ENAMETOOLONG;
+
+ int sock = open_socket (type, key, keylen);
+ if (sock < 0)
+ return sock;
+
+ /* The nscd stream protocol does not size information in a way that
+ is independent of request type. However, there is only one
+ request per connection, so the code below simply reads all data
+ that is available before end of stream. */
+
+ ssize_t ret = 0; /* Number of bytes read, or -1 on error. */
+ while (true)
+ {
+ /* Wait for data. Give up on timeout. */
+ if (wait_on_socket (sock, 5 * 1000) == 0)
+ break;
+ size_t remaining = response->length - ret;
+ ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, response->data + ret,
+ remaining));
+ if (nbytes < 0)
+ {
+ ret = -errno;
+ break;
+ }
+ if (nbytes == 0)
+ /* The end of the stream marks the end of packet. We cannot
+ tell if the data was truncated because nscd went away
+ unexpectedly. This will be recognized by the caller during
+ packet parsing. */
+ break;
+
+ /* Try reading more data in the next iteration after growing the
+ buffer. */
+ ret += nbytes;
+ if (ret == response->length && !scratch_buffer_grow_preserve (response))
+ {
+ ret = -ENOMEM;
+ break;
+ }
+ }
+
+ __close_nocancel_nostatus (sock);
+
+ return ret;
+}
--
2.53.0
More information about the Libc-alpha
mailing list