Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/ape/lib/ap/plan9/opendir.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "lib.h"
2
#include <stdlib.h>
3
#include <sys/stat.h>
4
#include <dirent.h>
5
#include <unistd.h>
6
#include <errno.h>
7
#include <string.h>
8
#include "sys9.h"
9
#include "dir.h"
10
 
11
#define DBLOCKSIZE 20
12
 
13
DIR *
14
opendir(const char *filename)
15
{
16
	int f;
17
	DIR *d;
18
	struct stat sb;
19
	Dir *d9;
20
 
21
	if((d9 = _dirstat(filename)) == nil){
22
		_syserrno();
23
		return NULL;
24
	}
25
	_dirtostat(&sb, d9, 0);
26
	free(d9);
27
	if(S_ISDIR(sb.st_mode) == 0) {
28
		errno = ENOTDIR;
29
		return NULL;
30
	}
31
 
32
	f = open(filename, O_RDONLY);
33
	if(f < 0){
34
		_syserrno();
35
		return NULL;
36
	}
37
	_fdinfo[f].flags |= FD_CLOEXEC;
38
	d = (DIR *)malloc(sizeof(DIR) + DBLOCKSIZE*sizeof(struct dirent));
39
	if(!d){
40
		errno = ENOMEM;
41
		return NULL;
42
	}
43
	d->dd_buf = (char *)d + sizeof(DIR);
44
	d->dd_fd = f;
45
	d->dd_loc = 0;
46
	d->dd_size = 0;
47
	d->dirs = nil;
48
	d->dirsize = 0;
49
	d->dirloc = 0;
50
	return d;
51
}
52
 
53
int
54
closedir(DIR *d)
55
{
56
	if(!d){
57
		errno = EBADF;
58
		return -1;
59
	}
60
	if(close(d->dd_fd) < 0)
61
		return -1;
62
	free(d->dirs);
63
	free(d);
64
	return 0;
65
}
66
 
67
void
68
rewinddir(DIR *d)
69
{
70
	if(!d)
71
		return;
72
	d->dd_loc = 0;
73
	d->dd_size = 0;
74
	d->dirsize = 0;
75
	d->dirloc = 0;
76
	free(d->dirs);
77
	d->dirs = nil;
78
	if(_SEEK(d->dd_fd, 0, 0) < 0){
79
		_syserrno();
80
		return;
81
	}
82
}
83
 
84
struct dirent *
85
readdir(DIR *d)
86
{
87
	int i;
88
	struct dirent *dr;
89
	Dir *dirs;
90
 
91
	if(!d){
92
		errno = EBADF;
93
		return NULL;
94
	}
95
	if(d->dd_loc >= d->dd_size){
96
		if(d->dirloc >= d->dirsize){
97
			free(d->dirs);
98
			d->dirs = NULL;
99
			d->dirsize = _dirread(d->dd_fd, &d->dirs);
100
			d->dirloc = 0;
101
		}
102
		if(d->dirsize < 0) {	/* malloc or read failed in _dirread? */
103
			free(d->dirs);
104
			d->dirs = NULL;
105
		}
106
		if(d->dirs == NULL)
107
			return NULL;
108
 
109
		dr = (struct dirent *)d->dd_buf;
110
		dirs = d->dirs;
111
		for(i=0; i<DBLOCKSIZE && d->dirloc < d->dirsize; i++){
112
			strncpy(dr[i].d_name, dirs[d->dirloc++].name, MAXNAMLEN);
113
			dr[i].d_name[MAXNAMLEN] = 0;
114
		}
115
		d->dd_loc = 0;
116
		d->dd_size = i*sizeof(struct dirent);
117
	}
118
	dr = (struct dirent*)(d->dd_buf+d->dd_loc);
119
	d->dd_loc += sizeof(struct dirent);
120
	return dr;
121
}