summaryrefslogtreecommitdiffstats
path: root/Mac/think
diff options
context:
space:
mode:
authorJack Jansen <jack.jansen@cwi.nl>1995-08-07 14:00:08 (GMT)
committerJack Jansen <jack.jansen@cwi.nl>1995-08-07 14:00:08 (GMT)
commitfc596038a5f1548538b0fc43dae8c721f739c44d (patch)
treebdd166b0450c73e0e0ba7b0e36025349fa8007f2 /Mac/think
parent63bf5982172cb6a68c5f5ab9d0382b6c99819125 (diff)
downloadcpython-fc596038a5f1548538b0fc43dae8c721f739c44d.zip
cpython-fc596038a5f1548538b0fc43dae8c721f739c44d.tar.gz
cpython-fc596038a5f1548538b0fc43dae8c721f739c44d.tar.bz2
Moved here because it is think-specific
Diffstat (limited to 'Mac/think')
-rw-r--r--Mac/think/fopenRF.c336
1 files changed, 336 insertions, 0 deletions
diff --git a/Mac/think/fopenRF.c b/Mac/think/fopenRF.c
new file mode 100644
index 0000000..04f192e
--- /dev/null
+++ b/Mac/think/fopenRF.c
@@ -0,0 +1,336 @@
+
+/*
+ * fopen.c
+ *
+ * Copyright (c) 1991 Symantec Corporation. All rights reserved.
+ *
+ */
+
+#include <MacHeaders>
+
+#include "stdio.h"
+#include "errno.h"
+#include "string.h"
+#include "ansi_private.h"
+
+extern long _ftype, _fcreator;
+
+#define fcbVPtr(fcb) (* (VCB **) (fcb + 20))
+#define fcbDirID(fcb) (* (long *) (fcb + 58))
+#define fcbCName(fcb) (fcb + 62)
+
+static void setfiletype(StringPtr, int);
+static void stdio_exit(void);
+static int fileio(FILE *, int);
+static int close(FILE *);
+static void replace(unsigned char *, size_t, int, int);
+
+FILE *freopenRF();
+FILE *__openRF();
+
+FILE *
+fopenRF(const char *filename, const char *mode)
+{
+ return(freopenRF(filename, mode, __getfile()));
+}
+
+
+FILE *
+freopenRF(const char *filename, const char *mode, FILE *fp)
+{
+ int omode, oflag;
+
+ /* interpret "rwa" */
+
+ if (mode[0] == 'r') {
+ omode = fsRdPerm;
+ oflag = 0;
+ }
+ else if (mode[0] == 'w') {
+ omode = fsWrPerm;
+ oflag = F_CREAT+F_TRUNC;
+ }
+ else if (mode[0] == 'a') {
+ omode = fsWrPerm;
+ oflag = F_CREAT+F_APPEND;
+ }
+ else {
+ errno = EINVAL;
+ return(NULL);
+ }
+
+ /* interpret "b+" */
+
+ if (mode[1] == 'b') {
+ oflag |= F_BINARY;
+ if (mode[2] == '+')
+ omode = fsRdWrPerm;
+ }
+ else if (mode[1] == '+') {
+ omode = fsRdWrPerm;
+ if (mode[2] == 'b')
+ oflag |= F_BINARY;
+ }
+
+ /* open the file */
+
+ return(__openRF(filename, omode, oflag, fp));
+}
+
+
+FILE *
+__openRF(const char *filename, int omode, int oflag, FILE *fp)
+{
+ IOParam pb;
+ char pname[FILENAME_MAX];
+
+ if (fp == NULL)
+ return(NULL);
+ fclose(fp);
+
+ /* set up pb */
+
+ pb.ioNamePtr = __c2p(filename, pname);
+ pb.ioVRefNum = 0;
+ pb.ioVersNum = 0;
+ pb.ioPermssn = omode;
+ pb.ioMisc = 0;
+
+ /* create file */
+
+ if (oflag & F_CREAT) {
+ PBCreateSync((ParmBlkPtr)&pb);
+ if (pb.ioResult == noErr)
+ oflag &= ~F_TRUNC;
+ else if (pb.ioResult == dupFNErr && !(oflag & F_EXCL))
+ oflag &= ~F_CREAT;
+ else {
+ errno = pb.ioResult;
+ return(NULL);
+ }
+ }
+
+ /* open file */
+
+ PBOpenRFSync((ParmBlkPtr)&pb);
+ if (pb.ioResult) {
+ errno = pb.ioResult;
+ if (oflag & F_CREAT)
+ PBDeleteSync((ParmBlkPtr)&pb);
+ return(NULL);
+ }
+ fp->refnum = pb.ioRefNum;
+
+ /* get/set file length */
+
+ if (oflag & F_TRUNC)
+ PBSetEOFSync((ParmBlkPtr)&pb);
+ else if (!(oflag & F_CREAT))
+ PBGetEOFSync((ParmBlkPtr)&pb);
+ fp->len = (fpos_t) pb.ioMisc;
+
+ /* initialize rest of FILE structure */
+
+ if (oflag & F_APPEND) {
+ fp->append = 1;
+ fp->pos = fp->len;
+ }
+ if (oflag & F_BINARY)
+ fp->binary = 1;
+ setvbuf(fp, NULL, _IOFBF, BUFSIZ);
+ fp->proc = fileio;
+
+ /* set file type */
+
+ if (oflag & (F_CREAT|F_TRUNC))
+ setfiletype(pb.ioNamePtr, oflag);
+
+ /* done */
+
+ __atexit_stdio(stdio_exit);
+ return(fp);
+}
+
+
+/*
+ * setfiletype - set type/creator of new file
+ *
+ */
+
+static void
+setfiletype(StringPtr name, int oflag)
+{
+ FileParam pb;
+
+ pb.ioNamePtr = name;
+ pb.ioVRefNum = 0;
+ pb.ioFVersNum = 0;
+ pb.ioFDirIndex = 0;
+ if (PBGetFInfoSync((ParmBlkPtr)&pb) == noErr) {
+ if (oflag & F_BINARY)
+ pb.ioFlFndrInfo.fdType = _ftype;
+ else
+ pb.ioFlFndrInfo.fdType = 'TEXT';
+ pb.ioFlFndrInfo.fdCreator = _fcreator;
+ PBSetFInfoSync((ParmBlkPtr)&pb);
+ }
+}
+
+
+/*
+ * stdio_exit - stdio shutdown routine
+ *
+ */
+
+static void
+stdio_exit(void)
+{
+ register FILE *fp;
+ int n;
+
+ for (fp = &__file[0], n = FOPEN_MAX; n--; fp++)
+ fclose(fp);
+}
+
+
+/*
+ * fileio - I/O handler proc for files and devices
+ *
+ */
+
+static int
+fileio(FILE *fp, int i)
+{
+ IOParam pb;
+
+ pb.ioRefNum = fp->refnum;
+ switch (i) {
+
+ /* read */
+
+ case 0:
+ pb.ioBuffer = (Ptr) fp->ptr;
+ pb.ioReqCount = fp->cnt;
+ pb.ioPosMode = fp->refnum > 0 ? fsFromStart : fsAtMark;
+ pb.ioPosOffset = fp->pos - fp->cnt;
+ PBReadSync((ParmBlkPtr)&pb);
+ if (pb.ioResult == eofErr) {
+ fp->pos = pb.ioPosOffset;
+ if (fp->cnt = pb.ioActCount)
+ pb.ioResult = 0;
+ else {
+ fp->eof = 1;
+ return(EOF);
+ }
+ }
+ if (!pb.ioResult && !fp->binary)
+ replace(fp->ptr, fp->cnt, '\r', '\n');
+ break;
+
+ /* write */
+
+ case 1:
+ pb.ioBuffer = (Ptr) fp->ptr;
+ pb.ioReqCount = fp->cnt;
+ pb.ioPosMode = fp->refnum > 0 ? fsFromStart : fsAtMark;
+ if ((pb.ioPosOffset = fp->pos - fp->cnt) > fp->len) {
+ pb.ioMisc = (Ptr) pb.ioPosOffset;
+ if (PBSetEOFSync((ParmBlkPtr)&pb) != noErr)
+ break;
+ }
+ if (!fp->binary)
+ replace(fp->ptr, fp->cnt, '\n', '\r');
+ PBWriteSync((ParmBlkPtr)&pb);
+ if (!pb.ioResult && pb.ioPosOffset > fp->len)
+ fp->len = pb.ioPosOffset;
+ break;
+
+ /* close */
+
+ case 2:
+ pb.ioResult = close(fp);
+ break;
+ }
+
+ /* done */
+
+ if (pb.ioResult) {
+ if (i < 2) {
+ fp->pos -= fp->cnt;
+ fp->cnt = 0;
+ }
+ fp->err = 1;
+ errno = pb.ioResult;
+ return(EOF);
+ }
+ return(0);
+}
+
+
+static int
+close(FILE *fp)
+{
+ HFileParam pb;
+ Str255 buf;
+ register char *fcb = FCBSPtr + fp->refnum;
+ VCB *vcb = fcbVPtr(fcb);
+ register char *s;
+ enum { none, MFS, HFS } del = none;
+
+ pb.ioVRefNum = vcb->vcbVRefNum;
+ if (fp->remove) {
+ pb.ioNamePtr = buf;
+ pb.ioFVersNum = 0;
+
+ /* close temporary file - HFS */
+
+ if (vcb->vcbSigWord == 0x4244) {
+ pb.ioDirID = fcbDirID(fcb);
+ s = fcbCName(fcb);
+ memcpy(buf, s, Length(s) + 1);
+ del = HFS;
+ }
+
+ /* close temporary file - MFS */
+
+ else if (vcb->vcbSigWord == 0xD2D7) {
+ for (pb.ioFDirIndex = 1; PBGetFInfoSync((ParmBlkPtr)&pb) == noErr; pb.ioFDirIndex++) {
+ if (pb.ioFRefNum == fp->refnum) {
+ del = MFS;
+ break;
+ }
+ }
+ }
+ }
+
+ /* close file and flush volume buffer */
+
+ pb.ioFRefNum = fp->refnum;
+ if (PBCloseSync((ParmBlkPtr)&pb) == noErr) {
+ if (del == MFS)
+ PBDeleteSync((ParmBlkPtr)&pb);
+ else if (del == HFS)
+ PBHDeleteSync((HParmBlkPtr)&pb);
+ pb.ioNamePtr = 0;
+ PBFlushVolSync((ParmBlkPtr)&pb);
+ }
+ return(pb.ioResult);
+}
+
+
+/*
+ * replace - routine for doing CR/LF conversion
+ *
+ */
+
+static void
+replace(register unsigned char *s, register size_t n, register int c1, register int c2)
+{
+#pragma options(honor_register)
+ register unsigned char *t;
+
+ for (; n && (t = memchr(s, c1, n)); s = t) {
+ *t++ = c2;
+ n -= t - s;
+ }
+}