if (retval != -1 || errno != EINVAL)
if (retval != -1 || (errno != EINVAL && errno != ENOSYS))
__GETDENTS (int fd, char *buf, size_t nbytes){  off64_t last_offset = -1;  ssize_t retval;#ifdef __NR_getdents64# ifndef __ASSUME_GETDENTS64_SYSCALL  if (!__have_no_getdents64)# endif    {# ifndef __ASSUME_GETDENTS64_SYSCALL      int saved_errno = errno;# endif      union      {	struct kernel_dirent64 k;	DIRENT_TYPE u;	char b[1];      } *kbuf = (void *) buf, *outp, *inp;      size_t kbytes = nbytes;      if (offsetof (DIRENT_TYPE, d_name)	  < offsetof (struct kernel_dirent64, d_name)	  && nbytes <= sizeof (DIRENT_TYPE))	{	  kbytes = nbytes + offsetof (struct kernel_dirent64, d_name)		   - offsetof (DIRENT_TYPE, d_name);	  kbuf = __alloca(kbytes);	}      retval = INLINE_SYSCALL (getdents64, 3, fd, CHECK_N(kbuf, kbytes),			       kbytes);# ifndef __ASSUME_GETDENTS64_SYSCALL      if (retval != -1 || errno != EINVAL)# endif	{	  const size_t size_diff = (offsetof (struct kernel_dirent64, d_name)				    - offsetof (DIRENT_TYPE, d_name));	  /* Return the error if encountered.  */	  if (retval == -1)	    return -1;	  /* If the structure returned by the kernel is identical to what we	     need, don't do any conversions.  */	  if (offsetof (DIRENT_TYPE, d_name)	      == offsetof (struct kernel_dirent64, d_name)	      && sizeof (outp->u.d_ino) == sizeof (inp->k.d_ino)	      && sizeof (outp->u.d_off) == sizeof (inp->k.d_off))	    return retval;	  /* These two pointers might alias the same memory buffer.	     Standard C requires that we always use the same type for them,	     so we must use the union type.  */	  inp = kbuf;	  outp = (void *) buf;	  while (&inp->b < &kbuf->b + retval)	    {	      const size_t alignment = __alignof__ (DIRENT_TYPE);	      /* Since inp->k.d_reclen is already aligned for the kernel		 structure this may compute a value that is bigger		 than necessary.  */	      size_t old_reclen = inp->k.d_reclen;	      size_t new_reclen = ((old_reclen - size_diff + alignment - 1)				  & ~(alignment - 1));	      /* Copy the data out of the old structure into temporary space.		 Then copy the name, which may overlap if BUF == KBUF.  */	      const uint64_t d_ino = inp->k.d_ino;	      const int64_t d_off = inp->k.d_off;	      const uint8_t d_type = inp->k.d_type;	      memmove (outp->u.d_name, inp->k.d_name,		       old_reclen - offsetof (struct kernel_dirent64, d_name));	      /* Now we have copied the data from INP and access only OUTP.  */	      DIRENT_SET_DP_INO (&outp->u, d_ino);	      outp->u.d_off = d_off;	      if ((sizeof (outp->u.d_ino) != sizeof (inp->k.d_ino)		   && outp->u.d_ino != d_ino)		  || (sizeof (outp->u.d_off) != sizeof (inp->k.d_off)		      && outp->u.d_off != d_off))		{		  /* Overflow.  If there was at least one entry		     before this one, return them without error,		     otherwise signal overflow.  */		  if (last_offset != -1)		    {		      __lseek64 (fd, last_offset, SEEK_SET);		      return outp->b - buf;		    }		  __set_errno (EOVERFLOW);		  return -1;		}	      last_offset = d_off;	      outp->u.d_reclen = new_reclen;	      outp->u.d_type = d_type;	      inp = (void *) inp + old_reclen;	      outp = (void *) outp + new_reclen;	    }	  return outp->b - buf;	}# ifndef __ASSUME_GETDENTS64_SYSCALL      __set_errno (saved_errno);      __have_no_getdents64 = 1;# endif    }#endif  {    size_t red_nbytes;    struct kernel_dirent *skdp, *kdp;    const size_t size_diff = (offsetof (DIRENT_TYPE, d_name)			      - offsetof (struct kernel_dirent, d_name));    red_nbytes = MIN (nbytes		      - ((nbytes / (offsetof (DIRENT_TYPE, d_name) + 14))			 * size_diff),		      nbytes - size_diff);    skdp = kdp = __alloca (red_nbytes);    retval = INLINE_SYSCALL (getdents, 3, fd,			     CHECK_N ((char *) kdp, red_nbytes), red_nbytes);    if (retval == -1)      return -1;    DIRENT_TYPE *dp = (DIRENT_TYPE *) buf;    while ((char *) kdp < (char *) skdp + retval)      {	const size_t alignment = __alignof__ (DIRENT_TYPE);	/* Since kdp->d_reclen is already aligned for the kernel structure	   this may compute a value that is bigger than necessary.  */	size_t new_reclen = ((kdp->d_reclen + size_diff + alignment - 1)			     & ~(alignment - 1));	if ((char *) dp + new_reclen > buf + nbytes)	  {	    /* Our heuristic failed.  We read too many entries.  Reset	       the stream.  */	    assert (last_offset != -1);	    __lseek64 (fd, last_offset, SEEK_SET);	    if ((char *) dp == buf)	      {		/* The buffer the user passed in is too small to hold even		   one entry.  */		__set_errno (EINVAL);		return -1;	      }	    break;	  }	last_offset = kdp->d_off;	DIRENT_SET_DP_INO(dp, kdp->d_ino);	dp->d_off = kdp->d_off;	dp->d_reclen = new_reclen;	dp->d_type = DT_UNKNOWN;	memcpy (dp->d_name, kdp->d_name,		kdp->d_reclen - offsetof (struct kernel_dirent, d_name));	dp = (DIRENT_TYPE *) ((char *) dp + new_reclen);	kdp = (struct kernel_dirent *) (((char *) kdp) + kdp->d_reclen);      }    return (char *) dp - buf;  }}