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 >
C/C++ Source or Header  |  1996-09-28  |  3KB  |  142 lines

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