├── ch01 ├── README.md ├── packageNotUsed.go ├── aSourceFile.go ├── curly.go ├── packageNotUsedUnderscore.go ├── getPackage.go ├── stdIN.go ├── stdOUT.go ├── logFatal.go ├── logPanic.go ├── printing.go ├── stdERR.go ├── cla.go ├── logFiles.go ├── newError.go └── errors.go ├── ch06 ├── htmlT.db ├── text.gotext ├── a.go ├── b.go ├── manyInit.go ├── useAPackage.go ├── ptrFun.go ├── returnPtr.go ├── aPackage.go ├── returnFunction.go ├── funFun.go ├── useSyscall.go ├── html.gohtml ├── textT.go ├── functions.go ├── returnNames.go └── htmlT.go ├── ch02 ├── nodeTreeMore.o ├── callClib │ ├── callC.h │ └── callC.c ├── nodeTree.go ├── justPanic.go ├── nodeTreeMore.go ├── cGo.go ├── usedByC.go ├── willUseGo.c ├── goEnv.go ├── unsafe.go ├── requiredVersion.go ├── defer.go ├── callC.go ├── panicRecover.go ├── moreUnsafe.go └── gColl.go ├── ch10 ├── closeNilChannel.go ├── maxprocs.go ├── forgetMutex.go ├── bufChannel.go ├── nilChannel.go ├── defineOrder.go ├── timeOut1.go ├── raceC.go ├── noRaceC.go ├── slowWWW.go ├── select.go ├── mutex.go ├── chSquare.go ├── timeOut2.go ├── monitor.go ├── rwMutex.go ├── workerPool.go ├── simpleContext.go └── useContext.go ├── ch08 ├── dataFile ├── ebpf.go ├── simpleFlag.go ├── ids.go ├── devRandom.go ├── permissions.go ├── handleTwo.go ├── bytes.go ├── str.go ├── handleAll.go ├── cat.go ├── ptraceRegs.go ├── byLine.go ├── byCharacter.go ├── readSize.go ├── byWord.go ├── goFind.go ├── funWithFlag.go ├── save.go ├── CSVplot.go ├── traceSyscall.go ├── kvSaveLoad.go └── SYSCALLS ├── ch07 ├── myInterface.go ├── ooo.go ├── assertion.go ├── methods.go ├── goCoIn.go ├── switch.go ├── useInterface.go ├── reflection.go └── advRefl.go ├── ch12 ├── README.md ├── MXrecords.go ├── NSrecords.go ├── netCapabilities.go ├── home.gohtml ├── webClient.go ├── netConfig.go ├── anotherTimeOut.go ├── insert.gohtml ├── update.gohtml ├── testWWW.go ├── www.go ├── DNS.go ├── testWWW_test.go ├── serverTimeOut.go ├── clientTimeOut.go ├── httpTrace.go ├── wwwProfile.go ├── advancedWebClient.go └── kvWeb.go ├── ch13 ├── README.md ├── sharedRPC.go ├── lowLevel.go ├── TCPclient.go ├── syscallNet.go ├── RPCclient.go ├── TCPserver.go ├── otherTCPclient.go ├── otherTCPserver.go ├── UDPclient.go ├── RPCserver.go ├── UDPserver.go ├── fiboTCP.go └── kvTCP.go ├── ch03 ├── failMap.go ├── reslice.go ├── parseTime.go ├── parseDate.go ├── usingTime.go ├── pointers.go ├── usingMaps.go ├── lenCap.go ├── loops.go ├── constants.go ├── slices.go ├── sortSlice.go ├── usingArrays.go ├── copySlice.go └── timeDate.go ├── ch11 ├── ex.go ├── xCompile.go ├── ex_test.go ├── documentMe_test.go ├── cannotReach.go ├── testMe.go ├── documentMe.go ├── benchmarkMe.go ├── writingBU_test.go ├── graph.dot ├── betterProfile.go ├── testMe_test.go ├── goGC.go ├── writingBU.go ├── benchmarkMe_test.go └── profileMe.go ├── ch09 ├── writeCh.go ├── simple.go ├── create.go ├── readCh.go ├── syncGo.go └── pipeline.go ├── ch04 ├── unicode.go ├── tuples.go ├── logEntries.txt ├── structures.go ├── runes.go ├── pointerStruct.go ├── strings.go ├── calculatePi_test.go ├── selectColumn.go ├── findIPv4.go ├── switch.go ├── changeDT.go ├── useStrings.go ├── keyValue.go └── calculatePi.go ├── ch05 ├── conRing.go ├── generatePassword.go ├── conList.go ├── conHeap.go ├── hashTable.go ├── binTree.go ├── randomNumbers.go ├── stack.go ├── hashTableLookup.go ├── queue.go ├── linkedList.go └── doublyLList.go ├── LICENSE └── README.md /ch01/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ch06/htmlT.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Mastering-Go/HEAD/ch06/htmlT.db -------------------------------------------------------------------------------- /ch02/nodeTreeMore.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Mastering-Go/HEAD/ch02/nodeTreeMore.o -------------------------------------------------------------------------------- /ch10/closeNilChannel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | var c chan string 5 | close(c) 6 | } 7 | -------------------------------------------------------------------------------- /ch08/dataFile: -------------------------------------------------------------------------------- 1 | 1,2 2 | 2,3 3 | 3,3 4 | 4,4 5 | 5,8 6 | 6,5 7 | -1,12 8 | -2,10 9 | -3,10 10 | -4,10 11 | -------------------------------------------------------------------------------- /ch07/myInterface.go: -------------------------------------------------------------------------------- 1 | package myInterface 2 | 3 | type Shape interface { 4 | Area() float64 5 | Perimeter() float64 6 | } 7 | -------------------------------------------------------------------------------- /ch02/callClib/callC.h: -------------------------------------------------------------------------------- 1 | #ifndef CALLC_H 2 | #define CALLC_H 3 | 4 | void cHello(); 5 | void printMessage(char* message); 6 | 7 | #endif -------------------------------------------------------------------------------- /ch02/nodeTree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("Hello there!") 9 | } 10 | -------------------------------------------------------------------------------- /ch01/packageNotUsed.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Hello there!") 10 | } 11 | -------------------------------------------------------------------------------- /ch12/README.md: -------------------------------------------------------------------------------- 1 | This directory contains the Go source file for Chapter 12 of Mastering Go 2 | https://www.packtpub.com/networking-and-servers/mastering-go 3 | -------------------------------------------------------------------------------- /ch01/aSourceFile.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("This is a sample Go program!") 9 | } 10 | -------------------------------------------------------------------------------- /ch13/README.md: -------------------------------------------------------------------------------- 1 | This directory contains the Go source files for Chapter 13 of Mastering Go. 2 | https://www.packtpub.com/networking-and-servers/mastering-go 3 | -------------------------------------------------------------------------------- /ch06/text.gotext: -------------------------------------------------------------------------------- 1 | Calculating the squares of some integers 2 | 3 | {{ range . }} The square of {{ printf "%d" .Number}} is {{ printf "%d" .Square}} 4 | {{ end }} 5 | -------------------------------------------------------------------------------- /ch08/ebpf.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/iovisor/gobpf" 6 | "os" 7 | "unsafe" 8 | ) 9 | 10 | func main() { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /ch01/curly.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() 8 | { 9 | fmt.Println("Go has strict rules for curly braces!") 10 | } 11 | 12 | -------------------------------------------------------------------------------- /ch01/packageNotUsedUnderscore.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | _ "os" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Hello there!") 10 | } 11 | -------------------------------------------------------------------------------- /ch06/a.go: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func init() { 8 | fmt.Println("init() a") 9 | } 10 | 11 | func FromA() { 12 | fmt.Println("fromA()") 13 | } 14 | -------------------------------------------------------------------------------- /ch01/getPackage.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/mactsouk/go/simpleGitHub" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(simpleGitHub.AddTwo(5, 6)) 10 | } 11 | -------------------------------------------------------------------------------- /ch03/failMap.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | 9 | aMap := map[string]int{} 10 | aMap = nil 11 | fmt.Println(aMap) 12 | aMap["test"] = 1 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ch06/b.go: -------------------------------------------------------------------------------- 1 | package b 2 | 3 | import ( 4 | "a" 5 | "fmt" 6 | ) 7 | 8 | func init() { 9 | fmt.Println("init() b") 10 | } 11 | 12 | func FromB() { 13 | fmt.Println("fromB()") 14 | a.FromA() 15 | } 16 | -------------------------------------------------------------------------------- /ch06/manyInit.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "a" 5 | "b" 6 | "fmt" 7 | ) 8 | 9 | func init() { 10 | fmt.Println("init() manyInit") 11 | } 12 | 13 | func main() { 14 | a.FromA() 15 | b.FromB() 16 | } 17 | -------------------------------------------------------------------------------- /ch02/callClib/callC.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "callC.h" 3 | 4 | void cHello() { 5 | printf("Hello from C!\n"); 6 | } 7 | 8 | void printMessage(char* message) { 9 | printf("Go send me %s\n", message); 10 | } -------------------------------------------------------------------------------- /ch06/useAPackage.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "aPackage" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Using aPackage!") 10 | aPackage.A() 11 | aPackage.B() 12 | fmt.Println(aPackage.MyConstant) 13 | } 14 | -------------------------------------------------------------------------------- /ch02/justPanic.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | if len(os.Args) == 1 { 10 | panic("Not enough arguments!") 11 | } 12 | 13 | fmt.Println("Thanks for the argument(s)!") 14 | } 15 | -------------------------------------------------------------------------------- /ch11/ex.go: -------------------------------------------------------------------------------- 1 | package ex 2 | 3 | func F1(n int) int { 4 | if n == 0 { 5 | return 0 6 | } 7 | if n == 1 || n == 2 { 8 | return 1 9 | } 10 | return F1(n-1) + F1(n-2) 11 | } 12 | 13 | func S1(s string) int { 14 | return len(s) 15 | } 16 | -------------------------------------------------------------------------------- /ch10/maxprocs.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | func getGOMAXPROCS() int { 9 | return runtime.GOMAXPROCS(0) 10 | } 11 | 12 | func main() { 13 | fmt.Printf("GOMAXPROCS: %d\n", getGOMAXPROCS()) 14 | } 15 | -------------------------------------------------------------------------------- /ch13/sharedRPC.go: -------------------------------------------------------------------------------- 1 | package sharedRPC 2 | 3 | type MyFloats struct { 4 | A1, A2 float64 5 | } 6 | 7 | type MyInterface interface { 8 | Multiply(arguments *MyFloats, reply *float64) error 9 | Power(arguments *MyFloats, reply *float64) error 10 | } 11 | -------------------------------------------------------------------------------- /ch06/ptrFun.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func getPtr(v *float64) float64 { 8 | return *v * *v 9 | } 10 | 11 | func main() { 12 | x := 12.2 13 | fmt.Println(getPtr(&x)) 14 | x = 12 15 | fmt.Println(getPtr(&x)) 16 | } 17 | -------------------------------------------------------------------------------- /ch06/returnPtr.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func returnPtr(x int) *int { 8 | y := x * x 9 | return &y 10 | } 11 | 12 | func main() { 13 | sq := returnPtr(10) 14 | fmt.Println("sq:", *sq) 15 | 16 | fmt.Println("sq:", sq) 17 | } 18 | -------------------------------------------------------------------------------- /ch11/xCompile.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | func main() { 9 | fmt.Print("You are using ", runtime.Compiler, " ") 10 | fmt.Println("on a", runtime.GOARCH, "machine") 11 | fmt.Println("with Go version", runtime.Version()) 12 | } 13 | -------------------------------------------------------------------------------- /ch02/nodeTreeMore.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func functionOne(x int) { 8 | fmt.Println(x) 9 | } 10 | 11 | func main() { 12 | varOne := 1 13 | varTwo := 2 14 | fmt.Println("Hello there!") 15 | functionOne(varOne) 16 | functionOne(varTwo) 17 | } 18 | -------------------------------------------------------------------------------- /ch06/aPackage.go: -------------------------------------------------------------------------------- 1 | package aPackage 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func A() { 8 | fmt.Println("This is function A!") 9 | } 10 | 11 | func B() { 12 | fmt.Println("privateConstant:", privateConstant) 13 | } 14 | 15 | const MyConstant = 123 16 | const privateConstant = 21 17 | -------------------------------------------------------------------------------- /ch01/stdIN.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | var f *os.File 11 | f = os.Stdin 12 | defer f.Close() 13 | 14 | scanner := bufio.NewScanner(f) 15 | for scanner.Scan() { 16 | fmt.Println(">", scanner.Text()) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ch02/cGo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //#include 4 | //void callC() { 5 | // printf("Calling C code!\n"); 6 | //} 7 | import "C" 8 | import "fmt" 9 | 10 | func main() { 11 | fmt.Println("A Go statement!") 12 | C.callC() 13 | fmt.Println("Another Go statement!") 14 | } 15 | -------------------------------------------------------------------------------- /ch03/reslice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | 7 | s1 := make([]int, 5) 8 | reSlice := s1[1:3] 9 | fmt.Println(s1) 10 | fmt.Println(reSlice) 11 | 12 | reSlice[0] = -100 13 | reSlice[1] = 123456 14 | fmt.Println(s1) 15 | fmt.Println(reSlice) 16 | 17 | } 18 | -------------------------------------------------------------------------------- /ch02/usedByC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "fmt" 7 | ) 8 | 9 | //export PrintMessage 10 | func PrintMessage() { 11 | fmt.Println("A Go function!") 12 | } 13 | 14 | //export Multiply 15 | func Multiply(a, b int) int { 16 | return a * b 17 | } 18 | 19 | func main() { 20 | } 21 | -------------------------------------------------------------------------------- /ch09/writeCh.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func writeToChannel(c chan int, x int) { 9 | fmt.Println(x) 10 | c <- x 11 | close(c) 12 | fmt.Println(x) 13 | } 14 | 15 | func main() { 16 | c := make(chan int) 17 | go writeToChannel(c, 10) 18 | time.Sleep(1 * time.Second) 19 | } 20 | -------------------------------------------------------------------------------- /ch11/ex_test.go: -------------------------------------------------------------------------------- 1 | package ex 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func ExampleF1() { 8 | fmt.Println(F1(10)) 9 | fmt.Println(F1(2)) 10 | // Output: 11 | // 55 12 | // 1 13 | } 14 | 15 | func ExampleS1() { 16 | fmt.Println(S1("123456789")) 17 | fmt.Println(S1("")) 18 | // Output: 19 | // 8 20 | // 0 21 | } 22 | -------------------------------------------------------------------------------- /ch02/willUseGo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "usedByC.h" 3 | 4 | int main(int argc, char **argv) { 5 | GoInt x = 12; 6 | GoInt y = 23; 7 | 8 | printf("About to call a Go function!\n"); 9 | PrintMessage(); 10 | GoInt p = Multiply(x,y); 11 | printf("Product: %d\n",(int)p); 12 | printf("It worked!\n"); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /ch11/documentMe_test.go: -------------------------------------------------------------------------------- 1 | package documentMe 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func ExampleS1() { 8 | fmt.Println(S1("123456789")) 9 | fmt.Println(S1("")) 10 | // Output: 11 | // 9 12 | // 0 13 | } 14 | 15 | func ExampleF1() { 16 | fmt.Println(F1(10)) 17 | fmt.Println(F1(2)) 18 | // Output: 19 | // 1 20 | // 55 21 | } 22 | -------------------------------------------------------------------------------- /ch08/simpleFlag.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | minusK := flag.Bool("k", true, "k") 10 | minusO := flag.Int("O", 1, "O") 11 | flag.Parse() 12 | 13 | valueK := *minusK 14 | valueO := *minusO 15 | valueO++ 16 | fmt.Println("-k:", valueK) 17 | fmt.Println("-O:", valueO) 18 | } 19 | -------------------------------------------------------------------------------- /ch04/unicode.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unicode" 6 | ) 7 | 8 | func main() { 9 | const sL = "\x99\x00ab\x50\x00\x23\x50\x29\x9c" 10 | 11 | for i := 0; i < len(sL); i++ { 12 | if unicode.IsPrint(rune(sL[i])) { 13 | fmt.Printf("%c\n", sL[i]) 14 | } else { 15 | fmt.Println("Not printable!") 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ch01/stdOUT.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | myString := "" 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | myString = "Please give me one argument!" 13 | } else { 14 | myString = arguments[1] 15 | } 16 | 17 | io.WriteString(os.Stdout, myString) 18 | io.WriteString(os.Stdout, "\n") 19 | } 20 | -------------------------------------------------------------------------------- /ch08/ids.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/user" 7 | ) 8 | 9 | func main() { 10 | fmt.Println("User id:", os.Getuid()) 11 | 12 | var u *user.User 13 | u, _ = user.Current() 14 | fmt.Print("Group ids: ") 15 | groupIDs, _ := u.GroupIds() 16 | for _, i := range groupIDs { 17 | fmt.Print(i, " ") 18 | } 19 | fmt.Println() 20 | } 21 | -------------------------------------------------------------------------------- /ch01/logFatal.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "log/syslog" 7 | ) 8 | 9 | func main() { 10 | sysLog, err := syslog.New(syslog.LOG_ALERT|syslog.LOG_MAIL, "Some program!") 11 | if err != nil { 12 | log.Fatal(err) 13 | } else { 14 | log.SetOutput(sysLog) 15 | } 16 | 17 | log.Fatal(sysLog) 18 | fmt.Println("Will you see this?") 19 | } 20 | -------------------------------------------------------------------------------- /ch01/logPanic.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "log/syslog" 7 | ) 8 | 9 | func main() { 10 | sysLog, err := syslog.New(syslog.LOG_ALERT|syslog.LOG_MAIL, "Some program!") 11 | if err != nil { 12 | log.Fatal(err) 13 | } else { 14 | log.SetOutput(sysLog) 15 | } 16 | 17 | log.Panic(sysLog) 18 | fmt.Println("Will you see this?") 19 | } 20 | -------------------------------------------------------------------------------- /ch01/printing.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | v1 := "123" 9 | v2 := 123 10 | v3 := "Have a nice day\n" 11 | v4 := "abc" 12 | 13 | fmt.Print(v1, v2, v3, v4) 14 | fmt.Println() 15 | fmt.Println(v1, v2, v3, v4) 16 | fmt.Print(v1, " ", v2, " ", v3, " ", v4, "\n") 17 | fmt.Printf("%s%d %s %s\n", v1, v2, v3, v4) 18 | } 19 | -------------------------------------------------------------------------------- /ch08/devRandom.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | f, err := os.Open("/dev/random") 11 | defer f.Close() 12 | 13 | if err != nil { 14 | fmt.Println(err) 15 | return 16 | } 17 | 18 | var seed int64 19 | binary.Read(f, binary.LittleEndian, &seed) 20 | fmt.Println("Seed:", seed) 21 | } 22 | -------------------------------------------------------------------------------- /ch09/simple.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func function() { 9 | for i := 0; i < 10; i++ { 10 | fmt.Print(i) 11 | } 12 | fmt.Println() 13 | } 14 | 15 | func main() { 16 | go function() 17 | 18 | go func() { 19 | for i := 10; i < 20; i++ { 20 | fmt.Print(i, " ") 21 | } 22 | }() 23 | 24 | time.Sleep(1 * time.Second) 25 | } 26 | -------------------------------------------------------------------------------- /ch02/goEnv.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | func main() { 9 | fmt.Print("You are using ", runtime.Compiler, " ") 10 | fmt.Println("on a", runtime.GOARCH, "machine") 11 | fmt.Println("Using Go version", runtime.Version()) 12 | fmt.Println("Number of CPUs:", runtime.NumCPU()) 13 | fmt.Println("Number of Goroutines:", runtime.NumGoroutine()) 14 | } 15 | -------------------------------------------------------------------------------- /ch08/permissions.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | arguments := os.Args 10 | if len(arguments) == 1 { 11 | fmt.Printf("usage: permissions filename\n") 12 | return 13 | } 14 | 15 | filename := arguments[1] 16 | info, _ := os.Stat(filename) 17 | mode := info.Mode() 18 | fmt.Println(filename, "mode is", mode.String()[1:10]) 19 | } 20 | -------------------------------------------------------------------------------- /ch04/tuples.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func retThree(x int) (int, int, int) { 8 | return 2 * x, x * x, -x 9 | } 10 | 11 | func main() { 12 | fmt.Println(retThree(10)) 13 | n1, n2, n3 := retThree(20) 14 | fmt.Println(n1, n2, n3) 15 | 16 | n1, n2 = n2, n1 17 | fmt.Println(n1, n2, n3) 18 | 19 | x1, x2, x3 := n1*2, n1*n1, -n1 20 | fmt.Println(x1, x2, x3) 21 | } 22 | -------------------------------------------------------------------------------- /ch11/cannotReach.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func f1() int { 8 | fmt.Println("Entering f1()") 9 | // return -10 10 | fmt.Println("Exiting f1()") 11 | return -1 12 | } 13 | 14 | func f2() int { 15 | if true { 16 | return 10 17 | } 18 | fmt.Println("Exiting f2()") 19 | return 0 20 | } 21 | 22 | func main() { 23 | fmt.Println(f1()) 24 | fmt.Println("Exiting program...") 25 | } 26 | -------------------------------------------------------------------------------- /ch01/stdERR.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | myString := "" 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | myString = "Please give me one argument!" 13 | } else { 14 | myString = arguments[1] 15 | } 16 | 17 | io.WriteString(os.Stdout, "This is Standard output\n") 18 | io.WriteString(os.Stderr, myString) 19 | io.WriteString(os.Stderr, "\n") 20 | } 21 | -------------------------------------------------------------------------------- /ch02/unsafe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | var value int64 = 5 10 | var p1 = &value 11 | var p2 = (*int32)(unsafe.Pointer(p1)) 12 | 13 | fmt.Println("*p1: ", *p1) 14 | fmt.Println("*p2: ", *p2) 15 | *p1 = 5434123412312431212 16 | fmt.Println(value) 17 | fmt.Println("*p2: ", *p2) 18 | *p1 = 54341234 19 | fmt.Println(value) 20 | fmt.Println("*p2: ", *p2) 21 | } 22 | -------------------------------------------------------------------------------- /ch06/returnFunction.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func funReturnFun() func() int { 8 | i := 0 9 | return func() int { 10 | i++ 11 | return i * i 12 | } 13 | } 14 | 15 | func main() { 16 | i := funReturnFun() 17 | j := funReturnFun() 18 | 19 | fmt.Println("1:", i()) 20 | fmt.Println("2:", i()) 21 | fmt.Println("j1:", j()) 22 | fmt.Println("j2:", j()) 23 | fmt.Println("3:", i()) 24 | } 25 | -------------------------------------------------------------------------------- /ch10/forgetMutex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | var m sync.Mutex 9 | 10 | func function() { 11 | m.Lock() 12 | fmt.Println("Locked!") 13 | } 14 | 15 | func main() { 16 | var w sync.WaitGroup 17 | 18 | go func() { 19 | defer w.Done() 20 | function() 21 | }() 22 | w.Add(1) 23 | 24 | go func() { 25 | defer w.Done() 26 | function() 27 | }() 28 | w.Add(1) 29 | 30 | w.Wait() 31 | } 32 | -------------------------------------------------------------------------------- /ch09/create.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | n := flag.Int("n", 10, "Number of goroutines") 11 | flag.Parse() 12 | 13 | count := *n 14 | fmt.Printf("Going to create %d goroutines.\n", count) 15 | for i := 0; i < count; i++ { 16 | go func(x int) { 17 | fmt.Printf("%d ", x) 18 | }(i) 19 | } 20 | 21 | time.Sleep(time.Second) 22 | fmt.Println("\nExiting...") 23 | } 24 | -------------------------------------------------------------------------------- /ch12/MXrecords.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | fmt.Println("Need a domain name!") 13 | return 14 | } 15 | 16 | domain := arguments[1] 17 | MXs, err := net.LookupMX(domain) 18 | if err != nil { 19 | fmt.Println(err) 20 | return 21 | } 22 | 23 | for _, MX := range MXs { 24 | fmt.Println(MX.Host) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch12/NSrecords.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | arguments := os.Args 11 | if len(arguments) == 1 { 12 | fmt.Println("Need a domain name!") 13 | return 14 | } 15 | 16 | domain := arguments[1] 17 | NSs, err := net.LookupNS(domain) 18 | if err != nil { 19 | fmt.Println(err) 20 | return 21 | } 22 | 23 | for _, NS := range NSs { 24 | fmt.Println(NS.Host) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch07/ooo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type a struct { 8 | XX int 9 | YY int 10 | } 11 | 12 | type b struct { 13 | AA string 14 | XX int 15 | } 16 | 17 | type c struct { 18 | A a 19 | B b 20 | } 21 | 22 | func (A a) A() { 23 | fmt.Println("Function A() for A") 24 | } 25 | 26 | func (B b) A() { 27 | fmt.Println("Function A() for B") 28 | } 29 | 30 | func main() { 31 | var i c 32 | i.A.A() 33 | i.B.A() 34 | } 35 | -------------------------------------------------------------------------------- /ch04/logEntries.txt: -------------------------------------------------------------------------------- 1 | - - [21/Nov/2017:19:28:09 +0200] "GET /AMEv2.tif.zip HTTP/1.1" 200 2188249 "-" 2 | - - [21/Jun/2017:19:28:09 +0200] "GET /AMEv2.tif.zip HTTP/1.1" 200 3 | - - [25/Lun/2017:20:05:34 +0200] "GET /MongoDjango.zip HTTP/1.1" 200 118362 4 | - - [Jun-21-17:19:28:09 +0200] "GET /AMEv2.tif.zip HTTP/1.1" 200 5 | - - [20/Nov/2017:20:05:34 +0200] "GET /MongoDjango.zip HTTP/1.1" 200 118362 6 | - - [35/Nov/2017:20:05:34 +0200] "GET MongoDjango.zip HTTP/1.1" 200 118362 7 | -------------------------------------------------------------------------------- /ch06/funFun.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func function1(i int) int { 6 | return i + i 7 | } 8 | 9 | func function2(i int) int { 10 | return i * i 11 | } 12 | 13 | func funFun(f func(int) int, v int) int { 14 | return f(v) 15 | } 16 | 17 | func main() { 18 | fmt.Println("function1:", funFun(function1, 123)) 19 | fmt.Println("function2:", funFun(function2, 123)) 20 | fmt.Println("Inline", funFun(func(i int) int { return i * i * i }, 123)) 21 | } 22 | -------------------------------------------------------------------------------- /ch07/assertion.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | var myInt interface{} = 123 9 | 10 | k, ok := myInt.(int) 11 | if ok { 12 | fmt.Println("Success:", k) 13 | } 14 | 15 | v, ok := myInt.(float64) 16 | if ok { 17 | fmt.Println(v) 18 | } else { 19 | fmt.Println("Failed without panicking!") 20 | } 21 | 22 | i := myInt.(int) 23 | fmt.Println("No cheking:", i) 24 | 25 | j := myInt.(bool) 26 | fmt.Println(j) 27 | } 28 | -------------------------------------------------------------------------------- /ch04/structures.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | 9 | type XYZ struct { 10 | X int 11 | Y int 12 | Z int 13 | } 14 | 15 | var s1 XYZ 16 | fmt.Println(s1.Y, s1.Z) 17 | 18 | p1 := XYZ{23, 12, -2} 19 | p2 := XYZ{Z: 12, Y: 13} 20 | fmt.Println(p1) 21 | fmt.Println(p2) 22 | 23 | pSlice := [4]XYZ{} 24 | pSlice[2] = p1 25 | pSlice[0] = p2 26 | fmt.Println(pSlice) 27 | p2 = XYZ{1, 2, 3} 28 | fmt.Println(pSlice) 29 | } 30 | -------------------------------------------------------------------------------- /ch03/parseTime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | var myTime string 12 | if len(os.Args) != 2 { 13 | fmt.Printf("usage: %s string\n", filepath.Base(os.Args[0])) 14 | os.Exit(1) 15 | } 16 | 17 | myTime = os.Args[1] 18 | d, err := time.Parse("15:04", myTime) 19 | if err == nil { 20 | fmt.Println("Full:", d) 21 | fmt.Println("Time:", d.Hour(), d.Minute()) 22 | } else { 23 | fmt.Println(err) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ch12/netCapabilities.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | ) 7 | 8 | func main() { 9 | interfaces, err := net.Interfaces() 10 | 11 | if err != nil { 12 | fmt.Print(err) 13 | return 14 | } 15 | 16 | for _, i := range interfaces { 17 | fmt.Printf("Name : %v\n", i.Name) 18 | fmt.Println("Interface Flags:", i.Flags.String()) 19 | fmt.Println("Interface MTU:", i.MTU) 20 | fmt.Println("Interface Hardware Address:", i.HardwareAddr) 21 | 22 | fmt.Println() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ch10/bufChannel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | numbers := make(chan int, 5) 9 | counter := 10 10 | 11 | for i := 0; i < counter; i++ { 12 | select { 13 | case numbers <- i: 14 | default: 15 | fmt.Println("Not enough space for", i) 16 | } 17 | } 18 | 19 | for i := 0; i < counter+5; i++ { 20 | select { 21 | case num := <-numbers: 22 | fmt.Println(num) 23 | default: 24 | fmt.Println("Nothing more to be done!") 25 | break 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ch12/home.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A Key Value Store! 6 | 7 | 8 | 9 | Home sweet home! 10 | List all elements! 11 | Change an element! 12 | Insert new element! 13 | 14 |

