data = (struct groupdata *) malloc (total + n);
data = (struct groupdata *) malloc (total + n + req->key_len);
cache_addgr (struct database *db, int fd, request_header *req, void *key,	     struct group *grp, uid_t owner, int type){  ssize_t total;  ssize_t written;  time_t t = time (NULL);  if (grp == NULL)    {      /* We have no data.  This means we send the standard reply for this	 case.  */      total = sizeof (notfound);      written = TEMP_FAILURE_RETRY (write (fd, &notfound, total));      void *copy = malloc (req->key_len);      /* If we cannot allocate memory simply do not cache the information.  */      if (copy != NULL)	{	  memcpy (copy, key, req->key_len);	  /* Compute the timeout time.  */	  t += db->negtimeout;	  /* Now get the lock to safely insert the records.  */	  pthread_rwlock_rdlock (&db->lock);	  cache_add (req->type, copy, req->key_len, &notfound,		     sizeof (notfound), (void *) -1, 0, t, db, owner);	  pthread_rwlock_unlock (&db->lock);	}    }  else    {      /* Determine the I/O structure.  */      struct groupdata *data;      size_t gr_name_len = strlen (grp->gr_name) + 1;      size_t gr_passwd_len = strlen (grp->gr_passwd) + 1;      size_t gr_mem_cnt = 0;      uint32_t *gr_mem_len;      size_t gr_mem_len_total = 0;      char *gr_name;      char *cp;      char buf[12];      ssize_t n;      size_t cnt;      /* We need this to insert the `bygid' entry.  */      n = snprintf (buf, sizeof (buf), "%d", grp->gr_gid) + 1;      /* Determine the length of all members.  */      while (grp->gr_mem[gr_mem_cnt])	++gr_mem_cnt;      gr_mem_len = (uint32_t *) alloca (gr_mem_cnt * sizeof (uint32_t));      for (gr_mem_cnt = 0; grp->gr_mem[gr_mem_cnt]; ++gr_mem_cnt)	{	  gr_mem_len[gr_mem_cnt] = strlen (grp->gr_mem[gr_mem_cnt]) + 1;	  gr_mem_len_total += gr_mem_len[gr_mem_cnt];	}      /* We allocate all data in one memory block: the iov vector,	 the response header and the dataset itself.  */      total = (sizeof (struct groupdata)	       + gr_mem_cnt * sizeof (uint32_t)	       + gr_name_len + gr_passwd_len + gr_mem_len_total);      data = (struct groupdata *) malloc (total + n);      if (data == NULL)	/* There is no reason to go on.  */	error (EXIT_FAILURE, errno, _("while allocating cache entry"));      data->resp.version = NSCD_VERSION;      data->resp.found = 1;      data->resp.gr_name_len = gr_name_len;      data->resp.gr_passwd_len = gr_passwd_len;      data->resp.gr_gid = grp->gr_gid;      data->resp.gr_mem_cnt = gr_mem_cnt;      cp = data->strdata;      /* This is the member string length array.  */      cp = mempcpy (cp, gr_mem_len, gr_mem_cnt * sizeof (uint32_t));      gr_name = cp;      cp = mempcpy (cp, grp->gr_name, gr_name_len);      cp = mempcpy (cp, grp->gr_passwd, gr_passwd_len);      for (cnt = 0; cnt < gr_mem_cnt; ++cnt)	cp = mempcpy (cp, grp->gr_mem[cnt], gr_mem_len[cnt]);      /* Finally the stringified GID value.  */      memcpy (cp, buf, n);      /* Write the result.  */      written = TEMP_FAILURE_RETRY (write (fd, &data->resp, total));      /* Compute the timeout time.  */      t += db->postimeout;      /* Now get the lock to safely insert the records.  */      pthread_rwlock_rdlock (&db->lock);      /* We have to add the value for both, byname and byuid.  */      cache_add (GETGRBYNAME, gr_name, gr_name_len, data,		 total, data, 0, t, db, owner);      /* If the key is different from the name add a separate entry.  */      if (type == GETGRBYNAME && strcmp (key, gr_name) != 0)	cache_add (GETGRBYNAME, key, strlen (key) + 1, data,		   total, data, 0, t, db, owner);      cache_add (GETGRBYGID, cp, n, data, total, data, 1, t, db, owner);      pthread_rwlock_unlock (&db->lock);    }  if (__builtin_expect (written != total, 0) && debug_level > 0)    {      char buf[256];      dbg_log (_("short write in %s: %s"),  __FUNCTION__,	       strerror_r (errno, buf, sizeof (buf)));    }}