+ /*
+ * should not be reached
+ */
+ return (0);
+}
+
+static int
+sd_openlog(vfs_context_t ctx)
+{
+ int error = 0;
+ struct timeval tv;
+
+ /* Open shutdown log */
+ if ((error = vnode_open(PROC_SHUTDOWN_LOG, (O_CREAT | FWRITE | O_NOFOLLOW), 0644, 0, &sd_logvp, ctx))) {
+ printf("Failed to open %s: error %d\n", PROC_SHUTDOWN_LOG, error);
+ sd_logvp = NULLVP;
+ return error;
+ }
+
+ vnode_setsize(sd_logvp, (off_t)0, 0, ctx);
+
+ /* Write a little header */
+ microtime(&tv);
+ sd_log(ctx, "Process shutdown log. Current time is %lu (in seconds).\n\n", tv.tv_sec);
+
+ return 0;
+}
+
+static int
+sd_closelog(vfs_context_t ctx)
+{
+ int error = 0;
+ if (sd_logvp != NULLVP) {
+ VNOP_FSYNC(sd_logvp, MNT_WAIT, ctx);
+ error = vnode_close(sd_logvp, FWRITE, ctx);
+ }
+
+ return error;
+}
+
+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);
+
+}