home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1938 / pmckpt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  4.7 KB  |  190 lines

  1. #include <sys/types.h>
  2. #include <sys/file.h>
  3. #include <sys/param.h>
  4. #include <signal.h>
  5. #include "pmckpt.h"
  6. #undef main
  7.  
  8. extern char *getenv();
  9. extern char *sbrk();
  10. extern ckpt_main();
  11. extern long tell();
  12. extern long lseek();
  13. extern int brk();
  14.  
  15. #define NUMFDS NOFILE /* portable */
  16. #define NUMSIGS 32 /* XXX */
  17. #define SIGRET void
  18.  
  19. /* XXX: t for text was an original misnomer. Should have been d for data. */
  20. /* XXX: Don't need the end of stack pointer. */
  21. /* XXX: Need BSD timer routines to signal through ckpt_point. */
  22.  
  23. /* XXX: Must initialize all these variables. We assume that the loader */
  24. /* puts symbols in order, with initialized data before uninitialized data. */
  25.  
  26. static int fd = -1; /* must be before sot */
  27. static long ckpt_diskbase = 1;
  28. static char *ckpt_stackbase = "";
  29. static char *ckpt_eotptr = ""; /* end of text pointer */
  30. static char *ckpt_sosptr = ""; /* start of stack pointer */
  31. static char *ckpt_eosptr = ""; /* end of stack pointer */
  32. static char *ckpt_origbrk = "";
  33. static char *ckpt_newbrk = "";
  34. char *ckpt_restore = (char *) 0;
  35. int ckpt_point = -1;
  36. static char ckpt_sot = 'x'; /* start of text */
  37. static char *ckpt_fn = "CHECKPOINT"; /* after sot: should be restored */
  38. static char *ckpt_fntemp = "CHECKPOINT.TEMP";
  39.  
  40. static struct /* restored automatically with the rest of the data */
  41.  {
  42.   /* We should but don't make a lot of effort to restore uids. */
  43.   /* It just wouldn't be portable between BSD and System V if we did. */
  44.   int uid;
  45.   long fpos[NUMFDS];
  46.   SIGRET (*handler[NUMSIGS])();
  47.  }
  48. ustate;
  49.  
  50. static void get_ustate()
  51. {
  52.  int i;
  53.  
  54.  ustate.uid = getuid();
  55.  for (i = 0;i < NUMFDS;i++)
  56.    ustate.fpos[i] = tell(i);
  57.  for (i = 0;i < NUMSIGS;i++)
  58.   {
  59.    /* We assume that no signal arrives in this period. That's stupid. */
  60.    ustate.handler[i] = signal(i,SIG_IGN);
  61.    (void) signal(i,ustate.handler[i]);
  62.   }
  63. }
  64.  
  65. static void set_ustate()
  66. {
  67.  int i;
  68.  
  69.  (void) setuid(ustate.uid); /*XXX*/
  70.  for (i = 0;i < NUMFDS;i++)
  71.    if (ustate.fpos[i] != -1)
  72.      (void) lseek(i,ustate.fpos[i],L_SET); /* XXX: what if fails? */
  73.  for (i = 0;i < NUMSIGS;i++)
  74.   {
  75.    /* XXX: race, race, glorious race */
  76.    (void) signal(i,ustate.handler[i]);
  77.   }
  78. }
  79.  
  80. #define horribly 1
  81.  
  82. static void die(e)
  83. int e;
  84. {
  85.  exit(e); /*XXX*/
  86. }
  87.  
  88. main(argc,argv,envp)
  89. int argc;
  90. char *argv[];
  91. char *envp[];
  92. {
  93.  char ckpt_sos; /* start of stack */
  94.  
  95.  ckpt_point = 0;
  96.  ckpt_origbrk = sbrk(0);
  97.  ckpt_sosptr = &ckpt_sos;
  98.  ckpt_set(&ckpt_eotptr);
  99.  if (!strcmp(argv[0],"CHECKPOINT"))
  100.   {
  101.    if ((fd = open(argv[1],O_RDONLY)) == -1) die(horribly);
  102.    argv += 2;
  103.    if (read(fd,&ckpt_restore,sizeof(ckpt_restore)) == -1) die(horribly);
  104.    if (read(fd,&ckpt_eosptr,sizeof(ckpt_eosptr)) == -1) die(horribly);
  105.    if (read(fd,&ckpt_newbrk,sizeof(ckpt_newbrk)) == -1) die(horribly);
  106.    ckpt_data_restore();
  107.    ckpt_heap_restore();
  108.    ckpt_stackbase = ckpt_sosptr;
  109.    if (ckpt_sosptr - ckpt_eosptr > 0)
  110.      ckpt_diskbase = lseek(fd,0L,L_XTND);
  111.    else
  112.      ckpt_diskbase = tell(fd);
  113.   }
  114.  return ckpt_main(argc,argv,envp);
  115. }
  116.  
  117. void ckpt_data_restore()
  118. {
  119.  /* read in information between &sot and eotptr */
  120.  if (read(fd,&ckpt_sot,ckpt_eotptr - &ckpt_sot) == -1) die(horribly);
  121. }
  122.  
  123. void ckpt_heap_restore()
  124. {
  125.  (void) brk(ckpt_newbrk);
  126.  if (read(fd,ckpt_origbrk,ckpt_newbrk - ckpt_origbrk) == -1) die(horribly);
  127. }
  128.  
  129. void ckpt_increment(left,right)
  130. char *left;
  131. char *right;
  132. {
  133.  if (right - left > 0)
  134.   {
  135.    if (lseek(fd,ckpt_diskbase + (left - ckpt_stackbase),L_SET) == -1)
  136.      die(horribly);
  137.    if (read(fd,left,right - left) == -1)
  138.      die(horribly);
  139.   }
  140.  else
  141.   {
  142.    /* character at ckpt_stackbase - x is at ckpt_diskbase + x */
  143.    if (lseek(fd,ckpt_diskbase - (ckpt_stackbase - right),L_SET) == -1)
  144.      die(horribly);
  145.    if (read(fd,right,left - right) == -1)
  146.      die(horribly);
  147.   }
  148. }
  149.  
  150. void ckpt_stack_restore()
  151. {
  152.  /* read in any final information between sosptr and ckpt_eosptr */
  153.  (void) close(fd);
  154.  set_ustate();
  155.  return;
  156. }
  157.  
  158. void ckpt_save(restore,eosptr)
  159. char *restore;
  160. char *eosptr;
  161. {
  162.  get_ustate();
  163.  if ((fd = open(ckpt_fntemp,O_RDWR | O_CREAT | O_TRUNC,0600)) == -1) return;
  164.  if (write(fd,&restore,sizeof(restore)) == -1) return;
  165.  if (write(fd,&eosptr,sizeof(eosptr)) == -1) return;
  166.  ckpt_newbrk = sbrk(0);
  167.  if (write(fd,&ckpt_newbrk,sizeof(ckpt_newbrk)) == -1) return;
  168.  if (write(fd,&ckpt_sot,ckpt_eotptr - &ckpt_sot) == -1) return;
  169.  if (write(fd,ckpt_origbrk,ckpt_newbrk - ckpt_origbrk) == -1) return;
  170.  if (eosptr - ckpt_sosptr > 0)
  171.   { if (write(fd,ckpt_sosptr,eosptr - ckpt_sosptr) == -1) return; }
  172.  else
  173.   { if (write(fd,eosptr,ckpt_sosptr - eosptr) == -1) return; }
  174.  (void) close(fd);
  175.  if (rename(ckpt_fntemp,ckpt_fn) == -1) return;
  176. }
  177.  
  178. void ckpt_schedule()
  179. {
  180.  ckpt_point = 1;
  181. }
  182.  
  183. void ckpt_init()
  184. {
  185.  if (getenv("CKPTFNTEMP"))
  186.    ckpt_fntemp = getenv("CKPTFNTEMP");
  187.  if (getenv("CKPTFN"))
  188.    ckpt_fn = getenv("CKPTFN");
  189. }
  190.