[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);
+}