diff options
author | Ulrich Drepper <drepper@redhat.com> | 2008-06-12 04:52:39 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2008-06-12 04:52:39 +0000 |
commit | 9ad58cc3ba614e13af5a6f3810f9b115899eb2ca (patch) | |
tree | 4c9eb1babf38f281adcc2cf80d08dbf7b648930d /nscd | |
parent | c128355211141f304e9257dc6d16b73ab57a1fd0 (diff) | |
download | glibc-9ad58cc3ba614e13af5a6f3810f9b115899eb2ca.zip glibc-9ad58cc3ba614e13af5a6f3810f9b115899eb2ca.tar.gz glibc-9ad58cc3ba614e13af5a6f3810f9b115899eb2ca.tar.bz2 |
* nscd/mem.c (gc): Initialize obstack earlier so that if we jump
out we don't use uninitialized memory.
* nscd/hstcache.c (cache_addhst): Send correct number of bytes to
the client.
Diffstat (limited to 'nscd')
-rw-r--r-- | nscd/hstcache.c | 42 | ||||
-rw-r--r-- | nscd/mem.c | 9 |
2 files changed, 31 insertions, 20 deletions
diff --git a/nscd/hstcache.c b/nscd/hstcache.c index d4dd51f..4333917 100644 --- a/nscd/hstcache.c +++ b/nscd/hstcache.c @@ -83,8 +83,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, struct hashentry *he, struct datahead *dh, int errval, int32_t ttl) { - ssize_t total; - ssize_t written; + bool all_written = true; time_t t = time (NULL); /* We allocate all data in one memory block: the iov vector, @@ -108,18 +107,17 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, if (reload_count != UINT_MAX) /* Do not reset the value if we never not reload the record. */ dh->nreloads = reload_count - 1; - - written = total = 0; } else { /* We have no data. This means we send the standard reply for this case. */ - written = total = sizeof (notfound); + ssize_t total = sizeof (notfound); - if (fd != -1) - written = TEMP_FAILURE_RETRY (send (fd, ¬found, total, - MSG_NOSIGNAL)); + if (fd != -1 && + TEMP_FAILURE_RETRY (send (fd, ¬found, total, + MSG_NOSIGNAL)) != total) + all_written = false; dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, IDX_result_data); @@ -181,6 +179,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, char *key_copy = NULL; char *cp; size_t cnt; + ssize_t total; /* Determine the number of aliases. */ h_aliases_cnt = 0; @@ -208,7 +207,6 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, + h_name_len + h_aliases_cnt * sizeof (uint32_t) + h_addr_list_cnt * hst->h_length); - written = total; /* If we refill the cache, first assume the reconrd did not change. Allocate memory on the cache since it is likely @@ -260,6 +258,9 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, dataset->resp.h_addr_list_cnt = h_addr_list_cnt; dataset->resp.error = NETDB_SUCCESS; + /* Make sure there is no gap. */ + assert ((char *) (&dataset->resp.error + 1) == dataset->strdata); + cp = dataset->strdata; cp = mempcpy (cp, hst->h_name, h_name_len); @@ -286,6 +287,8 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, we explicitly add the name here. */ key_copy = memcpy (cp, key, req->key_len); + assert ((char *) &dataset->resp + dataset->head.recsize == cp); + /* Now we can determine whether on refill we have to create a new record or not. */ if (he != NULL) @@ -351,20 +354,27 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, <= (sizeof (struct database_pers_head) + db->head->module * sizeof (ref_t) + db->head->data_size)); - written = sendfileall (fd, db->wr_fd, - (char *) &dataset->resp - - (char *) db->head, total); + ssize_t written = sendfileall (fd, db->wr_fd, + (char *) &dataset->resp + - (char *) db->head, + dataset->head.recsize); + if (written != dataset->head.recsize) + { # ifndef __ASSUME_SENDFILE - if (written == -1 && errno == ENOSYS) - goto use_write; + if (written == -1 && errno == ENOSYS) + goto use_write; # endif + all_written = false; + } } else # ifndef __ASSUME_SENDFILE use_write: # endif #endif - written = writeall (fd, &dataset->resp, total); + if (writeall (fd, &dataset->resp, dataset->head.recsize) + != dataset->head.recsize) + all_written = false; } /* Add the record to the database. But only if it has not been @@ -414,7 +424,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, } } - if (__builtin_expect (written != total, 0) && debug_level > 0) + if (__builtin_expect (!all_written, 0) && debug_level > 0) { char buf[256]; dbg_log (_("short write in %s: %s"), __FUNCTION__, @@ -235,6 +235,11 @@ gc (struct database_dyn *db) /* Sort the entries by their address. */ qsort (he, cnt, sizeof (struct hashentry *), sort_he); +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free + struct obstack ob; + obstack_init (&ob); + /* Determine the highest used address. */ size_t high = nmark; while (high > 0 && mark[high - 1] == 0) @@ -307,10 +312,6 @@ gc (struct database_dyn *db) size_t size; struct moveinfo *next; } *moves = NULL; -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - struct obstack ob; - obstack_init (&ob); while (byte < high) { |