home *** CD-ROM | disk | FTP | other *** search
- head 1.2;
- access;
- symbols
- version39-41:1.1;
- locks;
- comment @ * @;
-
-
- 1.2
- date 92.07.28.00.32.04; author mwild; state Exp;
- branches;
- next 1.1;
-
- 1.1
- date 92.05.14.19.55.40; author mwild; state Exp;
- branches;
- next ;
-
-
- desc
- @open(2) function
- @
-
-
- 1.2
- log
- @pass convert_dir the original signal mask, to check for pending signals
- @
- text
- @/*
- * This file is part of ixemul.library for the Amiga.
- * Copyright (C) 1991, 1992 Markus M. Wild
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: open.c,v 1.1 1992/05/14 19:55:40 mwild Exp $
- *
- * $Log: open.c,v $
- * Revision 1.1 1992/05/14 19:55:40 mwild
- * Initial revision
- *
- */
-
- #define KERNEL
- #include "ixemul.h"
-
- #undef DEBUG
-
- #ifdef DEBUG
- #define DP(a) kprintf a
- #else
- #define DP(a)
- #endif
-
- /* standard functions.. could get overridden in a network environment */
- extern int __ioctl (), __fselect (), __close ();
-
- /* "normal" functions, means do half-async writes & sync reads */
- extern int __write (), __read ();
-
- /* sync-write, waits for completion of write, this gets enabled by
- * O_FSYNC */
- extern int __sync_write ();
-
- extern void __fasync_handler ();
-
- /* incore functions */
- extern int __mread (), __mclose ();
-
- extern int __ioerr_to_errno ();
-
-
- int
- open (char *name, int mode, int perms)
- {
- int fd;
- struct file *f;
- BPTR fh;
- int len, late_stat;
- int omask, error;
- int amode;
-
- mode = FFLAGS(mode);
-
- DP(("open1: write (2,.. %s.\n", write (2, "WR2", 3) == 3 ? "works" : "doesn't work"));
-
- if ((errno = falloc (&f, &fd)) != 0) return -1;
- /* we now got the file, ie. since its count is > 0, no other process
- * will get it with falloc() */
-
- DP(("open2: write (2,.. %s.\n", write (2, "WR2", 3) == 3 ? "works" : "doesn't work"));
-
- DP(("open3: write (2,.. %s.\n", write (2, "WR2", 3) == 3 ? "works" : "doesn't work"));
- /* init those fields */
- f->f_stb_dirty = 0;
- late_stat = 0;
- if (syscall (SYS_stat, name, &f->f_stb) < 0)
- {
- /* there can mainly be two reasons for stat() to fail. Either the
- * file really doesn't exist (ENOENT), or then the filesystem/handler
- * doesn't support file locks. */
-
- /* if we should get out of here without an error, init the stat
- * buffer after having opened the file with __fstat, this sets some
- * reasonable parameters (see end of function). */
- late_stat = 1;
-
- #if 0
- /* GRRR this sounded too good to be true, stat("*") returns
- * ENOENT, so this trick doesn't work */
-
- /* if the file doesn't exist, this is an error if not O_CREAT */
- if ((errno == ENOENT) && !(mode&O_CREAT)) return -1;
- #endif
-
- if ((errno == ENOENT) && (mode&O_CREAT))
- {
- /* can't set permissions on an open file, so this has to be done
- * by 'close' */
- f->f_stb.st_mode = perms;
- f->f_stb_dirty = 1;
- }
- }
-
- DP(("open4: write (2,.. %s.\n", write (2, "WR2", 3) == 3 ? "works" : "doesn't work"));
- f->f_flags = mode & FMASK;
-
- /* initialise the packet. The only thing needed at this time is its
- * header, filling in of port, action & args will be done when it's
- * used */
- __init_std_packet (&f->f_sp);
-
- /* ok, so lets try to open the file... */
-
- /* since we may obtain a filehandle, that wouldn't be closed if we break
- * too early, inhibit signals */
- omask = syscall (SYS_sigsetmask, ~0);
-
- /* do this *only* if the stat() above was successful !! */
- if (!late_stat && S_ISDIR (f->f_stb.st_mode) && !(mode & FWRITE))
- {
- if (convert_dir (f, name, omask) == 0)
- goto ret_ok;
- else
- goto error;
- }
-
- DP(("open5: write (2,.. %s.\n", write (2, "WR2", 3) == 3 ? "works" : "doesn't work"));
- #if 0
- fh = __open (name, MODE_OLDFILE);
-
- if (!fh && !(mode & O_CREAT))
- {
- error = __ioerr_to_errno (IoErr ());
- goto error;
- }
- else if (fh && ((mode&(O_EXCL|O_CREAT))==(O_EXCL|O_CREAT)))
- {
- __Close (fh);
- error = EEXIST;
- goto error;
- }
- else if (!fh && (mode & O_CREAT))
- {
- fh = __open (name, MODE_NEWFILE);
- }
- else if (fh && (mode & O_TRUNC))
- {
- __Close (fh);
- fh = __open (name, MODE_NEWFILE);
- }
- #else
- if (!(mode & FWRITE))
- amode = MODE_OLDFILE;
- else
- switch (mode & (O_CREAT|O_TRUNC|O_EXCL))
- {
- case 0:
- amode = MODE_OLDFILE;
- break;
-
- case O_EXCL:
- case O_EXCL|O_TRUNC:
- /* can never succeed ! */
- error = EINVAL;
- goto error;
-
- case O_CREAT|O_EXCL:
- case O_CREAT|O_EXCL|O_TRUNC:
- if (! late_stat)
- {
- error = EEXIST;
- goto error;
- }
- /* FALL INTO (O_CREAT|O_TRUNC, O_TRUNC is cheated.. ) */
-
- case O_TRUNC:
- /* in strict Unix terminology, this is an erronous implementation,
- we should call truncate() and then open OLDFILE. Doing it this
- way makes the file lose its protection bits! */
- /* FALL INTO */
-
- case O_CREAT|O_TRUNC:
- amode = MODE_NEWFILE;
- break;
-
- case O_CREAT:
- /* I just hope that all handlers support this correctly.... */
- amode = MODE_READWRITE; /* means: open existing, create if necessary */
- break;
- }
-
- fh = __open (name, amode);
- #endif
-
- if (! fh)
- {
- error = __ioerr_to_errno (IoErr ());
- goto error;
- }
-
- /* now.. we're lucky, we actually opened the file! */
- f->f_fh = (struct FileHandle *) BTOCPTR(fh);
-
- if (mode & FWRITE)
- f->f_write = (mode & O_FSYNC) ? __sync_write : __write;
- if (mode & FREAD)
- f->f_read = __read;
-
- #if 0
- /* won't work that way, I'll think something up later.. */
-
- /* in this case, we have to setup a handler that is called when ever
- * something arrives at the rw-port, and then walk our filetable and
- * decide whether the packet belonged to a file that has FASYNC set */
- if (mode & FASYNC) signal (__rwport->mp_SigBit, __fasync_handler);
- #endif
-
- f->f_ioctl = __ioctl;
- f->f_select = __fselect;
- f->f_close = __close;
- f->f_type = DTYPE_FILE;
-
- ret_ok:
- /*
- * have to use kmalloc() instead of malloc(), because this is no task-private
- * data, it could (in the future) be shared by other tasks
- */
- f->f_name = (void *) kmalloc (strlen (name) + 1);
- strcpy (f->f_name, name);
-
- /* ok, we're almost done. If desired, init the stat buffer to the
- * information we can get from an open file descriptor */
- if (late_stat) __fstat (f);
-
- /* if the file qualifies, try to change it into a DTYPE_MEM file */
- if (!late_stat && f->f_stb.st_size < ix.ix_membuf_limit && mode == FREAD)
- {
- void *buf;
-
- DP(("open6: write (2,.. %s.\n", write (2, "WR2", 3) == 3 ? "works" : "doesn't work"));
- /* try to obtain the needed memory */
- buf = (void *) kmalloc (f->f_stb.st_size);
- if (buf)
- if (syscall (SYS_read, fd, buf, f->f_stb.st_size) == f->f_stb.st_size)
- {
- DP(("open7: write (2,.. %s.\n", write (2, "WR2", 3) == 3 ? "works" : "doesn't work"));
- __Close (CTOBPTR (f->f_fh));
- DP(("open8: write (2,.. %s.\n", write (2, "WR2", 3) == 3 ? "works" : "doesn't work"));
- f->f_type = DTYPE_MEM;
- f->f_mf.mf_offset = 0;
- f->f_mf.mf_buffer = buf;
- f->f_read = __mread;
- f->f_close = __mclose;
- f->f_ioctl = 0;
- f->f_select = 0;
- }
- else
- kfree (buf);
- }
-
- syscall (SYS_sigsetmask, omask);
-
- errno = error;
- /* return the descriptor */
- return fd;
-
- error:
- /* free the file */
- u.u_ofile[fd] = 0;
- f->f_count--;
- syscall (SYS_sigsetmask, omask);
- errno = error;
- return -1;
- }
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d19 1
- a19 1
- * $Id$
- d21 4
- a24 1
- * $Log$
- d125 1
- a125 1
- if (convert_dir (f, name) == 0)
- @
-