[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: mint 1.12



Hello!

As the sync and shutdown patches did not make it into mint 1.12, here
they are again, this time relative to mint 1.12. However, there is a
small difference, a bug fix. Now the reboot or halt can be done from
any terminal, without hanging if the parent process exits...

Regards,
Ulrich

--
+---------------+----------------------------+-----------------------+
| Ulrich Kuehn  | Internet:                  | Life is uncertain --  |
| Cand.Math.Inf | kuehn@math.uni-muenster.de | eat the dessert first |
+---------------+----------------------------+-----------------------+

-------if you cut here, you will probably destroy your monitor---------
diff -uw old/debug.c ./debug.c
--- old/debug.c	Mon Nov 14 11:36:08 1994
+++ ./debug.c	Thu Nov 17 15:58:46 1994
@@ -522,6 +522,71 @@
 }
 
 
+/* uk: a normal halt() function without an error message. This function
+ *     may only be called if all processes are shut down and the file
+ *     systems are synced.
+ */
+
+static const char *haltmsg[MAXLANG] = {
+"System halted.\r\n",
+"System angehalten.\r\n",	/* German */
+"System halted.\r\n",		/* French */
+"System halted.\r\n",		/* UK */
+"System halted.\r\n",		/* Spanish */
+"System halted.\r\n"		/* Italian */
+};
+
+
+EXITING
+void halt()
+{
+	long r;
+	long key;
+	int scan;
+	extern long tosssp;	/* in main.c */
+#ifdef PROFILING
+	extern EXITING _exit P_((int)) NORETURN;
+#endif
+	restr_intr();	/* restore interrupts to normal */
+#ifdef DEBUG_INFO
+	debug_ws("halt() called, system halting...\r\n");
+#else
+	debug_ws(haltmsg[gl_lang]);
+#endif
+	sys_q[READY_Q] = 0;	/* prevent context switches */
+
+	for(;;) {
+		/* get a key; if ctl-alt then do it, else halt */
+		key = Bconin(out_device);
+		if ((key & 0x0c000000L) == 0x0c000000L) {
+			scan = (int) ((key >> 16) & 0xff);
+			do_func_key(scan);
+		}
+		else {
+			break;
+		}
+	}
+	for(;;) {
+		debug_ws(haltmsg[gl_lang]);
+		r = Bconin(2);
+
+		if ((r & 0x0ff) == 'x') {
+			extern int no_mem_prot;
+			if (!no_mem_prot)
+				restr_mmu();
+			restr_screen();
+			(void)Super((void *)tosssp);	/* gratuitous (void *) for Lattice */
+#ifdef PROFILING
+			_exit(0);
+#else
+			Pterm0();
+#endif
+		}
+	}
+}
+
+
+
 static const char *rebootmsg[MAXLANG] = {
 "FATAL ERROR. You must reboot the system.\r\n",
 "FATALER FEHLER. Das System mu? neu gestartet werden.\r\n",	/* German */
@@ -564,9 +629,17 @@
 		debug_ws(rebootmsg[gl_lang]);
 		r = Bconin(2);
 
-		if ( (r & 0x0ff) == 'x' ) {
+		if ( ((r & 0x0ff) == 'x') || ((r & 0xff) == 's') ) {
 			extern int no_mem_prot;
 			close_filesys();
+
+			/* if the user pressed 's', try to sync before halting the system */
+			if ((r & 0xff) == 's')
+			{
+				debug_ws("Syncing...");
+				s_ync();
+				debug_ws("done.\r\n");
+			}
 			if (!no_mem_prot)
 				restr_mmu();
 			restr_screen();
@@ -594,7 +667,7 @@
 
 	switch (scan) {
 	case DEL:
-		reboot();
+		s_hutdown(1);
 		break;
 	case UNDO:
 		killgroup(con_tty.pgrp, SIGQUIT, 1);
diff -uw old/dos.c ./dos.c
--- old/dos.c	Mon Nov 14 12:28:38 1994
+++ ./dos.c	Thu Nov 17 16:05:20 1994
@@ -777,6 +777,98 @@
 	return 0;
 }
 
+/* uk: shutdown function
+ *     if the parameter is nonzero, reboot the machine, otherwise
+ *     halt it after syncing the file systems.
+ */
+
+/* this is mostly from main.c:
+ * shut down processes; this involves waking them all up, and sending
+ * them SIGTERM to give them a chance to clean up after themselves
+ */
+
+static void
+shutmedown(p)
+	PROC *p;
+{
+	wake(WAIT_Q, (long)s_hutdown);
+	p->wait_cond = 0;
+}
+
+long ARGS_ON_STACK
+s_hutdown(long restart)
+{
+	/* only root may shut down the system */
+	if ((curproc->euid == 0) || (curproc->ruid == 0))
+	{
+		PROC *p;
+		int proc_left = 0;
+
+		DEBUG(("Shutting processes down..."));
+		DEBUG(("This is pid %d", curproc->pid));
+
+		/* Ignore signals, that could terminate this process */
+		curproc->sighandle[SIGCHLD] = SIG_IGN;
+		curproc->sighandle[SIGTERM] = SIG_IGN;
+		curproc->sighandle[SIGABRT] = SIG_IGN;
+		curproc->sighandle[SIGQUIT] = SIG_IGN;
+		curproc->sighandle[SIGHUP] = SIG_IGN;
+
+		for (p = proclist; p; p = p->gl_next) {
+			if (p->pid == 0) continue;
+			if (p == curproc) continue;  /* curproc is trapped in this code */
+			if (p->wait_q != ZOMBIE_Q && p->wait_q != TSR_Q) {
+				if (p->wait_q != READY_Q) {
+	 				short sr = spl7();
+					rm_q(p->wait_q, p);
+					add_q(READY_Q, p);
+					spl(sr);
+				}
+				DEBUG(("Posting SIGTERM for pid %d", p->pid));
+				post_sig(p, SIGTERM);
+				proc_left++;
+			}
+		}
+
+		if (proc_left) {
+			/* sleep a little while, to give the other processes a chance to
+			   shut down
+			 */
+
+			if (addtimeout(1000, shutmedown))
+				do {
+					DEBUG(("Sleeping..."));
+					sleep(WAIT_Q, (long)s_hutdown);
+				} while (curproc->wait_cond == (long)s_hutdown);
+
+			DEBUG(("Killing all processes..."));
+			for (p = proclist; p; p = p->gl_next)
+			{
+				if ((p->pid == 0) || (p == curproc))
+					continue;
+				DEBUG(("Posting SIGKILL for pid %d", p->pid));
+				post_sig(p, SIGKILL);
+			}
+		}
+		sys_q[READY_Q] = 0;
+		DEBUG(("Syncing file systems..."));
+		close_filesys();
+		s_ync();   /* additional sync() */
+		if (restart)
+		{
+			DEBUG(("Rebooting..."));
+			reboot();
+		}
+		else
+		{
+			DEBUG(("Halting system..."));
+			halt();
+		}
+	}
+	return EACCDN;	
+}
+
+
 /*
  * routine for initializing DOS
  *
@@ -921,7 +1013,10 @@
 	dos_tab[0x148] = p_setgroups;
 	dos_tab[0x149] = t_setitimer;
 
-	/* 0x14a-0x151 reserved */
+	/* 0x14a-0x149 reserved */
+
+	dos_tab[0x150] = s_ync;
+	dos_tab[0x151] = s_hutdown;
 
 	dos_tab[0x152] = d_readlabel;
 	dos_tab[0x153] = d_writelabel;
diff -uw old/file.h ./file.h
--- old/file.h	Mon Nov 14 12:12:10 1994
+++ ./file.h	Thu Nov 17 15:59:48 1994
@@ -160,6 +160,7 @@
 #define FS_NOXBIT	0x04	/* if a file can be read, it can be executed */
 #define	FS_LONGPATH	0x08	/* file system understands "size" argument to
 				   "getname" */
+#define FS_DO_SYNC    0x20  /* file system has a sync function */
 	long	ARGS_ON_STACK (*root) P_((int drv, fcookie *fc));
 	long	ARGS_ON_STACK (*lookup) P_((fcookie *dir, const char *name, fcookie *fc));
 	long	ARGS_ON_STACK (*creat) P_((fcookie *dir, const char *name, unsigned mode,
@@ -192,6 +193,7 @@
 	long	ARGS_ON_STACK (*dskchng) P_((int drv));
 	long	ARGS_ON_STACK (*release) P_((fcookie *));
 	long	ARGS_ON_STACK (*dupcookie) P_((fcookie *new, fcookie *old));
+	long	ARGS_ON_STACK (*sync) P_((void));
 } FILESYS;
 
 /*
diff -uw old/filesys.c ./filesys.c
--- old/filesys.c	Tue Aug 30 07:55:44 1994
+++ ./filesys.c	Thu Nov 17 15:59:52 1994
@@ -113,6 +113,26 @@
 	unifs_init();
 }
 
+
+/* uk: go through the list of file systems and call their sync() function
+ *     if they wish to.
+ */
+long
+s_ync()
+{
+	FILESYS *fs;
+
+	TRACE(("Syncing file systems..."));
+	for (fs = active_fs;  fs;  fs = fs->next)
+	{
+		if (fs->fsflags & FS_DO_SYNC)
+			(*fs->sync)();
+	}
+	TRACE(("Syncing done."));
+	return 0;
+}
+
+
 /*
  * load file systems from disk
  * this routine is called after process 0 is set up, but before any user
diff -uw old/main.c ./main.c
--- old/main.c	Tue Nov 15 18:08:50 1994
+++ ./main.c	Thu Nov 17 15:59:54 1994
@@ -184,6 +184,8 @@
 
 extern Func bios_tab[], dos_tab[];
 
+extern long sync_time;
+
 /* kernel info that is passed to loaded file systems and device drivers */
 
 struct kerinfo kernelinfo = {
@@ -564,6 +566,8 @@
 			sleep(WAIT_Q, (long)shutdown);
 		} while (curproc->wait_cond == (long)shutdown);
 	}
+	/* uk: do an additional sync for the file systems */
+	s_ync();
 }
 
 #if defined(__GNUC__) || defined(__MINT__)
@@ -589,6 +593,8 @@
 	long yn;
 	FILEPTR *f;
 
+	extern void start_sysupdate();
+	
 #if defined(__GNUC__) || defined(__MINT__)
 	UNUSED(envp);
 #endif
@@ -851,6 +857,9 @@
 /* load the configuration file */
 	load_config();
 
+/* start system update daemon */
+	start_sysupdate();
+
 	*((long *)0x4c2L) |= PSEUDODRVS;
 
 	if (init_env == 0)
@@ -1145,6 +1154,7 @@
  * DEBUG_DEVNO=n	-- set debug device number to (decimal number) n
  * HARDSCROLL=n		-- set hard-scroll size to n, range 0-99.
  * SLICES=nnn		-- set multitasking granularity
+ * UPDATE=n   -- set the sync time in seconds for the system update daemon
  * echo message		-- print a message on the screen
  * alias drive path	-- make a fake drive pointing at a path
  * cd dir		-- change directory/drive
@@ -1273,6 +1283,14 @@
 	if (!strcmp(name, "PSEUDODRIVES")) {
 		FORCE("PSEUDODRIVES= no longer supported");
 		return;
+	}
+
+	/* uk: set update time for system update daemon */
+	if (!strcmp(name, "UPDATE")) {
+		extern long sync_time;
+
+		sync_time = atol(val);
+		return;
 	}
 	FORCE("Unknown variable `%s'", name);
 }
diff -uw old/makefile ./makefile
--- old/makefile	Tue Nov 15 18:46:10 1994
+++ ./makefile	Thu Nov 17 16:01:42 1994
@@ -60,17 +60,20 @@
 COBJS = bios.o xbios.o console.o dos.o dosdir.o dosfile.o dosmem.o dossig.o \
 	filesys.o main.o mem.o proc.o signal.o timeout.o tty.o util.o \
 	biosfs.o pipefs.o procfs.o tosfs.o debug.o rendez.o \
-	unifs.o shmfs.o fasttext.o welcome.o nalloc2.o memprot.o realloc.o
+	unifs.o shmfs.o fasttext.o welcome.o nalloc2.o memprot.o realloc.o \
+	update.o
 
 COBJS030 = bios.o0 xbios.o0 console.o0 dos.o0 dosdir.o0 dosfile.o0 dosmem.o0 dossig.o0 \
 	filesys.o0 main.o0 mem.o0 proc.o0 signal.o0 timeout.o0 tty.o0 util.o0 \
 	biosfs.o0 pipefs.o0 procfs.o0 tosfs.o0 debug.o0 rendez.o0 \
-	unifs.o0 shmfs.o0 fasttext.o0 welcome.o0 nalloc2.o0 memprot.o realloc.o0
+	unifs.o0 shmfs.o0 fasttext.o0 welcome.o0 nalloc2.o0 memprot.o realloc.o0 \
+	update.o
 
 CFILES = bios.c xbios.c console.c dos.c dosdir.c dosfile.c dosmem.c dossig.c \
 	filesys.c main.c mem.c proc.c signal.c timeout.c tty.c util.c \
 	biosfs.c pipefs.c procfs.c tosfs.c debug.c rendez.c \
-	unifs.c shmfs.c fasttext.c welcome.c nalloc2.c memprot.c realloc.c
+	unifs.c shmfs.c fasttext.c welcome.c nalloc2.c memprot.c realloc.c \
+	update.c
 
 HFILES = assert.h atarierr.h basepage.h cookie.h ctype.h debug.h fasttext.h \
 	file.h inline.h loadave.h mem.h mint.h proc.h proto.h signal.h sproto.h \
diff -uw old/proto.h ./proto.h
--- old/proto.h	Mon Nov 14 14:07:00 1994
+++ ./proto.h	Thu Nov 17 16:08:24 1994
@@ -102,6 +102,7 @@
 long ARGS_ON_STACK s_ysconf P_((int which));
 long ARGS_ON_STACK s_alert P_((char *msg));
 long ARGS_ON_STACK s_uptime P_((unsigned long *cur_uptim, unsigned long loadave[3]));
+long ARGS_ON_STACK s_hutdown P_((long restart));
 void init_dos P_((void));
 
 /* dosdir.c */
@@ -193,6 +194,7 @@
 void load_filesys P_((void));
 void load_devdriver P_((void));
 void close_filesys P_((void));
+long s_ync P_((void));
 void ARGS_ON_STACK changedrv P_((unsigned drv));
 int disk_changed P_((int drv));
 long relpath2cookie
@@ -389,6 +391,7 @@
 void ARGS_ON_STACK FORCE P_((const char *s, ...));
 void PAUSE P_((void));
 EXITING void ARGS_ON_STACK FATAL P_((const char *s, ...)) NORETURN;
+EXITING void halt P_((void)) NORETURN;
 EXITING void HALT P_((void)) NORETURN;
 void DUMPLOG P_((void));
 void do_func_key P_((int));
@@ -423,3 +426,6 @@
 
 /* welcome.c */
 int boot_kernel_p P_((void));
+
+/* update.c */
+void start_sysupdate P_((void));
diff -uw old/update.c ./update.c
--- old/update.c	Thu Nov 17 16:12:00 1994
+++ ./update.c	Thu Nov 17 16:08:56 1994
@@ -0,0 +1,72 @@
+/* uk: this is the system update daemon, its only purpose is to call
+ *     Sync() in regular intervals, so file systems get their sync()
+ *     function called.
+ */
+
+#include <mintbind.h>
+
+#include "mint.h"
+
+#ifndef Sync    /* temporary hack for gnu c */
+#ifdef __GNUC__
+#define Sync() (void)(trap_1_w(0x150))
+#endif
+#endif
+
+long update_stksize = 1024;
+long sync_time = 5;
+
+
+void do_sync(long);
+void update(long);
+
+
+void
+do_sync(long sig)
+{
+	Sync();
+}
+
+void
+update(long bp)
+{
+	setstack(bp+256+update_stksize);
+	Psignal(SIGALRM, do_sync);
+	Psignal(SIGTERM, do_sync);
+	Psignal(SIGQUIT, do_sync);
+	Psignal(SIGHUP, do_sync);
+	Psignal(SIGTSTP, do_sync);
+	Psignal(SIGINT, do_sync);
+	Psignal(SIGABRT, do_sync);
+	Psignal(SIGUSR1, do_sync);
+	Psignal(SIGUSR2, do_sync);
+
+	for (;;)
+	{
+		int tsync;
+		tsync = sync_time;
+		while (tsync > 32)
+		{
+			(void)Fselect(32000, 0L, 0L, 0L);
+			tsync -= 32;
+		}
+		if (tsync > 0)
+			(void)Fselect(tsync*1000L, 0L, 0L, 0L);
+			do_sync(0);
+	}
+}
+
+
+/* start a new asynchronous process */
+void
+start_sysupdate()
+{
+	BASEPAGE *b;
+	int pid;
+
+	b = (BASEPAGE*)p_exec(5, 0L, "", 0L);  /* create basepage */
+	(void)m_shrink(0, (virtaddr)b, 256+update_stksize);
+	b->p_tbase = (long)update;
+	b->p_hitpa = (long)b +256+update_stksize;
+	pid = (short)p_exec(104, "sysupdate", b, 0L);
+}