home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / unix / src / open.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-29  |  2.8 KB  |  120 lines

  1. #include "amiga.h"
  2. #include "files.h"
  3. #include "amigados.h"
  4. #include <utility/tagitem.h>
  5. #include <stdarg.h>
  6. #include <fcntl.h>
  7. #include <string.h>
  8.  
  9.  
  10. int open(char *path, int flags, ...)
  11. {
  12.   int fd, acc = flags & 3, rd, wr, exists = TRUE, amode;
  13.   struct FileInfoBlock *fib;
  14.   BPTR plock, fh;
  15.   long fdflags, protection;
  16.   APTR pwindow = _us->pr_WindowPtr;
  17.  
  18.   chkabort();
  19.  
  20.   rd = acc == O_RDONLY || acc == O_RDWR;
  21.   wr = acc == O_WRONLY || acc == O_RDWR;
  22.  
  23.   if (stricmp(path, "NIL:") == 0) amode = -1;
  24.   else
  25.     {
  26.       _us->pr_WindowPtr = (APTR)-1;
  27.       plock = Lock(path, ACCESS_READ);
  28.       _us->pr_WindowPtr = pwindow;
  29.       if (!plock)
  30.     {
  31.       int err = convert_oserr(IoErr());
  32.  
  33.       /* Devices like pipe: don't like Lock ... */
  34.       if (err == ENOENT && (flags & O_CREAT) ||
  35.           _OSERR == ERROR_ACTION_NOT_KNOWN ||
  36.           _OSERR == 0)    /* Some devices (tape:) don't set IoErr() ... */
  37.         {
  38.           va_list vmode;
  39.  
  40.           exists = FALSE;
  41.           if (flags & O_CREAT)
  42.         {
  43.           if (flags & 0x8000) /* SAS C runtime called us, no mode */
  44.             amode = FIBF_EXECUTE; /* Maybe 0 ? */
  45.           else
  46.             {
  47.               va_start(vmode, flags);
  48.               amode = _make_protection(va_arg(vmode, int));
  49.               va_end(vmode);
  50.             }
  51.         }
  52.           else amode = -1;    /* Assume complete access */
  53.         }
  54.       else
  55.         {
  56.           errno = err;
  57.           return -1;
  58.         }
  59.     }
  60.       else /* File already exists, play with it */
  61.     {
  62.       /* Get protection */
  63.       if (!((fib = AllocDosObjectTags(DOS_FIB, TAG_END)) &&
  64.         Examine(plock, fib)))
  65.         {
  66.           if (fib) FreeDosObject(DOS_FIB, fib);
  67.           ERROR;
  68.         }
  69.       amode = fib->fib_Protection;
  70.       FreeDosObject(DOS_FIB, fib);
  71.       UnLock(plock);
  72.  
  73.       /* Check access */
  74.       if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
  75.         {
  76.           errno = EEXIST;
  77.           return -1;
  78.         }
  79.       if ((rd && (amode & FIBF_READ) || wr && (amode & FIBF_WRITE)))
  80.         {
  81.           errno = EACCES;
  82.           return -1;
  83.         }
  84.  
  85.       /* Truncate files, by opening in MODE_NEWFILE, then closing it.
  86.          This allows the file to be opened in shared mode after that (READWRITE or
  87.          OLDFILE), which is consistent with the unix semantics. */
  88.       if (flags & O_TRUNC)
  89.         {
  90.           BPTR tfh;
  91.  
  92.           if (tfh = Open(path, MODE_NEWFILE)) Close(tfh);
  93.           else ERROR;
  94.         }
  95.     }
  96.     }
  97.   if (!(fh = Open(path, flags & O_CREAT ? MODE_READWRITE : MODE_OLDFILE)))
  98.     ERROR;
  99.  
  100.   
  101.   /* Protection is set when file is closed because OFS & FFS
  102.      don't appreciate it being done on MODE_NEWFILE files. */
  103.   if ((flags & O_TRUNC) || !exists) protection = amode;
  104.   else protection = -1;
  105.  
  106.   fdflags = 0;
  107.   if (rd) fdflags |= FI_READ;
  108.   if (wr) fdflags |= FI_WRITE;
  109.   if (flags & O_APPEND) fdflags |= O_APPEND;
  110.  
  111.   fd = _alloc_amigafd(fh, protection, fdflags);
  112.   if (fd < 0)
  113.     {
  114.       _us->pr_WindowPtr = (APTR)-1;
  115.       Close(fh);
  116.       _us->pr_WindowPtr = pwindow;
  117.     }
  118.   return fd;
  119. }
  120.