+static void
+sd_log(vfs_context_t ctx, const char *fmt, ...)
+{
+ int resid, log_error, len;
+ char logbuf[100];
+ va_list arglist;
+
+ /* If the log isn't open yet, open it */
+ if (sd_logvp == NULLVP) {
+ if (sd_openlog(ctx) != 0) {
+ /* Couldn't open, we fail out */
+ return;
+ }
+ }
+
+ va_start(arglist, fmt);
+ len = vsnprintf(logbuf, sizeof(logbuf), fmt, arglist);
+ log_error = vn_rdwr(UIO_WRITE, sd_logvp, (caddr_t)logbuf, len, sd_log_offset,
+ UIO_SYSSPACE, IO_UNIT | IO_NOAUTH, vfs_context_ucred(ctx), &resid, vfs_context_proc(ctx));
+ if (log_error == EIO || log_error == 0) {
+ sd_log_offset += (len - resid);
+ }
+
+ va_end(arglist);
+
+}
+
+static int
+sd_filt1(proc_t p, void * args)
+{
+ proc_t self = current_proc();
+ struct sd_filterargs * sf = (struct sd_filterargs *)args;
+ int delayterm = sf-> delayterm;
+ int shutdownstate = sf->shutdownstate;
+
+ if (((p->p_flag&P_SYSTEM) != 0) || (p->p_ppid == 0)
+ ||(p == self) || (p->p_stat == SZOMB)
+ || (p->p_shutdownstate != shutdownstate)
+ ||((delayterm == 0) && ((p->p_lflag& P_LDELAYTERM) == P_LDELAYTERM))
+ || ((p->p_sigcatch & sigmask(SIGTERM))== 0)) {
+ return(0);
+ }
+ else
+ return(1);
+}
+
+
+static int
+sd_callback1(proc_t p, void * args)
+{
+ struct sd_iterargs * sd = (struct sd_iterargs *)args;
+ int signo = sd->signo;
+ int setsdstate = sd->setsdstate;
+ int countproc = sd->countproc;
+
+ proc_lock(p);
+ p->p_shutdownstate = setsdstate;
+ if (p->p_stat != SZOMB) {
+ proc_unlock(p);
+ if (countproc != 0) {
+ proc_list_lock();
+ p->p_listflag |= P_LIST_EXITCOUNT;
+ proc_shutdown_exitcount++;
+ proc_list_unlock();
+ }
+
+ psignal(p, signo);
+ if (countproc != 0)
+ sd->activecount++;
+ } else
+ proc_unlock(p);
+ return(PROC_RETURNED);
+}
+
+static int
+sd_filt2(proc_t p, void * args)
+{
+ proc_t self = current_proc();
+ struct sd_filterargs * sf = (struct sd_filterargs *)args;
+ int delayterm = sf-> delayterm;
+ int shutdownstate = sf->shutdownstate;
+
+ if (((p->p_flag&P_SYSTEM) != 0) || (p->p_ppid == 0)
+ ||(p == self) || (p->p_stat == SZOMB)
+ || (p->p_shutdownstate == shutdownstate)
+ ||((delayterm == 0) && ((p->p_lflag& P_LDELAYTERM) == P_LDELAYTERM))) {
+ return(0);
+ }
+ else
+ return(1);
+}
+
+static int
+sd_callback2(proc_t p, void * args)
+{
+ struct sd_iterargs * sd = (struct sd_iterargs *)args;
+ int signo = sd->signo;
+ int setsdstate = sd->setsdstate;
+ int countproc = sd->countproc;
+
+ proc_lock(p);
+ p->p_shutdownstate = setsdstate;
+ if (p->p_stat != SZOMB) {
+ proc_unlock(p);
+ if (countproc != 0) {
+ proc_list_lock();
+ p->p_listflag |= P_LIST_EXITCOUNT;
+ proc_shutdown_exitcount++;
+ proc_list_unlock();
+ }
+ psignal(p, signo);
+ if (countproc != 0)
+ sd->activecount++;
+ } else
+ proc_unlock(p);
+
+ return(PROC_RETURNED);
+
+}
+
+static int
+sd_callback3(proc_t p, void * args)
+{
+ struct sd_iterargs * sd = (struct sd_iterargs *)args;
+ vfs_context_t ctx = vfs_context_current();
+
+ int setsdstate = sd->setsdstate;
+
+ proc_lock(p);
+ p->p_shutdownstate = setsdstate;
+ if (p->p_stat != SZOMB) {
+ /*
+ * NOTE: following code ignores sig_lock and plays
+ * with exit_thread correctly. This is OK unless we
+ * are a multiprocessor, in which case I do not
+ * understand the sig_lock. This needs to be fixed.
+ * XXX
+ */
+ if (p->exit_thread) { /* someone already doing it */
+ proc_unlock(p);
+ /* give him a chance */
+ thread_block(THREAD_CONTINUE_NULL);
+ } else {
+ p->exit_thread = current_thread();
+ printf(".");
+
+ sd_log(ctx, "%s[%d] had to be forced closed with exit1().\n", p->p_comm, p->p_pid);
+
+ proc_unlock(p);
+ KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_FRCEXIT) | DBG_FUNC_NONE,
+ p->p_pid, 0, 1, 0, 0);
+ sd->activecount++;
+ exit1(p, 1, (int *)NULL);
+ }
+ } else
+ proc_unlock(p);
+
+ return(PROC_RETURNED);
+}
+
+