home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
emacs-19.28-src.tgz
/
tar.out
/
fsf
/
emacs
/
unixlib
/
src
/
open.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
3KB
|
142 lines
#include "amiga.h"
#include "files.h"
#include "amigaos.h"
#include <utility/tagitem.h>
#include <stdarg.h>
#include <fcntl.h>
#include <string.h>
#undef open
int __open(const char *path, int flags, ...)
{
int fd, acc = flags & 3, rd, wr, exists = TRUE, amode;
struct FileInfoBlock *fib;
BPTR plock, fh;
long fdflags, protection;
APTR pwindow = _us->pr_WindowPtr;
ULONG create = MODE_READWRITE; /* Mode to use when creating files. */
chkabort();
rd = acc == O_RDONLY || acc == O_RDWR;
wr = acc == O_WRONLY || acc == O_RDWR;
if (stricmp(path, "NIL:") == 0) amode = -1;
else
{
_us->pr_WindowPtr = (APTR)-1;
plock = Lock(path, ACCESS_READ);
_us->pr_WindowPtr = pwindow;
if (!plock)
{
int err = convert_oserr(IoErr()), ok;
/* Devices like pipe: don't like Lock ... */
if (_OSERR == ERROR_ACTION_NOT_KNOWN ||
_OSERR == 0) /* Some devices (tape:) don't set IoErr() ... */
{
ok = TRUE;
/* Most non-lockable devices don't like MODE_READWRITE.
So we have to throw shareable files out the window */
create = MODE_NEWFILE;
}
else /* Missing file ok if we are creating. */
ok = err == ENOENT && (flags & O_CREAT);
if (ok)
{
va_list vmode;
exists = FALSE;
if (flags & O_CREAT)
{
if (flags & 0x8000) /* SAS C runtime called us, no mode */
amode = FIBF_EXECUTE; /* Maybe 0 ? */
else
{
va_start(vmode, flags);
amode = _make_protection(va_arg(vmode, int));
va_end(vmode);
}
}
else amode = -1; /* Assume complete access */
}
else
{
errno = err;
return -1;
}
}
else /* File already exists, play with it */
{
/* Get protection */
if (!((fib = AllocDosObjectTags(DOS_FIB, TAG_END)) &&
Examine(plock, fib)))
{
if (fib) FreeDosObject(DOS_FIB, fib);
ERROR;
}
amode = fib->fib_Protection;
FreeDosObject(DOS_FIB, fib);
UnLock(plock);
/* Check access */
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
{
errno = EEXIST;
return -1;
}
if ((rd && (amode & FIBF_READ) || wr && (amode & FIBF_WRITE)))
{
errno = EACCES;
return -1;
}
/* Truncate files, by opening in MODE_NEWFILE, then closing it.
This allows the file to be opened in shared mode after that (READWRITE or
OLDFILE), which is consistent with the unix semantics. */
if (flags & O_TRUNC)
{
BPTR tfh;
if (tfh = Open(path, MODE_NEWFILE)) Close(tfh);
else ERROR;
}
}
}
if (!(fh = Open(path, flags & O_CREAT ? create : MODE_OLDFILE)))
ERROR;
/* Protection is set when file is closed because OFS & FFS
don't appreciate it being done on MODE_NEWFILE files. */
if ((flags & O_TRUNC) || !exists) protection = amode;
else protection = -1;
fdflags = 0;
if (rd) fdflags |= FI_READ;
if (wr) fdflags |= FI_WRITE;
if (flags & O_APPEND) fdflags |= O_APPEND;
fd = _alloc_amigafd(fh, protection, fdflags);
if (fd < 0)
{
_us->pr_WindowPtr = (APTR)-1;
Close(fh);
_us->pr_WindowPtr = pwindow;
}
return fd;
}
int open(const char *path, int flags, ...)
{
va_list vmode;
va_start(vmode, flags);
return __open(path, flags, va_arg(vmode, int));
va_end(vmode);
}