home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / e20313sr.zip / emacs / 20.3.1 / src / vmsmap.c < prev    next >
C/C++ Source or Header  |  1999-07-31  |  6KB  |  226 lines

  1. /* VMS mapping of data and alloc arena for GNU Emacs.
  2.    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
  3.    
  4.    This file is part of GNU Emacs.
  5.  
  6. GNU Emacs is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU Emacs is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Emacs; see the file COPYING.  If not, write to
  18. the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. Boston, MA 02111-1307, USA.  */
  20.  
  21. /* Written by Mukesh Prasad.  */
  22.  
  23. #ifdef VMS
  24.  
  25. #include <config.h>
  26. #include "lisp.h"
  27. #include <rab.h>
  28. #include <fab.h>
  29. #include <rmsdef.h>
  30. #include <secdef.h>
  31.  
  32. /* RMS block size */
  33. #define    BLOCKSIZE    512
  34.  
  35. /* Maximum number of bytes to be written in one RMS write.
  36.  * Must be a multiple of BLOCKSIZE.
  37.  */
  38. #define    MAXWRITE    (BLOCKSIZE * 30)
  39.  
  40. /* This funniness is to ensure that sdata occurs alphabetically BEFORE the
  41.    $DATA psect and that edata occurs after ALL Emacs psects.  This is
  42.    because the VMS linker sorts all psects in a cluster alphabetically
  43.    during the linking, unless you use the cluster_psect command.  Emacs
  44.    uses the cluster command to group all Emacs psects into one cluster;
  45.    this keeps the dumped data separate from any loaded libraries. */
  46.  
  47. globaldef {"$D$ATA"} char sdata[512]; /* Start of saved data area */
  48. globaldef {"__DATA"} char edata[512]; /* End of saved data area */
  49.  
  50. /* Structure to write into first block of map file.
  51.  */
  52.  
  53. struct map_data
  54. {
  55.   char * sdata;            /* Start of data area */
  56.   char * edata;            /* End of data area */
  57.   int  datablk;            /* Block in file to map data area from/to */
  58. };
  59.  
  60. static void fill_fab (), fill_rab ();
  61. static int write_data ();
  62.  
  63. extern char *start_of_data ();
  64. extern int vms_out_initial;    /* Defined in malloc.c */
  65.  
  66. /* Maps in the data and alloc area from the map file.
  67.  */
  68.  
  69. int
  70. mapin_data (name)
  71.      char * name;
  72. {
  73.   struct FAB fab;
  74.   struct RAB rab;
  75.   int status, size;
  76.   int inadr[2];
  77.   struct map_data map_data;
  78.   
  79.   /* Open map file. */
  80.   fab = cc$rms_fab;
  81.   fab.fab$b_fac = FAB$M_BIO|FAB$M_GET;
  82.   fab.fab$l_fna = name;
  83.   fab.fab$b_fns = strlen (name);
  84.   status = sys$open (&fab);
  85.   if (status != RMS$_NORMAL)
  86.     {
  87.       printf ("Map file not available, running bare Emacs....\n");
  88.       return 0;            /* Map file not available */
  89.     }
  90.   /* Connect the RAB block */
  91.   rab = cc$rms_rab;
  92.   rab.rab$l_fab = &fab;
  93.   rab.rab$b_rac = RAB$C_SEQ;
  94.   rab.rab$l_rop = RAB$M_BIO;
  95.   status = sys$connect (&rab);
  96.   if (status != RMS$_NORMAL)
  97.     lib$stop (status);
  98.   /* Read the header data */
  99.   rab.rab$l_ubf = &map_data;
  100.   rab.rab$w_usz = sizeof (map_data);
  101.   rab.rab$l_bkt = 0;
  102.   status = sys$read (&rab);
  103.   if (status != RMS$_NORMAL)
  104.     lib$stop (status);
  105.   status = sys$close (&fab);
  106.   if (status != RMS$_NORMAL)
  107.     lib$stop (status);
  108.   if (map_data.sdata != start_of_data ())
  109.     {
  110.       printf ("Start of data area has moved: cannot map in data.\n");
  111.       return 0;
  112.     }
  113.   if (map_data.edata != edata)
  114.     {
  115.       printf ("End of data area has moved: cannot map in data.\n");
  116.       return 0;
  117.     }
  118.   fab.fab$l_fop |= FAB$M_UFO;
  119.   status = sys$open (&fab);
  120.   if (status != RMS$_NORMAL)
  121.     lib$stop (status);
  122.   /* Map data area. */
  123.   inadr[0] = map_data.sdata;
  124.   inadr[1] = map_data.edata;
  125.   status = sys$crmpsc (inadr, 0, 0, SEC$M_CRF | SEC$M_WRT, 0, 0, 0,
  126.                fab.fab$l_stv, 0, map_data.datablk, 0, 0);
  127.   if (! (status & 1))
  128.     lib$stop (status);
  129. }
  130.  
  131. /* Writes the data and alloc area to the map file.
  132.  */
  133. mapout_data (into)
  134.      char * into;
  135. {
  136.   struct FAB fab;
  137.   struct RAB rab;
  138.   int status;
  139.   struct map_data map_data;
  140.   int datasize, msize;
  141.  
  142.   if (vms_out_initial)
  143.     {
  144.       error ("Out of initial allocation. Must rebuild emacs with more memory (VMS_ALLOCATION_SIZE).");
  145.       return 0;
  146.     }
  147.   map_data.sdata = start_of_data ();
  148.   map_data.edata = edata;
  149.   datasize = map_data.edata - map_data.sdata + 1;
  150.   map_data.datablk = 2 + (sizeof (map_data) + BLOCKSIZE - 1) / BLOCKSIZE;
  151.   /* Create map file. */
  152.   fab = cc$rms_fab;
  153.   fab.fab$b_fac = FAB$M_BIO|FAB$M_PUT;
  154.   fab.fab$l_fna = into;
  155.   fab.fab$b_fns = strlen (into);
  156.   fab.fab$l_fop = FAB$M_CBT;
  157.   fab.fab$b_org = FAB$C_SEQ;
  158.   fab.fab$b_rat = 0;
  159.   fab.fab$b_rfm = FAB$C_VAR;
  160.   fab.fab$l_alq = 1 + map_data.datablk +
  161.               ((datasize + BLOCKSIZE - 1) / BLOCKSIZE);
  162.   status = sys$create (&fab);
  163.   if (status != RMS$_NORMAL)
  164.     {
  165.       error ("Could not create map file");
  166.       return 0;
  167.     }
  168.   /* Connect the RAB block */
  169.   rab = cc$rms_rab;
  170.   rab.rab$l_fab = &fab;
  171.   rab.rab$b_rac = RAB$C_SEQ;
  172.   rab.rab$l_rop = RAB$M_BIO;
  173.   status = sys$connect (&rab);
  174.   if (status != RMS$_NORMAL)
  175.     {
  176.       error ("RMS connect to map file failed");
  177.       return 0;
  178.     }
  179.   /* Write the header */
  180.   rab.rab$l_rbf = &map_data;
  181.   rab.rab$w_rsz = sizeof (map_data);
  182.   status = sys$write (&rab);
  183.   if (status != RMS$_NORMAL)
  184.     {
  185.       error ("RMS write (header) to map file failed");
  186.       return 0;
  187.     }
  188.   if (! write_data (&rab, map_data.datablk, map_data.sdata, datasize))
  189.     return 0;
  190.   status = sys$close (&fab);
  191.   if (status != RMS$_NORMAL)
  192.     {
  193.       error ("RMS close on map file failed");
  194.       return 0;
  195.     }
  196.   return 1;
  197. }
  198.  
  199. static int
  200. write_data (rab, firstblock, data, length)
  201.      struct RAB * rab;
  202.      char * data;
  203. {
  204.   int status;
  205.   
  206.   rab->rab$l_bkt = firstblock;
  207.   while (length > 0)
  208.     {
  209.       rab->rab$l_rbf = data;
  210.       rab->rab$w_rsz = length > MAXWRITE ? MAXWRITE : length;
  211.       status = sys$write (rab, 0, 0);
  212.       if (status != RMS$_NORMAL)
  213.     {
  214.       error ("RMS write to map file failed");
  215.       return 0;
  216.     }
  217.       data = &data[MAXWRITE];
  218.       length -= MAXWRITE;
  219.       rab->rab$l_bkt = 0;
  220.     }
  221.   return 1;
  222. }                /* write_data */
  223.  
  224. #endif /* VMS */
  225.  
  226.