home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.004 / xemacs-1 / xemacs-19.13 / src / vmsmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-25  |  5.9 KB  |  227 lines

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