if (__lstat (name, &st) < 0) { int save = errno; (void) __closedir (dirstream); __set_errno (save); goto lose; } if (st.st_dev == thisdev && st.st_ino == thisino)
if (__lstat (name, &st) >= 0 && st.st_dev == thisdev && st.st_ino == thisino)
__getcwd (buf, size)     char *buf;     size_t size;{  static const char dots[]    = "../../../../../../../../../../../../../../../../../../../../../../../\../../../../../../../../../../../../../../../../../../../../../../../../../../\../../../../../../../../../../../../../../../../../../../../../../../../../..";  const char *dotp, *dotlist;  size_t dotsize;  dev_t rootdev, thisdev;  ino_t rootino, thisino;  char *path;  register char *pathp;  struct stat st;  int prev_errno = errno;  if (size == 0)    {      if (buf != NULL)	{	  __set_errno (EINVAL);	  return NULL;	}      size = PATH_MAX + 1;    }  if (buf != NULL)    path = buf;  else    {      path = malloc (size);      if (path == NULL)	return NULL;    }  pathp = path + size;  *--pathp = '\0';  if (__lstat (".", &st) < 0)    return NULL;  thisdev = st.st_dev;  thisino = st.st_ino;  if (__lstat ("/", &st) < 0)    return NULL;  rootdev = st.st_dev;  rootino = st.st_ino;  dotsize = sizeof (dots) - 1;  dotp = &dots[sizeof (dots)];  dotlist = dots;  while (!(thisdev == rootdev && thisino == rootino))    {      register DIR *dirstream;      struct dirent *d;      dev_t dotdev;      ino_t dotino;      char mount_point;      /* Look at the parent directory.  */      if (dotp == dotlist)	{	  /* My, what a deep directory tree you have, Grandma.  */	  char *new;	  if (dotlist == dots)	    {	      new = malloc (dotsize * 2 + 1);	      if (new == NULL)		return NULL;#ifdef HAVE_MEMPCPY	      dotp = mempcpy (new, dots, dotsize);#else	      memcpy (new, dots, dotsize);	      dotp = &new[dotsize];#endif	    }	  else	    {	      new = realloc ((__ptr_t) dotlist, dotsize * 2 + 1);	      if (new == NULL)		goto lose;	      dotp = &new[dotsize];	    }#ifdef HAVE_MEMPCPY	  *((char *) mempcpy ((char *) dotp, new, dotsize)) = '\0';	  dotsize *= 2;#else	  memcpy ((char *) dotp, new, dotsize);	  dotsize *= 2;	  new[dotsize] = '\0';#endif	  dotlist = new;	}      dotp -= 3;      /* Figure out if this directory is a mount point.  */      if (__lstat (dotp, &st) < 0)	goto lose;      dotdev = st.st_dev;      dotino = st.st_ino;      mount_point = dotdev != thisdev;      /* Search for the last directory.  */      dirstream = __opendir (dotp);      if (dirstream == NULL)	goto lose;      /* Clear errno to distinguish EOF from error if readdir returns	 NULL.  */      __set_errno (0);      while ((d = __readdir (dirstream)) != NULL)	{	  if (d->d_name[0] == '.' &&	      (d->d_name[1] == '\0' ||	       (d->d_name[1] == '.' && d->d_name[2] == '\0')))	    continue;	  if (mount_point || (ino_t) d->d_ino == thisino)	    {	      char name[dotlist + dotsize - dotp + 1 + _D_ALLOC_NAMLEN (d)];#ifdef HAVE_MEMPCPY	      char *tmp = mempcpy (name, dotp, dotlist + dotsize - dotp);	      *tmp++ = '/';	      strcpy (tmp, d->d_name);#else	      memcpy (name, dotp, dotlist + dotsize - dotp);	      name[dotlist + dotsize - dotp] = '/';	      strcpy (&name[dotlist + dotsize - dotp + 1], d->d_name);#endif	      if (__lstat (name, &st) < 0)		{		  int save = errno;		  (void) __closedir (dirstream);		  __set_errno (save);		  goto lose;		}	      if (st.st_dev == thisdev && st.st_ino == thisino)		break;	    }	}      if (d == NULL)	{	  int save = errno;	  (void) __closedir (dirstream);	  if (save == 0)	    /* EOF on dirstream, which means that the current directory	       has been removed.  */	    save = ENOENT;	  __set_errno (save);	  goto lose;	}      else	{	  size_t namlen = _D_EXACT_NAMLEN (d);	  if ((size_t) (pathp - path) <= namlen)	    {	      if (buf != NULL)		{		  (void) __closedir (dirstream);		  __set_errno (ERANGE);		  goto lose;		}	      else		{		  char *tmp;		  size *= 2;		  tmp = realloc (path, size);		  if (tmp == NULL)		    {		      (void) __closedir (dirstream);		      free (path);		      __set_errno (ENOMEM);/* closedir might have changed it.*/		      goto lose;		    }		  pathp = &tmp[pathp - path + size / 2];		  path = tmp;		  /* Move current contents up to the end of the buffer.		     This is guaranteed to be non-overlapping.  */		  memcpy (pathp, pathp - size / 2, path + size - pathp);		}	    }	  pathp -= namlen;	  (void) memcpy (pathp, d->d_name, namlen);	  *--pathp = '/';	  (void) __closedir (dirstream);	}      thisdev = dotdev;      thisino = dotino;    }  if (pathp == &path[size - 1])    *--pathp = '/';  if (dotlist != dots)    free ((__ptr_t) dotlist);  memmove (path, pathp, path + size - pathp);  /* Restore errno on successful return.  */  __set_errno (prev_errno);  return path; lose:  if (dotlist != dots)    free ((__ptr_t) dotlist);  return NULL;}