0
0
mirror of https://github.com/python/cpython.git synced 2024-12-01 03:01:36 +01:00
cpython/Mac/fopenRF.c

337 lines
5.9 KiB
C
Raw Normal View History

1994-05-06 16:16:55 +02:00
/*
1995-01-02 20:13:30 +01:00
* fopen.c
1994-05-06 16:16:55 +02:00
*
1995-01-02 20:13:30 +01:00
* Copyright (c) 1991 Symantec Corporation. All rights reserved.
1994-05-06 16:16:55 +02:00
*
*/
1995-01-02 20:13:30 +01:00
#include <MacHeaders>
1994-05-06 16:16:55 +02:00
#include "stdio.h"
#include "errno.h"
#include "string.h"
#include "ansi_private.h"
1995-01-02 20:13:30 +01:00
extern long _ftype, _fcreator;
1994-05-06 16:16:55 +02:00
#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);
1995-01-02 20:13:30 +01:00
FILE *freopenRF();
FILE *__openRF();
1994-05-06 16:16:55 +02:00
FILE *
1995-01-02 20:13:30 +01:00
fopenRF(const char *filename, const char *mode)
1994-05-06 16:16:55 +02:00
{
return(freopenRF(filename, mode, __getfile()));
}
FILE *
1995-01-02 20:13:30 +01:00
freopenRF(const char *filename, const char *mode, FILE *fp)
1994-05-06 16:16:55 +02:00
{
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 *
1995-01-02 20:13:30 +01:00
__openRF(const char *filename, int omode, int oflag, FILE *fp)
1994-05-06 16:16:55 +02:00
{
1995-01-02 20:13:30 +01:00
IOParam pb;
1994-05-06 16:16:55 +02:00
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) {
1995-01-02 20:13:30 +01:00
PBCreateSync((ParmBlkPtr)&pb);
1994-05-06 16:16:55 +02:00
if (pb.ioResult == noErr)
oflag &= ~F_TRUNC;
else if (pb.ioResult == dupFNErr && !(oflag & F_EXCL))
oflag &= ~F_CREAT;
else {
errno = pb.ioResult;
return(NULL);
}
}
1995-01-02 20:13:30 +01:00
/* open file */
1994-05-06 16:16:55 +02:00
1995-01-02 20:13:30 +01:00
PBOpenRFSync((ParmBlkPtr)&pb);
1994-05-06 16:16:55 +02:00
if (pb.ioResult) {
errno = pb.ioResult;
1995-01-02 20:13:30 +01:00
if (oflag & F_CREAT)
PBDeleteSync((ParmBlkPtr)&pb);
1994-05-06 16:16:55 +02:00
return(NULL);
}
fp->refnum = pb.ioRefNum;
/* get/set file length */
1995-01-02 20:13:30 +01:00
if (oflag & F_TRUNC)
PBSetEOFSync((ParmBlkPtr)&pb);
else if (!(oflag & F_CREAT))
PBGetEOFSync((ParmBlkPtr)&pb);
1994-05-06 16:16:55 +02:00
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
1995-01-02 20:13:30 +01:00
setfiletype(StringPtr name, int oflag)
1994-05-06 16:16:55 +02:00
{
1995-01-02 20:13:30 +01:00
FileParam pb;
1994-05-06 16:16:55 +02:00
pb.ioNamePtr = name;
pb.ioVRefNum = 0;
pb.ioFVersNum = 0;
pb.ioFDirIndex = 0;
1995-01-02 20:13:30 +01:00
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);
1994-05-06 16:16:55 +02:00
}
}
/*
* stdio_exit - stdio shutdown routine
*
*/
static void
1995-01-02 20:13:30 +01:00
stdio_exit(void)
1994-05-06 16:16:55 +02:00
{
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
1995-01-02 20:13:30 +01:00
fileio(FILE *fp, int i)
1994-05-06 16:16:55 +02:00
{
1995-01-02 20:13:30 +01:00
IOParam pb;
1994-05-06 16:16:55 +02:00
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;
1995-01-02 20:13:30 +01:00
PBReadSync((ParmBlkPtr)&pb);
1994-05-06 16:16:55 +02:00
if (pb.ioResult == eofErr) {
fp->pos = pb.ioPosOffset;
if (fp->cnt = pb.ioActCount)
pb.ioResult = 0;
else {
fp->eof = 1;
return(EOF);
}
}
1995-01-02 20:13:30 +01:00
if (!pb.ioResult && !fp->binary)
1994-05-06 16:16:55 +02:00
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;
1995-01-02 20:13:30 +01:00
if (PBSetEOFSync((ParmBlkPtr)&pb) != noErr)
break;
1994-05-06 16:16:55 +02:00
}
if (!fp->binary)
replace(fp->ptr, fp->cnt, '\n', '\r');
1995-01-02 20:13:30 +01:00
PBWriteSync((ParmBlkPtr)&pb);
if (!pb.ioResult && pb.ioPosOffset > fp->len)
1994-05-06 16:16:55 +02:00
fp->len = pb.ioPosOffset;
break;
/* close */
case 2:
pb.ioResult = close(fp);
break;
}
/* done */
if (pb.ioResult) {
1995-01-02 20:13:30 +01:00
if (i < 2) {
fp->pos -= fp->cnt;
fp->cnt = 0;
}
1994-05-06 16:16:55 +02:00
fp->err = 1;
errno = pb.ioResult;
return(EOF);
}
return(0);
}
static int
1995-01-02 20:13:30 +01:00
close(FILE *fp)
1994-05-06 16:16:55 +02:00
{
HFileParam pb;
Str255 buf;
register char *fcb = FCBSPtr + fp->refnum;
VCB *vcb = fcbVPtr(fcb);
register char *s;
1995-01-02 20:13:30 +01:00
enum { none, MFS, HFS } del = none;
1994-05-06 16:16:55 +02:00
pb.ioVRefNum = vcb->vcbVRefNum;
1995-01-02 20:13:30 +01:00
if (fp->remove) {
pb.ioNamePtr = buf;
pb.ioFVersNum = 0;
1994-05-06 16:16:55 +02:00
1995-01-02 20:13:30 +01:00
/* close temporary file - HFS */
if (vcb->vcbSigWord == 0x4244) {
pb.ioDirID = fcbDirID(fcb);
s = fcbCName(fcb);
memcpy(buf, s, Length(s) + 1);
del = HFS;
1994-05-06 16:16:55 +02:00
}
1995-01-02 20:13:30 +01:00
/* 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;
}
}
1994-05-06 16:16:55 +02:00
}
}
1995-01-02 20:13:30 +01:00
/* close file and flush volume buffer */
1994-05-06 16:16:55 +02:00
1995-01-02 20:13:30 +01:00
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);
}
1994-05-06 16:16:55 +02:00
return(pb.ioResult);
}
/*
* replace - routine for doing CR/LF conversion
*
*/
static void
1995-01-02 20:13:30 +01:00
replace(register unsigned char *s, register size_t n, register int c1, register int c2)
1994-05-06 16:16:55 +02:00
{
1995-01-02 20:13:30 +01:00
#pragma options(honor_register)
1994-05-06 16:16:55 +02:00
register unsigned char *t;
for (; n && (t = memchr(s, c1, n)); s = t) {
*t++ = c2;
n -= t - s;
}
}