137 lines
2.8 KiB

  1. #include <stdio.h>
  2. #include "util.h"
  3. #if (defined(sun) && ! defined(sparc)) || defined(vax)
  4. #include <signal.h>
  5. #include <sys/types.h>
  6. #include <sys/time.h>
  7. static char *save_stack_base;
  8. static char *stack_lo_addr;
  9. static char *stack_hi_addr;
  10. static int stack_size;
  11. static int restart_global_flag;
  12. static char *old_file_name;
  13. static char *new_file_name;
  14. char *util_save_sp; /* set by util_restart_save_state() */
  15. extern char *sbrk();
  16. static void
  17. grow_stack()
  18. {
  19. int i, space[256];
  20. for(i = 0; i < 256; i++) {
  21. space[i] = 0;
  22. }
  23. if ((char *) &i > stack_lo_addr) {
  24. grow_stack();
  25. }
  26. }
  27. /* ARGSUSED */
  28. static int
  29. handle_sigquit(int sig, int code, struct sigcontext *scp)
  30. {
  31. if (util_restart_save_state()) {
  32. /* we are restarting ! -- return from signal */
  33. } else {
  34. /* copy stack to user data space */
  35. stack_lo_addr = util_save_sp;
  36. stack_size = stack_hi_addr - stack_lo_addr + 1;
  37. save_stack_base = sbrk(stack_size);
  38. (void) memcpy(save_stack_base, stack_lo_addr, stack_size);
  39. /* write a new executable */
  40. (void) fprintf(stderr, "Writing executable %s ...\n", new_file_name);
  41. (void) util_save_image(old_file_name, new_file_name);
  42. /* terminate if signal was a QUIT */
  43. if (sig == SIGQUIT) {
  44. (void) _exit(1);
  45. }
  46. }
  47. }
  48. static void
  49. restart_program()
  50. {
  51. (void) fprintf(stderr, "Continuing execution ...\n");
  52. /* create the stack */
  53. grow_stack();
  54. #ifdef vax
  55. asm("movl _util_save_sp,sp");
  56. #endif
  57. #ifdef sun
  58. asm("movl _util_save_sp,sp");
  59. #endif
  60. /* copy the stack back from user space */
  61. (void) memcpy(stack_lo_addr, save_stack_base, stack_size);
  62. /* remove the sbrk for the stack */
  63. if (sbrk(-stack_size) < 0) {
  64. perror("sbrk");
  65. }
  66. util_restart_restore_state(); /* jump back into handle_sigquit() */
  67. }
  68. void
  69. util_restart(char const *old, char const *neW, int interval)
  70. {
  71. struct itimerval itimer;
  72. #ifdef vax
  73. #ifdef ultrix
  74. stack_hi_addr = (char *) 0x7fffe3ff; /* ultrix */
  75. #else
  76. stack_hi_addr = (char *) 0x7fffebff; /* bsd 4.3 */
  77. #endif
  78. #endif
  79. #ifdef sun
  80. stack_hi_addr = (char *) 0x0effffff; /* Sun OS 3.2, 3.4 */
  81. #endif
  82. old_file_name = old;
  83. new_file_name = neW;
  84. (void) signal(SIGQUIT, handle_sigquit);
  85. if (interval > 0) {
  86. (void) signal(SIGVTALRM, handle_sigquit);
  87. itimer.it_interval.tv_sec = interval;
  88. itimer.it_interval.tv_usec = 0;
  89. itimer.it_value.tv_sec = interval;
  90. itimer.it_value.tv_usec = 0;
  91. if (setitimer(ITIMER_VIRTUAL, &itimer, (struct itimerval *) 0) < 0) {
  92. perror("setitimer");
  93. exit(1);
  94. }
  95. }
  96. if (restart_global_flag) {
  97. restart_program();
  98. }
  99. restart_global_flag = 1;
  100. }
  101. #else
  102. /* ARGSUSED */
  103. void
  104. util_restart(char const *old, char const *neW, int interval)
  105. {
  106. (void) fprintf(stderr,
  107. "util_restart: not supported on your operating system/hardware\n");
  108. }
  109. #endif