Welcome to the Go KV store!

15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ch03/parseDate.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | 12 | var myDate string 13 | if len(os.Args) != 2 { 14 | fmt.Printf("usage: %s string\n", filepath.Base(os.Args[0])) 15 | return 16 | } 17 | 18 | myDate = os.Args[1] 19 | d, err := time.Parse("02 January 2006", myDate) 20 | if err == nil { 21 | fmt.Println("Full:", d) 22 | fmt.Println("Time:", d.Day(), d.Month(), d.Year()) 23 | } else { 24 | fmt.Println(err) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch02/requiredVersion.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | myVersion := runtime.Version() 12 | major := strings.Split(myVersion, ".")[0][2] 13 | minor := strings.Split(myVersion, ".")[1] 14 | m1, _ := strconv.Atoi(string(major)) 15 | m2, _ := strconv.Atoi(minor) 16 | 17 | if m1 == 1 && m2 < 8 { 18 | fmt.Println("Need Go version 1.8 or higher!") 19 | return 20 | } 21 | 22 | fmt.Println("You are using Go version 1.8 or higher!") 23 | } 24 | -------------------------------------------------------------------------------- /ch02/defer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func d1() { 8 | for i := 3; i > 0; i-- { 9 | defer fmt.Print(i, " ") 10 | } 11 | } 12 | 13 | func d2() { 14 | for i := 3; i > 0; i-- { 15 | defer func() { 16 | fmt.Print(i, " ") 17 | }() 18 | } 19 | fmt.Println() 20 | } 21 | 22 | func d3() { 23 | for i := 3; i > 0; i-- { 24 | defer func(n int) { 25 | fmt.Print(n, " ") 26 | }(i) 27 | } 28 | } 29 | 30 | func main() { 31 | d1() 32 | d2() 33 | fmt.Println() 34 | d3() 35 | fmt.Println() 36 | } 37 | -------------------------------------------------------------------------------- /ch04/runes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | const r1 = '€' 9 | fmt.Println("(int32) r1:", r1) 10 | fmt.Printf("(HEX) r1: %x\n", r1) 11 | fmt.Printf("(as a String) r1: %s\n", r1) 12 | fmt.Printf("(as a character) r1: %c\n", r1) 13 | 14 | fmt.Println("A string is a collection of runes:", []byte("Mihalis")) 15 | aString := []byte("Mihalis") 16 | for x, y := range aString { 17 | fmt.Println(x, y) 18 | fmt.Printf("Char: %c\n", aString[x]) 19 | } 20 | fmt.Printf("%s\n", aString) 21 | } 22 | -------------------------------------------------------------------------------- /ch09/readCh.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func writeToChannel(c chan int, x int) { 9 | fmt.Println("1", x) 10 | c <- x 11 | close(c) 12 | fmt.Println("2", x) 13 | } 14 | 15 | func main() { 16 | c := make(chan int) 17 | go writeToChannel(c, 10) 18 | time.Sleep(1 * time.Second) 19 | fmt.Println("Read:", <-c) 20 | time.Sleep(1 * time.Second) 21 | 22 | _, ok := <-c 23 | if ok { 24 | fmt.Println("Channel is open!") 25 | } else { 26 | fmt.Println("Channel is closed!") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ch11/testMe.go: -------------------------------------------------------------------------------- 1 | package testMe 2 | 3 | func f1(n int) int { 4 | if n == 0 { 5 | return 0 6 | } 7 | if n == 1 { 8 | return 1 9 | } 10 | return f1(n-1) + f1(n-2) 11 | } 12 | 13 | func f2(n int) int { 14 | if n == 0 { 15 | return 0 16 | } 17 | if n == 1 { 18 | return 2 19 | } 20 | 21 | return f2(n-1) + f2(n-2) 22 | } 23 | 24 | func s1(s string) int { 25 | if s == "" { 26 | return 0 27 | } 28 | n := 1 29 | for range s { 30 | n++ 31 | } 32 | return n 33 | } 34 | 35 | func s2(s string) int { 36 | return len(s) 37 | } 38 | -------------------------------------------------------------------------------- /ch13/lowLevel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | ) 7 | 8 | func main() { 9 | netaddr, err := net.ResolveIPAddr("ip4", "127.0.0.1") 10 | if err != nil { 11 | fmt.Println(err) 12 | return 13 | } 14 | conn, err := net.ListenIP("ip4:icmp", netaddr) 15 | if err != nil { 16 | fmt.Println(err) 17 | return 18 | } 19 | 20 | buffer := make([]byte, 1024) 21 | n, _, err := conn.ReadFrom(buffer) 22 | if err != nil { 23 | fmt.Println(err) 24 | return 25 | } 26 | 27 | fmt.Printf("% X\n", buffer[0:n]) 28 | } 29 | -------------------------------------------------------------------------------- /ch07/methods.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type twoInts struct { 8 | X int64 9 | Y int64 10 | } 11 | 12 | func regularFunction(a, b twoInts) twoInts { 13 | temp := twoInts{X: a.X + b.X, Y: a.Y + b.Y} 14 | return temp 15 | } 16 | 17 | func (a twoInts) method(b twoInts) twoInts { 18 | temp := twoInts{X: a.X + b.X, Y: a.Y + b.Y} 19 | return temp 20 | } 21 | 22 | func main() { 23 | i := twoInts{X: 1, Y: 2} 24 | j := twoInts{X: -5, Y: -2} 25 | fmt.Println(regularFunction(i, j)) 26 | fmt.Println(i.method(j)) 27 | } 28 | -------------------------------------------------------------------------------- /ch02/callC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // #cgo CFLAGS: -I${SRCDIR}/callClib 4 | // #cgo LDFLAGS: ${SRCDIR}/callC.a 5 | // #include 6 | // #include 7 | import "C" 8 | 9 | import ( 10 | "fmt" 11 | "unsafe" 12 | ) 13 | 14 | func main() { 15 | fmt.Println("Going to call a C function!") 16 | C.cHello() 17 | 18 | fmt.Println("Going to call another C function!") 19 | myMessage := C.CString("This is Mihalis!") 20 | defer C.free(unsafe.Pointer(myMessage)) 21 | C.printMessage(myMessage) 22 | 23 | fmt.Println("All perfectly done!") 24 | } 25 | -------------------------------------------------------------------------------- /ch02/panicRecover.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func a() { 8 | fmt.Println("Inside a()") 9 | defer func() { 10 | if c := recover(); c != nil { 11 | fmt.Println("Recover inside a()!") 12 | } 13 | }() 14 | fmt.Println("About to call b()") 15 | b() 16 | fmt.Println("b() exited!") 17 | fmt.Println("Exiting a().") 18 | } 19 | 20 | func b() { 21 | fmt.Println("Inside b()") 22 | panic("Panic in b()!") 23 | fmt.Println("Exiting b()") 24 | } 25 | 26 | func main() { 27 | a() 28 | fmt.Println("main() ended!") 29 | } 30 | -------------------------------------------------------------------------------- /ch06/useSyscall.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "syscall" 7 | ) 8 | 9 | func main() { 10 | pid, _, _ := syscall.Syscall(39, 0, 0, 0) 11 | fmt.Println("My pid is", pid) 12 | uid, _, _ := syscall.Syscall(24, 0, 0, 0) 13 | fmt.Println("User ID:", uid) 14 | 15 | message := []byte{'H', 'e', 'l', 'l', 'o', '!', '\n'} 16 | fd := 1 17 | syscall.Write(fd, message) 18 | 19 | fmt.Println("Using syscall.Exec()") 20 | command := "/bin/ls" 21 | env := os.Environ() 22 | syscall.Exec(command, []string{"ls", "-a", "-x"}, env) 23 | } 24 | -------------------------------------------------------------------------------- /ch07/goCoIn.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type first struct{} 8 | 9 | func (a first) F() { 10 | a.shared() 11 | } 12 | 13 | func (a first) shared() { 14 | fmt.Println("This is shared() from first!") 15 | } 16 | 17 | type second struct { 18 | first 19 | } 20 | 21 | func (a second) shared() { 22 | fmt.Println("This is shared() from second!") 23 | } 24 | 25 | func main() { 26 | first{}.F() 27 | second{}.shared() 28 | i := second{} 29 | j := i.first 30 | j.F() 31 | // (i.first).F() 32 | // (second{}.first).F() 33 | } 34 | -------------------------------------------------------------------------------- /ch10/nilChannel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | ) 8 | 9 | func add(c chan int) { 10 | sum := 0 11 | t := time.NewTimer(time.Second) 12 | 13 | for { 14 | select { 15 | case input := <-c: 16 | sum = sum + input 17 | case <-t.C: 18 | c = nil 19 | fmt.Println(sum) 20 | } 21 | } 22 | } 23 | 24 | func send(c chan int) { 25 | for { 26 | c <- rand.Intn(10) 27 | } 28 | } 29 | 30 | func main() { 31 | c := make(chan int) 32 | go add(c) 33 | go send(c) 34 | 35 | time.Sleep(3 * time.Second) 36 | } 37 | -------------------------------------------------------------------------------- /ch12/webClient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "os" 8 | "path/filepath" 9 | ) 10 | 11 | func main() { 12 | if len(os.Args) != 2 { 13 | fmt.Printf("Usage: %s URL\n", filepath.Base(os.Args[0])) 14 | return 15 | } 16 | 17 | URL := os.Args[1] 18 | data, err := http.Get(URL) 19 | 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } else { 24 | defer data.Body.Close() 25 | _, err := io.Copy(os.Stdout, data.Body) 26 | if err != nil { 27 | fmt.Println(err) 28 | return 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ch03/usingTime.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Epoch time:", time.Now().Unix()) 10 | t := time.Now() 11 | fmt.Println(t, t.Format(time.RFC3339)) 12 | fmt.Println(t.Weekday(), t.Day(), t.Month(), t.Year()) 13 | 14 | time.Sleep(time.Second) 15 | t1 := time.Now() 16 | fmt.Println("Time difference:", t1.Sub(t)) 17 | 18 | formatT := t.Format("01 January 2006") 19 | fmt.Println(formatT) 20 | loc, _ := time.LoadLocation("Europe/Paris") 21 | londonTime := t.In(loc) 22 | fmt.Println("Paris:", londonTime) 23 | } 24 | -------------------------------------------------------------------------------- /ch12/netConfig.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | ) 7 | 8 | func main() { 9 | interfaces, err := net.Interfaces() 10 | if err != nil { 11 | fmt.Println(err) 12 | return 13 | } 14 | 15 | for _, i := range interfaces { 16 | fmt.Printf("Interface: %v\n", i.Name) 17 | byName, err := net.InterfaceByName(i.Name) 18 | if err != nil { 19 | fmt.Println(err) 20 | } 21 | 22 | addresses, err := byName.Addrs() 23 | for k, v := range addresses { 24 | fmt.Printf("Interface Address #%v : %v\n", k, v.String()) 25 | } 26 | fmt.Println() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ch09/syncGo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "sync" 7 | ) 8 | 9 | func main() { 10 | n := flag.Int("n", 20, "Number of goroutines") 11 | flag.Parse() 12 | count := *n 13 | fmt.Printf("Going to create %d goroutines.\n", count) 14 | 15 | var waitGroup sync.WaitGroup 16 | fmt.Printf("%#v\n", waitGroup) 17 | for i := 0; i < count; i++ { 18 | waitGroup.Add(1) 19 | go func(x int) { 20 | defer waitGroup.Done() 21 | fmt.Printf("%d ", x) 22 | }(i) 23 | } 24 | 25 | fmt.Printf("%#v\n", waitGroup) 26 | waitGroup.Wait() 27 | fmt.Println("\nExiting...") 28 | } 29 | -------------------------------------------------------------------------------- /ch01/cla.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | func main() { 10 | if len(os.Args) == 1 { 11 | fmt.Println("Please give one or more floats.") 12 | return 13 | } 14 | 15 | arguments := os.Args 16 | min, _ := strconv.ParseFloat(arguments[1], 64) 17 | max, _ := strconv.ParseFloat(arguments[1], 64) 18 | 19 | for i := 2; i < len(arguments); i++ { 20 | n, _ := strconv.ParseFloat(arguments[i], 64) 21 | if n < min { 22 | min = n 23 | } 24 | if n > max { 25 | max = n 26 | } 27 | } 28 | 29 | fmt.Println("Min:", min) 30 | fmt.Println("Max:", max) 31 | } 32 | -------------------------------------------------------------------------------- /ch10/defineOrder.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func A(a, b chan struct{}) { 9 | <-a 10 | fmt.Println("A()!") 11 | time.Sleep(time.Second) 12 | close(b) 13 | } 14 | 15 | func B(a, b chan struct{}) { 16 | <-a 17 | fmt.Println("B()!") 18 | close(b) 19 | } 20 | 21 | func C(a chan struct{}) { 22 | <-a 23 | fmt.Println("C()!") 24 | } 25 | 26 | func main() { 27 | x := make(chan struct{}) 28 | y := make(chan struct{}) 29 | z := make(chan struct{}) 30 | 31 | go C(z) 32 | go A(x, y) 33 | go C(z) 34 | go B(y, z) 35 | go C(z) 36 | 37 | close(x) 38 | time.Sleep(3 * time.Second) 39 | } 40 | -------------------------------------------------------------------------------- /ch10/timeOut1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | c1 := make(chan string) 10 | go func() { 11 | time.Sleep(time.Second * 3) 12 | c1 <- "c1 OK" 13 | }() 14 | 15 | select { 16 | case res := <-c1: 17 | fmt.Println(res) 18 | case <-time.After(time.Second * 1): 19 | fmt.Println("timeout c1") 20 | } 21 | 22 | c2 := make(chan string) 23 | go func() { 24 | time.Sleep(3 * time.Second) 25 | c2 <- "c2 OK" 26 | }() 27 | 28 | select { 29 | case res := <-c2: 30 | fmt.Println(res) 31 | case <-time.After(4 * time.Second): 32 | fmt.Println("timeout c2") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ch05/conRing.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "container/ring" 5 | "fmt" 6 | ) 7 | 8 | var size int = 10 9 | 10 | func main() { 11 | myRing := ring.New(size + 1) 12 | fmt.Println("Empty ring:", *myRing) 13 | 14 | for i := 0; i < myRing.Len()-1; i++ { 15 | myRing.Value = i 16 | myRing = myRing.Next() 17 | } 18 | 19 | myRing.Value = 2 20 | 21 | sum := 0 22 | myRing.Do(func(x interface{}) { 23 | t := x.(int) 24 | sum = sum + t 25 | }) 26 | fmt.Println("Sum:", sum) 27 | 28 | for i := 0; i < myRing.Len()+2; i++ { 29 | myRing = myRing.Next() 30 | fmt.Print(myRing.Value, " ") 31 | } 32 | fmt.Println() 33 | } 34 | -------------------------------------------------------------------------------- /ch03/pointers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func getPointer(n *int) { 8 | *n = *n * *n 9 | 10 | } 11 | 12 | func returnPointer(n int) *int { 13 | v := n * n 14 | return &v 15 | } 16 | 17 | func main() { 18 | i := -10 19 | j := 25 20 | 21 | pI := &i 22 | pJ := &j 23 | 24 | fmt.Println("pI memory:", pI) 25 | fmt.Println("pJ memory:", pJ) 26 | fmt.Println("pI value:", *pI) 27 | fmt.Println("pJ value:", *pJ) 28 | 29 | *pI = 123456 30 | *pI-- 31 | fmt.Println("i:", i) 32 | 33 | getPointer(pJ) 34 | fmt.Println("j:", j) 35 | k := returnPointer(12) 36 | fmt.Println(*k) 37 | fmt.Println(k) 38 | } 39 | -------------------------------------------------------------------------------- /ch08/handleTwo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | "time" 9 | ) 10 | 11 | func handleSignal(signal os.Signal) { 12 | fmt.Println("handleSignal() Caught:", signal) 13 | } 14 | 15 | func main() { 16 | sigs := make(chan os.Signal, 1) 17 | signal.Notify(sigs, os.Interrupt, syscall.SIGINFO) 18 | go func() { 19 | for { 20 | sig := <-sigs 21 | switch sig { 22 | case os.Interrupt: 23 | fmt.Println("Caught:", sig) 24 | case syscall.SIGINFO: 25 | handleSignal(sig) 26 | return 27 | } 28 | } 29 | }() 30 | 31 | for { 32 | fmt.Printf(".") 33 | time.Sleep(20 * time.Second) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch11/documentMe.go: -------------------------------------------------------------------------------- 1 | // This package is for showcasing the documentation capabilities of Go 2 | // It is a naive package! 3 | package documentMe 4 | 5 | // Pie is a global variable 6 | // This is a silly comment! 7 | const Pie = 3.1415912 8 | 9 | // The S1() function finds the length of a string 10 | // It iterates over the string using range 11 | func S1(s string) int { 12 | if s == "" { 13 | return 0 14 | } 15 | n := 0 16 | for range s { 17 | n++ 18 | } 19 | return n 20 | } 21 | 22 | // The F1() function returns the double value of its input integer 23 | // A better function name would have been Double()! 24 | func F1(n int) int { 25 | return 2 * n 26 | } 27 | -------------------------------------------------------------------------------- /ch06/html.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Doing Maths in Go! 6 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {{ range . }} 28 | 29 | 30 | 31 | 32 | 33 | {{ end }} 34 | 35 |
NumberDoubleSquare
{{ .Number }} {{ .Double }} {{ .Square }}
36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /ch01/logFiles.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "log/syslog" 7 | "os" 8 | "path/filepath" 9 | ) 10 | 11 | func main() { 12 | 13 | programName := filepath.Base(os.Args[0]) 14 | sysLog, err := syslog.New(syslog.LOG_INFO|syslog.LOG_LOCAL7, programName) 15 | if err != nil { 16 | log.Fatal(err) 17 | } else { 18 | log.SetOutput(sysLog) 19 | } 20 | log.Println("LOG_INFO + LOG_LOCAL7: Logging in Go!") 21 | 22 | sysLog, err = syslog.New(syslog.LOG_MAIL, "Some program!") 23 | if err != nil { 24 | log.Fatal(err) 25 | } else { 26 | log.SetOutput(sysLog) 27 | } 28 | 29 | log.Println("LOG_MAIL: Logging in Go!") 30 | fmt.Println("Will you see this?") 31 | } 32 | -------------------------------------------------------------------------------- /ch06/textT.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "text/template" 7 | ) 8 | 9 | type Entry struct { 10 | Number int 11 | Square int 12 | } 13 | 14 | func main() { 15 | arguments := os.Args 16 | if len(arguments) != 2 { 17 | fmt.Println("Need the template file!") 18 | return 19 | } 20 | 21 | tFile := arguments[1] 22 | DATA := [][]int{{-1, 1}, {-2, 4}, {-3, 9}, {-4, 16}} 23 | var Entries []Entry 24 | 25 | for _, i := range DATA { 26 | if len(i) == 2 { 27 | temp := Entry{Number: i[0], Square: i[1]} 28 | Entries = append(Entries, temp) 29 | } 30 | } 31 | 32 | t := template.Must(template.ParseGlob(tFile)) 33 | t.Execute(os.Stdout, Entries) 34 | } 35 | -------------------------------------------------------------------------------- /ch01/newError.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func returnError(a, b int) error { 9 | if a == b { 10 | err := errors.New("Error in returnError() function!") 11 | return err 12 | } else { 13 | return nil 14 | } 15 | } 16 | 17 | func main() { 18 | err := returnError(1, 2) 19 | if err == nil { 20 | fmt.Println("returnError() ended normally!") 21 | } else { 22 | fmt.Println(err) 23 | } 24 | 25 | err = returnError(10, 10) 26 | if err == nil { 27 | fmt.Println("returnError() ended normally!") 28 | } else { 29 | fmt.Println(err) 30 | } 31 | 32 | if err.Error() == "Error in returnError() function!" { 33 | fmt.Println("!!") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch04/pointerStruct.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type myStructure struct { 8 | Name string 9 | Surname string 10 | Height int32 11 | } 12 | 13 | func createStruct(n, s string, h int32) *myStructure { 14 | if h > 300 { 15 | h = 0 16 | } 17 | return &myStructure{n, s, h} 18 | } 19 | 20 | func retStructure(n, s string, h int32) myStructure { 21 | if h > 300 { 22 | h = 0 23 | } 24 | return myStructure{n, s, h} 25 | } 26 | 27 | func main() { 28 | s1 := createStruct("Mihalis", "Tsoukalos", 123) 29 | s2 := retStructure("Mihalis", "Tsoukalos", 123) 30 | fmt.Println((*s1).Name) 31 | fmt.Println(s2.Name) 32 | fmt.Println(s1) 33 | fmt.Println(s2) 34 | } 35 | -------------------------------------------------------------------------------- /ch08/bytes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "os" 8 | ) 9 | 10 | func main() { 11 | var buffer bytes.Buffer 12 | buffer.Write([]byte("This is")) 13 | fmt.Fprintf(&buffer, " a string!\n") 14 | buffer.WriteTo(os.Stdout) 15 | buffer.WriteTo(os.Stdout) 16 | 17 | buffer.Reset() 18 | buffer.Write([]byte("Mastering Go!")) 19 | r := bytes.NewReader([]byte(buffer.String())) 20 | fmt.Println(buffer.String()) 21 | for { 22 | b := make([]byte, 3) 23 | n, err := r.Read(b) 24 | if err == io.EOF { 25 | break 26 | } 27 | 28 | if err != nil { 29 | fmt.Println(err) 30 | continue 31 | } 32 | fmt.Printf("Read %s Bytes: %d\n", b, n) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ch03/usingMaps.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | 9 | iMap := make(map[string]int) 10 | iMap["k1"] = 12 11 | iMap["k2"] = 13 12 | fmt.Println("iMap:", iMap) 13 | 14 | anotherMap := map[string]int{ 15 | "k1": 12, 16 | "k2": 13, 17 | } 18 | 19 | fmt.Println("anotherMap:", anotherMap) 20 | delete(anotherMap, "k1") 21 | delete(anotherMap, "k1") 22 | delete(anotherMap, "k1") 23 | fmt.Println("anotherMap:", anotherMap) 24 | 25 | _, ok := iMap["doesItExist"] 26 | if ok { 27 | fmt.Println("Exists!") 28 | } else { 29 | fmt.Println("Does NOT exist") 30 | } 31 | 32 | for key, value := range iMap { 33 | fmt.Println(key, value) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch10/raceC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "sync" 8 | ) 9 | 10 | func main() { 11 | arguments := os.Args 12 | if len(arguments) != 2 { 13 | fmt.Println("Give me a natural number!") 14 | os.Exit(1) 15 | } 16 | numGR, err := strconv.Atoi(os.Args[1]) 17 | if err != nil { 18 | fmt.Println(err) 19 | return 20 | } 21 | 22 | var waitGroup sync.WaitGroup 23 | var i int 24 | 25 | k := make(map[int]int) 26 | k[1] = 12 27 | 28 | for i = 0; i < numGR; i++ { 29 | waitGroup.Add(1) 30 | go func() { 31 | defer waitGroup.Done() 32 | k[i] = i 33 | }() 34 | } 35 | 36 | k[2] = 10 37 | waitGroup.Wait() 38 | fmt.Printf("k = %#v\n", k) 39 | } 40 | -------------------------------------------------------------------------------- /ch08/str.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | 12 | r := strings.NewReader("test") 13 | fmt.Println("r length:", r.Len()) 14 | 15 | b := make([]byte, 1) 16 | for { 17 | n, err := r.Read(b) 18 | if err == io.EOF { 19 | break 20 | } 21 | 22 | if err != nil { 23 | fmt.Println(err) 24 | continue 25 | } 26 | fmt.Printf("Read %s Bytes: %d\n", b, n) 27 | } 28 | 29 | s := strings.NewReader("This is an error!\n") 30 | fmt.Println("r length:", s.Len()) 31 | n, err := s.WriteTo(os.Stderr) 32 | 33 | if err != nil { 34 | fmt.Println(err) 35 | return 36 | } 37 | fmt.Printf("Wrote %d bytes to os.Stderr\n", n) 38 | } 39 | -------------------------------------------------------------------------------- /ch02/moreUnsafe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unsafe" 6 | ) 7 | 8 | func main() { 9 | array := [...]int{0, 1, -2, 3, 4} 10 | pointer := &array[0] 11 | fmt.Print(*pointer, " ") 12 | memoryAddress := uintptr(unsafe.Pointer(pointer)) + unsafe.Sizeof(array[0]) 13 | 14 | for i := 0; i < len(array)-1; i++ { 15 | pointer = (*int)(unsafe.Pointer(memoryAddress)) 16 | fmt.Print(*pointer, " ") 17 | memoryAddress = uintptr(unsafe.Pointer(pointer)) + unsafe.Sizeof(array[0]) 18 | } 19 | fmt.Println() 20 | pointer = (*int)(unsafe.Pointer(memoryAddress)) 21 | fmt.Print("One more: ", *pointer, " ") 22 | memoryAddress = uintptr(unsafe.Pointer(pointer)) + unsafe.Sizeof(array[0]) 23 | fmt.Println() 24 | } 25 | -------------------------------------------------------------------------------- /ch11/benchmarkMe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func fibo1(n int) int { 8 | if n == 0 { 9 | return 0 10 | } else if n == 1 { 11 | return 1 12 | } else { 13 | return fibo1(n-1) + fibo1(n-2) 14 | } 15 | } 16 | 17 | func fibo2(n int) int { 18 | if n == 0 || n == 1 { 19 | return n 20 | } 21 | return fibo2(n-1) + fibo2(n-2) 22 | } 23 | 24 | func fibo3(n int) int { 25 | fn := make(map[int]int) 26 | for i := 0; i <= n; i++ { 27 | var f int 28 | if i <= 2 { 29 | f = 1 30 | } else { 31 | f = fn[i-1] + fn[i-2] 32 | } 33 | fn[i] = f 34 | } 35 | return fn[n] 36 | } 37 | 38 | func main() { 39 | fmt.Println(fibo1(40)) 40 | fmt.Println(fibo2(40)) 41 | fmt.Println(fibo3(40)) 42 | } 43 | -------------------------------------------------------------------------------- /ch03/lenCap.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func printSlice(x []int) { 8 | for _, number := range x { 9 | fmt.Print(number, " ") 10 | } 11 | fmt.Println() 12 | } 13 | 14 | func main() { 15 | aSlice := []int{-1, 0, 4} 16 | fmt.Printf("aSlice: ") 17 | printSlice(aSlice) 18 | 19 | fmt.Printf("Cap: %d, Length: %d\n", cap(aSlice), len(aSlice)) 20 | aSlice = append(aSlice, -100) 21 | fmt.Printf("aSlice: ") 22 | printSlice(aSlice) 23 | fmt.Printf("Cap: %d, Length: %d\n", cap(aSlice), len(aSlice)) 24 | 25 | aSlice = append(aSlice, -2) 26 | aSlice = append(aSlice, -3) 27 | aSlice = append(aSlice, -4) 28 | printSlice(aSlice) 29 | fmt.Printf("Cap: %d, Length: %d\n", cap(aSlice), len(aSlice)) 30 | } 31 | -------------------------------------------------------------------------------- /ch08/handleAll.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | "time" 9 | ) 10 | 11 | func handle(signal os.Signal) { 12 | fmt.Println("Received:", signal) 13 | } 14 | 15 | func main() { 16 | sigs := make(chan os.Signal, 1) 17 | signal.Notify(sigs) 18 | go func() { 19 | for { 20 | sig := <-sigs 21 | switch sig { 22 | case os.Interrupt: 23 | handle(sig) 24 | case syscall.SIGTERM: 25 | handle(sig) 26 | os.Exit(0) 27 | case syscall.SIGUSR2: 28 | fmt.Println("Handling syscall.SIGUSR2!") 29 | default: 30 | fmt.Println("Ignoring:", sig) 31 | } 32 | } 33 | }() 34 | 35 | for { 36 | fmt.Printf(".") 37 | time.Sleep(30 * time.Second) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ch08/cat.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | ) 9 | 10 | func printFile(filename string) error { 11 | f, err := os.Open(filename) 12 | if err != nil { 13 | return err 14 | } 15 | defer f.Close() 16 | scanner := bufio.NewScanner(f) 17 | for scanner.Scan() { 18 | io.WriteString(os.Stdout, scanner.Text()) 19 | io.WriteString(os.Stdout, "\n") 20 | } 21 | return nil 22 | } 23 | 24 | func main() { 25 | filename := "" 26 | arguments := os.Args 27 | if len(arguments) == 1 { 28 | io.Copy(os.Stdout, os.Stdin) 29 | return 30 | } 31 | 32 | for i := 1; i < len(arguments); i++ { 33 | filename = arguments[i] 34 | err := printFile(filename) 35 | if err != nil { 36 | fmt.Println(err) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ch03/loops.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | 9 | for i := 0; i < 100; i++ { 10 | if i%20 == 0 { 11 | continue 12 | } 13 | 14 | if i == 95 { 15 | break 16 | } 17 | 18 | fmt.Print(i, " ") 19 | } 20 | 21 | fmt.Println() 22 | i := 10 23 | for { 24 | if i < 0 { 25 | break 26 | } 27 | fmt.Print(i, " ") 28 | i-- 29 | } 30 | fmt.Println() 31 | 32 | i = 0 33 | anExpression := true 34 | for ok := true; ok; ok = anExpression { 35 | if i > 10 { 36 | anExpression = false 37 | } 38 | 39 | fmt.Print(i, " ") 40 | i++ 41 | } 42 | fmt.Println() 43 | 44 | anArray := [5]int{0, 1, -1, 2, -2} 45 | for i, value := range anArray { 46 | fmt.Println("index:", i, "value: ", value) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ch07/switch.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type square struct { 8 | X float64 9 | } 10 | 11 | type circle struct { 12 | R float64 13 | } 14 | 15 | type rectangle struct { 16 | X float64 17 | Y float64 18 | } 19 | 20 | func tellInterface(x interface{}) { 21 | switch v := x.(type) { 22 | case square: 23 | fmt.Println("This is a square!") 24 | case circle: 25 | fmt.Printf("%v is a circle!\n", v) 26 | case rectangle: 27 | fmt.Println("This is a rectangle!") 28 | default: 29 | fmt.Printf("Unknown type %T!\n", v) 30 | } 31 | } 32 | 33 | func main() { 34 | x := circle{R: 10} 35 | tellInterface(x) 36 | y := rectangle{X: 4, Y: 1} 37 | tellInterface(y) 38 | z := square{X: 4} 39 | tellInterface(z) 40 | tellInterface(10) 41 | } 42 | -------------------------------------------------------------------------------- /ch06/functions.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | func doubleSquare(x int) (int, int) { 10 | return x * 2, x * x 11 | } 12 | 13 | func main() { 14 | arguments := os.Args 15 | if len(arguments) != 2 { 16 | fmt.Println("The program needs 1 argument!") 17 | return 18 | } 19 | 20 | y, err := strconv.Atoi(arguments[1]) 21 | if err != nil { 22 | fmt.Println(err) 23 | return 24 | } 25 | 26 | square := func(s int) int { 27 | return s * s 28 | } 29 | fmt.Println("The square of", y, "is", square(y)) 30 | 31 | double := func(s int) int { 32 | return s + s 33 | } 34 | fmt.Println("The double of", y, "is", double(y)) 35 | 36 | fmt.Println(doubleSquare(y)) 37 | d, s := doubleSquare(y) 38 | fmt.Println(d, s) 39 | } 40 | -------------------------------------------------------------------------------- /ch10/noRaceC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "sync" 8 | ) 9 | 10 | var aMutex sync.Mutex 11 | 12 | func main() { 13 | arguments := os.Args 14 | if len(arguments) != 2 { 15 | fmt.Println("Give me a natural number!") 16 | os.Exit(1) 17 | } 18 | numGR, err := strconv.Atoi(os.Args[1]) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | 24 | var waitGroup sync.WaitGroup 25 | var i int 26 | 27 | k := make(map[int]int) 28 | k[1] = 12 29 | 30 | for i = 0; i < numGR; i++ { 31 | waitGroup.Add(1) 32 | go func(j int) { 33 | defer waitGroup.Done() 34 | aMutex.Lock() 35 | k[j] = j 36 | aMutex.Unlock() 37 | }(i) 38 | } 39 | 40 | waitGroup.Wait() 41 | k[2] = 10 42 | fmt.Printf("k = %#v\n", k) 43 | } 44 | -------------------------------------------------------------------------------- /ch13/TCPclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | arguments := os.Args 13 | if len(arguments) == 1 { 14 | fmt.Println("Please provide host:port.") 15 | return 16 | } 17 | 18 | CONNECT := arguments[1] 19 | c, err := net.Dial("tcp", CONNECT) 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } 24 | 25 | for { 26 | reader := bufio.NewReader(os.Stdin) 27 | fmt.Print(">> ") 28 | text, _ := reader.ReadString('\n') 29 | fmt.Fprintf(c, text+"\n") 30 | 31 | message, _ := bufio.NewReader(c).ReadString('\n') 32 | fmt.Print("->: " + message) 33 | if strings.TrimSpace(string(text)) == "STOP" { 34 | fmt.Println("TCP client exiting...") 35 | return 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ch05/generatePassword.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | func random(min, max int) int { 12 | return rand.Intn(max-min) + min 13 | } 14 | 15 | func main() { 16 | MIN := 0 17 | MAX := 94 18 | SEED := time.Now().Unix() 19 | var LENGTH int64 = 8 20 | 21 | arguments := os.Args 22 | switch len(arguments) { 23 | case 2: 24 | LENGTH, _ = strconv.ParseInt(os.Args[1], 10, 64) 25 | default: 26 | fmt.Println("Using default values!") 27 | } 28 | 29 | rand.Seed(SEED) 30 | 31 | startChar := "!" 32 | var i int64 = 1 33 | for { 34 | myRand := random(MIN, MAX) 35 | newChar := string(startChar[0] + byte(myRand)) 36 | fmt.Print(newChar) 37 | if i == LENGTH { 38 | break 39 | } 40 | i++ 41 | } 42 | fmt.Println() 43 | } 44 | -------------------------------------------------------------------------------- /ch08/ptraceRegs.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | "syscall" 8 | "time" 9 | ) 10 | 11 | func main() { 12 | var r syscall.PtraceRegs 13 | cmd := exec.Command(os.Args[1], os.Args[2:]...) 14 | 15 | cmd.Stdout = os.Stdout 16 | cmd.Stderr = os.Stderr 17 | 18 | cmd.SysProcAttr = &syscall.SysProcAttr{Ptrace: true} 19 | err := cmd.Start() 20 | if err != nil { 21 | fmt.Println("Start:", err) 22 | return 23 | } 24 | 25 | err = cmd.Wait() 26 | fmt.Printf("State: %v\n", err) 27 | wpid := cmd.Process.Pid 28 | 29 | err = syscall.PtraceGetRegs(wpid, &r) 30 | if err != nil { 31 | fmt.Println("PtraceGetRegs:", err) 32 | return 33 | } 34 | fmt.Printf("Registers: %#v\n", r) 35 | fmt.Printf("R15=%d, Gs=%d\n", r.R15, r.Gs) 36 | 37 | time.Sleep(2 * time.Second) 38 | } 39 | -------------------------------------------------------------------------------- /ch13/syscallNet.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "syscall" 7 | ) 8 | 9 | func main() { 10 | fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP) 11 | if err != nil { 12 | fmt.Println("Error in syscall.Socket:", err) 13 | return 14 | } 15 | 16 | f := os.NewFile(uintptr(fd), "captureICMP") 17 | if f == nil { 18 | fmt.Println("Error in os.NewFile:", err) 19 | return 20 | } 21 | 22 | err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, 256) 23 | if err != nil { 24 | fmt.Println("Error in syscall.Socket:", err) 25 | return 26 | } 27 | 28 | for { 29 | buf := make([]byte, 1024) 30 | numRead, err := f.Read(buf) 31 | if err != nil { 32 | fmt.Println(err) 33 | } 34 | fmt.Printf("% X\n", buf[:numRead]) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ch03/constants.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Digit int 8 | type Power2 int 9 | 10 | const PI = 3.1415926 11 | 12 | const ( 13 | C1 = "C1C1C1" 14 | C2 = "C2C2C2" 15 | C3 = "C3C3C3" 16 | ) 17 | 18 | func main() { 19 | 20 | const s1 = 123 21 | var v1 float32 = s1 * 12 22 | fmt.Println(v1) 23 | fmt.Println(PI) 24 | 25 | // const s2 float64 = 123 26 | // var v2 float32 = s2 * 12 27 | 28 | const ( 29 | Zero Digit = iota 30 | One 31 | Two 32 | Three 33 | Four 34 | ) 35 | 36 | fmt.Println(One) 37 | fmt.Println(Two) 38 | 39 | const ( 40 | p2_0 Power2 = 1 << iota 41 | _ 42 | p2_2 43 | _ 44 | p2_4 45 | _ 46 | p2_6 47 | ) 48 | 49 | fmt.Println("2^0:", p2_0) 50 | fmt.Println("2^2:", p2_2) 51 | fmt.Println("2^4:", p2_4) 52 | fmt.Println("2^6:", p2_6) 53 | 54 | } 55 | -------------------------------------------------------------------------------- /ch13/RPCclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/rpc" 6 | "os" 7 | "sharedRPC" 8 | ) 9 | 10 | func main() { 11 | arguments := os.Args 12 | if len(arguments) == 1 { 13 | fmt.Println("Please provide a host:port string!") 14 | return 15 | } 16 | 17 | CONNECT := arguments[1] 18 | c, err := rpc.Dial("tcp", CONNECT) 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | 24 | args := sharedRPC.MyFloats{16, -0.5} 25 | var reply float64 26 | 27 | err = c.Call("MyInterface.Multiply", args, &reply) 28 | if err != nil { 29 | fmt.Println(err) 30 | return 31 | } 32 | fmt.Printf("Reply (Multiply): %f\n", reply) 33 | 34 | err = c.Call("MyInterface.Power", args, &reply) 35 | if err != nil { 36 | fmt.Println(err) 37 | return 38 | } 39 | fmt.Printf("Reply (Power): %f\n", reply) 40 | } 41 | -------------------------------------------------------------------------------- /ch02/gColl.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | "time" 7 | ) 8 | 9 | func printStats(mem runtime.MemStats) { 10 | runtime.ReadMemStats(&mem) 11 | fmt.Println("mem.Alloc:", mem.Alloc) 12 | fmt.Println("mem.TotalAlloc:", mem.TotalAlloc) 13 | fmt.Println("mem.HeapAlloc:", mem.HeapAlloc) 14 | fmt.Println("mem.NumGC:", mem.NumGC) 15 | fmt.Println("-----") 16 | } 17 | 18 | func main() { 19 | var mem runtime.MemStats 20 | printStats(mem) 21 | 22 | for i := 0; i < 10; i++ { 23 | s := make([]byte, 50000000) 24 | if s == nil { 25 | fmt.Println("Operation failed!") 26 | } 27 | } 28 | printStats(mem) 29 | 30 | for i := 0; i < 10; i++ { 31 | s := make([]byte, 100000000) 32 | if s == nil { 33 | fmt.Println("Operation failed!") 34 | } 35 | time.Sleep(5 * time.Second) 36 | } 37 | printStats(mem) 38 | } 39 | -------------------------------------------------------------------------------- /ch03/slices.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | aSlice := []int{1, 2, 3, 4, 5} 9 | fmt.Println(aSlice) 10 | integer := make([]int, 2) 11 | fmt.Println(integer) 12 | 13 | integer = nil 14 | fmt.Println(integer) 15 | 16 | anArray := [5]int{-1, -2, -3, -4, -5} 17 | refAnArray := anArray[:] 18 | fmt.Println(anArray) 19 | fmt.Println(refAnArray) 20 | anArray[4] = -100 21 | fmt.Println(refAnArray) 22 | 23 | s := make([]byte, 5) 24 | fmt.Println(s) 25 | twoD := make([][]int, 3) 26 | fmt.Println(twoD) 27 | fmt.Println() 28 | 29 | for i := 0; i < len(twoD); i++ { 30 | for j := 0; j < 2; j++ { 31 | twoD[i] = append(twoD[i], i*j) 32 | } 33 | } 34 | 35 | for _, x := range twoD { 36 | for i, y := range x { 37 | fmt.Println("i:", i, "value:", y) 38 | } 39 | fmt.Println() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch08/byLine.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | ) 10 | 11 | func lineByLine(file string) error { 12 | var err error 13 | 14 | f, err := os.Open(file) 15 | if err != nil { 16 | return err 17 | } 18 | defer f.Close() 19 | 20 | r := bufio.NewReader(f) 21 | for { 22 | line, err := r.ReadString('\n') 23 | if err == io.EOF { 24 | break 25 | } else if err != nil { 26 | fmt.Printf("error reading file %s", err) 27 | break 28 | } 29 | fmt.Print(line) 30 | } 31 | return nil 32 | } 33 | 34 | func main() { 35 | flag.Parse() 36 | if len(flag.Args()) == 0 { 37 | fmt.Printf("usage: byLine [ ...]\n") 38 | return 39 | } 40 | 41 | for _, file := range flag.Args() { 42 | err := lineByLine(file) 43 | if err != nil { 44 | fmt.Println(err) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ch01/errors.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "os" 7 | "strconv" 8 | ) 9 | 10 | func main() { 11 | if len(os.Args) == 1 { 12 | fmt.Println("Please give one or more floats.") 13 | os.Exit(1) 14 | } 15 | 16 | arguments := os.Args 17 | var err error = errors.New("An error") 18 | k := 1 19 | var n float64 20 | for err != nil { 21 | if k >= len(arguments) { 22 | fmt.Println("None of the arguments is a float!") 23 | return 24 | } 25 | n, err = strconv.ParseFloat(arguments[k], 64) 26 | k++ 27 | } 28 | 29 | min, max := n, n 30 | for i := 2; i < len(arguments); i++ { 31 | n, err := strconv.ParseFloat(arguments[i], 64) 32 | if err == nil { 33 | if n < min { 34 | min = n 35 | } 36 | if n > max { 37 | max = n 38 | } 39 | } 40 | } 41 | 42 | fmt.Println("Min:", min) 43 | fmt.Println("Max:", max) 44 | } 45 | -------------------------------------------------------------------------------- /ch03/sortSlice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | type aStructure struct { 9 | person string 10 | height int 11 | weight int 12 | } 13 | 14 | func main() { 15 | 16 | mySlice := make([]aStructure, 0) 17 | mySlice = append(mySlice, aStructure{"Mihalis", 180, 90}) 18 | mySlice = append(mySlice, aStructure{"Bill", 134, 45}) 19 | mySlice = append(mySlice, aStructure{"Marietta", 155, 45}) 20 | mySlice = append(mySlice, aStructure{"Epifanios", 144, 50}) 21 | mySlice = append(mySlice, aStructure{"Athina", 134, 40}) 22 | 23 | fmt.Println("0:", mySlice) 24 | sort.Slice(mySlice, func(i, j int) bool { 25 | return mySlice[i].height < mySlice[j].height 26 | }) 27 | fmt.Println("<:", mySlice) 28 | sort.Slice(mySlice, func(i, j int) bool { 29 | return mySlice[i].height > mySlice[j].height 30 | }) 31 | fmt.Println(">:", mySlice) 32 | } 33 | -------------------------------------------------------------------------------- /ch03/usingArrays.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | anArray := [4]int{1, 2, 4, -4} 9 | twoD := [4][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}} 10 | threeD := [2][2][2]int{{{1, 0}, {-2, 4}}, {{5, -1}, {7, 0}}} 11 | 12 | fmt.Println("The length of", anArray, "is", len(anArray)) 13 | fmt.Println("The first element of", twoD, "is", twoD[0][0]) 14 | fmt.Println("The length of", threeD, "is", len(threeD)) 15 | 16 | for i := 0; i < len(threeD); i++ { 17 | v := threeD[i] 18 | for j := 0; j < len(v); j++ { 19 | m := v[j] 20 | for k := 0; k < len(m); k++ { 21 | fmt.Print(m[k], " ") 22 | } 23 | } 24 | fmt.Println() 25 | } 26 | 27 | for _, v := range threeD { 28 | for _, m := range v { 29 | for _, s := range m { 30 | fmt.Print(s, " ") 31 | } 32 | } 33 | fmt.Println() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch11/writingBU_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | ) 8 | 9 | var ERR error 10 | 11 | func benchmarkCreate(b *testing.B, buffer, filesize int) { 12 | var err error 13 | for i := 0; i < b.N; i++ { 14 | err = Create("/tmp/random", buffer, filesize) 15 | } 16 | ERR = err 17 | 18 | err = os.Remove("/tmp/random") 19 | if err != nil { 20 | fmt.Println(err) 21 | } 22 | } 23 | 24 | func Benchmark1Create(b *testing.B) { 25 | benchmarkCreate(b, 1, 1000000) 26 | } 27 | 28 | func Benchmark2Create(b *testing.B) { 29 | benchmarkCreate(b, 2, 1000000) 30 | } 31 | 32 | func Benchmark4Create(b *testing.B) { 33 | benchmarkCreate(b, 4, 1000000) 34 | } 35 | 36 | func Benchmark10Create(b *testing.B) { 37 | benchmarkCreate(b, 10, 1000000) 38 | } 39 | 40 | func Benchmark1000Create(b *testing.B) { 41 | benchmarkCreate(b, 1000, 1000000) 42 | } 43 | -------------------------------------------------------------------------------- /ch06/returnNames.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | func namedMinMax(x, y int) (min, max int) { 10 | if x > y { 11 | min = y 12 | max = x 13 | } else { 14 | min = x 15 | max = y 16 | } 17 | return 18 | } 19 | 20 | func minMax(x, y int) (min, max int) { 21 | if x > y { 22 | min = y 23 | max = x 24 | } else { 25 | min = x 26 | max = y 27 | } 28 | return min, max 29 | } 30 | 31 | func main() { 32 | arguments := os.Args 33 | if len(arguments) < 3 { 34 | fmt.Println("The program needs at least 2 arguments!") 35 | return 36 | } 37 | 38 | a1, _ := strconv.Atoi(arguments[1]) 39 | a2, _ := strconv.Atoi(arguments[2]) 40 | 41 | fmt.Println(minMax(a1, a2)) 42 | min, max := minMax(a1, a2) 43 | fmt.Println(min, max) 44 | 45 | fmt.Println(namedMinMax(a1, a2)) 46 | min, max = namedMinMax(a1, a2) 47 | fmt.Println(min, max) 48 | } 49 | -------------------------------------------------------------------------------- /ch08/byCharacter.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | ) 10 | 11 | func charByChar(file string) error { 12 | var err error 13 | f, err := os.Open(file) 14 | if err != nil { 15 | return err 16 | } 17 | defer f.Close() 18 | 19 | r := bufio.NewReader(f) 20 | for { 21 | line, err := r.ReadString('\n') 22 | if err == io.EOF { 23 | break 24 | } else if err != nil { 25 | fmt.Printf("error reading file %s", err) 26 | return err 27 | } 28 | 29 | for _, x := range line { 30 | fmt.Println(string(x)) 31 | } 32 | } 33 | return nil 34 | } 35 | 36 | func main() { 37 | flag.Parse() 38 | if len(flag.Args()) == 0 { 39 | fmt.Printf("usage: byChar [ ...]\n") 40 | return 41 | } 42 | 43 | for _, file := range flag.Args() { 44 | err := charByChar(file) 45 | if err != nil { 46 | fmt.Println(err) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ch11/graph.dot: -------------------------------------------------------------------------------- 1 | digraph G 2 | { 3 | graph [dpi = 300, bgcolor = "gray"]; 4 | rankdir = LR; 5 | node [shape=record, width=.2, height=.2, color="white" ]; 6 | 7 | node0 [label = " | | | | | | ", height = 3]; 8 | node[ width=2 ]; 9 | node1 [label = "{ r0 | 123 |

}", color="gray" ]; 10 | node2 [label = "{ r10 | 13 |

}" ]; 11 | node3 [label = "{ r11 | 23 |

}" ]; 12 | node4 [label = "{ r12 | 326 |

}" ]; 13 | node5 [label = "{ r13 | 1f3 |

}" ]; 14 | node6 [label = "{ r20 | 143 |

}" ]; 15 | node7 [label = "{ r40 | b23 |

}" ]; 16 | 17 | node0:p0 -> node1:e [dir=both color="red:blue"]; 18 | node0:p1 -> node2:e [dir=back arrowhead=diamond]; 19 | node2:p -> node3:e; 20 | node3:p -> node4:e [dir=both arrowtail=box color="red"]; 21 | node4:p -> node5:e [dir=forward]; 22 | node0:p2 -> node6:e [dir=none color="orange"]; 23 | node0:p4 -> node7:e; 24 | } 25 | -------------------------------------------------------------------------------- /ch10/slowWWW.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "net/http" 7 | "os" 8 | "time" 9 | ) 10 | 11 | func random(min, max int) int { 12 | return rand.Intn(max-min) + min 13 | } 14 | 15 | func myHandler(w http.ResponseWriter, r *http.Request) { 16 | delay := random(0, 15) 17 | time.Sleep(time.Duration(delay) * time.Second) 18 | 19 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 20 | fmt.Fprintf(w, "Delay: %d\n", delay) 21 | fmt.Printf("Served: %s\n", r.Host) 22 | } 23 | 24 | func main() { 25 | seed := time.Now().Unix() 26 | rand.Seed(seed) 27 | 28 | PORT := ":8001" 29 | arguments := os.Args 30 | if len(arguments) == 1 { 31 | fmt.Println("Using default port number: ", PORT) 32 | } else { 33 | PORT = ":" + arguments[1] 34 | } 35 | 36 | http.HandleFunc("/", myHandler) 37 | err := http.ListenAndServe(PORT, nil) 38 | if err != nil { 39 | fmt.Println(err) 40 | os.Exit(10) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ch03/copySlice.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | 9 | a6 := []int{-10, 1, 2, 3, 4, 5} 10 | a4 := []int{-1, -2, -3, -4} 11 | fmt.Println("a6:", a6) 12 | fmt.Println("a4:", a4) 13 | 14 | copy(a6, a4) 15 | fmt.Println("a6:", a6) 16 | fmt.Println("a4:", a4) 17 | fmt.Println() 18 | 19 | b6 := []int{-10, 1, 2, 3, 4, 5} 20 | b4 := []int{-1, -2, -3, -4} 21 | fmt.Println("b6:", b6) 22 | fmt.Println("b4:", b4) 23 | copy(b4, b6) 24 | fmt.Println("b6:", b6) 25 | fmt.Println("b4:", b4) 26 | 27 | fmt.Println() 28 | array4 := [4]int{4, -4, 4, -4} 29 | s6 := []int{1, 1, -1, -1, 5, -5} 30 | copy(s6, array4[0:]) 31 | fmt.Println("array4:", array4[0:]) 32 | fmt.Println("s6:", s6) 33 | 34 | fmt.Println() 35 | 36 | array5 := [5]int{5, -5, 5, -5, 5} 37 | s7 := []int{7, 7, -7, -7, 7, -7, 7} 38 | copy(array5[0:], s7) 39 | fmt.Println("array5:", array5) 40 | fmt.Println("s7:", s7) 41 | } 42 | -------------------------------------------------------------------------------- /ch12/anotherTimeOut.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "os" 8 | "strconv" 9 | "time" 10 | ) 11 | 12 | var timeout = time.Duration(time.Second) 13 | 14 | func main() { 15 | if len(os.Args) == 1 { 16 | fmt.Println("Please provide a URL") 17 | return 18 | } 19 | 20 | if len(os.Args) == 3 { 21 | temp, err := strconv.Atoi(os.Args[2]) 22 | if err != nil { 23 | fmt.Println("Using Default Timeout!") 24 | } else { 25 | timeout = time.Duration(time.Duration(temp) * time.Second) 26 | } 27 | } 28 | 29 | URL := os.Args[1] 30 | 31 | client := http.Client{ 32 | Timeout: timeout, 33 | } 34 | client.Get(URL) 35 | 36 | data, err := client.Get(URL) 37 | if err != nil { 38 | fmt.Println(err) 39 | return 40 | } else { 41 | defer data.Body.Close() 42 | _, err := io.Copy(os.Stdout, data.Body) 43 | if err != nil { 44 | fmt.Println(err) 45 | return 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ch05/conList.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "container/list" 5 | "fmt" 6 | "strconv" 7 | ) 8 | 9 | func printList(l *list.List) { 10 | for t := l.Back(); t != nil; t = t.Prev() { 11 | fmt.Print(t.Value, " ") 12 | } 13 | fmt.Println() 14 | 15 | for t := l.Front(); t != nil; t = t.Next() { 16 | fmt.Print(t.Value, " ") 17 | } 18 | 19 | fmt.Println() 20 | } 21 | 22 | func main() { 23 | 24 | values := list.New() 25 | 26 | e1 := values.PushBack("One") 27 | e2 := values.PushBack("Two") 28 | values.PushFront("Three") 29 | values.InsertBefore("Four", e1) 30 | values.InsertAfter("Five", e2) 31 | values.Remove(e2) 32 | values.Remove(e2) 33 | values.InsertAfter("FiveFive", e2) 34 | values.PushBackList(values) 35 | 36 | printList(values) 37 | 38 | values.Init() 39 | fmt.Printf("After Init(): %v\n", values) 40 | 41 | for i := 0; i < 20; i++ { 42 | values.PushFront(strconv.Itoa(i)) 43 | } 44 | 45 | printList(values) 46 | } 47 | -------------------------------------------------------------------------------- /ch11/betterProfile.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/pkg/profile" 6 | ) 7 | 8 | var VARIABLE int 9 | 10 | func N1(n int) bool { 11 | for i := 2; i < n; i++ { 12 | if (n % i) == 0 { 13 | return false 14 | } 15 | } 16 | return true 17 | } 18 | 19 | func Multiply(a, b int) int { 20 | if a == 1 { 21 | return b 22 | } 23 | if a == 0 || b == 0 { 24 | return 0 25 | } 26 | if a < 0 { 27 | return -Multiply(-a, b) 28 | } 29 | return b + Multiply(a-1, b) 30 | } 31 | 32 | func main() { 33 | defer profile.Start(profile.ProfilePath("/tmp")).Stop() 34 | 35 | total := 0 36 | for i := 2; i < 200000; i++ { 37 | n := N1(i) 38 | if n { 39 | total++ 40 | } 41 | } 42 | fmt.Println("Total: ", total) 43 | 44 | total = 0 45 | for i := 0; i < 5000; i++ { 46 | for j := 0; j < 400; j++ { 47 | k := Multiply(i, j) 48 | VARIABLE = k 49 | total++ 50 | } 51 | } 52 | fmt.Println("Total: ", total) 53 | } 54 | -------------------------------------------------------------------------------- /ch13/TCPserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | "time" 10 | ) 11 | 12 | func main() { 13 | arguments := os.Args 14 | if len(arguments) == 1 { 15 | fmt.Println("Please provide port number") 16 | return 17 | } 18 | 19 | PORT := ":" + arguments[1] 20 | l, err := net.Listen("tcp", PORT) 21 | if err != nil { 22 | fmt.Println(err) 23 | return 24 | } 25 | defer l.Close() 26 | 27 | c, err := l.Accept() 28 | if err != nil { 29 | fmt.Println(err) 30 | return 31 | } 32 | 33 | for { 34 | netData, err := bufio.NewReader(c).ReadString('\n') 35 | if err != nil { 36 | fmt.Println(err) 37 | return 38 | } 39 | if strings.TrimSpace(string(netData)) == "STOP" { 40 | fmt.Println("Exiting TCP server!") 41 | return 42 | } 43 | 44 | fmt.Print("-> ", string(netData)) 45 | t := time.Now() 46 | myTime := t.Format(time.RFC3339) + "\n" 47 | c.Write([]byte(myTime)) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ch07/useInterface.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "myInterface" 7 | ) 8 | 9 | type square struct { 10 | X float64 11 | } 12 | 13 | type circle struct { 14 | R float64 15 | } 16 | 17 | func (s square) Area() float64 { 18 | return s.X * s.X 19 | } 20 | 21 | func (s square) Perimeter() float64 { 22 | return 4 * s.X 23 | } 24 | 25 | func (s circle) Area() float64 { 26 | return s.R * s.R * math.Pi 27 | } 28 | 29 | func (s circle) Perimeter() float64 { 30 | return 2 * s.R * math.Pi 31 | } 32 | 33 | func Calculate(x myInterface.Shape) { 34 | _, ok := x.(circle) 35 | if ok { 36 | fmt.Println("Is a circle!") 37 | } 38 | 39 | v, ok := x.(square) 40 | if ok { 41 | fmt.Println("Is a square:", v) 42 | } 43 | 44 | fmt.Println(x.Area()) 45 | fmt.Println(x.Perimeter()) 46 | } 47 | 48 | func main() { 49 | x := square{X: 10} 50 | fmt.Println("Perimeter:", x.Perimeter()) 51 | Calculate(x) 52 | y := circle{R: 5} 53 | Calculate(y) 54 | } 55 | -------------------------------------------------------------------------------- /ch10/select.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | func gen(min, max int, createNumber chan int, end chan bool) { 12 | for { 13 | select { 14 | case createNumber <- rand.Intn(max-min) + min: 15 | case <-end: 16 | close(end) 17 | return 18 | case <-time.After(4 * time.Second): 19 | fmt.Println("\ntime.After()!") 20 | } 21 | } 22 | } 23 | 24 | func main() { 25 | rand.Seed(time.Now().Unix()) 26 | createNumber := make(chan int) 27 | end := make(chan bool) 28 | 29 | if len(os.Args) != 2 { 30 | fmt.Println("Please give me an integer!") 31 | return 32 | } 33 | 34 | n, _ := strconv.Atoi(os.Args[1]) 35 | fmt.Printf("Going to create %d random numbers.\n", n) 36 | go gen(0, 2*n, createNumber, end) 37 | 38 | for i := 0; i < n; i++ { 39 | fmt.Printf("%d ", <-createNumber) 40 | } 41 | 42 | time.Sleep(5 * time.Second) 43 | fmt.Println("Exiting...") 44 | end <- true 45 | } 46 | -------------------------------------------------------------------------------- /ch12/insert.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A Key Value Store! 6 | 7 | 8 | 9 | Home sweet home! 10 | List all elements! 11 | Change an element! 12 | Insert new element! 13 | 14 | {{if .Success}} 15 |

Element inserted!

16 | {{else}} 17 |

Please fill in the fields:

18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 28 |
29 | {{end}} 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ch12/update.gohtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A Key Value Store! 6 | 7 | 8 | 9 | Home sweet home! 10 | List all elements! 11 | Change an element! 12 | Insert new element! 13 | 14 | {{if .Success}} 15 |

Element updated!

16 | {{else}} 17 |

Please fill in the fields:

18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 28 |
29 | {{end}} 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ch08/readSize.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "strconv" 8 | ) 9 | 10 | func readSize(f *os.File, size int) []byte { 11 | buffer := make([]byte, size) 12 | 13 | n, err := f.Read(buffer) 14 | if err == io.EOF { 15 | return nil 16 | } 17 | 18 | if err != nil { 19 | fmt.Println(err) 20 | return nil 21 | } 22 | 23 | return buffer[0:n] 24 | } 25 | 26 | func main() { 27 | arguments := os.Args 28 | if len(arguments) != 3 { 29 | fmt.Println(" ") 30 | return 31 | } 32 | 33 | bufferSize, err := strconv.Atoi(os.Args[1]) 34 | if err != nil { 35 | fmt.Println(err) 36 | return 37 | } 38 | 39 | file := os.Args[2] 40 | f, err := os.Open(file) 41 | if err != nil { 42 | fmt.Println(err) 43 | return 44 | } 45 | defer f.Close() 46 | 47 | for { 48 | readData := readSize(f, bufferSize) 49 | if readData != nil { 50 | fmt.Print(string(readData)) 51 | } else { 52 | break 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ch04/strings.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | const sLiteral = "\x99\x42\x32\x55\x50\x35\x23\x50\x29\x9c" 9 | fmt.Println(sLiteral) 10 | fmt.Printf("x: %x\n", sLiteral) 11 | 12 | fmt.Printf("sLiteral length: %d\n", len(sLiteral)) 13 | 14 | for i := 0; i < len(sLiteral); i++ { 15 | fmt.Printf("%x ", sLiteral[i]) 16 | } 17 | fmt.Println() 18 | 19 | fmt.Printf("q: %q\n", sLiteral) 20 | fmt.Printf("+q: %+q\n", sLiteral) 21 | fmt.Printf(" x: % x\n", sLiteral) 22 | 23 | fmt.Printf("s: As a string: %s\n", sLiteral) 24 | 25 | s2 := "€£³" 26 | for x, y := range s2 { 27 | fmt.Printf("%#U starts at byte position %d\n", y, x) 28 | } 29 | 30 | fmt.Printf("s2 length: %d\n", len(s2)) 31 | 32 | const s3 = "ab12AB" 33 | fmt.Println("s3:", s3) 34 | fmt.Printf("x: % x\n", s3) 35 | 36 | fmt.Printf("s3 length: %d\n", len(s3)) 37 | 38 | for i := 0; i < len(s3); i++ { 39 | fmt.Printf("%x ", s3[i]) 40 | } 41 | fmt.Println() 42 | } 43 | -------------------------------------------------------------------------------- /ch10/mutex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | var ( 12 | m sync.Mutex 13 | v1 int 14 | ) 15 | 16 | func change(i int) { 17 | m.Lock() 18 | time.Sleep(time.Second) 19 | v1 = v1 + 1 20 | if v1%10 == 0 { 21 | v1 = v1 - 10*i 22 | } 23 | m.Unlock() 24 | } 25 | 26 | func read() int { 27 | m.Lock() 28 | a := v1 29 | m.Unlock() 30 | return a 31 | } 32 | 33 | func main() { 34 | if len(os.Args) != 2 { 35 | fmt.Println("Please give me an integer!") 36 | return 37 | } 38 | 39 | numGR, err := strconv.Atoi(os.Args[1]) 40 | if err != nil { 41 | fmt.Println(err) 42 | return 43 | } 44 | var waitGroup sync.WaitGroup 45 | 46 | fmt.Printf("%d ", read()) 47 | for i := 0; i < numGR; i++ { 48 | waitGroup.Add(1) 49 | go func(i int) { 50 | defer waitGroup.Done() 51 | change(i) 52 | fmt.Printf("-> %d", read()) 53 | }(i) 54 | } 55 | 56 | waitGroup.Wait() 57 | fmt.Printf("-> %d\n", read()) 58 | } 59 | -------------------------------------------------------------------------------- /ch12/testWWW.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | ) 8 | 9 | func CheckStatusOK(w http.ResponseWriter, r *http.Request) { 10 | w.WriteHeader(http.StatusOK) 11 | fmt.Fprintf(w, `Fine!`) 12 | } 13 | 14 | func StatusNotFound(w http.ResponseWriter, r *http.Request) { 15 | w.WriteHeader(http.StatusNotFound) 16 | } 17 | 18 | func MyHandler(w http.ResponseWriter, r *http.Request) { 19 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 20 | fmt.Printf("Served: %s\n", r.Host) 21 | } 22 | 23 | func main() { 24 | PORT := ":8001" 25 | arguments := os.Args 26 | if len(arguments) == 1 { 27 | fmt.Println("Using default port number: ", PORT) 28 | } else { 29 | PORT = ":" + arguments[1] 30 | } 31 | 32 | http.HandleFunc("/CheckStatusOK", CheckStatusOK) 33 | http.HandleFunc("/StatusNotFound", StatusNotFound) 34 | http.HandleFunc("/", MyHandler) 35 | 36 | err := http.ListenAndServe(PORT, nil) 37 | if err != nil { 38 | fmt.Println(err) 39 | return 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ch10/chSquare.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | var times int 11 | 12 | func f1(cc chan chan int, f chan bool) { 13 | c := make(chan int) 14 | cc <- c 15 | defer close(c) 16 | 17 | sum := 0 18 | select { 19 | case x := <-c: 20 | for i := 0; i <= x; i++ { 21 | sum = sum + i 22 | } 23 | c <- sum 24 | case <-f: 25 | return 26 | } 27 | } 28 | 29 | func main() { 30 | arguments := os.Args 31 | if len(arguments) != 2 { 32 | fmt.Println("Need just one integer argument!") 33 | return 34 | } 35 | 36 | times, err := strconv.Atoi(arguments[1]) 37 | if err != nil { 38 | fmt.Println(err) 39 | return 40 | } 41 | 42 | cc := make(chan chan int) 43 | 44 | for i := 1; i < times+1; i++ { 45 | f := make(chan bool) 46 | go f1(cc, f) 47 | ch := <-cc 48 | ch <- i 49 | for sum := range ch { 50 | fmt.Print("Sum(", i, ")=", sum) 51 | } 52 | fmt.Println() 53 | time.Sleep(time.Second) 54 | close(f) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ch08/byWord.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | "regexp" 10 | ) 11 | 12 | func wordByWord(file string) error { 13 | var err error 14 | f, err := os.Open(file) 15 | if err != nil { 16 | return err 17 | } 18 | defer f.Close() 19 | 20 | r := bufio.NewReader(f) 21 | for { 22 | line, err := r.ReadString('\n') 23 | if err == io.EOF { 24 | break 25 | } else if err != nil { 26 | fmt.Printf("error reading file %s", err) 27 | return err 28 | } 29 | 30 | r := regexp.MustCompile("[^\\s]+") 31 | words := r.FindAllString(line, -1) 32 | for i := 0; i < len(words); i++ { 33 | fmt.Println(words[i]) 34 | } 35 | } 36 | return nil 37 | } 38 | 39 | func main() { 40 | flag.Parse() 41 | if len(flag.Args()) == 0 { 42 | fmt.Printf("usage: byWord [ ...]\n") 43 | return 44 | } 45 | 46 | for _, file := range flag.Args() { 47 | err := wordByWord(file) 48 | if err != nil { 49 | fmt.Println(err) 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ch12/www.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | "time" 8 | ) 9 | 10 | func myHandler(w http.ResponseWriter, r *http.Request) { 11 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 12 | fmt.Printf("Served: %s\n", r.Host) 13 | } 14 | 15 | func timeHandler(w http.ResponseWriter, r *http.Request) { 16 | t := time.Now().Format(time.RFC1123) 17 | Body := "The current time is:" 18 | fmt.Fprintf(w, "

%s

", Body) 19 | fmt.Fprintf(w, "

%s

\n", t) 20 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 21 | fmt.Printf("Served time for: %s\n", r.Host) 22 | } 23 | 24 | func main() { 25 | PORT := ":8001" 26 | arguments := os.Args 27 | if len(arguments) != 1 { 28 | PORT = ":" + arguments[1] 29 | } 30 | fmt.Println("Using port number: ", PORT) 31 | 32 | http.HandleFunc("/time", timeHandler) 33 | http.HandleFunc("/", myHandler) 34 | err := http.ListenAndServe(PORT, nil) 35 | if err != nil { 36 | fmt.Println(err) 37 | return 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ch05/conHeap.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "container/heap" 5 | "fmt" 6 | ) 7 | 8 | type heapFloat32 []float32 9 | 10 | func (n *heapFloat32) Pop() interface{} { 11 | old := *n 12 | x := old[len(old)-1] 13 | new := old[0 : len(old)-1] 14 | *n = new 15 | return x 16 | } 17 | 18 | func (n *heapFloat32) Push(x interface{}) { 19 | *n = append(*n, x.(float32)) 20 | } 21 | 22 | func (n heapFloat32) Len() int { 23 | return len(n) 24 | } 25 | 26 | func (n heapFloat32) Less(a, b int) bool { 27 | return n[a] < n[b] 28 | } 29 | 30 | func (n heapFloat32) Swap(a, b int) { 31 | n[a], n[b] = n[b], n[a] 32 | } 33 | 34 | func main() { 35 | myHeap := &heapFloat32{1.2, 2.1, 3.1, -100.1} 36 | heap.Init(myHeap) 37 | size := len(*myHeap) 38 | fmt.Printf("Heap size: %d\n", size) 39 | fmt.Printf("%v\n", myHeap) 40 | myHeap.Push(float32(-100.2)) 41 | myHeap.Push(float32(0.2)) 42 | fmt.Printf("Heap size: %d\n", len(*myHeap)) 43 | fmt.Printf("%v\n", myHeap) 44 | heap.Init(myHeap) 45 | fmt.Printf("%v\n", myHeap) 46 | } 47 | -------------------------------------------------------------------------------- /ch12/DNS.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | func lookIP(address string) ([]string, error) { 10 | hosts, err := net.LookupAddr(address) 11 | if err != nil { 12 | return nil, err 13 | } 14 | return hosts, nil 15 | } 16 | 17 | func lookHostname(hostname string) ([]string, error) { 18 | IPs, err := net.LookupHost(hostname) 19 | if err != nil { 20 | return nil, err 21 | } 22 | return IPs, nil 23 | } 24 | 25 | func main() { 26 | arguments := os.Args 27 | if len(arguments) == 1 { 28 | fmt.Println("Please provide an argument!") 29 | return 30 | } 31 | 32 | input := arguments[1] 33 | IPaddress := net.ParseIP(input) 34 | 35 | if IPaddress == nil { 36 | IPs, err := lookHostname(input) 37 | if err == nil { 38 | for _, singleIP := range IPs { 39 | fmt.Println(singleIP) 40 | } 41 | } 42 | } else { 43 | hosts, err := lookIP(input) 44 | if err == nil { 45 | for _, hostname := range hosts { 46 | fmt.Println(hostname) 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ch13/otherTCPclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | arguments := os.Args 13 | if len(arguments) == 1 { 14 | fmt.Println("Please provide a server:port string!") 15 | return 16 | } 17 | 18 | CONNECT := arguments[1] 19 | 20 | tcpAddr, err := net.ResolveTCPAddr("tcp4", CONNECT) 21 | if err != nil { 22 | fmt.Println("ResolveTCPAddr:", err.Error()) 23 | return 24 | } 25 | 26 | conn, err := net.DialTCP("tcp4", nil, tcpAddr) 27 | if err != nil { 28 | fmt.Println("DialTCP:", err.Error()) 29 | return 30 | } 31 | 32 | for { 33 | reader := bufio.NewReader(os.Stdin) 34 | fmt.Print(">> ") 35 | text, _ := reader.ReadString('\n') 36 | fmt.Fprintf(conn, text+"\n") 37 | 38 | message, _ := bufio.NewReader(conn).ReadString('\n') 39 | fmt.Print("->: " + message) 40 | if strings.TrimSpace(string(text)) == "STOP" { 41 | fmt.Println("TCP client exiting...") 42 | conn.Close() 43 | return 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ch08/goFind.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | ) 9 | 10 | var minusD bool = false 11 | var minusF bool = false 12 | 13 | func walk(path string, info os.FileInfo, err error) error { 14 | fileInfo, err := os.Stat(path) 15 | if err != nil { 16 | return err 17 | } 18 | 19 | mode := fileInfo.Mode() 20 | if mode.IsRegular() && minusF { 21 | fmt.Println("+", path) 22 | return nil 23 | } 24 | 25 | if mode.IsDir() && minusD { 26 | fmt.Println("*", path) 27 | return nil 28 | } 29 | 30 | fmt.Println(path) 31 | return nil 32 | } 33 | 34 | func main() { 35 | starD := flag.Bool("d", false, "Signify directories") 36 | plusF := flag.Bool("f", false, "Signify regular files") 37 | flag.Parse() 38 | flags := flag.Args() 39 | 40 | Path := "." 41 | if len(flags) == 1 { 42 | Path = flags[0] 43 | } 44 | 45 | minusD = *starD 46 | minusF = *plusF 47 | 48 | err := filepath.Walk(Path, walk) 49 | if err != nil { 50 | fmt.Println(err) 51 | os.Exit(1) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ch11/testMe_test.go: -------------------------------------------------------------------------------- 1 | package testMe 2 | 3 | import "testing" 4 | 5 | func TestS1(t *testing.T) { 6 | if s1("123456789") != 9 { 7 | t.Error(`s1("123456789") != 9`) 8 | } 9 | 10 | if s1("") != 0 { 11 | t.Error(`s1("") != 0`) 12 | } 13 | } 14 | 15 | func TestS2(t *testing.T) { 16 | if s2("123456789") != 9 { 17 | t.Error(`s2("123456789") != 9`) 18 | } 19 | 20 | if s2("") != 0 { 21 | t.Error(`s2("") != 0`) 22 | } 23 | } 24 | 25 | func TestF1(t *testing.T) { 26 | if f1(0) != 0 { 27 | t.Error(`f1(0) != 0`) 28 | } 29 | 30 | if f1(1) != 1 { 31 | t.Error(`f1(1) != 1`) 32 | } 33 | 34 | if f1(2) != 1 { 35 | t.Error(`f1(2) != 1`) 36 | } 37 | 38 | if f1(10) != 55 { 39 | t.Error(`f1(10) != 55`) 40 | } 41 | 42 | } 43 | 44 | func TestF2(t *testing.T) { 45 | if f2(0) != 0 { 46 | t.Error(`f2(0) != 0`) 47 | } 48 | 49 | if f2(1) != 1 { 50 | t.Error(`f2(1) != 1`) 51 | } 52 | 53 | if f2(2) != 1 { 54 | t.Error(`f2(2) != 1`) 55 | } 56 | 57 | if f2(10) != 55 { 58 | t.Error(`f2(10) != 55`) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ch05/hashTable.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const SIZE = 15 8 | 9 | type Node struct { 10 | Value int 11 | Next *Node 12 | } 13 | 14 | type HashTable struct { 15 | Table map[int]*Node 16 | Size int 17 | } 18 | 19 | func hashFunction(i, size int) int { 20 | return (i % size) 21 | } 22 | 23 | func insert(hash *HashTable, value int) int { 24 | index := hashFunction(value, hash.Size) 25 | element := Node{Value: value, Next: hash.Table[index]} 26 | hash.Table[index] = &element 27 | return index 28 | } 29 | 30 | func traverse(hash *HashTable) { 31 | for k := range hash.Table { 32 | if hash.Table[k] != nil { 33 | t := hash.Table[k] 34 | for t != nil { 35 | fmt.Printf("%d -> ", t.Value) 36 | t = t.Next 37 | } 38 | fmt.Println() 39 | } 40 | } 41 | } 42 | 43 | func main() { 44 | table := make(map[int]*Node, SIZE) 45 | hash := &HashTable{Table: table, Size: SIZE} 46 | fmt.Println("Number of spaces:", hash.Size) 47 | for i := 0; i < 120; i++ { 48 | insert(hash, i) 49 | } 50 | traverse(hash) 51 | } 52 | -------------------------------------------------------------------------------- /ch03/timeDate.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | 11 | logs := []string{"127.0.0.1 - - [16/Nov/2017:10:49:46 +0200] 325504", 12 | "127.0.0.1 - - [16/Nov/2017:10:16:41 +0200] \"GET /CVEN HTTP/1.1\" 200 12531 \"-\" \"Mozilla/5.0 AppleWebKit/537.36", 13 | "127.0.0.1 200 9412 - - [12/Nov/2017:06:26:05 +0200] \"GET \"http://www.mtsoukalos.eu/taxonomy/term/47\" 1507", 14 | "[12/Nov/2017:16:27:21 +0300]", 15 | "[12/Nov/2017:20:88:21 +0200]", 16 | "[12/Nov/2017:20:21 +0200]", 17 | } 18 | 19 | for _, logEntry := range logs { 20 | r := regexp.MustCompile(`.*\[(\d\d\/\w+/\d\d\d\d:\d\d:\d\d:\d\d.*)\].*`) 21 | if r.MatchString(logEntry) { 22 | match := r.FindStringSubmatch(logEntry) 23 | dt, err := time.Parse("02/Jan/2006:15:04:05 -0700", match[1]) 24 | if err == nil { 25 | newFormat := dt.Format(time.RFC850) 26 | fmt.Println(newFormat) 27 | } else { 28 | fmt.Println("Not a valid date time format!") 29 | } 30 | } else { 31 | fmt.Println("Not a match!") 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ch04/calculatePi_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | // TestPi is a regression test for the Pi function. Run: go test calculatePi_test.go calculatePi.go 9 | func TestPi(t *testing.T) { 10 | tests := map[uint]string{ 11 | 1: "4", 12 | 2: "3", 13 | 60: "3.14159265358979324", 14 | 600: "3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105557", 15 | // 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196 16 | // ^ First 200 digits of Pi. Source: https://www.piday.org/million/ 17 | } 18 | for input, expected := range tests { 19 | t.Run("", func(t *testing.T) { 20 | precision = input 21 | actual := Pi(precision) 22 | if fmt.Sprintf("%v", actual) != expected { 23 | t.Errorf("Pi(%d) = %v; want %s", input, actual, expected) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ch07/reflection.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "reflect" 7 | ) 8 | 9 | type a struct { 10 | X int 11 | Y float64 12 | Z string 13 | } 14 | 15 | type b struct { 16 | F int 17 | G int 18 | H string 19 | I float64 20 | } 21 | 22 | func main() { 23 | x := 100 24 | xRefl := reflect.ValueOf(&x).Elem() 25 | xType := xRefl.Type() 26 | fmt.Printf("The type of x is %s.\n", xType) 27 | // fmt.Printf("The type of x is %s.\n", reflect.TypeOf(x)) 28 | 29 | A := a{100, 200.12, "Struct a"} 30 | B := b{1, 2, "Struct b", -1.2} 31 | var r reflect.Value 32 | 33 | arguments := os.Args 34 | if len(arguments) == 1 { 35 | r = reflect.ValueOf(&A).Elem() 36 | } else { 37 | r = reflect.ValueOf(&B).Elem() 38 | } 39 | 40 | iType := r.Type() 41 | fmt.Printf("i Type: %s\n", iType) 42 | fmt.Printf("The %d fields of %s are:\n", r.NumField(), iType) 43 | 44 | for i := 0; i < r.NumField(); i++ { 45 | fmt.Printf("Field name: %s ", iType.Field(i).Name) 46 | fmt.Printf("with type: %s ", r.Field(i).Type()) 47 | fmt.Printf("and value %v\n", r.Field(i).Interface()) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ch12/testWWW_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/httptest" 7 | "testing" 8 | ) 9 | 10 | func TestCheckStatusOK(t *testing.T) { 11 | req, err := http.NewRequest("GET", "/CheckStatusOK", nil) 12 | if err != nil { 13 | fmt.Println(err) 14 | return 15 | } 16 | 17 | rr := httptest.NewRecorder() 18 | handler := http.HandlerFunc(CheckStatusOK) 19 | handler.ServeHTTP(rr, req) 20 | 21 | status := rr.Code 22 | if status != http.StatusOK { 23 | t.Errorf("handler returned %v", status) 24 | } 25 | 26 | expect := `Fine!` 27 | if rr.Body.String() != expect { 28 | t.Errorf("handler returned %v", rr.Body.String()) 29 | } 30 | } 31 | 32 | func TestStatusNotFound(t *testing.T) { 33 | req, err := http.NewRequest("GET", "/StatusNotFound", nil) 34 | if err != nil { 35 | fmt.Println(err) 36 | return 37 | } 38 | 39 | rr := httptest.NewRecorder() 40 | handler := http.HandlerFunc(StatusNotFound) 41 | handler.ServeHTTP(rr, req) 42 | 43 | status := rr.Code 44 | if status != http.StatusNotFound { 45 | t.Errorf("handler returned %v", status) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ch10/timeOut2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | func timeout(w *sync.WaitGroup, t time.Duration) bool { 12 | temp := make(chan int) 13 | go func() { 14 | time.Sleep(5 * time.Second) 15 | defer close(temp) 16 | w.Wait() 17 | }() 18 | 19 | select { 20 | case <-temp: 21 | return false 22 | case <-time.After(t): 23 | return true 24 | } 25 | } 26 | 27 | func main() { 28 | arguments := os.Args 29 | if len(arguments) != 2 { 30 | fmt.Println("Need a time duration!") 31 | return 32 | } 33 | 34 | var w sync.WaitGroup 35 | w.Add(1) 36 | 37 | t, err := strconv.Atoi(arguments[1]) 38 | if err != nil { 39 | fmt.Println(err) 40 | return 41 | } 42 | 43 | duration := time.Duration(int32(t)) * time.Millisecond 44 | fmt.Printf("Timeout period is %s\n", duration) 45 | 46 | if timeout(&w, duration) { 47 | fmt.Println("Timed out!") 48 | } else { 49 | fmt.Println("OK!") 50 | } 51 | 52 | w.Done() 53 | if timeout(&w, duration) { 54 | fmt.Println("Timed out!") 55 | } else { 56 | fmt.Println("OK!") 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ch11/goGC.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "runtime" 7 | "runtime/trace" 8 | "time" 9 | ) 10 | 11 | func printStats(mem runtime.MemStats) { 12 | runtime.ReadMemStats(&mem) 13 | fmt.Println("mem.Alloc:", mem.Alloc) 14 | fmt.Println("mem.TotalAlloc:", mem.TotalAlloc) 15 | fmt.Println("mem.HeapAlloc:", mem.HeapAlloc) 16 | fmt.Println("mem.NumGC:", mem.NumGC) 17 | fmt.Println("-----") 18 | } 19 | 20 | func main() { 21 | f, err := os.Create("/tmp/traceFile.out") 22 | if err != nil { 23 | panic(err) 24 | } 25 | defer f.Close() 26 | 27 | err = trace.Start(f) 28 | if err != nil { 29 | fmt.Println(err) 30 | return 31 | } 32 | defer trace.Stop() 33 | 34 | var mem runtime.MemStats 35 | printStats(mem) 36 | 37 | for i := 0; i < 3; i++ { 38 | s := make([]byte, 50000000) 39 | if s == nil { 40 | fmt.Println("Operation failed!") 41 | } 42 | } 43 | printStats(mem) 44 | 45 | for i := 0; i < 5; i++ { 46 | s := make([]byte, 100000000) 47 | if s == nil { 48 | fmt.Println("Operation failed!") 49 | } 50 | time.Sleep(time.Millisecond) 51 | } 52 | printStats(mem) 53 | } 54 | -------------------------------------------------------------------------------- /ch13/otherTCPserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | arguments := os.Args 12 | if len(arguments) == 1 { 13 | fmt.Println("Please provide a port number!") 14 | return 15 | } 16 | 17 | SERVER := "localhost" + ":" + arguments[1] 18 | 19 | s, err := net.ResolveTCPAddr("tcp", SERVER) 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } 24 | 25 | l, err := net.ListenTCP("tcp", s) 26 | if err != nil { 27 | fmt.Println(err) 28 | return 29 | } 30 | 31 | buffer := make([]byte, 1024) 32 | conn, err := l.Accept() 33 | if err != nil { 34 | fmt.Println(err) 35 | return 36 | } 37 | 38 | for { 39 | n, err := conn.Read(buffer) 40 | if err != nil { 41 | fmt.Println(err) 42 | return 43 | } 44 | 45 | if strings.TrimSpace(string(buffer[0:n])) == "STOP" { 46 | fmt.Println("Exiting TCP server!") 47 | conn.Close() 48 | return 49 | } 50 | 51 | fmt.Print("> ", string(buffer[0:n-1])) 52 | _, err = conn.Write(buffer) 53 | if err != nil { 54 | fmt.Println(err) 55 | return 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ch10/monitor.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "sync" 9 | "time" 10 | ) 11 | 12 | var readValue = make(chan int) 13 | var writeValue = make(chan int) 14 | 15 | func set(newValue int) { 16 | writeValue <- newValue 17 | } 18 | 19 | func read() int { 20 | return <-readValue 21 | } 22 | 23 | func monitor() { 24 | var value int 25 | for { 26 | select { 27 | case newValue := <-writeValue: 28 | value = newValue 29 | fmt.Printf("%d ", value) 30 | case readValue <- value: 31 | } 32 | } 33 | } 34 | 35 | func main() { 36 | if len(os.Args) != 2 { 37 | fmt.Println("Please give an integer!") 38 | return 39 | } 40 | n, err := strconv.Atoi(os.Args[1]) 41 | if err != nil { 42 | fmt.Println(err) 43 | return 44 | } 45 | 46 | fmt.Printf("Going to create %d random numbers.\n", n) 47 | rand.Seed(time.Now().Unix()) 48 | go monitor() 49 | var w sync.WaitGroup 50 | 51 | for r := 0; r < n; r++ { 52 | w.Add(1) 53 | go func() { 54 | defer w.Done() 55 | set(rand.Intn(10 * n)) 56 | }() 57 | } 58 | w.Wait() 59 | fmt.Printf("\nLast value: %d\n", read()) 60 | } 61 | -------------------------------------------------------------------------------- /ch08/funWithFlag.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "strings" 7 | ) 8 | 9 | type NamesFlag struct { 10 | Names []string 11 | } 12 | 13 | func (s *NamesFlag) GetNames() []string { 14 | return s.Names 15 | } 16 | 17 | func (s *NamesFlag) String() string { 18 | return fmt.Sprint(s.Names) 19 | } 20 | 21 | func (s *NamesFlag) Set(v string) error { 22 | if len(s.Names) > 0 { 23 | return fmt.Errorf("Cannot use names flag more than once!") 24 | } 25 | 26 | names := strings.Split(v, ",") 27 | for _, item := range names { 28 | s.Names = append(s.Names, item) 29 | } 30 | return nil 31 | } 32 | 33 | func main() { 34 | var manyNames NamesFlag 35 | minusK := flag.Int("k", 0, "An int") 36 | minusO := flag.String("o", "Mihalis", "The name") 37 | flag.Var(&manyNames, "names", "Comma-separated list") 38 | 39 | flag.Parse() 40 | fmt.Println("-k:", *minusK) 41 | fmt.Println("-o:", *minusO) 42 | 43 | for i, item := range manyNames.GetNames() { 44 | fmt.Println(i, item) 45 | } 46 | 47 | fmt.Println("Remaining command line arguments:") 48 | for index, val := range flag.Args() { 49 | fmt.Println(index, ":", val) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ch13/UDPclient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | arguments := os.Args 13 | if len(arguments) == 1 { 14 | fmt.Println("Please provide a host:port string") 15 | return 16 | } 17 | CONNECT := arguments[1] 18 | 19 | s, err := net.ResolveUDPAddr("udp4", CONNECT) 20 | c, err := net.DialUDP("udp4", nil, s) 21 | 22 | if err != nil { 23 | fmt.Println(err) 24 | return 25 | } 26 | 27 | fmt.Printf("The UDP server is %s\n", c.RemoteAddr().String()) 28 | defer c.Close() 29 | 30 | for { 31 | reader := bufio.NewReader(os.Stdin) 32 | fmt.Print(">> ") 33 | text, _ := reader.ReadString('\n') 34 | data := []byte(text + "\n") 35 | _, err = c.Write(data) 36 | if strings.TrimSpace(string(data)) == "STOP" { 37 | fmt.Println("Exiting UDP client!") 38 | return 39 | } 40 | 41 | if err != nil { 42 | fmt.Println(err) 43 | return 44 | } 45 | 46 | buffer := make([]byte, 1024) 47 | n, _, err := c.ReadFromUDP(buffer) 48 | if err != nil { 49 | fmt.Println(err) 50 | return 51 | } 52 | fmt.Printf("Reply: %s\n", string(buffer[0:n])) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ch05/binTree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | ) 8 | 9 | type Tree struct { 10 | Left *Tree 11 | Value int 12 | Right *Tree 13 | } 14 | 15 | func traverse(t *Tree) { 16 | if t == nil { 17 | return 18 | } 19 | traverse(t.Left) 20 | fmt.Print(t.Value, " ") 21 | traverse(t.Right) 22 | } 23 | 24 | func create(n int) *Tree { 25 | var t *Tree 26 | rand.Seed(time.Now().Unix()) 27 | for i := 0; i < 2*n; i++ { 28 | temp := rand.Intn(n * 2) 29 | t = insert(t, temp) 30 | } 31 | return t 32 | } 33 | 34 | func insert(t *Tree, v int) *Tree { 35 | if t == nil { 36 | return &Tree{nil, v, nil} 37 | } 38 | 39 | if v == t.Value { 40 | return t 41 | } 42 | 43 | if v < t.Value { 44 | t.Left = insert(t.Left, v) 45 | return t 46 | } 47 | t.Right = insert(t.Right, v) 48 | return t 49 | } 50 | 51 | func main() { 52 | tree := create(10) 53 | fmt.Println("The value of the root of the tree is", tree.Value) 54 | traverse(tree) 55 | fmt.Println() 56 | tree = insert(tree, -10) 57 | tree = insert(tree, -2) 58 | traverse(tree) 59 | fmt.Println() 60 | fmt.Println("The value of the root of the tree is", tree.Value) 61 | } 62 | -------------------------------------------------------------------------------- /ch13/RPCserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "net" 7 | "net/rpc" 8 | "os" 9 | "sharedRPC" 10 | ) 11 | 12 | type MyInterface struct{} 13 | 14 | func Power(x, y float64) float64 { 15 | return math.Pow(x, y) 16 | } 17 | 18 | func (t *MyInterface) Multiply(arguments *sharedRPC.MyFloats, reply *float64) error { 19 | *reply = arguments.A1 * arguments.A2 20 | return nil 21 | } 22 | 23 | func (t *MyInterface) Power(arguments *sharedRPC.MyFloats, reply *float64) error { 24 | *reply = Power(arguments.A1, arguments.A2) 25 | return nil 26 | } 27 | 28 | func main() { 29 | PORT := ":1234" 30 | arguments := os.Args 31 | if len(arguments) != 1 { 32 | PORT = ":" + arguments[1] 33 | } 34 | 35 | myInterface := new(MyInterface) 36 | rpc.Register(myInterface) 37 | t, err := net.ResolveTCPAddr("tcp4", PORT) 38 | if err != nil { 39 | fmt.Println(err) 40 | return 41 | } 42 | l, err := net.ListenTCP("tcp4", t) 43 | if err != nil { 44 | fmt.Println(err) 45 | return 46 | } 47 | 48 | for { 49 | c, err := l.Accept() 50 | if err != nil { 51 | continue 52 | } 53 | fmt.Printf("%s\n", c.RemoteAddr()) 54 | rpc.ServeConn(c) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ch04/selectColumn.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | "strconv" 9 | "strings" 10 | ) 11 | 12 | func main() { 13 | arguments := os.Args 14 | if len(arguments) < 2 { 15 | fmt.Printf("usage: selectColumn column [ [... = column { 52 | fmt.Println((data[column-1])) 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ch12/serverTimeOut.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | "time" 8 | ) 9 | 10 | func myHandler(w http.ResponseWriter, r *http.Request) { 11 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 12 | fmt.Printf("Served: %s\n", r.Host) 13 | } 14 | 15 | func timeHandler(w http.ResponseWriter, r *http.Request) { 16 | t := time.Now().Format(time.RFC1123) 17 | Body := "The current time is:" 18 | fmt.Fprintf(w, "

%s

", Body) 19 | fmt.Fprintf(w, "

%s

\n", t) 20 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 21 | fmt.Printf("Served time for: %s\n", r.Host) 22 | } 23 | 24 | func main() { 25 | PORT := ":8001" 26 | arguments := os.Args 27 | if len(arguments) != 1 { 28 | PORT = ":" + arguments[1] 29 | } 30 | fmt.Println("Using port number:", PORT) 31 | 32 | m := http.NewServeMux() 33 | srv := &http.Server{ 34 | Addr: PORT, 35 | Handler: m, 36 | ReadTimeout: 3 * time.Second, 37 | WriteTimeout: 3 * time.Second, 38 | } 39 | 40 | m.HandleFunc("/time", timeHandler) 41 | m.HandleFunc("/", myHandler) 42 | 43 | err := srv.ListenAndServe() 44 | if err != nil { 45 | fmt.Println(err) 46 | return 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ch04/findIPv4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "net" 8 | "os" 9 | "path/filepath" 10 | "regexp" 11 | ) 12 | 13 | func findIP(input string) string { 14 | partIP := "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])" 15 | grammar := partIP + "\\." + partIP + "\\." + partIP + "\\." + partIP 16 | matchMe := regexp.MustCompile(grammar) 17 | return matchMe.FindString(input) 18 | } 19 | 20 | func main() { 21 | arguments := os.Args 22 | if len(arguments) < 2 { 23 | fmt.Printf("usage: %s logFile\n", filepath.Base(arguments[0])) 24 | os.Exit(1) 25 | } 26 | 27 | for _, filename := range arguments[1:] { 28 | f, err := os.Open(filename) 29 | if err != nil { 30 | fmt.Printf("error opening file %s\n", err) 31 | os.Exit(-1) 32 | } 33 | defer f.Close() 34 | 35 | r := bufio.NewReader(f) 36 | for { 37 | line, err := r.ReadString('\n') 38 | if err == io.EOF { 39 | break 40 | } else if err != nil { 41 | fmt.Printf("error reading file %s", err) 42 | break 43 | } 44 | 45 | ip := findIP(line) 46 | trial := net.ParseIP(ip) 47 | if trial.To4() == nil { 48 | continue 49 | } else { 50 | fmt.Println(ip) 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ch08/save.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "io/ioutil" 8 | "os" 9 | ) 10 | 11 | func main() { 12 | s := []byte("Data to write\n") 13 | 14 | f1, err := os.Create("f1.txt") 15 | if err != nil { 16 | fmt.Println("Cannot create file", err) 17 | return 18 | } 19 | defer f1.Close() 20 | fmt.Fprintf(f1, string(s)) 21 | 22 | f2, err := os.Create("f2.txt") 23 | if err != nil { 24 | fmt.Println("Cannot create file", err) 25 | return 26 | } 27 | defer f2.Close() 28 | n, err := f2.WriteString(string(s)) 29 | fmt.Printf("wrote %d bytes\n", n) 30 | 31 | f3, err := os.Create("f3.txt") 32 | if err != nil { 33 | fmt.Println(err) 34 | return 35 | } 36 | w := bufio.NewWriter(f3) 37 | n, err = w.WriteString(string(s)) 38 | fmt.Printf("wrote %d bytes\n", n) 39 | w.Flush() 40 | 41 | f4 := "f4.txt" 42 | err = ioutil.WriteFile(f4, s, 0644) 43 | if err != nil { 44 | fmt.Println(err) 45 | return 46 | } 47 | 48 | f5, err := os.Create("f5.txt") 49 | if err != nil { 50 | fmt.Println(err) 51 | return 52 | } 53 | n, err = io.WriteString(f5, string(s)) 54 | if err != nil { 55 | fmt.Println(err) 56 | return 57 | } 58 | fmt.Printf("wrote %d bytes\n", n) 59 | } 60 | -------------------------------------------------------------------------------- /ch13/UDPserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "net" 7 | "os" 8 | "strconv" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | func random(min, max int) int { 14 | return rand.Intn(max-min) + min 15 | } 16 | 17 | func main() { 18 | arguments := os.Args 19 | if len(arguments) == 1 { 20 | fmt.Println("Please provide a port number!") 21 | return 22 | } 23 | PORT := ":" + arguments[1] 24 | 25 | s, err := net.ResolveUDPAddr("udp4", PORT) 26 | if err != nil { 27 | fmt.Println(err) 28 | return 29 | } 30 | 31 | connection, err := net.ListenUDP("udp4", s) 32 | if err != nil { 33 | fmt.Println(err) 34 | return 35 | } 36 | 37 | defer connection.Close() 38 | buffer := make([]byte, 1024) 39 | rand.Seed(time.Now().Unix()) 40 | 41 | for { 42 | n, addr, err := connection.ReadFromUDP(buffer) 43 | fmt.Print("-> ", string(buffer[0:n-1])) 44 | 45 | if strings.TrimSpace(string(buffer[0:n])) == "STOP" { 46 | fmt.Println("Exiting UDP server!") 47 | return 48 | } 49 | 50 | data := []byte(strconv.Itoa(random(1, 1001))) 51 | fmt.Printf("data: %s\n", string(data)) 52 | _, err = connection.WriteToUDP(data, addr) 53 | if err != nil { 54 | fmt.Println(err) 55 | return 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ch12/clientTimeOut.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net" 7 | "net/http" 8 | "os" 9 | "path/filepath" 10 | "strconv" 11 | "time" 12 | ) 13 | 14 | var timeout = time.Duration(time.Second) 15 | 16 | func Timeout(network, host string) (net.Conn, error) { 17 | conn, err := net.DialTimeout(network, host, timeout) 18 | if err != nil { 19 | return nil, err 20 | } 21 | conn.SetDeadline(time.Now().Add(timeout)) 22 | return conn, nil 23 | } 24 | 25 | func main() { 26 | if len(os.Args) == 1 { 27 | fmt.Printf("Usage: %s URL TIMEOUT\n", filepath.Base(os.Args[0])) 28 | return 29 | } 30 | 31 | if len(os.Args) == 3 { 32 | temp, err := strconv.Atoi(os.Args[2]) 33 | if err != nil { 34 | fmt.Println("Using Default Timeout!") 35 | } else { 36 | timeout = time.Duration(time.Duration(temp) * time.Second) 37 | } 38 | } 39 | 40 | URL := os.Args[1] 41 | t := http.Transport{ 42 | Dial: Timeout, 43 | } 44 | 45 | client := http.Client{ 46 | Transport: &t, 47 | } 48 | 49 | data, err := client.Get(URL) 50 | if err != nil { 51 | fmt.Println(err) 52 | return 53 | } else { 54 | defer data.Body.Close() 55 | _, err := io.Copy(os.Stdout, data.Body) 56 | if err != nil { 57 | fmt.Println(err) 58 | return 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ch05/randomNumbers.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | func random(min, max int) int { 12 | return rand.Intn(max-min) + min 13 | } 14 | 15 | func main() { 16 | MIN := 0 17 | MAX := 100 18 | TOTAL := 100 19 | SEED := time.Now().Unix() 20 | 21 | arguments := os.Args 22 | switch len(arguments) { 23 | case 2: 24 | fmt.Println("Usage: ./randomNumbers MIN MAX TOTAL SEED") 25 | MIN, _ = strconv.Atoi(arguments[1]) 26 | MAX = MIN + 100 27 | case 3: 28 | fmt.Println("Usage: ./randomNumbers MIN MAX TOTAL SEED") 29 | MIN, _ = strconv.Atoi(arguments[1]) 30 | MAX, _ = strconv.Atoi(arguments[2]) 31 | case 4: 32 | fmt.Println("Usage: ./randomNumbers MIN MAX TOTAL SEED") 33 | MIN, _ = strconv.Atoi(arguments[1]) 34 | MAX, _ = strconv.Atoi(arguments[2]) 35 | TOTAL, _ = strconv.Atoi(arguments[3]) 36 | case 5: 37 | MIN, _ = strconv.Atoi(arguments[1]) 38 | MAX, _ = strconv.Atoi(arguments[2]) 39 | TOTAL, _ = strconv.Atoi(arguments[3]) 40 | SEED, _ = strconv.ParseInt(arguments[4], 10, 64) 41 | default: 42 | fmt.Println("Using default values!") 43 | } 44 | 45 | rand.Seed(SEED) 46 | for i := 0; i < TOTAL; i++ { 47 | myrand := random(MIN, MAX) 48 | fmt.Print(myrand) 49 | fmt.Print(" ") 50 | } 51 | fmt.Println() 52 | } 53 | -------------------------------------------------------------------------------- /ch07/advRefl.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "reflect" 7 | ) 8 | 9 | type t1 int 10 | type t2 int 11 | 12 | type a struct { 13 | X int 14 | Y float64 15 | Text string 16 | } 17 | 18 | func (a1 a) compareStruct(a2 a) bool { 19 | r1 := reflect.ValueOf(&a1).Elem() 20 | r2 := reflect.ValueOf(&a2).Elem() 21 | 22 | for i := 0; i < r1.NumField(); i++ { 23 | if r1.Field(i).Interface() != r2.Field(i).Interface() { 24 | return false 25 | } 26 | } 27 | return true 28 | } 29 | 30 | func printMethods(i interface{}) { 31 | r := reflect.ValueOf(i) 32 | t := r.Type() 33 | fmt.Printf("Type to examine: %s\n", t) 34 | 35 | for j := 0; j < r.NumMethod(); j++ { 36 | m := r.Method(j).Type() 37 | fmt.Println(t.Method(j).Name, "-->", m) 38 | } 39 | } 40 | 41 | func main() { 42 | x1 := t1(100) 43 | x2 := t2(100) 44 | fmt.Printf("The type of x1 is %s\n", reflect.TypeOf(x1)) 45 | fmt.Printf("The type of x2 is %s\n", reflect.TypeOf(x2)) 46 | 47 | var p struct{} 48 | r := reflect.New(reflect.ValueOf(&p).Type()).Elem() 49 | fmt.Printf("The type of r is %s\n", reflect.TypeOf(r)) 50 | 51 | a1 := a{1, 2.1, "A1"} 52 | a2 := a{1, -2, "A2"} 53 | 54 | if a1.compareStruct(a1) { 55 | fmt.Println("Equal!") 56 | } 57 | 58 | if !a1.compareStruct(a2) { 59 | fmt.Println("Not Equal!") 60 | } 61 | 62 | var f *os.File 63 | printMethods(f) 64 | } 65 | -------------------------------------------------------------------------------- /ch12/httpTrace.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "net/http/httptrace" 8 | "os" 9 | ) 10 | 11 | func main() { 12 | if len(os.Args) != 2 { 13 | fmt.Printf("Usage: URL\n") 14 | return 15 | } 16 | 17 | URL := os.Args[1] 18 | client := http.Client{} 19 | 20 | req, _ := http.NewRequest("GET", URL, nil) 21 | trace := &httptrace.ClientTrace{ 22 | GotFirstResponseByte: func() { 23 | fmt.Println("First response byte!") 24 | }, 25 | GotConn: func(connInfo httptrace.GotConnInfo) { 26 | fmt.Printf("Got Conn: %+v\n", connInfo) 27 | }, 28 | DNSDone: func(dnsInfo httptrace.DNSDoneInfo) { 29 | fmt.Printf("DNS Info: %+v\n", dnsInfo) 30 | }, 31 | ConnectStart: func(network, addr string) { 32 | fmt.Println("Dial start") 33 | }, 34 | ConnectDone: func(network, addr string, err error) { 35 | fmt.Println("Dial done") 36 | }, 37 | WroteHeaders: func() { 38 | fmt.Println("Wrote headers") 39 | }, 40 | } 41 | 42 | req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) 43 | fmt.Println("Requesting data from server!") 44 | _, err := http.DefaultTransport.RoundTrip(req) 45 | if err != nil { 46 | fmt.Println(err) 47 | return 48 | } 49 | 50 | response, err := client.Do(req) 51 | if err != nil { 52 | fmt.Println(err) 53 | return 54 | } 55 | 56 | io.Copy(os.Stdout, response.Body) 57 | } 58 | -------------------------------------------------------------------------------- /ch13/fiboTCP.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "net" 7 | "os" 8 | "strconv" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | func f(n int) int { 14 | fn := make(map[int]int) 15 | for i := 0; i <= n; i++ { 16 | var f int 17 | if i <= 2 { 18 | f = 1 19 | } else { 20 | f = fn[i-1] + fn[i-2] 21 | } 22 | fn[i] = f 23 | } 24 | return fn[n] 25 | } 26 | 27 | func handleConnection(c net.Conn) { 28 | for { 29 | netData, err := bufio.NewReader(c).ReadString('\n') 30 | if err != nil { 31 | fmt.Println(err) 32 | os.Exit(100) 33 | } 34 | 35 | temp := strings.TrimSpace(string(netData)) 36 | if temp == "STOP" { 37 | break 38 | } 39 | 40 | fibo := "-1\n" 41 | n, err := strconv.Atoi(temp) 42 | if err == nil { 43 | fibo = strconv.Itoa(f(n)) + "\n" 44 | } 45 | c.Write([]byte(string(fibo))) 46 | } 47 | time.Sleep(5 * time.Second) 48 | c.Close() 49 | } 50 | 51 | func main() { 52 | arguments := os.Args 53 | if len(arguments) == 1 { 54 | fmt.Println("Please provide a port number!") 55 | return 56 | } 57 | 58 | PORT := ":" + arguments[1] 59 | l, err := net.Listen("tcp4", PORT) 60 | if err != nil { 61 | fmt.Println(err) 62 | return 63 | } 64 | defer l.Close() 65 | 66 | for { 67 | c, err := l.Accept() 68 | if err != nil { 69 | fmt.Println(err) 70 | return 71 | } 72 | go handleConnection(c) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /ch09/pipeline.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | var CLOSEA = false 12 | 13 | var DATA = make(map[int]bool) 14 | 15 | func random(min, max int) int { 16 | return rand.Intn(max-min) + min 17 | } 18 | 19 | func first(min, max int, out chan<- int) { 20 | for { 21 | if CLOSEA { 22 | close(out) 23 | return 24 | } 25 | out <- random(min, max) 26 | } 27 | } 28 | 29 | func second(out chan<- int, in <-chan int) { 30 | for x := range in { 31 | fmt.Print(x, " ") 32 | _, ok := DATA[x] 33 | if ok { 34 | CLOSEA = true 35 | } else { 36 | DATA[x] = true 37 | out <- x 38 | } 39 | } 40 | fmt.Println() 41 | close(out) 42 | } 43 | 44 | func third(in <-chan int) { 45 | var sum int 46 | sum = 0 47 | for x2 := range in { 48 | sum = sum + x2 49 | } 50 | fmt.Printf("The sum of the random numbers is %d\n", sum) 51 | } 52 | 53 | func main() { 54 | if len(os.Args) != 3 { 55 | fmt.Println("Need two integer parameters!") 56 | os.Exit(1) 57 | } 58 | 59 | n1, _ := strconv.Atoi(os.Args[1]) 60 | n2, _ := strconv.Atoi(os.Args[2]) 61 | 62 | if n1 > n2 { 63 | fmt.Printf("%d should be smaller than %d\n", n1, n2) 64 | return 65 | } 66 | 67 | rand.Seed(time.Now().UnixNano()) 68 | A := make(chan int) 69 | B := make(chan int) 70 | 71 | go first(n1, n2, A) 72 | go second(B, A) 73 | third(B) 74 | } 75 | -------------------------------------------------------------------------------- /ch05/stack.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Node struct { 8 | Value int 9 | Next *Node 10 | } 11 | 12 | var size = 0 13 | var stack = new(Node) 14 | 15 | func Push(v int) bool { 16 | if stack == nil { 17 | stack = &Node{v, nil} 18 | size = 1 19 | return true 20 | } 21 | 22 | temp := &Node{v, nil} 23 | temp.Next = stack 24 | stack = temp 25 | size++ 26 | return true 27 | } 28 | 29 | func Pop(t *Node) (int, bool) { 30 | if size == 0 { 31 | return 0, false 32 | } 33 | 34 | if size == 1 { 35 | size = 0 36 | stack = nil 37 | return t.Value, true 38 | } 39 | 40 | stack = stack.Next 41 | size-- 42 | return t.Value, true 43 | } 44 | 45 | func traverse(t *Node) { 46 | if size == 0 { 47 | fmt.Println("Empty Stack!") 48 | return 49 | } 50 | 51 | for t != nil { 52 | fmt.Printf("%d -> ", t.Value) 53 | t = t.Next 54 | } 55 | fmt.Println() 56 | } 57 | 58 | func main() { 59 | 60 | stack = nil 61 | v, b := Pop(stack) 62 | if b { 63 | fmt.Print(v, " ") 64 | } else { 65 | fmt.Println("Pop() failed!") 66 | } 67 | 68 | Push(100) 69 | traverse(stack) 70 | Push(200) 71 | traverse(stack) 72 | 73 | for i := 0; i < 10; i++ { 74 | Push(i) 75 | } 76 | 77 | for i := 0; i < 15; i++ { 78 | v, b := Pop(stack) 79 | if b { 80 | fmt.Print(v, " ") 81 | } else { 82 | break 83 | } 84 | } 85 | fmt.Println() 86 | traverse(stack) 87 | } 88 | -------------------------------------------------------------------------------- /ch12/wwwProfile.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/pprof" 7 | "os" 8 | "time" 9 | ) 10 | 11 | func myHandler(w http.ResponseWriter, r *http.Request) { 12 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 13 | fmt.Printf("Served: %s\n", r.Host) 14 | } 15 | 16 | func timeHandler(w http.ResponseWriter, r *http.Request) { 17 | t := time.Now().Format(time.RFC1123) 18 | Body := "The current time is:" 19 | fmt.Fprintf(w, "

%s

", Body) 20 | fmt.Fprintf(w, "

%s

\n", t) 21 | fmt.Fprintf(w, "Serving: %s\n", r.URL.Path) 22 | fmt.Printf("Served time for: %s\n", r.Host) 23 | } 24 | 25 | func main() { 26 | PORT := ":8001" 27 | arguments := os.Args 28 | if len(arguments) == 1 { 29 | fmt.Println("Using default port number: ", PORT) 30 | } else { 31 | PORT = ":" + arguments[1] 32 | fmt.Println("Using port number: ", PORT) 33 | } 34 | 35 | r := http.NewServeMux() 36 | r.HandleFunc("/time", timeHandler) 37 | r.HandleFunc("/", myHandler) 38 | 39 | r.HandleFunc("/debug/pprof/", pprof.Index) 40 | r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) 41 | r.HandleFunc("/debug/pprof/profile", pprof.Profile) 42 | r.HandleFunc("/debug/pprof/symbol", pprof.Symbol) 43 | r.HandleFunc("/debug/pprof/trace", pprof.Trace) 44 | 45 | err := http.ListenAndServe(PORT, r) 46 | if err != nil { 47 | fmt.Println(err) 48 | return 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ch05/hashTableLookup.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const SIZE = 15 8 | 9 | type Node struct { 10 | Value int 11 | Next *Node 12 | } 13 | 14 | type HashTable struct { 15 | Table map[int]*Node 16 | Size int 17 | } 18 | 19 | func hashFunction(i, size int) int { 20 | return (i % size) 21 | } 22 | 23 | func insert(hash *HashTable, value int) int { 24 | index := hashFunction(value, hash.Size) 25 | element := Node{Value: value, Next: hash.Table[index]} 26 | hash.Table[index] = &element 27 | return index 28 | } 29 | 30 | func traverse(hash *HashTable) { 31 | for k := range hash.Table { 32 | if hash.Table[k] != nil { 33 | t := hash.Table[k] 34 | for t != nil { 35 | fmt.Printf("%d -> ", t.Value) 36 | t = t.Next 37 | } 38 | fmt.Println() 39 | } 40 | } 41 | } 42 | 43 | func lookup(hash *HashTable, value int) bool { 44 | index := hashFunction(value, hash.Size) 45 | if hash.Table[index] != nil { 46 | t := hash.Table[index] 47 | for t != nil { 48 | if t.Value == value { 49 | return true 50 | } 51 | t = t.Next 52 | } 53 | } 54 | return false 55 | } 56 | 57 | func main() { 58 | table := make(map[int]*Node, SIZE) 59 | hash := &HashTable{Table: table, Size: SIZE} 60 | for i := 0; i < 120; i++ { 61 | insert(hash, i) 62 | } 63 | 64 | for i := 10; i < 125; i++ { 65 | if !lookup(hash, i) { 66 | fmt.Println(i, "is not in the hash table!") 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ch08/CSVplot.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/csv" 5 | "fmt" 6 | "github.com/Arafatk/glot" 7 | "os" 8 | "strconv" 9 | ) 10 | 11 | func main() { 12 | if len(os.Args) != 2 { 13 | fmt.Println("Need a data file!") 14 | return 15 | } 16 | 17 | file := os.Args[1] 18 | _, err := os.Stat(file) 19 | if err != nil { 20 | fmt.Println("Cannot stat", file) 21 | return 22 | } 23 | 24 | f, err := os.Open(file) 25 | if err != nil { 26 | fmt.Println("Cannot open", file) 27 | fmt.Println(err) 28 | return 29 | } 30 | defer f.Close() 31 | 32 | reader := csv.NewReader(f) 33 | reader.FieldsPerRecord = -1 34 | allRecords, err := reader.ReadAll() 35 | if err != nil { 36 | fmt.Println(err) 37 | return 38 | } 39 | 40 | xP := []float64{} 41 | yP := []float64{} 42 | for _, rec := range allRecords { 43 | x, _ := strconv.ParseFloat(rec[0], 64) 44 | y, _ := strconv.ParseFloat(rec[1], 64) 45 | xP = append(xP, x) 46 | yP = append(yP, y) 47 | } 48 | 49 | points := [][]float64{} 50 | points = append(points, xP) 51 | points = append(points, yP) 52 | fmt.Println(points) 53 | 54 | dimensions := 2 55 | persist := true 56 | debug := false 57 | plot, _ := glot.NewPlot(dimensions, persist, debug) 58 | 59 | plot.SetTitle("Using Glot with CSV data") 60 | plot.SetXLabel("X-Axis") 61 | plot.SetYLabel("Y-Axis") 62 | style := "circle" 63 | plot.AddPointGroup("Circle:", style, points) 64 | plot.SavePlot("output.png") 65 | } 66 | -------------------------------------------------------------------------------- /ch04/switch.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "regexp" 7 | "strconv" 8 | ) 9 | 10 | func main() { 11 | 12 | arguments := os.Args 13 | if len(arguments) < 2 { 14 | fmt.Println("usage: switch number.") 15 | os.Exit(1) 16 | } 17 | 18 | number, err := strconv.Atoi(arguments[1]) 19 | if err != nil { 20 | fmt.Println("This value is not an integer:", number) 21 | } else { 22 | switch { 23 | case number < 0: 24 | fmt.Println("Less than zero!") 25 | case number > 0: 26 | fmt.Println("Bigger than zero!") 27 | default: 28 | fmt.Println("Zero!") 29 | } 30 | } 31 | 32 | asString := arguments[1] 33 | switch asString { 34 | case "5": 35 | fmt.Println("Five!") 36 | case "0": 37 | fmt.Println("Zero!") 38 | default: 39 | fmt.Println("Do not care!") 40 | } 41 | 42 | var negative = regexp.MustCompile(`-`) 43 | var floatingPoint = regexp.MustCompile(`\d?\.\d`) 44 | var email = regexp.MustCompile(`^[^@]+@[^@.]+\.[^@.]+`) 45 | 46 | switch { 47 | case negative.MatchString(asString): 48 | fmt.Println("Negative number") 49 | case floatingPoint.MatchString(asString): 50 | fmt.Println("Floating point!") 51 | case email.MatchString(asString): 52 | fmt.Println("It is an email!") 53 | fallthrough 54 | default: 55 | fmt.Println("Something else!") 56 | } 57 | 58 | var aType error = nil 59 | switch aType.(type) { 60 | case nil: 61 | fmt.Println("It is nil interface!") 62 | default: 63 | fmt.Println("Not nil interface!") 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ch10/rwMutex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "sync" 7 | "time" 8 | ) 9 | 10 | var Password = secret{password: "myPassword"} 11 | 12 | type secret struct { 13 | RWM sync.RWMutex 14 | password string 15 | } 16 | 17 | func Change(c *secret, pass string) { 18 | c.RWM.Lock() 19 | fmt.Println("LChange") 20 | time.Sleep(10 * time.Second) 21 | c.password = pass 22 | c.RWM.Unlock() 23 | } 24 | 25 | func show(c *secret) string { 26 | c.RWM.RLock() 27 | fmt.Print("show") 28 | time.Sleep(3 * time.Second) 29 | defer c.RWM.RUnlock() 30 | return c.password 31 | } 32 | 33 | func showWithLock(c *secret) string { 34 | c.RWM.Lock() 35 | fmt.Println("showWithLock") 36 | time.Sleep(3 * time.Second) 37 | defer c.RWM.Unlock() 38 | return c.password 39 | } 40 | 41 | func main() { 42 | var showFunction = func(c *secret) string { return "" } 43 | if len(os.Args) != 2 { 44 | fmt.Println("Using sync.RWMutex!") 45 | showFunction = show 46 | } else { 47 | fmt.Println("Using sync.Mutex!") 48 | showFunction = showWithLock 49 | } 50 | 51 | var waitGroup sync.WaitGroup 52 | 53 | fmt.Println("Pass:", showFunction(&Password)) 54 | for i := 0; i < 15; i++ { 55 | waitGroup.Add(1) 56 | go func() { 57 | defer waitGroup.Done() 58 | fmt.Println("Go Pass:", showFunction(&Password)) 59 | }() 60 | } 61 | 62 | go func() { 63 | waitGroup.Add(1) 64 | defer waitGroup.Done() 65 | Change(&Password, "123456") 66 | }() 67 | 68 | waitGroup.Wait() 69 | fmt.Println("Pass:", showFunction(&Password)) 70 | } 71 | -------------------------------------------------------------------------------- /ch11/writingBU.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "os" 7 | "strconv" 8 | ) 9 | 10 | var BUFFERSIZE int 11 | var FILESIZE int 12 | 13 | func random(min, max int) int { 14 | return rand.Intn(max-min) + min 15 | } 16 | 17 | func createBuffer(buf *[]byte, count int) { 18 | *buf = make([]byte, count) 19 | if count == 0 { 20 | return 21 | } 22 | 23 | for i := 0; i < count; i++ { 24 | intByte := byte(random(0, 100)) 25 | if len(*buf) > count { 26 | return 27 | } 28 | *buf = append(*buf, intByte) 29 | } 30 | } 31 | 32 | func Create(dst string, b, f int) error { 33 | _, err := os.Stat(dst) 34 | if err == nil { 35 | return fmt.Errorf("File %s already exists.", dst) 36 | } 37 | 38 | destination, err := os.Create(dst) 39 | if err != nil { 40 | return err 41 | } 42 | defer destination.Close() 43 | 44 | if err != nil { 45 | panic(err) 46 | } 47 | 48 | buf := make([]byte, 0) 49 | for { 50 | createBuffer(&buf, b) 51 | buf = buf[:b] 52 | if _, err := destination.Write(buf); err != nil { 53 | return err 54 | } 55 | 56 | if f < 0 { 57 | break 58 | } 59 | f = f - len(buf) 60 | } 61 | return err 62 | } 63 | 64 | func main() { 65 | if len(os.Args) != 3 { 66 | fmt.Println("Need BUFFERSIZE FILESIZE!") 67 | return 68 | } 69 | 70 | output := "/tmp/randomFile" 71 | BUFFERSIZE, _ = strconv.Atoi(os.Args[1]) 72 | FILESIZE, _ = strconv.Atoi(os.Args[2]) 73 | err := Create(output, BUFFERSIZE, FILESIZE) 74 | if err != nil { 75 | fmt.Println(err) 76 | } 77 | 78 | err = os.Remove(output) 79 | if err != nil { 80 | fmt.Println(err) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ch12/advancedWebClient.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/httputil" 7 | "net/url" 8 | "os" 9 | "path/filepath" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | func main() { 15 | if len(os.Args) != 2 { 16 | fmt.Printf("Usage: %s URL\n", filepath.Base(os.Args[0])) 17 | return 18 | } 19 | 20 | URL, err := url.Parse(os.Args[1]) 21 | if err != nil { 22 | fmt.Println("Error in parsing:", err) 23 | return 24 | } 25 | 26 | c := &http.Client{ 27 | Timeout: 15 * time.Second, 28 | } 29 | request, err := http.NewRequest("GET", URL.String(), nil) 30 | if err != nil { 31 | fmt.Println("Get:", err) 32 | return 33 | } 34 | 35 | httpData, err := c.Do(request) 36 | if err != nil { 37 | fmt.Println("Error in Do():", err) 38 | return 39 | } 40 | 41 | fmt.Println("Status code:", httpData.Status) 42 | header, _ := httputil.DumpResponse(httpData, false) 43 | fmt.Print(string(header)) 44 | 45 | contentType := httpData.Header.Get("Content-Type") 46 | characterSet := strings.SplitAfter(contentType, "charset=") 47 | if len(characterSet) > 1 { 48 | fmt.Println("Character Set:", characterSet[1]) 49 | } 50 | 51 | if httpData.ContentLength == -1 { 52 | fmt.Println("ContentLength is unknown!") 53 | } else { 54 | fmt.Println("ContentLength:", httpData.ContentLength) 55 | } 56 | 57 | length := 0 58 | var buffer [1024]byte 59 | r := httpData.Body 60 | for { 61 | n, err := r.Read(buffer[0:]) 62 | if err != nil { 63 | fmt.Println(err) 64 | break 65 | } 66 | length = length + n 67 | } 68 | fmt.Println("Calculated response data length:", length) 69 | } 70 | -------------------------------------------------------------------------------- /ch05/queue.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Node struct { 8 | Value int 9 | Next *Node 10 | } 11 | 12 | var size = 0 13 | var queue = new(Node) 14 | 15 | func Push(t *Node, v int) bool { 16 | if queue == nil { 17 | queue = &Node{v, nil} 18 | size++ 19 | return true 20 | } 21 | 22 | t = &Node{v, nil} 23 | t.Next = queue 24 | queue = t 25 | size++ 26 | 27 | return true 28 | } 29 | 30 | func Pop(t *Node) (int, bool) { 31 | if size == 0 { 32 | return 0, false 33 | } 34 | 35 | if size == 1 { 36 | queue = nil 37 | size-- 38 | return t.Value, true 39 | } 40 | 41 | temp := t 42 | for (t.Next) != nil { 43 | temp = t 44 | t = t.Next 45 | } 46 | 47 | v := (temp.Next).Value 48 | temp.Next = nil 49 | 50 | size-- 51 | return v, true 52 | } 53 | 54 | func traverse(t *Node) { 55 | if size == 0 { 56 | fmt.Println("Empty Queue!") 57 | return 58 | } 59 | 60 | for t != nil { 61 | fmt.Printf("%d -> ", t.Value) 62 | t = t.Next 63 | } 64 | fmt.Println() 65 | } 66 | 67 | func main() { 68 | queue = nil 69 | Push(queue, 10) 70 | fmt.Println("Size:", size) 71 | traverse(queue) 72 | 73 | v, b := Pop(queue) 74 | if b { 75 | fmt.Println("Pop:", v) 76 | } 77 | fmt.Println("Size:", size) 78 | 79 | for i := 0; i < 5; i++ { 80 | Push(queue, i) 81 | } 82 | traverse(queue) 83 | fmt.Println("Size:", size) 84 | 85 | v, b = Pop(queue) 86 | if b { 87 | fmt.Println("Pop:", v) 88 | } 89 | fmt.Println("Size:", size) 90 | 91 | v, b = Pop(queue) 92 | if b { 93 | fmt.Println("Pop:", v) 94 | } 95 | fmt.Println("Size:", size) 96 | traverse(queue) 97 | } 98 | -------------------------------------------------------------------------------- /ch04/changeDT.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | "regexp" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | func main() { 14 | 15 | arguments := os.Args 16 | if len(arguments) == 1 { 17 | fmt.Println("Please provide one text file to process!") 18 | os.Exit(1) 19 | } 20 | 21 | filename := arguments[1] 22 | f, err := os.Open(filename) 23 | if err != nil { 24 | fmt.Printf("error opening file %s", err) 25 | os.Exit(1) 26 | } 27 | defer f.Close() 28 | 29 | notAMatch := 0 30 | r := bufio.NewReader(f) 31 | for { 32 | line, err := r.ReadString('\n') 33 | if err == io.EOF { 34 | break 35 | } else if err != nil { 36 | fmt.Printf("error reading file %s", err) 37 | } 38 | 39 | r1 := regexp.MustCompile(`.*\[(\d\d\/\w+/\d\d\d\d:\d\d:\d\d:\d\d.*)\] .*`) 40 | if r1.MatchString(line) { 41 | match := r1.FindStringSubmatch(line) 42 | d1, err := time.Parse("02/Jan/2006:15:04:05 -0700", match[1]) 43 | if err == nil { 44 | newFormat := d1.Format(time.Stamp) 45 | fmt.Print(strings.Replace(line, match[1], newFormat, 1)) 46 | } else { 47 | notAMatch++ 48 | } 49 | continue 50 | } 51 | 52 | r2 := regexp.MustCompile(`.*\[(\w+\-\d\d-\d\d:\d\d:\d\d:\d\d.*)\] .*`) 53 | if r2.MatchString(line) { 54 | match := r2.FindStringSubmatch(line) 55 | d1, err := time.Parse("Jan-02-06:15:04:05 -0700", match[1]) 56 | if err == nil { 57 | newFormat := d1.Format(time.Stamp) 58 | fmt.Print(strings.Replace(line, match[1], newFormat, 1)) 59 | } else { 60 | notAMatch++ 61 | } 62 | continue 63 | } 64 | } 65 | fmt.Println(notAMatch, "lines did not match!") 66 | } 67 | -------------------------------------------------------------------------------- /ch11/benchmarkMe_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var result int 8 | 9 | func benchmarkfibo1(b *testing.B, n int) { 10 | var r int 11 | for i := 0; i < b.N; i++ { 12 | r = fibo1(n) 13 | } 14 | result = r 15 | } 16 | 17 | func benchmarkfibo2(b *testing.B, n int) { 18 | var r int 19 | for i := 0; i < b.N; i++ { 20 | r = fibo2(n) 21 | } 22 | result = r 23 | } 24 | 25 | func benchmarkfibo3(b *testing.B, n int) { 26 | var r int 27 | for i := 0; i < b.N; i++ { 28 | r = fibo3(n) 29 | } 30 | result = r 31 | } 32 | 33 | func Benchmark30fibo1(b *testing.B) { 34 | benchmarkfibo1(b, 30) 35 | } 36 | 37 | func Benchmark30fibo2(b *testing.B) { 38 | benchmarkfibo2(b, 30) 39 | } 40 | 41 | func Benchmark30fibo3(b *testing.B) { 42 | benchmarkfibo3(b, 30) 43 | } 44 | 45 | func Benchmark50fibo1(b *testing.B) { 46 | benchmarkfibo1(b, 50) 47 | } 48 | 49 | func Benchmark50fibo2(b *testing.B) { 50 | benchmarkfibo2(b, 50) 51 | } 52 | 53 | func Benchmark50fibo3(b *testing.B) { 54 | benchmarkfibo3(b, 50) 55 | } 56 | 57 | // This is a correct benchmark function 58 | func BenchmarkFiboIV(b *testing.B) { 59 | for i := 0; i < b.N; i++ { 60 | _ = fibo3(10) 61 | } 62 | } 63 | 64 | // This is also a correct benchmark function 65 | func BenchmarkFiboIII(b *testing.B) { 66 | _ = fibo3(b.N) 67 | } 68 | 69 | // This benchmark function never converges 70 | // func BenchmarkFiboI(b *testing.B) { 71 | // for i := 0; i < b.N; i++ { 72 | // _ = fibo1(i) 73 | // } 74 | // } 75 | 76 | // This benchmark function never converges 77 | // func BenchmarkFiboII(b *testing.B) { 78 | // for i := 0; i < b.N; i++ { 79 | // _ = fibo2(b.N) 80 | // } 81 | // } 82 | -------------------------------------------------------------------------------- /ch06/htmlT.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | _ "github.com/mattn/go-sqlite3" 7 | "html/template" 8 | "net/http" 9 | "os" 10 | ) 11 | 12 | type Entry struct { 13 | Number int 14 | Double int 15 | Square int 16 | } 17 | 18 | var DATA []Entry 19 | var tFile string 20 | 21 | func myHandler(w http.ResponseWriter, r *http.Request) { 22 | fmt.Printf("Host: %s Path: %s\n", r.Host, r.URL.Path) 23 | myT := template.Must(template.ParseGlob(tFile)) 24 | myT.ExecuteTemplate(w, tFile, DATA) 25 | } 26 | 27 | func main() { 28 | arguments := os.Args 29 | if len(arguments) != 3 { 30 | fmt.Println("Need Database File + Template File!") 31 | return 32 | } 33 | 34 | database := arguments[1] 35 | tFile = arguments[2] 36 | 37 | db, err := sql.Open("sqlite3", database) 38 | if err != nil { 39 | fmt.Println(nil) 40 | return 41 | } 42 | 43 | fmt.Println("Emptying database table.") 44 | _, err = db.Exec("DELETE FROM data") 45 | if err != nil { 46 | fmt.Println(nil) 47 | return 48 | } 49 | 50 | fmt.Println("Populating", database) 51 | stmt, _ := db.Prepare("INSERT INTO data(number, double, square) values(?,?,?)") 52 | for i := 20; i < 50; i++ { 53 | _, _ = stmt.Exec(i, 2*i, i*i) 54 | } 55 | 56 | rows, err := db.Query("SELECT * FROM data") 57 | if err != nil { 58 | fmt.Println(nil) 59 | return 60 | } 61 | 62 | var n int 63 | var d int 64 | var s int 65 | for rows.Next() { 66 | err = rows.Scan(&n, &d, &s) 67 | temp := Entry{Number: n, Double: d, Square: s} 68 | DATA = append(DATA, temp) 69 | } 70 | 71 | http.HandleFunc("/", myHandler) 72 | err = http.ListenAndServe(":8080", nil) 73 | if err != nil { 74 | fmt.Println(err) 75 | return 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /ch10/workerPool.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | type Client struct { 12 | id int 13 | integer int 14 | } 15 | 16 | type Data struct { 17 | job Client 18 | square int 19 | } 20 | 21 | var ( 22 | size = 10 23 | clients = make(chan Client, size) 24 | data = make(chan Data, size) 25 | ) 26 | 27 | func worker(w *sync.WaitGroup) { 28 | for c := range clients { 29 | square := c.integer * c.integer 30 | output := Data{c, square} 31 | data <- output 32 | time.Sleep(time.Second) 33 | } 34 | w.Done() 35 | } 36 | 37 | func makeWP(n int) { 38 | var w sync.WaitGroup 39 | for i := 0; i < n; i++ { 40 | w.Add(1) 41 | go worker(&w) 42 | } 43 | w.Wait() 44 | close(data) 45 | } 46 | 47 | func create(n int) { 48 | for i := 0; i < n; i++ { 49 | c := Client{i, i} 50 | clients <- c 51 | } 52 | close(clients) 53 | } 54 | 55 | func main() { 56 | fmt.Println("Capacity of clients:", cap(clients)) 57 | fmt.Println("Capacity of data:", cap(data)) 58 | 59 | if len(os.Args) != 3 { 60 | fmt.Println("Need #jobs and #workers!") 61 | os.Exit(1) 62 | } 63 | 64 | nJobs, err := strconv.Atoi(os.Args[1]) 65 | if err != nil { 66 | fmt.Println(err) 67 | return 68 | } 69 | 70 | nWorkers, err := strconv.Atoi(os.Args[2]) 71 | if err != nil { 72 | fmt.Println(err) 73 | return 74 | } 75 | 76 | go create(nJobs) 77 | finished := make(chan interface{}) 78 | go func() { 79 | for d := range data { 80 | fmt.Printf("Client ID: %d\tint: ", d.job.id) 81 | fmt.Printf("%d\tsquare: %d\n", d.job.integer, d.square) 82 | } 83 | finished <- true 84 | }() 85 | 86 | makeWP(nWorkers) 87 | fmt.Printf(": %v\n", <-finished) 88 | } 89 | -------------------------------------------------------------------------------- /ch10/simpleContext.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | func f1(t int) { 12 | c1 := context.Background() 13 | c1, cancel := context.WithCancel(c1) 14 | defer cancel() 15 | 16 | go func() { 17 | time.Sleep(4 * time.Second) 18 | cancel() 19 | }() 20 | 21 | select { 22 | case <-c1.Done(): 23 | fmt.Println("f1():", c1.Err()) 24 | return 25 | case r := <-time.After(time.Duration(t) * time.Second): 26 | fmt.Println("f1():", r) 27 | } 28 | return 29 | } 30 | 31 | func f2(t int) { 32 | c2 := context.Background() 33 | c2, cancel := context.WithTimeout(c2, time.Duration(t)*time.Second) 34 | defer cancel() 35 | 36 | go func() { 37 | time.Sleep(4 * time.Second) 38 | cancel() 39 | }() 40 | 41 | select { 42 | case <-c2.Done(): 43 | fmt.Println("f2():", c2.Err()) 44 | return 45 | case r := <-time.After(time.Duration(t) * time.Second): 46 | fmt.Println("f2():", r) 47 | } 48 | return 49 | } 50 | 51 | func f3(t int) { 52 | c3 := context.Background() 53 | deadline := time.Now().Add(time.Duration(2*t) * time.Second) 54 | c3, cancel := context.WithDeadline(c3, deadline) 55 | defer cancel() 56 | 57 | go func() { 58 | time.Sleep(4 * time.Second) 59 | cancel() 60 | }() 61 | 62 | select { 63 | case <-c3.Done(): 64 | fmt.Println("f3():", c3.Err()) 65 | return 66 | case r := <-time.After(time.Duration(t) * time.Second): 67 | fmt.Println("f3():", r) 68 | } 69 | return 70 | } 71 | 72 | func main() { 73 | if len(os.Args) != 2 { 74 | fmt.Println("Need a delay!") 75 | return 76 | } 77 | 78 | delay, err := strconv.Atoi(os.Args[1]) 79 | if err != nil { 80 | fmt.Println(err) 81 | return 82 | } 83 | fmt.Println("Delay:", delay) 84 | 85 | f1(delay) 86 | f2(delay) 87 | f3(delay) 88 | } 89 | -------------------------------------------------------------------------------- /ch04/useStrings.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | s "strings" 6 | "unicode" 7 | ) 8 | 9 | var f = fmt.Printf 10 | 11 | func main() { 12 | upper := s.ToUpper("Hello there!") 13 | f("To Upper: %s\n", upper) 14 | f("To Lower: %s\n", s.ToLower("Hello THERE")) 15 | 16 | f("%s\n", s.Title("tHis wiLL be A title!")) 17 | 18 | f("EqualFold: %v\n", s.EqualFold("Mihalis", "MIHAlis")) 19 | f("EqualFold: %v\n", s.EqualFold("Mihalis", "MIHAli")) 20 | 21 | f("Prefix: %v\n", s.HasPrefix("Mihalis", "Mi")) 22 | f("Prefix: %v\n", s.HasPrefix("Mihalis", "mi")) 23 | f("Suffix: %v\n", s.HasSuffix("Mihalis", "is")) 24 | f("Suffix: %v\n", s.HasSuffix("Mihalis", "IS")) 25 | 26 | f("Index: %v\n", s.Index("Mihalis", "ha")) 27 | f("Index: %v\n", s.Index("Mihalis", "Ha")) 28 | f("Count: %v\n", s.Count("Mihalis", "i")) 29 | f("Count: %v\n", s.Count("Mihalis", "I")) 30 | f("Repeat: %s\n", s.Repeat("ab", 5)) 31 | 32 | f("TrimSpace: %s\n", s.TrimSpace(" \tThis is a line. \n")) 33 | f("TrimLeft: %s", s.TrimLeft(" \tThis is a\t line. \n", "\n\t ")) 34 | f("TrimRight: %s\n", s.TrimRight(" \tThis is a\t line. \n", "\n\t ")) 35 | 36 | f("Compare: %v\n", s.Compare("Mihalis", "MIHALIS")) 37 | f("Compare: %v\n", s.Compare("Mihalis", "Mihalis")) 38 | f("Compare: %v\n", s.Compare("MIHALIS", "MIHalis")) 39 | 40 | f("Fields: %v\n", s.Fields("This is a string!")) 41 | f("Fields: %v\n", s.Fields("Thisis\na\tstring!")) 42 | 43 | f("%s\n", s.Split("abcd efg", "")) 44 | f("%s\n", s.Replace("abcd efg", "", "_", -1)) 45 | f("%s\n", s.Replace("abcd efg", "", "_", 4)) 46 | f("%s\n", s.Replace("abcd efg", "", "_", 2)) 47 | 48 | lines := []string{"Line 1", "Line 2", "Line 3"} 49 | f("Join: %s\n", s.Join(lines, "+++")) 50 | 51 | f("SplitAfter: %s\n", s.SplitAfter("123++432++", "++")) 52 | 53 | trimFunction := func(c rune) bool { 54 | return !unicode.IsLetter(c) 55 | } 56 | f("TrimFunc: %s\n", s.TrimFunc("123 abc ABC \t .", trimFunction)) 57 | } 58 | -------------------------------------------------------------------------------- /ch05/linkedList.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Node struct { 8 | Value int 9 | Next *Node 10 | } 11 | 12 | var root = new(Node) 13 | 14 | func addNode(t *Node, v int) int { 15 | if root == nil { 16 | t = &Node{v, nil} 17 | root = t 18 | return 0 19 | } 20 | 21 | if v == t.Value { 22 | fmt.Println("Node already exists:", v) 23 | return -1 24 | } 25 | 26 | if t.Next == nil { 27 | t.Next = &Node{v, nil} 28 | return -2 29 | } 30 | 31 | return addNode(t.Next, v) 32 | } 33 | 34 | func traverse(t *Node) { 35 | if t == nil { 36 | fmt.Println("-> Empty list!") 37 | return 38 | } 39 | 40 | for t != nil { 41 | fmt.Printf("%d -> ", t.Value) 42 | t = t.Next 43 | } 44 | fmt.Println() 45 | } 46 | 47 | func lookupNode(t *Node, v int) bool { 48 | if root == nil { 49 | t = &Node{v, nil} 50 | root = t 51 | return false 52 | } 53 | 54 | if v == t.Value { 55 | return true 56 | } 57 | 58 | if t.Next == nil { 59 | return false 60 | } 61 | 62 | return lookupNode(t.Next, v) 63 | } 64 | 65 | func size(t *Node) int { 66 | if t == nil { 67 | fmt.Println("-> Empty list!") 68 | return 0 69 | } 70 | 71 | i := 0 72 | for t != nil { 73 | i++ 74 | t = t.Next 75 | } 76 | return i 77 | } 78 | 79 | func main() { 80 | fmt.Println(root) 81 | root = nil 82 | traverse(root) 83 | addNode(root, 1) 84 | addNode(root, -1) 85 | traverse(root) 86 | addNode(root, 10) 87 | addNode(root, 5) 88 | addNode(root, 45) 89 | addNode(root, 5) 90 | addNode(root, 5) 91 | traverse(root) 92 | addNode(root, 100) 93 | traverse(root) 94 | 95 | if lookupNode(root, 100) { 96 | fmt.Println("Node exists!") 97 | } else { 98 | fmt.Println("Node does not exist!") 99 | } 100 | 101 | if lookupNode(root, -100) { 102 | fmt.Println("Node exists!") 103 | } else { 104 | fmt.Println("Node does not exist!") 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /ch08/traceSyscall.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "os/exec" 8 | "strings" 9 | "syscall" 10 | ) 11 | 12 | var maxSyscalls = 0 13 | 14 | const SYSCALLFILE = "SYSCALLS" 15 | 16 | func main() { 17 | var SYSTEMCALLS []string 18 | f, err := os.Open(SYSCALLFILE) 19 | defer f.Close() 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } 24 | 25 | scanner := bufio.NewScanner(f) 26 | for scanner.Scan() { 27 | line := scanner.Text() 28 | line = strings.Replace(line, " ", "", -1) 29 | line = strings.Replace(line, "SYS_", "", -1) 30 | temp := strings.ToLower(strings.Split(line, "=")[0]) 31 | SYSTEMCALLS = append(SYSTEMCALLS, temp) 32 | maxSyscalls++ 33 | } 34 | 35 | COUNTER := make([]int, maxSyscalls) 36 | var regs syscall.PtraceRegs 37 | cmd := exec.Command(os.Args[1], os.Args[2:]...) 38 | 39 | cmd.Stdin = os.Stdin 40 | cmd.Stdout = os.Stdout 41 | cmd.Stderr = os.Stderr 42 | cmd.SysProcAttr = &syscall.SysProcAttr{Ptrace: true} 43 | 44 | err = cmd.Start() 45 | err = cmd.Wait() 46 | if err != nil { 47 | fmt.Println("Wait:", err) 48 | } 49 | 50 | pid := cmd.Process.Pid 51 | fmt.Println("Process ID:", pid) 52 | 53 | before := true 54 | forCount := 0 55 | for { 56 | if before { 57 | err := syscall.PtraceGetRegs(pid, ®s) 58 | if err != nil { 59 | break 60 | } 61 | if regs.Orig_rax > uint64(maxSyscalls) { 62 | fmt.Println("Unknown:", regs.Orig_rax) 63 | return 64 | } 65 | 66 | COUNTER[regs.Orig_rax]++ 67 | forCount++ 68 | } 69 | 70 | err = syscall.PtraceSyscall(pid, 0) 71 | if err != nil { 72 | fmt.Println("PtraceSyscall:", err) 73 | return 74 | } 75 | 76 | _, err = syscall.Wait4(pid, nil, 0, nil) 77 | if err != nil { 78 | fmt.Println("Wait4:", err) 79 | return 80 | } 81 | before = !before 82 | } 83 | 84 | for i, x := range COUNTER { 85 | if x != 0 { 86 | fmt.Println(SYSTEMCALLS[i], "->", x) 87 | } 88 | } 89 | fmt.Println("Total System Calls:", forCount) 90 | } 91 | -------------------------------------------------------------------------------- /ch10/useContext.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "os" 9 | "strconv" 10 | "sync" 11 | "time" 12 | ) 13 | 14 | var ( 15 | myUrl string 16 | delay int = 5 17 | w sync.WaitGroup 18 | ) 19 | 20 | type myData struct { 21 | r *http.Response 22 | err error 23 | } 24 | 25 | func connect(c context.Context) error { 26 | defer w.Done() 27 | data := make(chan myData, 1) 28 | 29 | tr := &http.Transport{} 30 | httpClient := &http.Client{Transport: tr} 31 | 32 | req, _ := http.NewRequest("GET", myUrl, nil) 33 | 34 | go func() { 35 | response, err := httpClient.Do(req) 36 | if err != nil { 37 | fmt.Println(err) 38 | data <- myData{nil, err} 39 | return 40 | } else { 41 | pack := myData{response, err} 42 | data <- pack 43 | } 44 | }() 45 | 46 | select { 47 | case <-c.Done(): 48 | tr.CancelRequest(req) 49 | <-data 50 | fmt.Println("The request was cancelled!") 51 | return c.Err() 52 | case ok := <-data: 53 | err := ok.err 54 | resp := ok.r 55 | if err != nil { 56 | fmt.Println("Error select:", err) 57 | return err 58 | } 59 | defer resp.Body.Close() 60 | 61 | realHTTPData, err := ioutil.ReadAll(resp.Body) 62 | if err != nil { 63 | fmt.Println("Error select:", err) 64 | return err 65 | } 66 | fmt.Printf("Server Response: %s\n", realHTTPData) 67 | 68 | } 69 | return nil 70 | } 71 | 72 | func main() { 73 | if len(os.Args) == 1 { 74 | fmt.Println("Need a URL and a delay!") 75 | return 76 | } 77 | 78 | myUrl = os.Args[1] 79 | if len(os.Args) == 3 { 80 | t, err := strconv.Atoi(os.Args[2]) 81 | if err != nil { 82 | fmt.Println(err) 83 | return 84 | } 85 | delay = t 86 | } 87 | 88 | fmt.Println("Delay:", delay) 89 | c := context.Background() 90 | c, cancel := context.WithTimeout(c, time.Duration(delay)*time.Second) 91 | defer cancel() 92 | 93 | fmt.Printf("Connecting to %s \n", myUrl) 94 | w.Add(1) 95 | go connect(c) 96 | w.Wait() 97 | fmt.Println("Exiting...") 98 | } 99 | -------------------------------------------------------------------------------- /ch05/doublyLList.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Node struct { 8 | Value int 9 | Previous *Node 10 | Next *Node 11 | } 12 | 13 | func addNode(t *Node, v int) int { 14 | if root == nil { 15 | t = &Node{v, nil, nil} 16 | root = t 17 | return 0 18 | } 19 | 20 | if v == t.Value { 21 | fmt.Println("Node already exists:", v) 22 | return -1 23 | } 24 | 25 | if t.Next == nil { 26 | temp := t 27 | t.Next = &Node{v, temp, nil} 28 | return -2 29 | } 30 | 31 | return addNode(t.Next, v) 32 | } 33 | 34 | func traverse(t *Node) { 35 | if t == nil { 36 | fmt.Println("-> Empty list!") 37 | return 38 | } 39 | 40 | for t != nil { 41 | fmt.Printf("%d -> ", t.Value) 42 | t = t.Next 43 | } 44 | fmt.Println() 45 | } 46 | 47 | func reverse(t *Node) { 48 | if t == nil { 49 | fmt.Println("-> Empty list!") 50 | return 51 | } 52 | 53 | temp := t 54 | for t != nil { 55 | temp = t 56 | t = t.Next 57 | } 58 | 59 | for temp.Previous != nil { 60 | fmt.Printf("%d -> ", temp.Value) 61 | temp = temp.Previous 62 | } 63 | fmt.Printf("%d -> ", temp.Value) 64 | fmt.Println() 65 | } 66 | 67 | func size(t *Node) int { 68 | if t == nil { 69 | fmt.Println("-> Empty list!") 70 | return 0 71 | } 72 | 73 | n := 0 74 | for t != nil { 75 | n++ 76 | t = t.Next 77 | } 78 | return n 79 | } 80 | 81 | func lookupNode(t *Node, v int) bool { 82 | if root == nil { 83 | return false 84 | } 85 | 86 | if v == t.Value { 87 | return true 88 | } 89 | 90 | if t.Next == nil { 91 | return false 92 | } 93 | 94 | return lookupNode(t.Next, v) 95 | } 96 | 97 | var root = new(Node) 98 | 99 | func main() { 100 | fmt.Println(root) 101 | root = nil 102 | traverse(root) 103 | addNode(root, 1) 104 | addNode(root, 1) 105 | traverse(root) 106 | addNode(root, 10) 107 | addNode(root, 5) 108 | addNode(root, 0) 109 | addNode(root, 0) 110 | traverse(root) 111 | addNode(root, 100) 112 | fmt.Println("Size:", size(root)) 113 | traverse(root) 114 | reverse(root) 115 | } 116 | -------------------------------------------------------------------------------- /ch11/profileMe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "os" 7 | "runtime" 8 | "runtime/pprof" 9 | "time" 10 | ) 11 | 12 | func fibo1(n int) int64 { 13 | if n == 0 || n == 1 { 14 | return int64(n) 15 | } 16 | time.Sleep(time.Millisecond) 17 | return int64(fibo2(n-1)) + int64(fibo2(n-2)) 18 | } 19 | 20 | func fibo2(n int) int { 21 | fn := make(map[int]int) 22 | for i := 0; i <= n; i++ { 23 | var f int 24 | if i <= 2 { 25 | f = 1 26 | } else { 27 | f = fn[i-1] + fn[i-2] 28 | } 29 | fn[i] = f 30 | } 31 | time.Sleep(50 * time.Millisecond) 32 | return fn[n] 33 | } 34 | 35 | func N1(n int) bool { 36 | k := math.Floor(float64(n/2 + 1)) 37 | for i := 2; i < int(k); i++ { 38 | if (n % i) == 0 { 39 | return false 40 | } 41 | } 42 | return true 43 | } 44 | 45 | func N2(n int) bool { 46 | for i := 2; i < n; i++ { 47 | if (n % i) == 0 { 48 | return false 49 | } 50 | } 51 | return true 52 | } 53 | 54 | func main() { 55 | cpuFile, err := os.Create("/tmp/cpuProfile.out") 56 | if err != nil { 57 | fmt.Println(err) 58 | return 59 | } 60 | pprof.StartCPUProfile(cpuFile) 61 | defer pprof.StopCPUProfile() 62 | 63 | total := 0 64 | for i := 2; i < 100000; i++ { 65 | n := N1(i) 66 | if n { 67 | total = total + 1 68 | } 69 | } 70 | fmt.Println("Total primes:", total) 71 | 72 | total = 0 73 | for i := 2; i < 100000; i++ { 74 | n := N2(i) 75 | if n { 76 | total = total + 1 77 | } 78 | } 79 | fmt.Println("Total primes:", total) 80 | 81 | for i := 1; i < 90; i++ { 82 | n := fibo1(i) 83 | fmt.Print(n, " ") 84 | } 85 | fmt.Println() 86 | 87 | for i := 1; i < 90; i++ { 88 | n := fibo2(i) 89 | fmt.Print(n, " ") 90 | } 91 | fmt.Println() 92 | 93 | runtime.GC() 94 | 95 | // Memory profiling! 96 | memory, err := os.Create("/tmp/memoryProfile.out") 97 | if err != nil { 98 | fmt.Println(err) 99 | return 100 | } 101 | defer memory.Close() 102 | 103 | for i := 0; i < 10; i++ { 104 | s := make([]byte, 50000000) 105 | if s == nil { 106 | fmt.Println("Operation failed!") 107 | } 108 | time.Sleep(50 * time.Millisecond) 109 | } 110 | 111 | err = pprof.WriteHeapProfile(memory) 112 | if err != nil { 113 | fmt.Println(err) 114 | return 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /ch04/keyValue.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | type myElement struct { 11 | Name string 12 | Surname string 13 | Id string 14 | } 15 | 16 | var DATA = make(map[string]myElement) 17 | 18 | func ADD(k string, n myElement) bool { 19 | if k == "" { 20 | return false 21 | } 22 | 23 | if LOOKUP(k) == nil { 24 | DATA[k] = n 25 | return true 26 | } 27 | return false 28 | } 29 | 30 | func DELETE(k string) bool { 31 | if LOOKUP(k) != nil { 32 | delete(DATA, k) 33 | return true 34 | } 35 | return false 36 | } 37 | 38 | func LOOKUP(k string) *myElement { 39 | _, ok := DATA[k] 40 | if ok { 41 | n := DATA[k] 42 | return &n 43 | } else { 44 | return nil 45 | } 46 | } 47 | 48 | func CHANGE(k string, n myElement) bool { 49 | DATA[k] = n 50 | return true 51 | } 52 | 53 | func PRINT() { 54 | for k, d := range DATA { 55 | fmt.Printf("key: %s value: %v\n", k, d) 56 | } 57 | } 58 | 59 | func main() { 60 | scanner := bufio.NewScanner(os.Stdin) 61 | for scanner.Scan() { 62 | text := scanner.Text() 63 | text = strings.TrimSpace(text) 64 | tokens := strings.Fields(text) 65 | 66 | switch len(tokens) { 67 | case 0: 68 | continue 69 | case 1: 70 | tokens = append(tokens, "") 71 | tokens = append(tokens, "") 72 | tokens = append(tokens, "") 73 | tokens = append(tokens, "") 74 | case 2: 75 | tokens = append(tokens, "") 76 | tokens = append(tokens, "") 77 | tokens = append(tokens, "") 78 | case 3: 79 | tokens = append(tokens, "") 80 | tokens = append(tokens, "") 81 | case 4: 82 | tokens = append(tokens, "") 83 | } 84 | 85 | switch tokens[0] { 86 | case "PRINT": 87 | PRINT() 88 | case "STOP": 89 | return 90 | case "DELETE": 91 | if !DELETE(tokens[1]) { 92 | fmt.Println("Delete operation failed!") 93 | } 94 | case "ADD": 95 | n := myElement{tokens[2], tokens[3], tokens[4]} 96 | if !ADD(tokens[1], n) { 97 | fmt.Println("Add operation failed!") 98 | } 99 | case "LOOKUP": 100 | n := LOOKUP(tokens[1]) 101 | if n != nil { 102 | fmt.Printf("%v\n", *n) 103 | } 104 | case "CHANGE": 105 | n := myElement{tokens[2], tokens[3], tokens[4]} 106 | if !CHANGE(tokens[1], n) { 107 | fmt.Println("Update operation failed!") 108 | } 109 | default: 110 | fmt.Println("Unknown command – please try again!") 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /ch04/calculatePi.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "math/big" 7 | "os" 8 | "strconv" 9 | ) 10 | 11 | var precision uint = 0 12 | 13 | func Pi(accuracy uint) *big.Float { 14 | k := 0 15 | pi := new(big.Float).SetPrec(precision).SetFloat64(0) 16 | k1k2k3 := new(big.Float).SetPrec(precision).SetFloat64(0) 17 | k4k5k6 := new(big.Float).SetPrec(precision).SetFloat64(0) 18 | temp := new(big.Float).SetPrec(precision).SetFloat64(0) 19 | minusOne := new(big.Float).SetPrec(precision).SetFloat64(-1) 20 | total := new(big.Float).SetPrec(precision).SetFloat64(0) 21 | 22 | two2Six := math.Pow(2, 6) 23 | two2SixBig := new(big.Float).SetPrec(precision).SetFloat64(two2Six) 24 | 25 | for { 26 | if k > int(accuracy) { 27 | break 28 | } 29 | k1 := new(big.Float).SetPrec(precision) 30 | k1.Quo(big.NewFloat(1), big.NewFloat(float64(10*k+9))) 31 | k2 := new(big.Float).SetPrec(precision) 32 | k2.Quo(big.NewFloat(64), big.NewFloat(float64(10*k+3))) 33 | k3 := new(big.Float).SetPrec(precision) 34 | k3.Quo(big.NewFloat(32), big.NewFloat(float64(4*k+1))) 35 | k1k2k3.Sub(k1, k2) 36 | k1k2k3.Sub(k1k2k3, k3) 37 | 38 | k4 := new(big.Float).SetPrec(precision) 39 | k4.Quo(big.NewFloat(4), big.NewFloat(float64(10*k+5))) 40 | k5 := new(big.Float).SetPrec(precision) 41 | k5.Quo(big.NewFloat(4), big.NewFloat(float64(10*k+7))) 42 | k6 := new(big.Float).SetPrec(precision) 43 | k6.Quo(big.NewFloat(1), big.NewFloat(float64(4*k+3))) 44 | k4k5k6.Add(k4, k5) 45 | k4k5k6.Add(k4k5k6, k6) 46 | k4k5k6 = k4k5k6.Mul(k4k5k6, minusOne) 47 | temp.Add(k1k2k3, k4k5k6) 48 | 49 | k7temp := new(big.Int).Exp(big.NewInt(-1), big.NewInt(int64(k)), nil) 50 | k8temp := new(big.Int).Exp(big.NewInt(1024), big.NewInt(int64(k)), nil) 51 | 52 | k7 := new(big.Float).SetPrec(precision).SetFloat64(0) 53 | k7.SetInt(k7temp) 54 | k8 := new(big.Float).SetPrec(precision).SetFloat64(0) 55 | k8.SetInt(k8temp) 56 | 57 | k9 := new(big.Float).SetPrec(precision) 58 | k9.Quo(big.NewFloat(256), big.NewFloat(float64(10*k+1))) 59 | k9.Add(k9, temp) 60 | total.Mul(k9, k7) 61 | total.Quo(total, k8) 62 | pi.Add(pi, total) 63 | 64 | k = k + 1 65 | } 66 | pi.Quo(pi, two2SixBig) 67 | return pi 68 | } 69 | 70 | func main() { 71 | arguments := os.Args 72 | if len(arguments) == 1 { 73 | fmt.Println("Please provide one numeric argument!") 74 | os.Exit(1) 75 | } 76 | 77 | temp, _ := strconv.ParseUint(arguments[1], 10, 32) 78 | precision = uint(temp) * 3 79 | 80 | PI := Pi(precision) 81 | fmt.Println(PI) 82 | } 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mastering Go 2 | This is the code repository for [Mastering Go](https://www.packtpub.com/networking-and-servers/mastering-go?utm_source=github&utm_medium=repository&utm_campaign=9781788626545), published by [Packt](https://www.packtpub.com/?utm_source=github). It contains all the supporting project files necessary to work through the book from start to finish. 3 | 4 | There is a **3rd edition** of Mastering Go! You can find more about it [here](https://github.com/mactsouk/mastering-Go-3rd). 5 | 6 | ## About the Book 7 | The Go programming language, often referred to as Golang (albeit wrongly), is really making strides, with some masterclass developments, architected by the greatest programming minds. Tobias Lutke, CEO of Shopify, recently quoted as saying “Go will be the server language of the future”, powerful words, with much ambition. Go programmers are in high demand, but more controversially, Go takes the stage, where C and Unix programmers previously led the way. 8 | 9 | The growth of the Go language has seen it become the means by which systems, networking, web, and cloud applications are implemented. Comfortable with syntax, you’ll benefit by mastering the use of the libraries and utilise its features, speed, and efficiency, for which the Go ecology is justly famous. 10 | 11 | You already know a little Go syntax and you’ve written some small projects, most Go programmers face the difficulty of having to integrate their Golang skills with production code. Typical introductions to Go programming, often stop short of this transition, the author continue on, showing you just how to tackle this. 12 | 13 | Offering a compendium of Go, the book begins with an account of how Go has been implemented, also, the reader will benefit from a dedicated chapter, an in-depth account of concurrency, systems and network programming, imperative for modern-day native cloud development. 14 | ## Instructions and Navigations 15 | All of the code is organized into folders. Each folder starts with a number followed by the application name. For example, Chapter02. 16 | 17 | 18 | 19 | The code will look like the following: 20 | ``` 21 | package main 22 | 23 | import ( 24 | "fmt" 25 | ) 26 | 27 | func main() { 28 | fmt.Println("This is a sample Go program!") 29 | } 30 | ``` 31 | 32 | 33 | 34 | ## Related Products 35 | * [Security with Go](https://www.packtpub.com/networking-and-servers/security-go?utm_source=github&utm_medium=repository&utm_campaign=9781788627917) 36 | 37 | * [Go Standard Library Cookbook](https://www.packtpub.com/application-development/go-standard-library-cookbook?utm_source=github&utm_medium=repository&utm_campaign=9781788475273) 38 | 39 | * [Isomorphic Go](https://www.packtpub.com/web-development/isomorphic-go?utm_source=github&utm_medium=repository&utm_campaign=9781788394185) 40 | -------------------------------------------------------------------------------- /ch08/kvSaveLoad.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "encoding/gob" 6 | "fmt" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | type myElement struct { 12 | Name string 13 | Surname string 14 | Id string 15 | } 16 | 17 | var DATA = make(map[string]myElement) 18 | var DATAFILE = "/tmp/dataFile.gob" 19 | 20 | func save() error { 21 | fmt.Println("Saving", DATAFILE) 22 | err := os.Remove(DATAFILE) 23 | if err != nil { 24 | fmt.Println(err) 25 | } 26 | 27 | saveTo, err := os.Create(DATAFILE) 28 | if err != nil { 29 | fmt.Println("Cannot create", DATAFILE) 30 | return err 31 | } 32 | defer saveTo.Close() 33 | 34 | encoder := gob.NewEncoder(saveTo) 35 | err = encoder.Encode(DATA) 36 | if err != nil { 37 | fmt.Println("Cannot save to", DATAFILE) 38 | return err 39 | } 40 | return nil 41 | } 42 | 43 | func load() error { 44 | fmt.Println("Loading", DATAFILE) 45 | loadFrom, err := os.Open(DATAFILE) 46 | defer loadFrom.Close() 47 | if err != nil { 48 | fmt.Println("Empty key/value store!") 49 | return err 50 | } 51 | 52 | decoder := gob.NewDecoder(loadFrom) 53 | decoder.Decode(&DATA) 54 | return nil 55 | } 56 | 57 | func ADD(k string, n myElement) bool { 58 | if k == "" { 59 | return false 60 | } 61 | 62 | if LOOKUP(k) == nil { 63 | DATA[k] = n 64 | return true 65 | } 66 | return false 67 | } 68 | 69 | func DELETE(k string) bool { 70 | if LOOKUP(k) != nil { 71 | delete(DATA, k) 72 | return true 73 | } 74 | return false 75 | } 76 | 77 | func LOOKUP(k string) *myElement { 78 | _, ok := DATA[k] 79 | if ok { 80 | n := DATA[k] 81 | return &n 82 | } else { 83 | return nil 84 | } 85 | } 86 | 87 | func CHANGE(k string, n myElement) bool { 88 | DATA[k] = n 89 | return true 90 | } 91 | 92 | func PRINT() { 93 | for k, d := range DATA { 94 | fmt.Printf("key: %s value: %v\n", k, d) 95 | } 96 | } 97 | 98 | func main() { 99 | err := load() 100 | if err != nil { 101 | fmt.Println(err) 102 | } 103 | 104 | scanner := bufio.NewScanner(os.Stdin) 105 | for scanner.Scan() { 106 | text := scanner.Text() 107 | text = strings.TrimSpace(text) 108 | tokens := strings.Fields(text) 109 | 110 | switch len(tokens) { 111 | case 0: 112 | continue 113 | case 1: 114 | tokens = append(tokens, "") 115 | tokens = append(tokens, "") 116 | tokens = append(tokens, "") 117 | tokens = append(tokens, "") 118 | case 2: 119 | tokens = append(tokens, "") 120 | tokens = append(tokens, "") 121 | tokens = append(tokens, "") 122 | case 3: 123 | tokens = append(tokens, "") 124 | tokens = append(tokens, "") 125 | case 4: 126 | tokens = append(tokens, "") 127 | } 128 | 129 | switch tokens[0] { 130 | case "PRINT": 131 | PRINT() 132 | case "STOP": 133 | err = save() 134 | if err != nil { 135 | fmt.Println(err) 136 | } 137 | return 138 | case "DELETE": 139 | if !DELETE(tokens[1]) { 140 | fmt.Println("Delete operation failed!") 141 | } 142 | case "ADD": 143 | n := myElement{tokens[2], tokens[3], tokens[4]} 144 | if !ADD(tokens[1], n) { 145 | fmt.Println("Add operation failed!") 146 | } 147 | case "LOOKUP": 148 | n := LOOKUP(tokens[1]) 149 | if n != nil { 150 | fmt.Printf("%v\n", *n) 151 | } 152 | case "CHANGE": 153 | n := myElement{tokens[2], tokens[3], tokens[4]} 154 | if !CHANGE(tokens[1], n) { 155 | fmt.Println("Update operation failed!") 156 | } 157 | default: 158 | fmt.Println("Unknown command – please try again!") 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /ch12/kvWeb.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/gob" 5 | "fmt" 6 | "html/template" 7 | "net/http" 8 | "os" 9 | ) 10 | 11 | type myElement struct { 12 | Name string 13 | Surname string 14 | Id string 15 | } 16 | 17 | var DATA = make(map[string]myElement) 18 | var DATAFILE = "/tmp/dataFile.gob" 19 | 20 | func save() error { 21 | fmt.Println("Saving", DATAFILE) 22 | err := os.Remove(DATAFILE) 23 | if err != nil { 24 | fmt.Println(err) 25 | } 26 | 27 | saveTo, err := os.Create(DATAFILE) 28 | if err != nil { 29 | fmt.Println("Cannot create", DATAFILE) 30 | return err 31 | } 32 | defer saveTo.Close() 33 | 34 | encoder := gob.NewEncoder(saveTo) 35 | err = encoder.Encode(DATA) 36 | if err != nil { 37 | fmt.Println("Cannot save to", DATAFILE) 38 | return err 39 | } 40 | return nil 41 | } 42 | 43 | func load() error { 44 | fmt.Println("Loading", DATAFILE) 45 | loadFrom, err := os.Open(DATAFILE) 46 | defer loadFrom.Close() 47 | if err != nil { 48 | fmt.Println("Empty key/value store!") 49 | return err 50 | } 51 | 52 | decoder := gob.NewDecoder(loadFrom) 53 | decoder.Decode(&DATA) 54 | return nil 55 | } 56 | 57 | func ADD(k string, n myElement) bool { 58 | if k == "" { 59 | return false 60 | } 61 | 62 | if LOOKUP(k) == nil { 63 | DATA[k] = n 64 | return true 65 | } 66 | return false 67 | } 68 | 69 | func DELETE(k string) bool { 70 | if LOOKUP(k) != nil { 71 | delete(DATA, k) 72 | return true 73 | } 74 | return false 75 | } 76 | 77 | func LOOKUP(k string) *myElement { 78 | _, ok := DATA[k] 79 | if ok { 80 | n := DATA[k] 81 | return &n 82 | } else { 83 | return nil 84 | } 85 | } 86 | 87 | func CHANGE(k string, n myElement) bool { 88 | DATA[k] = n 89 | return true 90 | } 91 | 92 | func PRINT() { 93 | for k, d := range DATA { 94 | fmt.Printf("key: %s value: %v\n", k, d) 95 | } 96 | } 97 | 98 | func homePage(w http.ResponseWriter, r *http.Request) { 99 | fmt.Println("Serving", r.Host, "for", r.URL.Path) 100 | myT := template.Must(template.ParseGlob("home.gohtml")) 101 | myT.ExecuteTemplate(w, "home.gohtml", nil) 102 | } 103 | 104 | func listAll(w http.ResponseWriter, r *http.Request) { 105 | fmt.Println("Listing the contents of the KV store!") 106 | 107 | fmt.Fprintf(w, "Home sweet home!") 108 | fmt.Fprintf(w, "List all elements!") 109 | fmt.Fprintf(w, "Change an element!") 110 | fmt.Fprintf(w, "Insert new element!") 111 | 112 | fmt.Fprintf(w, "

The contents of the KV store are:

") 113 | fmt.Fprintf(w, "
    ") 114 | for k, v := range DATA { 115 | fmt.Fprintf(w, "
  • ") 116 | fmt.Fprintf(w, "%s with value: %v\n", k, v) 117 | fmt.Fprintf(w, "
  • ") 118 | } 119 | 120 | fmt.Fprintf(w, "
") 121 | } 122 | 123 | func changeElement(w http.ResponseWriter, r *http.Request) { 124 | fmt.Println("Changing an element of the KV store!") 125 | tmpl := template.Must(template.ParseFiles("update.gohtml")) 126 | if r.Method != http.MethodPost { 127 | tmpl.Execute(w, nil) 128 | return 129 | } 130 | 131 | key := r.FormValue("key") 132 | n := myElement{ 133 | Name: r.FormValue("name"), 134 | Surname: r.FormValue("surname"), 135 | Id: r.FormValue("id"), 136 | } 137 | 138 | if !CHANGE(key, n) { 139 | fmt.Println("Update operation failed!") 140 | } else { 141 | err := save() 142 | if err != nil { 143 | fmt.Println(err) 144 | return 145 | } 146 | tmpl.Execute(w, struct{ Success bool }{true}) 147 | } 148 | } 149 | 150 | func insertElement(w http.ResponseWriter, r *http.Request) { 151 | fmt.Println("Inserting an element to the KV store!") 152 | tmpl := template.Must(template.ParseFiles("insert.gohtml")) 153 | if r.Method != http.MethodPost { 154 | tmpl.Execute(w, nil) 155 | return 156 | } 157 | 158 | key := r.FormValue("key") 159 | n := myElement{ 160 | Name: r.FormValue("name"), 161 | Surname: r.FormValue("surname"), 162 | Id: r.FormValue("id"), 163 | } 164 | 165 | if !ADD(key, n) { 166 | fmt.Println("Add operation failed!") 167 | } else { 168 | err := save() 169 | if err != nil { 170 | fmt.Println(err) 171 | return 172 | } 173 | tmpl.Execute(w, struct{ Success bool }{true}) 174 | } 175 | } 176 | 177 | func main() { 178 | err := load() 179 | if err != nil { 180 | fmt.Println(err) 181 | } 182 | 183 | PORT := ":8001" 184 | arguments := os.Args 185 | if len(arguments) != 1 { 186 | PORT = ":" + arguments[1] 187 | } 188 | fmt.Println("Using port number: ", PORT) 189 | 190 | http.HandleFunc("/", homePage) 191 | http.HandleFunc("/change", changeElement) 192 | http.HandleFunc("/list", listAll) 193 | http.HandleFunc("/insert", insertElement) 194 | err = http.ListenAndServe(PORT, nil) 195 | if err != nil { 196 | fmt.Println(err) 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /ch13/kvTCP.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "encoding/gob" 6 | "fmt" 7 | "net" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | type myElement struct { 13 | Name string 14 | Surname string 15 | Id string 16 | } 17 | 18 | const welcome = "Welcome to the Key Value store!\n" 19 | 20 | var DATA = make(map[string]myElement) 21 | var DATAFILE = "/tmp/dataFile.gob" 22 | 23 | func handleConnection(c net.Conn) { 24 | c.Write([]byte(welcome)) 25 | for { 26 | netData, err := bufio.NewReader(c).ReadString('\n') 27 | if err != nil { 28 | fmt.Println(err) 29 | return 30 | } 31 | 32 | command := strings.TrimSpace(string(netData)) 33 | tokens := strings.Fields(command) 34 | switch len(tokens) { 35 | case 0: 36 | continue 37 | case 1: 38 | tokens = append(tokens, "") 39 | tokens = append(tokens, "") 40 | tokens = append(tokens, "") 41 | tokens = append(tokens, "") 42 | case 2: 43 | tokens = append(tokens, "") 44 | tokens = append(tokens, "") 45 | tokens = append(tokens, "") 46 | case 3: 47 | tokens = append(tokens, "") 48 | tokens = append(tokens, "") 49 | case 4: 50 | tokens = append(tokens, "") 51 | } 52 | 53 | switch tokens[0] { 54 | case "STOP": 55 | err = save() 56 | if err != nil { 57 | fmt.Println(err) 58 | } 59 | c.Close() 60 | return 61 | case "PRINT": 62 | PRINT(c) 63 | case "DELETE": 64 | if !DELETE(tokens[1]) { 65 | netData := "Delete operation failed!\n" 66 | c.Write([]byte(netData)) 67 | } else { 68 | netData := "Delete operation successful!\n" 69 | c.Write([]byte(netData)) 70 | } 71 | case "ADD": 72 | n := myElement{tokens[2], tokens[3], tokens[4]} 73 | if !ADD(tokens[1], n) { 74 | netData := "Add operation failed!\n" 75 | c.Write([]byte(netData)) 76 | } else { 77 | netData := "Add operation successful!\n" 78 | c.Write([]byte(netData)) 79 | } 80 | err = save() 81 | if err != nil { 82 | fmt.Println(err) 83 | } 84 | case "LOOKUP": 85 | n := LOOKUP(tokens[1]) 86 | if n != nil { 87 | netData := fmt.Sprintf("%v\n", *n) 88 | c.Write([]byte(netData)) 89 | } else { 90 | netData := "Did not find key!\n" 91 | c.Write([]byte(netData)) 92 | } 93 | case "CHANGE": 94 | n := myElement{tokens[2], tokens[3], tokens[4]} 95 | if !CHANGE(tokens[1], n) { 96 | netData := "Update operation failed!\n" 97 | c.Write([]byte(netData)) 98 | } else { 99 | netData := "Update operation successful!\n" 100 | c.Write([]byte(netData)) 101 | } 102 | err = save() 103 | if err != nil { 104 | fmt.Println(err) 105 | } 106 | default: 107 | netData := "Unknown command – please try again!\n" 108 | c.Write([]byte(netData)) 109 | } 110 | } 111 | } 112 | 113 | func save() error { 114 | fmt.Println("Saving", DATAFILE) 115 | err := os.Remove(DATAFILE) 116 | if err != nil { 117 | fmt.Println(err) 118 | } 119 | 120 | saveTo, err := os.Create(DATAFILE) 121 | if err != nil { 122 | fmt.Println("Cannot create", DATAFILE) 123 | return err 124 | } 125 | defer saveTo.Close() 126 | 127 | encoder := gob.NewEncoder(saveTo) 128 | err = encoder.Encode(DATA) 129 | if err != nil { 130 | fmt.Println("Cannot save to", DATAFILE) 131 | return err 132 | } 133 | return nil 134 | } 135 | 136 | func load() error { 137 | fmt.Println("Loading", DATAFILE) 138 | loadFrom, err := os.Open(DATAFILE) 139 | defer loadFrom.Close() 140 | if err != nil { 141 | fmt.Println("Empty key/value store!") 142 | return err 143 | } 144 | 145 | decoder := gob.NewDecoder(loadFrom) 146 | decoder.Decode(&DATA) 147 | return nil 148 | } 149 | 150 | func ADD(k string, n myElement) bool { 151 | if k == "" { 152 | return false 153 | } 154 | 155 | if LOOKUP(k) == nil { 156 | DATA[k] = n 157 | return true 158 | } 159 | return false 160 | } 161 | 162 | func DELETE(k string) bool { 163 | if LOOKUP(k) != nil { 164 | delete(DATA, k) 165 | return true 166 | } 167 | return false 168 | } 169 | 170 | func LOOKUP(k string) *myElement { 171 | _, ok := DATA[k] 172 | if ok { 173 | n := DATA[k] 174 | return &n 175 | } else { 176 | return nil 177 | } 178 | } 179 | 180 | func CHANGE(k string, n myElement) bool { 181 | DATA[k] = n 182 | return true 183 | } 184 | 185 | func PRINT(c net.Conn) { 186 | for k, d := range DATA { 187 | netData := fmt.Sprintf("key: %s value: %v\n", k, d) 188 | c.Write([]byte(netData)) 189 | } 190 | } 191 | 192 | func main() { 193 | arguments := os.Args 194 | if len(arguments) == 1 { 195 | fmt.Println("Please provide a port number!") 196 | return 197 | } 198 | 199 | PORT := ":" + arguments[1] 200 | l, err := net.Listen("tcp", PORT) 201 | if err != nil { 202 | fmt.Println(err) 203 | return 204 | } 205 | defer l.Close() 206 | 207 | err = load() 208 | if err != nil { 209 | fmt.Println(err) 210 | } 211 | 212 | for { 213 | c, err := l.Accept() 214 | if err != nil { 215 | fmt.Println(err) 216 | os.Exit(100) 217 | } 218 | go handleConnection(c) 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /ch08/SYSCALLS: -------------------------------------------------------------------------------- 1 | SYS_READ = 0 2 | SYS_WRITE = 1 3 | SYS_OPEN = 2 4 | SYS_CLOSE = 3 5 | SYS_STAT = 4 6 | SYS_FSTAT = 5 7 | SYS_LSTAT = 6 8 | SYS_POLL = 7 9 | SYS_LSEEK = 8 10 | SYS_MMAP = 9 11 | SYS_MPROTECT = 10 12 | SYS_MUNMAP = 11 13 | SYS_BRK = 12 14 | SYS_RT_SIGACTION = 13 15 | SYS_RT_SIGPROCMASK = 14 16 | SYS_RT_SIGRETURN = 15 17 | SYS_IOCTL = 16 18 | SYS_PREAD64 = 17 19 | SYS_PWRITE64 = 18 20 | SYS_READV = 19 21 | SYS_WRITEV = 20 22 | SYS_ACCESS = 21 23 | SYS_PIPE = 22 24 | SYS_SELECT = 23 25 | SYS_SCHED_YIELD = 24 26 | SYS_MREMAP = 25 27 | SYS_MSYNC = 26 28 | SYS_MINCORE = 27 29 | SYS_MADVISE = 28 30 | SYS_SHMGET = 29 31 | SYS_SHMAT = 30 32 | SYS_SHMCTL = 31 33 | SYS_DUP = 32 34 | SYS_DUP2 = 33 35 | SYS_PAUSE = 34 36 | SYS_NANOSLEEP = 35 37 | SYS_GETITIMER = 36 38 | SYS_ALARM = 37 39 | SYS_SETITIMER = 38 40 | SYS_GETPID = 39 41 | SYS_SENDFILE = 40 42 | SYS_SOCKET = 41 43 | SYS_CONNECT = 42 44 | SYS_ACCEPT = 43 45 | SYS_SENDTO = 44 46 | SYS_RECVFROM = 45 47 | SYS_SENDMSG = 46 48 | SYS_RECVMSG = 47 49 | SYS_SHUTDOWN = 48 50 | SYS_BIND = 49 51 | SYS_LISTEN = 50 52 | SYS_GETSOCKNAME = 51 53 | SYS_GETPEERNAME = 52 54 | SYS_SOCKETPAIR = 53 55 | SYS_SETSOCKOPT = 54 56 | SYS_GETSOCKOPT = 55 57 | SYS_CLONE = 56 58 | SYS_FORK = 57 59 | SYS_VFORK = 58 60 | SYS_EXECVE = 59 61 | SYS_EXIT = 60 62 | SYS_WAIT4 = 61 63 | SYS_KILL = 62 64 | SYS_UNAME = 63 65 | SYS_SEMGET = 64 66 | SYS_SEMOP = 65 67 | SYS_SEMCTL = 66 68 | SYS_SHMDT = 67 69 | SYS_MSGGET = 68 70 | SYS_MSGSND = 69 71 | SYS_MSGRCV = 70 72 | SYS_MSGCTL = 71 73 | SYS_FCNTL = 72 74 | SYS_FLOCK = 73 75 | SYS_FSYNC = 74 76 | SYS_FDATASYNC = 75 77 | SYS_TRUNCATE = 76 78 | SYS_FTRUNCATE = 77 79 | SYS_GETDENTS = 78 80 | SYS_GETCWD = 79 81 | SYS_CHDIR = 80 82 | SYS_FCHDIR = 81 83 | SYS_RENAME = 82 84 | SYS_MKDIR = 83 85 | SYS_RMDIR = 84 86 | SYS_CREAT = 85 87 | SYS_LINK = 86 88 | SYS_UNLINK = 87 89 | SYS_SYMLINK = 88 90 | SYS_READLINK = 89 91 | SYS_CHMOD = 90 92 | SYS_FCHMOD = 91 93 | SYS_CHOWN = 92 94 | SYS_FCHOWN = 93 95 | SYS_LCHOWN = 94 96 | SYS_UMASK = 95 97 | SYS_GETTIMEOFDAY = 96 98 | SYS_GETRLIMIT = 97 99 | SYS_GETRUSAGE = 98 100 | SYS_SYSINFO = 99 101 | SYS_TIMES = 100 102 | SYS_PTRACE = 101 103 | SYS_GETUID = 102 104 | SYS_SYSLOG = 103 105 | SYS_GETGID = 104 106 | SYS_SETUID = 105 107 | SYS_SETGID = 106 108 | SYS_GETEUID = 107 109 | SYS_GETEGID = 108 110 | SYS_SETPGID = 109 111 | SYS_GETPPID = 110 112 | SYS_GETPGRP = 111 113 | SYS_SETSID = 112 114 | SYS_SETREUID = 113 115 | SYS_SETREGID = 114 116 | SYS_GETGROUPS = 115 117 | SYS_SETGROUPS = 116 118 | SYS_SETRESUID = 117 119 | SYS_GETRESUID = 118 120 | SYS_SETRESGID = 119 121 | SYS_GETRESGID = 120 122 | SYS_GETPGID = 121 123 | SYS_SETFSUID = 122 124 | SYS_SETFSGID = 123 125 | SYS_GETSID = 124 126 | SYS_CAPGET = 125 127 | SYS_CAPSET = 126 128 | SYS_RT_SIGPENDING = 127 129 | SYS_RT_SIGTIMEDWAIT = 128 130 | SYS_RT_SIGQUEUEINFO = 129 131 | SYS_RT_SIGSUSPEND = 130 132 | SYS_SIGALTSTACK = 131 133 | SYS_UTIME = 132 134 | SYS_MKNOD = 133 135 | SYS_USELIB = 134 136 | SYS_PERSONALITY = 135 137 | SYS_USTAT = 136 138 | SYS_STATFS = 137 139 | SYS_FSTATFS = 138 140 | SYS_SYSFS = 139 141 | SYS_GETPRIORITY = 140 142 | SYS_SETPRIORITY = 141 143 | SYS_SCHED_SETPARAM = 142 144 | SYS_SCHED_GETPARAM = 143 145 | SYS_SCHED_SETSCHEDULER = 144 146 | SYS_SCHED_GETSCHEDULER = 145 147 | SYS_SCHED_GET_PRIORITY_MAX = 146 148 | SYS_SCHED_GET_PRIORITY_MIN = 147 149 | SYS_SCHED_RR_GET_INTERVAL = 148 150 | SYS_MLOCK = 149 151 | SYS_MUNLOCK = 150 152 | SYS_MLOCKALL = 151 153 | SYS_MUNLOCKALL = 152 154 | SYS_VHANGUP = 153 155 | SYS_MODIFY_LDT = 154 156 | SYS_PIVOT_ROOT = 155 157 | SYS__SYSCTL = 156 158 | SYS_PRCTL = 157 159 | SYS_ARCH_PRCTL = 158 160 | SYS_ADJTIMEX = 159 161 | SYS_SETRLIMIT = 160 162 | SYS_CHROOT = 161 163 | SYS_SYNC = 162 164 | SYS_ACCT = 163 165 | SYS_SETTIMEOFDAY = 164 166 | SYS_MOUNT = 165 167 | SYS_UMOUNT2 = 166 168 | SYS_SWAPON = 167 169 | SYS_SWAPOFF = 168 170 | SYS_REBOOT = 169 171 | SYS_SETHOSTNAME = 170 172 | SYS_SETDOMAINNAME = 171 173 | SYS_IOPL = 172 174 | SYS_IOPERM = 173 175 | SYS_CREATE_MODULE = 174 176 | SYS_INIT_MODULE = 175 177 | SYS_DELETE_MODULE = 176 178 | SYS_GET_KERNEL_SYMS = 177 179 | SYS_QUERY_MODULE = 178 180 | SYS_QUOTACTL = 179 181 | SYS_NFSSERVCTL = 180 182 | SYS_GETPMSG = 181 183 | SYS_PUTPMSG = 182 184 | SYS_AFS_SYSCALL = 183 185 | SYS_TUXCALL = 184 186 | SYS_SECURITY = 185 187 | SYS_GETTID = 186 188 | SYS_READAHEAD = 187 189 | SYS_SETXATTR = 188 190 | SYS_LSETXATTR = 189 191 | SYS_FSETXATTR = 190 192 | SYS_GETXATTR = 191 193 | SYS_LGETXATTR = 192 194 | SYS_FGETXATTR = 193 195 | SYS_LISTXATTR = 194 196 | SYS_LLISTXATTR = 195 197 | SYS_FLISTXATTR = 196 198 | SYS_REMOVEXATTR = 197 199 | SYS_LREMOVEXATTR = 198 200 | SYS_FREMOVEXATTR = 199 201 | SYS_TKILL = 200 202 | SYS_TIME = 201 203 | SYS_FUTEX = 202 204 | SYS_SCHED_SETAFFINITY = 203 205 | SYS_SCHED_GETAFFINITY = 204 206 | SYS_SET_THREAD_AREA = 205 207 | SYS_IO_SETUP = 206 208 | SYS_IO_DESTROY = 207 209 | SYS_IO_GETEVENTS = 208 210 | SYS_IO_SUBMIT = 209 211 | SYS_IO_CANCEL = 210 212 | SYS_GET_THREAD_AREA = 211 213 | SYS_LOOKUP_DCOOKIE = 212 214 | SYS_EPOLL_CREATE = 213 215 | SYS_EPOLL_CTL_OLD = 214 216 | SYS_EPOLL_WAIT_OLD = 215 217 | SYS_REMAP_FILE_PAGES = 216 218 | SYS_GETDENTS64 = 217 219 | SYS_SET_TID_ADDRESS = 218 220 | SYS_RESTART_SYSCALL = 219 221 | SYS_SEMTIMEDOP = 220 222 | SYS_FADVISE64 = 221 223 | SYS_TIMER_CREATE = 222 224 | SYS_TIMER_SETTIME = 223 225 | SYS_TIMER_GETTIME = 224 226 | SYS_TIMER_GETOVERRUN = 225 227 | SYS_TIMER_DELETE = 226 228 | SYS_CLOCK_SETTIME = 227 229 | SYS_CLOCK_GETTIME = 228 230 | SYS_CLOCK_GETRES = 229 231 | SYS_CLOCK_NANOSLEEP = 230 232 | SYS_EXIT_GROUP = 231 233 | SYS_EPOLL_WAIT = 232 234 | SYS_EPOLL_CTL = 233 235 | SYS_TGKILL = 234 236 | SYS_UTIMES = 235 237 | SYS_VSERVER = 236 238 | SYS_MBIND = 237 239 | SYS_SET_MEMPOLICY = 238 240 | SYS_GET_MEMPOLICY = 239 241 | SYS_MQ_OPEN = 240 242 | SYS_MQ_UNLINK = 241 243 | SYS_MQ_TIMEDSEND = 242 244 | SYS_MQ_TIMEDRECEIVE = 243 245 | SYS_MQ_NOTIFY = 244 246 | SYS_MQ_GETSETATTR = 245 247 | SYS_KEXEC_LOAD = 246 248 | SYS_WAITID = 247 249 | SYS_ADD_KEY = 248 250 | SYS_REQUEST_KEY = 249 251 | SYS_KEYCTL = 250 252 | SYS_IOPRIO_SET = 251 253 | SYS_IOPRIO_GET = 252 254 | SYS_INOTIFY_INIT = 253 255 | SYS_INOTIFY_ADD_WATCH = 254 256 | SYS_INOTIFY_RM_WATCH = 255 257 | SYS_MIGRATE_PAGES = 256 258 | SYS_OPENAT = 257 259 | SYS_MKDIRAT = 258 260 | SYS_MKNODAT = 259 261 | SYS_FCHOWNAT = 260 262 | SYS_FUTIMESAT = 261 263 | SYS_NEWFSTATAT = 262 264 | SYS_UNLINKAT = 263 265 | SYS_RENAMEAT = 264 266 | SYS_LINKAT = 265 267 | SYS_SYMLINKAT = 266 268 | SYS_READLINKAT = 267 269 | SYS_FCHMODAT = 268 270 | SYS_FACCESSAT = 269 271 | SYS_PSELECT6 = 270 272 | SYS_PPOLL = 271 273 | SYS_UNSHARE = 272 274 | SYS_SET_ROBUST_LIST = 273 275 | SYS_GET_ROBUST_LIST = 274 276 | SYS_SPLICE = 275 277 | SYS_TEE = 276 278 | SYS_SYNC_FILE_RANGE = 277 279 | SYS_VMSPLICE = 278 280 | SYS_MOVE_PAGES = 279 281 | SYS_UTIMENSAT = 280 282 | SYS_EPOLL_PWAIT = 281 283 | SYS_SIGNALFD = 282 284 | SYS_TIMERFD_CREATE = 283 285 | SYS_EVENTFD = 284 286 | SYS_FALLOCATE = 285 287 | SYS_TIMERFD_SETTIME = 286 288 | SYS_TIMERFD_GETTIME = 287 289 | SYS_ACCEPT4 = 288 290 | SYS_SIGNALFD4 = 289 291 | SYS_EVENTFD2 = 290 292 | SYS_EPOLL_CREATE1 = 291 293 | SYS_DUP3 = 292 294 | SYS_PIPE2 = 293 295 | SYS_INOTIFY_INIT1 = 294 296 | SYS_PREADV = 295 297 | SYS_PWRITEV = 296 298 | SYS_RT_TGSIGQUEUEINFO = 297 299 | SYS_PERF_EVENT_OPEN = 298 300 | SYS_RECVMMSG = 299 301 | SYS_FANOTIFY_INIT = 300 302 | SYS_FANOTIFY_MARK = 301 303 | SYS_PRLIMIT64 = 302 304 | --------------------------------------------------------------------------------