summaryrefslogtreecommitdiffstats
path: root/Mac/Compat/getwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'Mac/Compat/getwd.c')
-rw-r--r--Mac/Compat/getwd.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/Mac/Compat/getwd.c b/Mac/Compat/getwd.c
new file mode 100644
index 0000000..3a093ed
--- /dev/null
+++ b/Mac/Compat/getwd.c
@@ -0,0 +1,109 @@
+/* Get full pathname of current working directory. The pathname is
+ copied to the parameter array 'cwd', and a pointer to this array
+ is also returned as function result. If an error occurred, however,
+ the return value is NULL but 'cwd' is filled with an error message.
+
+ BUG: expect spectacular crashes when called from a directory whose
+ path would be over MAXPATH bytes long (files in such directories are
+ not reachable by full pathname).
+
+ Starting with the dir ID returned by PBHGetVol, we do successive
+ PBGetCatInfo's to get a component of the path until we reach the
+ root (recognized by a dir ID of 2). We move up along the path
+ using the dir ID of the parent directory returned by PBGetCatInfo.
+
+ Then we catenate the components found in reverse order with the volume
+ name (already gotten from PBHGetVol), with intervening and trailing
+ colons
+
+ The code works correctly on MFS disks (where it always returns the
+ volume name) by simply skipping the PBGetCatinfo calls in that case.
+ There is a 'bug' in PBGetCatInfo when called for an MFS disk (with
+ HFS running): it then seems to call PBHGetVInfo, which returns a
+ larger parameter block. But we won't run into this problem because
+ we never call PBGetCatInfo for the root (assuming that PBHGetVol
+ still sets the root ID in this case).
+
+ Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
+*/
+
+#ifdef MPW
+#include <Strings.h>
+#endif
+#include "macdefs.h"
+
+#define ROOTID 2 /* Root directory ID */
+
+char *
+getwd(cwd)
+ char *cwd;
+{
+ /* Universal parameter block. */
+ union {
+#ifdef THINK_C
+ HFileInfo f;
+ DirInfo d;
+ WDPBRec w;
+#else /* MPW */
+ struct HFileInfo f;
+ struct DirInfo d;
+ struct WDPBRec w;
+#endif
+ } pb;
+ char buf[MAXPATH]; /* Buffer to store the name components */
+ char *ecwd, *ebuf; /* Pointers to end of used part of cwd and buf */
+ int err; /* Error code of last I/O call */
+
+ /* First, get the default volume name and working directory ID. */
+
+ pb.w.ioNamePtr= (unsigned char *)cwd;
+ err= PBHGetVol(&pb.w, FALSE);
+ if (err != noErr) {
+ sprintf(cwd, "I/O error %d in PBHGetVol", err);
+ return NULL;
+ }
+ ecwd= strchr(p2cstr((unsigned char*)cwd), EOS);
+ ebuf= buf;
+ *ebuf = EOS;
+
+ /* Next, if at least we're running HFS, walk up the path. */
+
+ if (hfsrunning()) {
+ long dirid= pb.w.ioWDDirID;
+ pb.d.ioVRefNum= pb.w.ioWDVRefNum;
+ while (dirid != ROOTID) {
+ pb.d.ioNamePtr= (unsigned char *) ++ebuf;
+ pb.d.ioFDirIndex= -1;
+ pb.d.ioDrDirID= dirid;
+ err= PBGetCatInfo((CInfoPBPtr)&pb.d, FALSE);
+ if (err != noErr) {
+ sprintf(cwd, "I/O error %d in PBGetCatInfo", err);
+ return NULL;
+ }
+ dirid= pb.d.ioDrParID;
+ ebuf += strlen(p2cstr((unsigned char *)ebuf));
+ /* Should check for buf overflow */
+ }
+ }
+
+ /* Finally, reverse the list of components and append it to cwd.
+ Ebuf points at the EOS after last component,
+ and there is an EOS before the first component.
+ If there are no components, ebuf equals buf (but there
+ is still an EOS where it points).
+ Ecwd points at the EOS after the path built up so far,
+ initially the volume name.
+ We break out of the loop in the middle, thus
+ appending a colon at the end in all cases. */
+
+ for (;;) {
+ *ecwd++ = ':';
+ if (ebuf == buf)
+ break;
+ do { } while (*--ebuf != EOS); /* Find component start */
+ strcpy(ecwd, ebuf+1);
+ ecwd= strchr(ecwd, EOS);
+ }
+ *ecwd= EOS;
+ return cwd;
+}