libposix: implemented libposix_getdents
This commit is contained in:
parent
97c4c2bccb
commit
9947978c05
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#ifndef _LIBPOSIX_DIRENT
|
#ifndef _LIBPOSIX_DIRENT
|
||||||
#define _LIBPOSIX_DIRENT
|
#define _LIBPOSIX_DIRENT
|
||||||
|
|
||||||
/* dirent alias of stat(5) message.
|
/* dirent alias of stat(5) message.
|
||||||
* We (ab)use the fact that both 9P and Jehanne are little endian.
|
* We (ab)use the fact that both 9P and Jehanne are little endian.
|
||||||
* With the new file protocol this might change.
|
* With the new file protocol this might change.
|
||||||
|
@ -53,7 +54,7 @@ struct __attribute__((__packed__)) dirent
|
||||||
unsigned int __pad4__; /* don't use */
|
unsigned int __pad4__; /* don't use */
|
||||||
unsigned long d_filesize;
|
unsigned long d_filesize;
|
||||||
unsigned short d_namlen;
|
unsigned short d_namlen;
|
||||||
char* d_name;
|
char d_name[];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define _DIRENT_HAVE_D_RECLEN
|
#define _DIRENT_HAVE_D_RECLEN
|
||||||
|
@ -64,6 +65,16 @@ struct __attribute__((__packed__)) dirent
|
||||||
#define _DIRENT_HAVE_D_NAMLEN
|
#define _DIRENT_HAVE_D_NAMLEN
|
||||||
#undef _DIRENT_HAVE_D_OFF
|
#undef _DIRENT_HAVE_D_OFF
|
||||||
|
|
||||||
|
#define DT_UNKNOWN 0
|
||||||
|
#define DT_FIFO 1
|
||||||
|
#define DT_CHR 2
|
||||||
|
#define DT_DIR 4
|
||||||
|
#define DT_BLK 6
|
||||||
|
#define DT_REG 8
|
||||||
|
#define DT_LNK 10
|
||||||
|
#define DT_SOCK 12
|
||||||
|
#define DT_WHT 14
|
||||||
|
|
||||||
#endif /* _LIBPOSIX_DIRENT */
|
#endif /* _LIBPOSIX_DIRENT */
|
||||||
|
|
||||||
#ifndef _LIBPOSIX_H
|
#ifndef _LIBPOSIX_H
|
||||||
|
@ -110,7 +121,7 @@ extern void POSIX_free(void *ptr);
|
||||||
extern unsigned int POSIX_sleep(unsigned int seconds);
|
extern unsigned int POSIX_sleep(unsigned int seconds);
|
||||||
extern int POSIX_pipe(int *errnop, int fildes[2]);
|
extern int POSIX_pipe(int *errnop, int fildes[2]);
|
||||||
|
|
||||||
extern int libposix_getdents(int *errnop, int fd, struct dirent *buf, int buf_bytes);
|
extern int libposix_getdents(int *errnop, int fd, char *buf, int buf_bytes);
|
||||||
|
|
||||||
/* Library initialization
|
/* Library initialization
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
#include <lib9.h>
|
#include <lib9.h>
|
||||||
|
#include <9P2000.h>
|
||||||
#include <posix.h>
|
#include <posix.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
@ -360,7 +361,84 @@ POSIX_stat(int *errnop, const char *file, void *pstat)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
libposix_getdents(int *errnop, int fd, struct dirent *buf, int buf_bytes)
|
libposix_getdents(int *errnop, int fd, char *buf, int buf_bytes)
|
||||||
{
|
{
|
||||||
return 0;
|
#define MINSTATLEN (STATFIXLEN + 4) /* 4 = min (1 char) name, uid, gid, muid */
|
||||||
|
|
||||||
|
int r;
|
||||||
|
Dir *d;
|
||||||
|
struct dirent *dp;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if(fd < 0)
|
||||||
|
goto FailWithEBADF;
|
||||||
|
if(buf == nil)
|
||||||
|
goto FailWithEFAULT;
|
||||||
|
if(buf_bytes < MINSTATLEN)
|
||||||
|
goto FailWithEINVAL;
|
||||||
|
|
||||||
|
d = dirfstat(fd);
|
||||||
|
if(d == nil)
|
||||||
|
goto FailWithENOENT; /* removed? */
|
||||||
|
r = d->mode & DMDIR;
|
||||||
|
free(d);
|
||||||
|
|
||||||
|
if(r == 0)
|
||||||
|
goto FailWithENOTDIR; /* not a directory */
|
||||||
|
|
||||||
|
r = read(fd, buf, buf_bytes);
|
||||||
|
if(r < 0)
|
||||||
|
goto FailWithENOENT; /* removed? */
|
||||||
|
if(r < MINSTATLEN)
|
||||||
|
goto FailWithEIO;
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
while(p - buf < r){
|
||||||
|
/* here we adjust 9P2000 stat info to match
|
||||||
|
* dirent specification
|
||||||
|
*/
|
||||||
|
dp = (struct dirent *)p;
|
||||||
|
|
||||||
|
/* the count field in stat structure exclude itself */
|
||||||
|
dp->d_reclen += BIT16SZ;
|
||||||
|
|
||||||
|
/* 9P2000 strings are not NUL-terminated */
|
||||||
|
dp->d_name[dp->d_namlen] = '\0';
|
||||||
|
|
||||||
|
/* we have to map types to UNIX */
|
||||||
|
if(dp->d_type & (DMDIR >> 24))
|
||||||
|
dp->d_type = DT_DIR;
|
||||||
|
else if(dp->__pad1__ == '|') /* kernel device == devpipe */
|
||||||
|
dp->d_type = DT_FIFO;
|
||||||
|
else
|
||||||
|
dp->d_type = DT_REG; /* UNIX lack fantasy :-) */
|
||||||
|
|
||||||
|
p += dp->d_reclen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
|
||||||
|
FailWithEBADF:
|
||||||
|
*errnop = __libposix_get_errno(PosixEBADF);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FailWithEFAULT:
|
||||||
|
*errnop = __libposix_get_errno(PosixEFAULT);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FailWithEINVAL:
|
||||||
|
*errnop = __libposix_get_errno(PosixEINVAL);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FailWithENOENT:
|
||||||
|
*errnop = __libposix_get_errno(PosixENOENT);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FailWithENOTDIR:
|
||||||
|
*errnop = __libposix_get_errno(PosixENOTDIR);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FailWithEIO:
|
||||||
|
*errnop = __libposix_get_errno(PosixEIO);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue