133 lines
2.4 KiB
C
133 lines
2.4 KiB
C
/*
|
|
* Macintosh version of UNIX directory access package
|
|
* (opendir, readdir, closedir).
|
|
* Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
|
|
*/
|
|
|
|
#include "dirent.h"
|
|
#include "macdefs.h"
|
|
|
|
static DIR opened;
|
|
|
|
/*
|
|
* Open a directory. This means calling PBOpenWD.
|
|
* The value returned is always the address of opened, or NULL.
|
|
* (I have as yet no use for multiple open directories; this could
|
|
* be implemented by allocating memory dynamically.)
|
|
*/
|
|
|
|
DIR *
|
|
opendir(path)
|
|
char *path;
|
|
{
|
|
#ifdef TARGET_API_MAC_CARBON
|
|
Str255 ppath;
|
|
FSSpec fss;
|
|
int plen;
|
|
OSErr err;
|
|
|
|
if (opened.nextfile != 0) {
|
|
errno = EBUSY;
|
|
return NULL; /* A directory is already open. */
|
|
}
|
|
plen = strlen(path);
|
|
c2pstrcpy(ppath, path);
|
|
if ( ppath[plen] != ':' )
|
|
ppath[++plen] = ':';
|
|
ppath[++plen] = 'x';
|
|
ppath[0] = plen;
|
|
if( (err = FSMakeFSSpec(0, 0, ppath, &fss)) < 0 && err != fnfErr ) {
|
|
errno = EIO;
|
|
return NULL;
|
|
}
|
|
opened.dirid = fss.parID;
|
|
opened.vrefnum = fss.vRefNum;
|
|
opened.nextfile = 1;
|
|
return &opened;
|
|
#else
|
|
union {
|
|
WDPBRec d;
|
|
VolumeParam v;
|
|
} pb;
|
|
char ppath[MAXPATH];
|
|
short err;
|
|
|
|
if (opened.nextfile != 0) {
|
|
errno = EBUSY;
|
|
return NULL; /* A directory is already open. */
|
|
}
|
|
strncpy(ppath+1, path, ppath[0]= strlen(path));
|
|
pb.d.ioNamePtr= (unsigned char *)ppath;
|
|
pb.d.ioVRefNum= 0;
|
|
pb.d.ioWDProcID= 0;
|
|
pb.d.ioWDDirID= 0;
|
|
err= PBOpenWD((WDPBPtr)&pb, 0);
|
|
if (err != noErr) {
|
|
errno = ENOENT;
|
|
return NULL;
|
|
}
|
|
opened.dirid= pb.d.ioVRefNum;
|
|
opened.nextfile= 1;
|
|
return &opened;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Close a directory.
|
|
*/
|
|
|
|
void
|
|
closedir(dirp)
|
|
DIR *dirp;
|
|
{
|
|
#ifdef TARGET_API_MAC_CARBON
|
|
dirp->nextfile = 0;
|
|
#else
|
|
WDPBRec pb;
|
|
|
|
pb.ioVRefNum= dirp->dirid;
|
|
(void) PBCloseWD(&pb, 0);
|
|
dirp->dirid= 0;
|
|
dirp->nextfile= 0;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Read the next directory entry.
|
|
*/
|
|
|
|
struct dirent *
|
|
readdir(dp)
|
|
DIR *dp;
|
|
{
|
|
union {
|
|
DirInfo d;
|
|
FileParam f;
|
|
HFileInfo hf;
|
|
} pb;
|
|
short err;
|
|
static struct dirent dir;
|
|
|
|
dir.d_name[0]= 0;
|
|
pb.d.ioNamePtr= (unsigned char *)dir.d_name;
|
|
#ifdef TARGET_API_MAC_CARBON
|
|
pb.d.ioVRefNum= dp->vrefnum;
|
|
pb.d.ioDrDirID= dp->dirid;
|
|
#else
|
|
pb.d.ioVRefNum= dp->dirid;
|
|
pb.d.ioDrDirID= 0;
|
|
#endif
|
|
pb.d.ioFDirIndex= dp->nextfile++;
|
|
err= PBGetCatInfo((CInfoPBPtr)&pb, 0);
|
|
if (err != noErr) {
|
|
errno = EIO;
|
|
return NULL;
|
|
}
|
|
#ifdef TARGET_API_MAC_CARBON
|
|
p2cstrcpy(dir.d_name, (StringPtr)dir.d_name);
|
|
#else
|
|
(void) p2cstr((unsigned char *)dir.d_name);
|
|
#endif
|
|
return &dir;
|
|
}
|