home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / ixemul-45.0-src.tgz / tar.out / contrib / ixemul / library / mmap.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  3KB  |  141 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1996  Hans Verkuil
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #define _KERNEL
  21. #include "ixemul.h"
  22. #include "kprintf.h"
  23. #include <sys/mman.h>
  24.  
  25. extern int read(), write();
  26.  
  27. caddr_t mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
  28. {
  29.   struct mmap_mem *m;
  30.   
  31.   if (flags & MAP_FIXED)
  32.     {
  33.       errno = ENOMEM;
  34.       return NULL;
  35.     }
  36.   if (!(flags & MAP_ANON) && (fd < 0 || fd >= NOFILE || !u.u_ofile[fd]))
  37.     {
  38.       errno = EBADF;
  39.       return (caddr_t)-1;
  40.     }
  41.   m = malloc(sizeof(struct mmap_mem));
  42.   if (m == NULL)
  43.     {
  44.       errno = ENOMEM;
  45.       return (caddr_t)-1;
  46.     }
  47.   m->addr = malloc(len);
  48.   if (m->addr == NULL)
  49.     {
  50.       free(m);
  51.       errno = ENOMEM;
  52.       return (caddr_t)-1;
  53.     }
  54.   if (!(flags & MAP_ANON))
  55.     {
  56.       off_t curoff = lseek(fd, 0, SEEK_CUR);
  57.  
  58.       lseek(fd, offset, SEEK_SET);
  59.       read(fd, m->addr, len);
  60.       lseek(fd, curoff, SEEK_SET);
  61.     }
  62.   m->length = len;
  63.   m->prot = prot;
  64.   m->fd = fd;
  65.   m->flags = flags;
  66.   m->offset = offset;
  67.   m->next = u.u_mmap;
  68.   u.u_mmap = m;
  69.   return m->addr;
  70. }
  71.  
  72. static struct mmap_mem *find_mmap(caddr_t addr)
  73. {
  74.   struct mmap_mem *m = u.u_mmap;
  75.   
  76.   for (m = u.u_mmap; m; m = m->next)
  77.     if ((caddr_t)m->addr <= addr && (caddr_t)m->addr + m->length > addr)
  78.       break;
  79.   return m;
  80. }
  81.  
  82. /* NetBSD also doesn't support this */
  83. void madvise(caddr_t addr, int len, int behav)
  84. {
  85. }
  86.  
  87. int mlock(caddr_t addr, size_t len)
  88. {
  89.   return 0;
  90. }
  91.  
  92. int munlock(caddr_t addr, size_t len)
  93. {
  94.   return 0;
  95. }
  96.  
  97. void mprotect(caddr_t addr, size_t len, int prot)
  98. {
  99.   struct mmap_mem *m = find_mmap(addr);
  100.   
  101.   if (m)
  102.     m->prot = prot;
  103. }
  104.  
  105. void msync(caddr_t addr, int len)
  106. {
  107.   struct mmap_mem *m = find_mmap(addr);
  108.   int cur_off;
  109.   
  110.   if (!m || (m->flags & MAP_ANON) || !(m->prot & PROT_WRITE))
  111.     return;
  112.   cur_off = lseek(m->fd, 0, SEEK_CUR);
  113.   lseek(m->fd, m->offset, SEEK_SET);
  114.   write(m->fd, m->addr, m->length);
  115.   lseek(m->fd, cur_off, SEEK_SET);
  116. }
  117.  
  118. int munmap(caddr_t addr, size_t len)
  119. {
  120.   struct mmap_mem *m, *prev = NULL;
  121.  
  122.   for (m = u.u_mmap; m; m = m->next)
  123.     {
  124.       if ((caddr_t)m->addr <= addr && (caddr_t)m->addr + m->length > addr)
  125.         break;
  126.       prev = m;
  127.     }
  128.   if (!m)
  129.     {
  130.       errno = EINVAL;
  131.       return -1;
  132.     }
  133.   if (prev)
  134.     prev->next = m->next;
  135.   else
  136.     u.u_mmap = m->next;
  137.   free(m->addr);
  138.   free(m);
  139.   return 0;
  140. }
  141.