cmd/autogazelle/server_unix.go
func runServer() error {
	// Begin logging to the log file.
	logFile, err := os.OpenFile(*logPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		return err
	}
	defer logFile.Close()
	log.SetOutput(logFile)

	// Start listening on the socket before other initialization work. The client
	// will dial immediately after starting the server, and we don't want
	// the client to time out.
	os.Remove(*socketPath)
	ln, err := net.Listen("unix", *socketPath)
	if err != nil {
		return err
	}
	uln := ln.(*net.UnixListener)
	uln.SetUnlinkOnClose(true)
	defer ln.Close()
	if err := uln.SetDeadline(time.Now().Add(*serverTimeout)); err != nil {
		return err
	}
	log.Printf("started server with pid %d", os.Getpid())

	// Copy BUILD.in files to BUILD.
	restoreBuildFilesInRepo()

	// Listen for file writes within the repository.
	cancelWatch, err := watchDir(".", recordWrite)
	isWatching := err == nil
	if err != nil {
		log.Print(err)
	}
	if isWatching {
		defer cancelWatch()
	}

	// Wait for clients to connect. Each time the client connects, we run
	// gazelle, either in the whole repository or in changed directories.
	mode := fullMode
	for {
		c, err := ln.Accept()
		if err != nil {
			if operr, ok := err.(*net.OpError); ok {
				if operr.Timeout() {
					return nil
				}
				if operr.Temporary() {
					log.Printf("temporary watch error: %v", err)
					continue
				}
			}
			return err
		}

		log.SetOutput(io.MultiWriter(c, logFile))
		dirs := getAndClearWrittenDirs()
		for _, dir := range dirs {
			restoreBuildFilesInDir(dir)
		}
		if err := runGazelle(mode, dirs); err != nil {
			log.Print(err)
		}
		log.SetOutput(logFile)
		c.Close()
		if isWatching {
			mode = fastMode
		}
	}
}
func runServer() error {
	// Begin logging to the log file.
	logFile, err := os.OpenFile(*logPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		return err
	}
	defer logFile.Close()
	log.SetOutput(logFile)

	// Start listening on the socket before other initialization work. The client
	// will dial immediately after starting the server, and we don't want
	// the client to time out.
	os.Remove(*socketPath)
	ln, err := net.Listen("unix", *socketPath)
	if err != nil {
		return err
	}
	uln := ln.(*net.UnixListener)
	uln.SetUnlinkOnClose(true)
	defer ln.Close()
	if err := uln.SetDeadline(time.Now().Add(*serverTimeout)); err != nil {
		return err
	}
	log.Printf("started server with pid %d", os.Getpid())

	// Copy BUILD.in files to BUILD.
	restoreBuildFilesInRepo()

	// Listen for file writes within the repository.
	cancelWatch, err := watchDir(".", recordWrite)
	isWatching := err == nil
	if err != nil {
		log.Print(err)
	}
	if isWatching {
		defer cancelWatch()
	}

	// Wait for clients to connect. Each time the client connects, we run
	// gazelle, either in the whole repository or in changed directories.
	mode := fullMode
	for {
		c, err := ln.Accept()
		if err != nil {
			if operr, ok := err.(*net.OpError); ok {
				if operr.Timeout() {
					return nil
				}
				if operr.Temporary() {
					log.Printf("temporary watch error: %v", err)
					continue
				}
			}
			return err
		}

		log.SetOutput(io.MultiWriter(c, logFile))
		dirs := getAndClearWrittenDirs()
		for _, dir := range dirs {
			restoreBuildFilesInDir(dir)
		}
		if err := runGazelle(mode, dirs); err != nil {
			log.Print(err)
		}
		log.SetOutput(logFile)
		c.Close()
		if isWatching {
			mode = fastMode
		}
	}
}
// runServer performs the main work of the server. Once started, the server
// will:
//
// * Copy BUILD.in and BUILD.bazel.in files to BUILD and BUILD.bazel.
// * Watch for file system writes in the whole repository.
// * Listen for clients on a UNIX-domain socket.
//
// When the server accepts a connection, it runs Gazelle. On the first run,
// it runs Gazelle on the entire repository. On subsequent runs, it runs
// Gazelle only in directories that have changed.
//
// The server stops after being idle for a while. It can also be stopped
// with SIGINT or SIGTERM.