Add signal handling.
diff --git a/scaffold.go b/scaffold.go
index 0bfdc51..44fbcb2 100644
--- a/scaffold.go
+++ b/scaffold.go
@@ -2,17 +2,31 @@
 
 import (
 	"encoding/json"
+	"errors"
+	"fmt"
 	"net"
 	"net/http"
+	"os"
+	"os/signal"
+	"runtime"
+	"syscall"
 	"time"
 )
 
 const (
-	// DefaultGraceTimeout is the default amount of time to wait for a request to complete
+	// DefaultGraceTimeout is the default amount of time to wait for a request
+	// to complete. Default is 30 seconds, which is also the default grace period
+	// in Kubernetes.
 	DefaultGraceTimeout = 30 * time.Second
 )
 
 /*
+ErrSignalCaught is used in the "Shutdown" mechanism when the shutdown was
+caused by a SIGINT or SIGTERM.
+*/
+var ErrSignalCaught = errors.New("Caught shutdown signal")
+
+/*
 An HTTPScaffold provides a set of features on top of a standard HTTP
 listener. It includes an HTTP handler that may be plugged in to any
 standard Go HTTP server. It is intended to be placed before any other
@@ -20,6 +34,7 @@
 */
 type HTTPScaffold struct {
 	insecurePort     int
+	open             bool
 	tracker          *requestTracker
 	insecureListener net.Listener
 }
@@ -52,6 +67,9 @@
 
 /*
 Open opens up the port that was created when the scaffold was set up.
+This method is optional. It may be called before Listen so that we can
+retrieve the actual address where the server is listening before we actually
+start to listen.
 */
 func (s *HTTPScaffold) Open() error {
 	s.tracker = startRequestTracker(DefaultGraceTimeout)
@@ -63,6 +81,7 @@
 		return err
 	}
 	s.insecureListener = il
+	s.open = true
 	return nil
 }
 
@@ -80,15 +99,26 @@
 Listen will block until the server is shutdown using "Shutdown" or one of
 the other shutdown mechanisms. It must not be called until after "Open"
 has been called.
+If shut down, Listen will return the error that was passed to the "shutdown"
+method.
 */
-func (s *HTTPScaffold) Listen(baseHandler http.Handler) {
+func (s *HTTPScaffold) Listen(baseHandler http.Handler) error {
+	if !s.open {
+		err := s.Open()
+		if err != nil {
+			return err
+		}
+		s.open = true
+	}
+
 	handler := &httpHandler{
 		s:       s,
 		handler: baseHandler,
 	}
 	go http.Serve(s.insecureListener, handler)
-	<-s.tracker.C
+	err := <-s.tracker.C
 	s.insecureListener.Close()
+	return err
 }
 
 /*
@@ -101,12 +131,47 @@
 }
 
 /*
-CatchSignals directs the scaffold to catch SIGINT and SIGTERM (the signals
-sent by "Control-C" and "kill" by default) to trigger the markdown
-logic. Using this logic, when these signals are caught, the server will
-catch
+CatchSignals directs the scaffold to listen for common signals. It catches
+three signals. SIGINT (aka control-C) and SIGTERM (what "kill" sends by default)
+will cause the program to be marked down, and "SignalCaught" will be returned
+by the "Listen" method. SIGHUP ("kill -1" or "kill -HUP") will cause the
+stack trace of all the threads to be printed to stderr, just like a Java program.
 */
 func (s *HTTPScaffold) CatchSignals() {
+	sigChan := make(chan os.Signal, 1)
+	signal.Notify(sigChan, syscall.SIGINT)
+	signal.Notify(sigChan, syscall.SIGTERM)
+	signal.Notify(sigChan, syscall.SIGHUP)
+
+	go func() {
+		for {
+			sig := <-sigChan
+			switch sig {
+			case syscall.SIGINT, syscall.SIGTERM:
+				s.Shutdown(ErrSignalCaught)
+				signal.Reset()
+				return
+			case syscall.SIGHUP:
+				dumpStack()
+			}
+		}
+	}()
+}
+
+func dumpStack() {
+	stackSize := 32767
+	stackBuf := make([]byte, stackSize)
+	var w int
+
+	for w < stackSize {
+		w = runtime.Stack(stackBuf, true)
+		if w == stackSize {
+			stackSize *= 2
+			stackBuf = make([]byte, stackSize)
+		}
+	}
+
+	fmt.Fprint(os.Stderr, string(stackBuf[:w]))
 }
 
 type httpHandler struct {
diff --git a/scaffold_test.go b/scaffold_test.go
index 9422a94..8ba7c46 100644
--- a/scaffold_test.go
+++ b/scaffold_test.go
@@ -13,15 +13,15 @@
 var _ = Describe("Scaffold Tests", func() {
 	It("Validate framework", func() {
 		s := CreateHTTPScaffold()
-		stopChan := make(chan bool)
+		stopChan := make(chan error)
 		err := s.Open()
 		Expect(err).Should(Succeed())
 
 		go func() {
 			fmt.Fprintf(GinkgoWriter, "Gonna listen on %s\n", s.InsecureAddress())
-			s.Listen(&testHandler{})
+			stopErr := s.Listen(&testHandler{})
 			fmt.Fprintf(GinkgoWriter, "Done listening\n")
-			stopChan <- true
+			stopChan <- stopErr
 		}()
 
 		Eventually(func() bool {
@@ -30,8 +30,9 @@
 		resp, err := http.Get(fmt.Sprintf("http://%s", s.InsecureAddress()))
 		Expect(err).Should(Succeed())
 		Expect(resp.StatusCode).Should(Equal(200))
-		s.Shutdown(errors.New("Validate"))
-		Eventually(stopChan).Should(Receive(BeTrue()))
+		shutdownErr := errors.New("Validate")
+		s.Shutdown(shutdownErr)
+		Eventually(stopChan).Should(Receive(Equal(shutdownErr)))
 	})
 
 	It("Shutdown", func() {