You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							137 lines
						
					
					
						
							2.8 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							137 lines
						
					
					
						
							2.8 KiB
						
					
					
				| #include <stdio.h> | |
| #include "util.h" | |
|  | |
| #if (defined(sun) && ! defined(sparc)) || defined(vax) | |
|  | |
| #include <signal.h> | |
| #include <sys/types.h> | |
| #include <sys/time.h> | |
|  | |
| static char *save_stack_base; | |
| static char *stack_lo_addr; | |
| static char *stack_hi_addr; | |
| static int stack_size; | |
| 
 | |
| static int restart_global_flag; | |
| static char *old_file_name; | |
| static char *new_file_name; | |
| 
 | |
| char *util_save_sp;		/* set by util_restart_save_state() */ | |
| extern char *sbrk(); | |
|  | |
| static void | |
| grow_stack()  | |
| { | |
|     int i, space[256]; | |
| 
 | |
|     for(i = 0; i < 256; i++) { | |
| 	space[i] = 0; | |
|     } | |
|     if ((char *) &i > stack_lo_addr) { | |
| 	grow_stack(); | |
|     } | |
| } | |
| 
 | |
| 
 | |
| /* ARGSUSED */ | |
| static int | |
| handle_sigquit(int sig, int code, struct sigcontext *scp) | |
| { | |
|     if (util_restart_save_state()) { | |
| 	/* we are restarting ! -- return from signal */ | |
| 
 | |
|     } else { | |
| 	/* copy stack to user data space */ | |
| 	stack_lo_addr = util_save_sp; | |
| 	stack_size = stack_hi_addr - stack_lo_addr + 1; | |
| 	save_stack_base = sbrk(stack_size); | |
| 	(void) memcpy(save_stack_base, stack_lo_addr, stack_size); | |
| 
 | |
| 	/* write a new executable */ | |
| 	(void) fprintf(stderr, "Writing executable %s ...\n", new_file_name); | |
| 	(void) util_save_image(old_file_name, new_file_name); | |
| 
 | |
| 	/* terminate if signal was a QUIT */ | |
| 	if (sig == SIGQUIT) { | |
| 	    (void) _exit(1); | |
| 	} | |
|     } | |
| } | |
| 
 | |
| 
 | |
| static void | |
| restart_program() | |
| { | |
|     (void) fprintf(stderr, "Continuing execution ...\n"); | |
| 
 | |
|     /* create the stack */ | |
|     grow_stack(); | |
| 
 | |
| #ifdef vax | |
|     asm("movl _util_save_sp,sp"); | |
| #endif | |
| #ifdef sun | |
|     asm("movl _util_save_sp,sp"); | |
| #endif | |
|  | |
|     /* copy the stack back from user space */ | |
|     (void) memcpy(stack_lo_addr, save_stack_base, stack_size); | |
| 
 | |
|     /* remove the sbrk for the stack */ | |
|     if (sbrk(-stack_size) < 0) { | |
| 	perror("sbrk"); | |
|     } | |
| 
 | |
|     util_restart_restore_state();	/* jump back into handle_sigquit() */ | |
| } | |
|  | |
| void | |
| util_restart(char const *old, char const *neW, int interval) | |
| { | |
|     struct itimerval itimer; | |
| 
 | |
| #ifdef vax | |
| #ifdef ultrix | |
|     stack_hi_addr = (char *) 0x7fffe3ff;	/* ultrix */ | |
| #else | |
|     stack_hi_addr = (char *) 0x7fffebff;	/* bsd 4.3 */ | |
| #endif | |
| #endif | |
| #ifdef sun | |
|     stack_hi_addr = (char *) 0x0effffff;	/* Sun OS 3.2, 3.4 */  | |
| #endif | |
|  | |
|     old_file_name = old; | |
|     new_file_name = neW; | |
| 
 | |
|     (void) signal(SIGQUIT, handle_sigquit); | |
| 
 | |
|     if (interval > 0) { | |
| 	(void) signal(SIGVTALRM, handle_sigquit); | |
| 	itimer.it_interval.tv_sec = interval; | |
| 	itimer.it_interval.tv_usec = 0; | |
| 	itimer.it_value.tv_sec = interval; | |
| 	itimer.it_value.tv_usec = 0; | |
| 	if (setitimer(ITIMER_VIRTUAL, &itimer, (struct itimerval *) 0) < 0) { | |
| 	    perror("setitimer"); | |
| 	    exit(1); | |
| 	} | |
|     } | |
| 
 | |
|     if (restart_global_flag) { | |
| 	restart_program(); | |
|     } | |
|     restart_global_flag = 1; | |
| } | |
| 
 | |
| #else | |
|  | |
| /* ARGSUSED */ | |
| void | |
| util_restart(char const *old, char const *neW, int interval) | |
| { | |
|     (void) fprintf(stderr,  | |
| 	"util_restart: not supported on your operating system/hardware\n"); | |
| } | |
| 
 | |
| #endif
 |