lib9p

Go 9P library.
Log | Files | Refs | LICENSE

main.go (1752B)


      1 /*
      2 Semfs is a semaphore file system.
      3 The original idea is from this book ([Ballesteros 2006]).
      4 
      5 You can mount this file system via 9P using 9pfuse for example.
      6 The file system is initially empty, and you can make files on it.
      7 Each file represents a semaphore length of which is the number of tickets.
      8 To add tickets to an file, write the number of tickets to be added to the file.
      9 To consume a ticket, read the file.
     10 
     11 	$ 9pfuse localhost:5640 /mnt
     12 	$ echo 1 > /mnt/sem
     13 	$ ls -l /mnt/sem
     14 	-rw-rw-rw- 1 kenji kenji 1 Jan 17 08:16 /mnt/sem
     15 	$ cat /mnt/sem
     16 	$ ls -l /mnt/sem
     17 	-rw-rw-rw- 1 kenji kenji 0 Jan 17 08:17 /mnt/sem
     18 
     19 Reading a file with length 0 blocks until someone adds tickets to
     20 the file.
     21 
     22 	$ ls -l /mnt/sem
     23 	-rw-rw-rw- 1 kenji kenji 0 Jan 17 08:17 /mnt/sem
     24 	$ (cat /mnt/sem; echo done) & sleep 1; echo write; echo 1 > /mnt/sem
     25 	[2] 42872
     26 	write
     27 	$ done
     28 
     29 Usage:
     30 
     31 	semfs [-D]
     32 
     33 The Flags are:
     34 
     35 	-D
     36 		print very chatty 9P conversation dialogue to the standard output.
     37 
     38 [Ballesteros 2006]: http://doc.cat-v.org/plan_9/9.intro.pdf
     39 */
     40 package main
     41 
     42 import (
     43 	"context"
     44 	"flag"
     45 	"fmt"
     46 	"log"
     47 	"net"
     48 	"os"
     49 
     50 	"git.mtkn.jp/lib9p"
     51 )
     52 
     53 var dFlag = flag.Bool("D", false, "Prints chatty message to the stderr.")
     54 
     55 func main() {
     56 	flag.Parse()
     57 	if flag.NArg() != 0 {
     58 		fmt.Fprintf(os.Stderr, "usage: %s [-D]\n", os.Args[0])
     59 		os.Exit(1)
     60 	}
     61 	listener, err := net.Listen("tcp", "127.0.0.1:5640")
     62 	if err != nil {
     63 		log.Fatalf("listen tcp: %v", err)
     64 	}
     65 	fsys := &semFS{semfiles: make(map[int]*semFile)}
     66 	s := lib9p.NewServer(fsys)
     67 	if *dFlag {
     68 		s.Chatty()
     69 	}
     70 	for {
     71 		conn, err := listener.Accept()
     72 		if err != nil {
     73 			log.Printf("accept connection: %v", err)
     74 			continue
     75 		}
     76 		go func() {
     77 			defer conn.Close()
     78 			s.Serve(context.TODO(), conn, conn)
     79 		}()
     80 	}
     81 }