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
							 |