opendir.c 2.37 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * 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;
{
23
#if TARGET_API_MAC_CARBON
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
	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
48 49 50 51 52 53 54 55 56 57 58 59 60 61
	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;
62 63 64
	pb.d.ioWDProcID= 0;
	pb.d.ioWDDirID= 0;
	err= PBOpenWD((WDPBPtr)&pb, 0);
65 66 67 68 69 70 71
	if (err != noErr) {
		errno = ENOENT;
		return NULL;
	}
	opened.dirid= pb.d.ioVRefNum;
	opened.nextfile= 1;
	return &opened;
72
#endif
73 74 75 76 77 78 79 80 81 82
}

/*
 * Close a directory.
 */

void
closedir(dirp)
	DIR *dirp;
{
83
#if TARGET_API_MAC_CARBON
84 85 86 87 88 89
	dirp->nextfile = 0;
#else
	WDPBRec pb;
	
	pb.ioVRefNum= dirp->dirid;
	(void) PBCloseWD(&pb, 0);
90 91
	dirp->dirid= 0;
	dirp->nextfile= 0;
92
#endif
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
}

/*
 * 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;
113
#if TARGET_API_MAC_CARBON
114 115 116
	pb.d.ioVRefNum= dp->vrefnum;
	pb.d.ioDrDirID= dp->dirid;
#else
117 118
	pb.d.ioVRefNum= dp->dirid;
	pb.d.ioDrDirID= 0;
119 120 121
#endif
	pb.d.ioFDirIndex= dp->nextfile++;
	err= PBGetCatInfo((CInfoPBPtr)&pb, 0);
122 123 124 125
	if (err != noErr) {
		errno = EIO;
		return NULL;
	}
126
#if TARGET_API_MAC_CARBON
127 128
	p2cstrcpy(dir.d_name, (StringPtr)dir.d_name);
#else
129
	(void) p2cstr((unsigned char *)dir.d_name);
130
#endif
131 132
	return &dir;
}