home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / glibc-1.06 / sysdeps / mach / hurd / __brk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-31  |  3.8 KB  |  148 lines

  1. /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <errno.h>
  21. #include <sys/resource.h>
  22. #include <hurd.h>
  23. #include <gnu-stabs.h>
  24.  
  25.  
  26. /* Initial maximum size of the data segment (32MB, which is arbitrary).  */
  27. #define    DATA_SIZE    (32 * 1024 * 1024)
  28.  
  29.  
  30. /* Up to the page including this address is allocated from the kernel.
  31.    This address is the data resource limit.  */
  32. vm_address_t _hurd_data_end;
  33.  
  34. /* Up to this address is actually available to the user.
  35.    Pages beyond the one containing this address allow no access.  */
  36. vm_address_t _hurd_brk;
  37.  
  38. struct mutex _hurd_brk_lock;
  39.  
  40. /* Set the end of the process's data space to INADDR.
  41.    Return 0 if successful, -1 if not.  */
  42. int
  43. DEFUN(__brk, (inaddr), PTR inaddr)
  44. {
  45.   int ret;
  46.   __mutex_lock (&_hurd_brk_lock);
  47.   ret = _hurd_set_brk ((vm_address_t) inaddr);
  48.   __mutex_unlock (&_hurd_brk_lock);
  49.   return ret;
  50. }
  51.  
  52. int
  53. _hurd_set_brk (vm_address_t addr)
  54. {
  55.   error_t err;
  56.   vm_address_t pagend = round_page (addr);
  57.   vm_address_t pagebrk = round_page (_hurd_brk);
  58.  
  59.   if (pagend <= pagebrk)
  60.     {
  61.       if (pagend < pagebrk)
  62.     /* Make that memory inaccessible.  */
  63.     __vm_protect (__mach_task_self (), pagend, pagebrk - pagend,
  64.               0, VM_PROT_NONE);
  65.       _hurd_brk = addr;
  66.       return 0;
  67.     }
  68.  
  69.   if (pagend > _hurd_data_end)
  70.     {
  71.       /* Need to increase the resource limit.  */
  72.       errno = ENOMEM;
  73.       return -1;
  74.     }
  75.  
  76.   /* Make the memory accessible.  */
  77.   if (err = __vm_protect (__mach_task_self (), pagebrk, pagend - pagebrk,
  78.               0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE))
  79.     {
  80.       errno = err;
  81.       return -1;
  82.     }
  83.  
  84.   _hurd_brk = addr;
  85.   return 0;
  86. }
  87.  
  88. static void
  89. init_brk (void)
  90. {
  91.   extern char _end;
  92.   vm_address_t pagend;
  93.  
  94.   __mutex_init (&_hurd_brk_lock);
  95.  
  96.   _hurd_brk = &_end;
  97.  
  98.   pagend = round_page (&_end);
  99.  
  100.   _hurd_data_end = DATA_SIZE;
  101.  
  102.   if (pagend < _hurd_data_end)
  103.     {
  104.       /* We use vm_map to allocate and change permissions atomically.  */
  105.       if (!__vm_map (__mach_task_self (), &pagend, _hurd_data_end - pagend,
  106.              0, 0, MACH_PORT_NULL, 0, 0,
  107.              0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE,
  108.              VM_INHERIT_COPY)) /* ? */
  109.     _hurd_data_end = pagend;
  110.     }
  111. }
  112. text_set_element (__libc_subinit, init_brk);
  113.  
  114.  
  115. int
  116. _hurd_set_data_limit (const struct rlimit *lim)
  117. {
  118.   error_t err;
  119.   vm_address_t end = round_page (lim->rlim_max);
  120.  
  121.   if (lim->rlim_cur > lim->rlim_max)
  122.     {
  123.       errno = EINVAL;
  124.       return -1;
  125.     }
  126.  
  127.   __mutex_lock (&_hurd_brk_lock);
  128.   if (end > _hurd_data_end)
  129.     {
  130.       /* We use vm_map to allocate and change permissions atomically.  */
  131.       if (__vm_map (__mach_task_self (), &_hurd_data_end, end - _hurd_data_end,
  132.             0, 0, MACH_PORT_NULL, 0, 0,
  133.             0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE,
  134.             VM_INHERIT_COPY)) /* ? */
  135.     {
  136.       __mutex_unlock (&_hurd_brk_lock);
  137.       errno = ENOMEM;
  138.       return -1;
  139.     }
  140.     }
  141.   else if (end < _hurd_data_end)
  142.     __vm_deallocate (__mach_task_self (), end, _hurd_data_end - end);
  143.   _hurd_brk_limit = lim->rlim_cur;
  144.   _hurd_data_end = end;
  145.   __mutex_unlock (&_hurd_brk_lock);
  146.   return 0;
  147. }
  148.