summaryrefslogtreecommitdiffstats
path: root/Mac/Compat
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1994-08-19 10:51:31 (GMT)
committerGuido van Rossum <guido@python.org>1994-08-19 10:51:31 (GMT)
commitd4d77284408316a68cdc2ab9e8e1d4a06e534938 (patch)
treef25369ac9cc34663abcfd3be4b08035d8fe72c62 /Mac/Compat
parente89bc75048d0142859379b2b92e77d984fdbef6e (diff)
downloadcpython-d4d77284408316a68cdc2ab9e8e1d4a06e534938.zip
cpython-d4d77284408316a68cdc2ab9e8e1d4a06e534938.tar.gz
cpython-d4d77284408316a68cdc2ab9e8e1d4a06e534938.tar.bz2
Updates for THINK C 6.0. Moved the necessary UNIX emulation routines here.
Diffstat (limited to 'Mac/Compat')
-rw-r--r--Mac/Compat/chdir.c26
-rw-r--r--Mac/Compat/dirent.h22
-rw-r--r--Mac/Compat/getbootvol.c18
-rw-r--r--Mac/Compat/getwd.c109
-rw-r--r--Mac/Compat/mkdir.c30
-rw-r--r--Mac/Compat/opendir.c104
-rw-r--r--Mac/Compat/rmdir.c22
-rw-r--r--Mac/Compat/sync.c17
8 files changed, 348 insertions, 0 deletions
diff --git a/Mac/Compat/chdir.c b/Mac/Compat/chdir.c
new file mode 100644
index 0000000..b8ec6d7
--- /dev/null
+++ b/Mac/Compat/chdir.c
@@ -0,0 +1,26 @@
+/* Chdir for the Macintosh.
+ Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
+ Pathnames must be Macintosh paths, with colons as separators. */
+
+#include "macdefs.h"
+
+/* Change current directory. */
+
+int
+chdir(path)
+ char *path;
+{
+ WDPBRec pb;
+ char name[MAXPATH];
+
+ strncpy(name, path, sizeof name);
+ name[MAXPATH-1]= EOS;
+ pb.ioNamePtr= (StringPtr) c2pstr(name);
+ pb.ioVRefNum= 0;
+ pb.ioWDDirID= 0;
+ if (PBHSetVol(&pb, FALSE) != noErr) {
+ errno= ENOENT;
+ return -1;
+ }
+ return 0;
+}
diff --git a/Mac/Compat/dirent.h b/Mac/Compat/dirent.h
new file mode 100644
index 0000000..44cfc5a
--- /dev/null
+++ b/Mac/Compat/dirent.h
@@ -0,0 +1,22 @@
+/*
+ * "Dir.h" for the Macintosh.
+ * Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
+ */
+
+#define MAXNAMLEN 31
+#define MAXPATH 256
+
+#define DIR struct _dir
+
+struct _dir {
+ long dirid;
+ int nextfile;
+};
+
+struct dirent {
+ char d_name[MAXPATH];
+};
+
+extern DIR *opendir(char *);
+extern struct dirent *readdir(DIR *);
+extern void closedir(DIR *);
diff --git a/Mac/Compat/getbootvol.c b/Mac/Compat/getbootvol.c
new file mode 100644
index 0000000..8f5d28c
--- /dev/null
+++ b/Mac/Compat/getbootvol.c
@@ -0,0 +1,18 @@
+/* Return the name of the boot volume (not the current directory).
+ Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
+*/
+
+#include "macdefs.h"
+
+char *
+getbootvol()
+{
+ short vrefnum;
+ static unsigned char name[32];
+
+ (void) GetVol(name, &vrefnum);
+ p2cstr(name);
+ /* Shouldn't fail; return ":" if it does */
+ strcat((char *)name, ":");
+ return (char *)name;
+}
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;
+}
diff --git a/Mac/Compat/mkdir.c b/Mac/Compat/mkdir.c
new file mode 100644
index 0000000..b064761
--- /dev/null
+++ b/Mac/Compat/mkdir.c
@@ -0,0 +1,30 @@
+/* Mkdir for the Macintosh.
+ Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
+ Pathnames must be Macintosh paths, with colons as separators. */
+
+#include "macdefs.h"
+
+/* Create a directory. */
+
+int
+mkdir(path, mode)
+ char *path;
+ int mode; /* Ignored */
+{
+ HFileParam pb;
+ char name[MAXPATH];
+
+ if (!hfsrunning()) {
+ errno= ENODEV;
+ return -1;
+ }
+ strncpy(name, path, sizeof name);
+ pb.ioNamePtr= (StringPtr) c2pstr(name);
+ pb.ioVRefNum= 0;
+ pb.ioDirID= 0;
+ if (PBDirCreate((HParmBlkPtr)&pb, FALSE) != noErr) {
+ errno= EACCES;
+ return -1;
+ }
+ return 0;
+}
diff --git a/Mac/Compat/opendir.c b/Mac/Compat/opendir.c
new file mode 100644
index 0000000..74b8984
--- /dev/null
+++ b/Mac/Compat/opendir.c
@@ -0,0 +1,104 @@
+/*
+ * 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;
+{
+ 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;
+ if (hfsrunning()) {
+ pb.d.ioWDProcID= 0;
+ pb.d.ioWDDirID= 0;
+ err= PBOpenWD((WDPBPtr)&pb, FALSE);
+ }
+ else {
+ pb.v.ioVolIndex= 0;
+ err= PBGetVInfo((ParmBlkPtr)&pb, FALSE);
+ }
+ if (err != noErr) {
+ errno = ENOENT;
+ return NULL;
+ }
+ opened.dirid= pb.d.ioVRefNum;
+ opened.nextfile= 1;
+ return &opened;
+}
+
+/*
+ * Close a directory.
+ */
+
+void
+closedir(dirp)
+ DIR *dirp;
+{
+ if (hfsrunning()) {
+ WDPBRec pb;
+
+ pb.ioVRefNum= dirp->dirid;
+ (void) PBCloseWD(&pb, FALSE);
+ }
+ dirp->dirid= 0;
+ dirp->nextfile= 0;
+}
+
+/*
+ * 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;
+ pb.d.ioVRefNum= dp->dirid;
+ pb.d.ioFDirIndex= dp->nextfile++;
+ pb.d.ioDrDirID= 0;
+ if (hfsrunning())
+ err= PBGetCatInfo((CInfoPBPtr)&pb, FALSE);
+ else
+ err= PBGetFInfo((ParmBlkPtr)&pb, FALSE);
+ if (err != noErr) {
+ errno = EIO;
+ return NULL;
+ }
+ (void) p2cstr((unsigned char *)dir.d_name);
+ return &dir;
+}
diff --git a/Mac/Compat/rmdir.c b/Mac/Compat/rmdir.c
new file mode 100644
index 0000000..f31052f
--- /dev/null
+++ b/Mac/Compat/rmdir.c
@@ -0,0 +1,22 @@
+/* Rmdir for the Macintosh.
+ Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
+ Pathnames must be Macintosh paths, with colons as separators. */
+
+#include "macdefs.h"
+
+int
+rmdir(path)
+ char *path;
+{
+ IOParam pb;
+ char name[MAXPATH];
+
+ strncpy(name, path, sizeof name);
+ pb.ioNamePtr= (StringPtr) c2pstr(name);
+ pb.ioVRefNum= 0;
+ if (PBDelete((ParmBlkPtr)&pb, FALSE) != noErr) {
+ errno= EACCES;
+ return -1;
+ }
+ return 0;
+}
diff --git a/Mac/Compat/sync.c b/Mac/Compat/sync.c
new file mode 100644
index 0000000..a6487e1
--- /dev/null
+++ b/Mac/Compat/sync.c
@@ -0,0 +1,17 @@
+/* The equivalent of the Unix 'sync' system call: FlushVol.
+ Public domain by Guido van Rossum, CWI, Amsterdam (July 1987).
+ For now, we only flush the default volume
+ (since that's the only volume written to by MacB). */
+
+#include "macdefs.h"
+
+int
+sync()
+{
+ if (FlushVol((StringPtr)0, 0) == noErr)
+ return 0;
+ else {
+ errno= ENODEV;
+ return -1;
+ }
+}