File: readdir.c

package info (click to toggle)
libc-sparc 5.3.12-2
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 18,664 kB
  • ctags: 53,237
  • sloc: ansic: 181,379; asm: 5,080; makefile: 3,340; lex: 521; sh: 439; yacc: 401; awk: 28
file content (125 lines) | stat: -rw-r--r-- 2,813 bytes parent folder | download | duplicates (2)
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <dirent.h>
#include <errno.h>
#include <sys/syscall.h>

#include "../dirstream.h"

/*
 * readdir fills up the buffer with the readdir system call. it also
 * gives a third parameter (currently ignored, but should be 1) that
 * can with a future kernel be enhanced to be the number of entries
 * to be gotten.
 */

#ifdef __ELF__
#pragma weak readdir = __libc_readdir
#endif

struct dirent *
__libc_readdir(DIR * dir)
{
  int result;
  struct dirent *de;

  if (!dir) {
    errno = EBADF;
    return NULL; 
  }

  if (dir->dd_size <= dir->dd_nextloc)
  {
      /* read dir->dd_max bytes of directory entries. */
      __asm__ volatile ("or %%g0, %0, %%g1\n\t"
                        "or %%g0, %2, %%o0\n\t"
			"or %%g0, %3, %%o1\n\t"
			"or %%g0, %4, %%o2\n\t"
			"t 0x10\n\t"
			"bcc 1f\n\t"
			"or %%g0, %%o0, %0\n\t"
			"sub %%g0, %%o0, %0\n\t"
			"1:\n\t"
			: "=r" (result)
			: "0" (SYS_getdents), "r" ((long) dir->dd_fd),
			  "r" ((long) dir->dd_buf), "r" (dir->dd_max)
			: "g1", "o0", "o1", "o2");
    /* We have getdents(). */
    dir->dd_getdents = have_getdents;
    if (result <= 0)
    {
      errno = -result;
      return NULL;
    }

    dir->dd_size = result;
    dir->dd_nextloc = 0;
  }

  de = (struct dirent *) (((char *)dir->dd_buf) + dir->dd_nextloc);

  /* Am I right? H.J. */
  dir->dd_nextloc += de->d_reclen;

  /* We have to save the next offset here. */
  dir->dd_nextoff = de->d_off;

  return de;
}

#if 0
struct dirent *old_readdir(DIR * dir)
{
  int result;
  int count = NUMENT;

  if (!dir) {
    errno = EBADF;
    return NULL; 
  }

  if (dir->dd_size <= dir->dd_loc) {
    /* read count of directory entries. For now it should be one. */
#if defined(__PIC__) || defined (__pic__)
	__asm__ volatile ("pushl %%ebx\n\t"
			  "movl %%esi,%%ebx\n\t"
			  "int $0x80\n\t"
			  "popl %%ebx"
	:"=a" (result)
	:"0" (SYS_readdir),"S" (dir->dd_fd),
	"c" ((long) dir->dd_buf),"d" (count));
#else
        __asm__ volatile ("or %%g0, %0, %%g1\n\t"
		 "or %%g0, %1, %%o0\n\t"
		 "or %%g0, %2, %%o1\n\t"
		 "or %%g0, %3, %%o2\n\t"
		 "t 0x10\n\t"
		 "or %%g0, %%o0, %0\n\t"
		 : "=r" (result), "=r" ((long)dir->dd_fd), "=r" ((long)dir->dd_buf),
		   "=r" ((long)count)
		 : "0" (SYS_readdir), "1" ((long)dir->dd_fd),
		   "2" ((long) dir->dd_buf), "3" ((long)count)
		 : "g1", "o0", "o1", "o2");
#endif
    if (result <= 0) {
      if (result < 0)
	errno = -result;
      return NULL;
    }

    /*
     * Right now the readdir system call return the number of
     * characters in the name - in the future it will probably return
     * the number of entries gotten. No matter - right now we just
     * check for positive:
     */
#if 0
    dir->dd_size = result;
#else
    dir->dd_size = 1;
#endif

    dir->dd_loc = 0;
  }

  return &(dir->dd_buf [(dir->dd_loc)++]);
}
#endif