V10/libc/gen/pdirread.c
/* simulate new system call */
/* output is up to cnt bytes (up to some max)
* each directory entry gets a string which is
* the ascii representation of the inode number, a tab, and the
* zero-terminated file name. these zero-terminated strings are packed together
* This implementation freely returns short reads. End of directory
* is a 0 length read, -1 and ENOSPC indicate that cnt couldn't hold
* even the next entry
*/
#include "sys/types.h"
#include "sys/dir.h"
#include "errno.h"
char mb[4096], ncnv[23];
pdirread(fd, buf, cnt)
char *buf;
{ int n, m, j, loc;
char *p, *lp;
struct direct *d;
loc = lseek(fd, 0, 1);
n = read(fd, mb, sizeof(mb));
if(n <= 0)
return(n);
lp = p = buf;
d = (struct direct *) mb;
loop:
if(d->d_ino == 0)
goto incr;
for(m = d->d_ino, j = 22; m; j--) {
ncnv[j] = m % 10 + '0';
m /= 10;
}
for(++j; j < 23 && p < buf + cnt; )
*p++ = ncnv[j++];
if(j != 23 || p >= buf + cnt)
goto early;
*p++ = '\t';
for(j = 0; d->d_name[j] && j < DIRSIZ && p < buf + cnt; j++)
*p++ = d->d_name[j];
if(p >= buf + cnt)
goto early;
*p++ = 0;
incr:
lp = p;
n -= sizeof(*d);
d++;
if(lp < buf + cnt && n > 0)
goto loop;
done:
lseek(fd, loc + (char *)d - mb, 0);
return(lp - buf);
early:
*lp = 0;
if((char *)d != mb)
goto done;
errno = ENOSPC;
return(-1);
}