Annotation of GNUtools/emacs/src/unexshm.c, revision 1.1

1.1     ! root        1: /* Attempted unexec for AIX.
        !             2:    Copyright (c) 1990  Free Software Foundation, Inc.
        !             3: 
        !             4:   This file is not used because it occasionally fails to work.  This
        !             5:   happens because the bss address when Emacs is run is not always the
        !             6:   same.  If it happens to be different from what it was
        !             7:   when Emacs was dumped, the dumped data won't work.
        !             8:   No one has been able to prevent the address from varying.
        !             9: 
        !            10: This file is part of GNU Emacs.
        !            11: 
        !            12: GNU Emacs is free software; you can redistribute it and/or modify
        !            13: it under the terms of the GNU General Public License as published by
        !            14: the Free Software Foundation; either version 1, or (at your option)
        !            15: any later version.
        !            16: 
        !            17: GNU Emacs is distributed in the hope that it will be useful,
        !            18: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            19: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            20: GNU General Public License for more details.
        !            21: 
        !            22: You should have received a copy of the GNU General Public License
        !            23: along with GNU Emacs; see the file COPYING.  If not, write to
        !            24: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            25: 
        !            26: /* This is based on a public domain program written by IBM.  */
        !            27: 
        !            28: /*************** SYSTEM DEFINES *********************************/
        !            29: 
        !            30: #include "config.h"
        !            31: #include "paths.h"
        !            32: #include <sys/types.h>
        !            33: #include <sys/file.h>
        !            34: #include <fcntl.h>
        !            35: #include <sys/mode.h>
        !            36: #include <sys/ipc.h>
        !            37: #include <sys/shm.h>
        !            38: #include <malloc.h>
        !            39: #include <stdio.h>                             /* MWW */
        !            40: #include "lisp.h"
        !            41: 
        !            42: /*************** LOCAL DEFINES **********************************/
        !            43: 
        !            44: struct data_header             /* saved data header            */
        !            45: {
        !            46:   char *start;                 /* dump _data addr              */
        !            47:   char *end;                   /* dump _end addr               */
        !            48:   char *sbrk1;                 /* dump original sbrk addr      */
        !            49:   char *sbrk2;                 /* dump final sbrk addr */
        !            50:   int puresize;                        /* size of pure data dumped  */
        !            51: };
        !            52: 
        !            53: #define EMACSSHMKEY "EMACSSHMKEY"
        !            54: #define EMACS_DATA_FILE "EMACS-DATA"
        !            55: #define NEW_SHMGET_FLAGS (IPC_CREAT | S_IWUSR | S_IRUSR \
        !            56:       | S_IWGRP | S_IRGRP | S_IWOTH | S_IROTH)
        !            57: #define OLD_SHMAT_FLAGS SHM_RDONLY
        !            58: #define OLD_SHMGET_FLAGS (S_IRUSR | S_IRGRP | S_IROTH) 
        !            59: #define OLD_OPEN_FLAGS O_RDONLY
        !            60: #define NEW_OPEN_FLAGS (O_RDWR | O_CREAT | O_TRUNC)
        !            61: 
        !            62: /*************** EXTERNAL / GLOBAL DATA AREA ********************/
        !            63: 
        !            64: extern char _data;             /* start of data addr           */
        !            65: extern char _end;              /* end of all data + 1 addr     */
        !            66: static char *original_sbrk;    /* sbrk when dump first run     */
        !            67: 
        !            68: void
        !            69: map_in_data (use_dumped_data)
        !            70:      int use_dumped_data;
        !            71: {
        !            72:   int bufsize;                 /* malloc buffer size           */
        !            73:   struct data_header dh;       /* saved data header            */
        !            74:   int fd;                      /* saved data file descriptor   */
        !            75:   char *finaladdr;             /* last addr in bucket          */
        !            76:   char *ipckey = getenv (EMACSSHMKEY); /* env ipc key string   */
        !            77:   int length;                  /* dumped data lengths          */
        !            78:   char *newaddr;               /* new malloc buffer addr       */
        !            79:   int numblks;                 /* number of remaining mallocs  */
        !            80:   int shmid;                   /* shared memory id             */
        !            81:   key_t shmkey;                        /* shared memory key            */
        !            82:   /* Note that using malloc here may not be safe.  */
        !            83:   char name[sizeof (PATH_EXEC) + sizeof (EMACS_DATA_FILE) + 2];
        !            84: 
        !            85:   /* Consume remaining malloc space without increasing         */
        !            86:   /* the end of data space                                     */
        !            87:   original_sbrk = sbrk (0);
        !            88:   for (bufsize = 16; bufsize < getpagesize (); bufsize *= 2)
        !            89:     {
        !            90:       while ((newaddr = (char *)malloc (bufsize - 8)) < original_sbrk)
        !            91:        ;
        !            92:       for (numblks = (getpagesize () / bufsize) - 1; numblks > 0; numblks--)
        !            93:        malloc (bufsize - 8);
        !            94:       finaladdr = sbrk (0);
        !            95:     }
        !            96:   original_sbrk = sbrk (0);
        !            97: 
        !            98:   /* Determine ipc key from environment or default             */
        !            99:   if (ipckey && *ipckey)
        !           100:     shmkey = atoi (ipckey);
        !           101:   else
        !           102:     shmkey = SHMKEY;
        !           103: 
        !           104:   /* If we don't want the dumped data, get an unshared segment.  */
        !           105:   if (!use_dumped_data)
        !           106:     {
        !           107:       shmid = shmget (IPC_PRIVATE, PURESIZE, NEW_SHMGET_FLAGS);
        !           108:       if (shmid == -1
        !           109:          || shmat (shmid, (char *)PURE_SEG_BITS, 0) == -1)
        !           110:        {
        !           111:          fprintf (stderr, "emacs: failure obtaining new unshared memory segment.\n");
        !           112:          exit (1);
        !           113:        }
        !           114:       return;
        !           115:     }
        !           116: 
        !           117:   /* Compute the file name with the dumped data.  */
        !           118:   strcpy (name, PATH_EXEC);
        !           119:   strcat (name, "/");
        !           120:   strcat (name, EMACS_DATA_FILE);
        !           121: 
        !           122:   /* Open the file and make sure the addresses have not changed.  */
        !           123:   fd = open (name, OLD_OPEN_FLAGS, 0);
        !           124:   if (fd < 0)
        !           125:     {
        !           126:       fprintf (stderr, "emacs: failure opening `%s'\n", name);
        !           127:       exit (1);
        !           128:     }
        !           129:   if (read (fd, (char *)&dh, sizeof (dh)) != sizeof (dh)
        !           130:       || dh.start != &_data
        !           131:       || dh.end != &_end
        !           132:       || dh.sbrk1 != original_sbrk
        !           133:       || dh.puresize != PURESIZE)
        !           134:     {
        !           135:       fprintf (stderr, "emacs: header mismatch in `%s'\n", name);
        !           136:       exit (1);
        !           137:     }
        !           138: 
        !           139:   /* Load in the unshared contents.  */
        !           140:   if (!(length = dh.end - dh.start)
        !           141:       || read (fd, (char *)&_data, length) != length
        !           142:       || !(length = dh.sbrk2 - dh.sbrk1)
        !           143:       || brk (dh.sbrk2) == -1
        !           144:       || read (fd, dh.sbrk1, length) != length)
        !           145:     {
        !           146:       fprintf (stderr, "emacs: failure loading unshared data.\n");
        !           147:       exit (1);
        !           148:     }
        !           149: 
        !           150:   /* Attach to "pure data" shared memory segment               */
        !           151:   if ((shmid = shmget (shmkey, 0, 0)) == -1
        !           152:       || (newaddr = shmat (shmid, (char *)PURE_SEG_BITS, OLD_SHMAT_FLAGS)) == -1)
        !           153:     {
        !           154:       /* We were unable to open an existing segment.  Make a new one.  */
        !           155:       struct shmid_ds buf;
        !           156: 
        !           157:       /* First get rid of the one we tried to get.  */
        !           158:       shmdt ((char *)PURE_SEG_BITS);
        !           159:       shmctl (shmid, IPC_RMID, 0);
        !           160: 
        !           161:       /* If we could not write the data file,
        !           162:         don't make a shared segment that we could write.
        !           163:         Make an unshared segment instead.  */
        !           164:       if (access (name, W_OK) != 0)
        !           165:        {
        !           166:          shmid = shmget (IPC_PRIVATE, PURESIZE, NEW_SHMGET_FLAGS);
        !           167:          if (shmid == -1
        !           168:              || shmat (shmid, (char *)PURE_SEG_BITS, 0) == -1)
        !           169:            {
        !           170:              fprintf (stderr, "emacs: failure obtaining new unshared memory segment.\n");
        !           171:              exit (1);
        !           172:            }
        !           173: 
        !           174:          /* Load the proper data into it.  */
        !           175:          if (read (fd, PURE_SEG_BITS, PURESIZE) != PURESIZE)
        !           176:            {
        !           177:              fprintf (stderr, "emacs: failure loading shared memory data.\n");
        !           178:              shmdt ((char *)PURE_SEG_BITS);
        !           179:              shmctl (shmid, IPC_RMID, 0);
        !           180:              exit (1);
        !           181:            }
        !           182: 
        !           183:          close (fd);
        !           184:          return;
        !           185:        }
        !           186: 
        !           187:       /* Allocate the new shared segment and arrange to write it.  */
        !           188:       if ((shmid = shmget (shmkey, PURESIZE, NEW_SHMGET_FLAGS)) == -1
        !           189:          || shmat (shmid, (char *)PURE_SEG_BITS, 0) == -1)
        !           190:        {
        !           191:          fprintf (stderr, "emacs: failure obtaining new shared memory segment.\n");
        !           192:          shmdt ((char *)PURE_SEG_BITS);
        !           193:          shmctl (shmid, IPC_RMID, 0);
        !           194:          exit (1);
        !           195:        }
        !           196: 
        !           197:       /* Load the proper data into it.  */
        !           198:       if (read (fd, PURE_SEG_BITS, PURESIZE) != PURESIZE)
        !           199:        {
        !           200:          fprintf (stderr, "emacs: failure loading shared memory data.\n");
        !           201:          shmdt ((char *)PURE_SEG_BITS);
        !           202:          shmctl (shmid, IPC_RMID, 0);
        !           203:          exit (1);
        !           204:        }
        !           205: 
        !           206:       /* Detach from the segment and bring it back readonly.  */
        !           207:       shmdt ((char *)PURE_SEG_BITS);
        !           208: 
        !           209:       shmctl (shmid, IPC_STAT, &buf);
        !           210:       buf.shm_perm.mode = OLD_SHMGET_FLAGS;
        !           211:       shmctl (shmid, IPC_SET, &buf);
        !           212: 
        !           213:       newaddr = shmat (shmid, (char *)PURE_SEG_BITS, OLD_SHMAT_FLAGS);
        !           214:       if (newaddr == -1)
        !           215:        {
        !           216:          fprintf (stderr, "emacs: failure reattaching shared memory segment.\n");
        !           217:          shmctl (shmid, IPC_RMID, 0);
        !           218:          exit (1);
        !           219:        }
        !           220:     }
        !           221: 
        !           222:   close (fd);
        !           223: }
        !           224: 
        !           225: /* Dump the appropriate parts of memory into a file named NEW
        !           226:    from which the shared segment can be initialized.  */
        !           227: 
        !           228: void
        !           229: map_out_data (new)
        !           230:      char *new;
        !           231: {
        !           232:   struct data_header dh;       /* saved data header                    */
        !           233:   int fd;                      /* saved data file descriptor           */
        !           234:   int length;                  /* dumped data length; */
        !           235:   int shmid;
        !           236:   key_t shmkey;                        /* shared memory key            */
        !           237:   char *ipckey = getenv (EMACSSHMKEY); /* env ipc key string   */
        !           238: 
        !           239:   /* Determine ipc key from environment or default             */
        !           240:   if (ipckey && *ipckey)
        !           241:     shmkey = atoi (ipckey);
        !           242:   else
        !           243:     shmkey = SHMKEY;
        !           244:                                   
        !           245:   /* Create "saved data" file header */
        !           246:   dh.start = &_data;
        !           247:   dh.end = &_end;
        !           248:   dh.sbrk1 = original_sbrk;
        !           249:   dh.sbrk2 = sbrk (0);
        !           250:   dh.puresize = PURESIZE;
        !           251: 
        !           252:   /* Create new "saved data" dump file                         */
        !           253:   unlink (new);
        !           254:   fd = open (new, NEW_OPEN_FLAGS, 0666);
        !           255:   if (fd < 0)
        !           256:     report_file_error ("Opening dump file", Fcons (build_string (new), Qnil));
        !           257: 
        !           258:   /* Delete obsolete shared segment.  */
        !           259:   shmid = shmget (shmkey, 0, 0);
        !           260:   if (shmid != -1)
        !           261:     {
        !           262:       if (shmctl (shmid, IPC_RMID, 0) == 0)
        !           263:        fprintf (stderr, "Destroying existing shared segment\n");
        !           264:     }
        !           265: 
        !           266: 
        !           267:   /* Write saved header and data                               */
        !           268:   length = sizeof (dh);
        !           269:   if (write (fd, (char *)&dh, length) != length)
        !           270:     report_file_error ("Writing dump file header",
        !           271:                       Fcons (build_string (new), Qnil));
        !           272:   length = dh.end - dh.start;
        !           273:   if (write (fd, dh.start, length) != length)
        !           274:     report_file_error ("Writing low core in dump file",
        !           275:                       Fcons (build_string (new), Qnil));
        !           276:   length = dh.sbrk2 - dh.sbrk1;
        !           277:   if (write (fd, dh.sbrk1, length) != length)
        !           278:     report_file_error ("Writing heap in dump file",
        !           279:                       Fcons (build_string (new), Qnil));
        !           280:   length = PURESIZE;
        !           281:   if (write (fd, PURE_SEG_BITS, length) != length)
        !           282:     report_file_error ("Writing pure data in dump file",
        !           283:                       Fcons (build_string (new), Qnil));
        !           284:   close (fd);
        !           285: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.