cpython/Mac/Compat/opendir.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;
}