/* Cache handling for netgroup lookup.
- Copyright (C) 2011-2017 Free Software Foundation, Inc.
+ Copyright (C) 2011-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gmail.com>, 2011.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>. */
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
#include <alloca.h>
#include <assert.h>
static time_t
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
const char *key, uid_t uid, struct hashentry *he,
- struct datahead *dh, struct dataset **resultp)
+ struct datahead *dh, struct dataset **resultp,
+ void **tofreep)
{
if (__glibc_unlikely (debug_level > 0))
{
size_t group_len = strlen (key) + 1;
struct name_list *first_needed
= alloca (sizeof (struct name_list) + group_len);
+ *tofreep = NULL;
if (netgroup_database == NULL
- && __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
+ && __nss_database_lookup2 ("netgroup", NULL, NULL, &netgroup_database))
{
/* No such service. */
cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
memset (&data, '\0', sizeof (data));
buffer = xmalloc (buflen);
+ *tofreep = buffer;
first_needed->next = first_needed;
memcpy (first_needed->name, key, group_len);
data.needed_groups = first_needed;
since while inserting this thread might block and so would
unnecessarily let the receiver wait. */
writeout:
-#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && cacheable)
- {
- assert (db->wr_fd != -1);
- assert ((char *) &dataset->resp > (char *) db->data);
- assert ((char *) dataset - (char *) db->head + total
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
-# ifndef __ASSUME_SENDFILE
- ssize_t written =
-# endif
- sendfileall (fd, db->wr_fd, (char *) &dataset->resp
- - (char *) db->head, dataset->head.recsize);
-# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- }
- else
-#endif
- {
-#if defined HAVE_SENDFILE && !defined __ASSUME_SENDFILE
- use_write:
-#endif
- writeall (fd, &dataset->resp, dataset->head.recsize);
- }
+ writeall (fd, &dataset->resp, dataset->head.recsize);
}
if (cacheable)
}
out:
- free (buffer);
-
*resultp = dataset;
return timeout;
{
const char *group = key;
key = (char *) rawmemchr (key, '\0') + 1;
- size_t group_len = key - group - 1;
+ size_t group_len = key - group;
const char *host = *key++ ? key : NULL;
if (host != NULL)
key = (char *) rawmemchr (key, '\0') + 1;
group, group_len,
db, uid);
time_t timeout;
+ void *tofree;
if (result != NULL)
- timeout = result->head.timeout;
+ {
+ timeout = result->head.timeout;
+ tofree = NULL;
+ }
else
{
request_header req_get =
.key_len = group_len
};
timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL,
- &result);
+ &result, &tofree);
}
struct indataset
dh->timeout = timeout;
dh->ttl = dataset->head.ttl;
++dh->nreloads;
- return timeout;
+ if (cacheable)
+ pthread_rwlock_unlock (&db->lock);
+ goto out;
}
if (he == NULL)
/* We write the dataset before inserting it to the database
since while inserting this thread might block and so would
unnecessarily let the receiver wait. */
- assert (fd != -1);
+ assert (fd != -1);
-#ifdef HAVE_SENDFILE
- if (__builtin_expect (db->mmap_used, 1) && cacheable)
- {
- assert (db->wr_fd != -1);
- assert ((char *) &dataset->resp > (char *) db->data);
- assert ((char *) dataset - (char *) db->head + sizeof (*dataset)
- <= (sizeof (struct database_pers_head)
- + db->head->module * sizeof (ref_t)
- + db->head->data_size));
-# ifndef __ASSUME_SENDFILE
- ssize_t written =
-# endif
- sendfileall (fd, db->wr_fd,
- (char *) &dataset->resp - (char *) db->head,
- sizeof (innetgroup_response_header));
-# ifndef __ASSUME_SENDFILE
- if (written == -1 && errno == ENOSYS)
- goto use_write;
-# endif
- }
- else
-#endif
- {
-#if defined HAVE_SENDFILE && !defined __ASSUME_SENDFILE
- use_write:
-#endif
- writeall (fd, &dataset->resp, sizeof (innetgroup_response_header));
- }
+ writeall (fd, &dataset->resp, sizeof (innetgroup_response_header));
}
if (cacheable)
dh->usable = false;
}
+ out:
+ free (tofree);
return timeout;
}
+static time_t
+addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req,
+ const char *key, uid_t uid, struct hashentry *he,
+ struct datahead *dh)
+{
+ struct dataset *ignore;
+ void *tofree;
+ time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh,
+ &ignore, &tofree);
+ free (tofree);
+ return timeout;
+}
+
void
addgetnetgrent (struct database_dyn *db, int fd, request_header *req,
void *key, uid_t uid)
{
- struct dataset *ignore;
-
- addgetnetgrentX (db, fd, req, key, uid, NULL, NULL, &ignore);
+ addgetnetgrentX_ignore (db, fd, req, key, uid, NULL, NULL);
}
.type = GETNETGRENT,
.key_len = he->len
};
- struct dataset *ignore;
-
- return addgetnetgrentX (db, -1, &req, db->data + he->key, he->owner, he, dh,
- &ignore);
+ return addgetnetgrentX_ignore
+ (db, -1, &req, db->data + he->key, he->owner, he, dh);
}