summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/lib/readdir64.c
blob: b9b0aafcc3fe45be2c1dc62c2154c504e5c90c0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "dietfeatures.h"
#include "dietdirent.h"
#include <unistd.h>
#include <dirent.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "syscalls.h"

#ifndef __NR_getdents64
#define WANT_LARGEFILE_BACKCOMPAT
#endif

#ifndef WANT_LARGEFILE_BACKCOMPAT
struct dirent64* readdir64(DIR *d) {
  if (!d->num || (d->cur += ((struct dirent64*)(d->buf+d->cur))->d_reclen)>=d->num) {
    int res=getdents64(d->fd,(struct dirent64*)d->buf, sizeof (d->buf)-1);
    if (res<=0) return 0;
    d->num=res; d->cur=0;
  }
  return (struct dirent64*)(d->buf+d->cur);
}
#else
struct dirent64* readdir64(DIR *d) {
#ifdef __NR_getdents64
  static int trygetdents64=1;
#endif
  struct dirent* o;
  static struct dirent64 d64;
again:
#ifdef __NR_getdents64
  if (!trygetdents64) {
#endif
    if (!d->num || (d->cur += ((struct dirent*)(d->buf+d->cur))->d_reclen)>=d->num) {
      int res=getdents(d->fd,(struct dirent*)d->buf, sizeof (d->buf)-1);
      if (res<=0) return 0;
      d->num=res; d->cur=0;
    }
    o=(struct dirent*)(d->buf+d->cur);
    d64.d_ino=o->d_ino;
    d64.d_off=o->d_off;
    d64.d_reclen=o->d_reclen;
    strcpy(d64.d_name,o->d_name);
    d64.d_type=0;	/* is this correct? */
    return &d64;
#ifdef __NR_getdents64
  }
  if (!d->num || (d->cur += ((struct dirent64*)(d->buf+d->cur))->d_reclen)>=d->num) {
    int res=getdents64(d->fd,(struct dirent64*)d->buf,sizeof (d->buf));
    if (res<=0) {
      if (errno==ENOSYS) {
	trygetdents64=0;
	goto again;
      }
      return 0;
    }
    d->num=res; d->cur=0;
  }
  return (struct dirent64*)(d->buf+d->cur);
#endif
}
#endif