How do I use Win32's GetRawInputDeviceList in Go? - pointers

I'm trying to use the GetRawInputDeviceList function in Go and I keep getting the following error:
The parameter is incorrect.
Per the official documentation: the first parameter needs to be an array of RAWINPUTDEVICELIST structures for the devices attached to the system. I don't quite understand what combination of unsafe.Pointer, pointer arithmetic(?), and other things I need to do in order to get this to work correctly.
I found this Medium article that offers some guidance, but it's not directly applicable to my use case. I don't have enough experience working with pointers and manual memory management to apply it to my problem. I don't know how to translate this C++ example to Go, and I got so desperate that I tried to convert a working VBA solution to Go with no success.
I have two questions regarding this matter:
How do I convert an array of structs in Go to the appropriate type expected for a Windows API call?
How do I convert the result of the Windows API call back to an array of structs with populated data?
Environment
Here's my system/language details:
macOS Mojave v10.14.6
Go v1.10.7 (required to run executables on Windows XP)
I'm targeting Windows XP, so I run the following command to compile it:
env GOOS=windows GOARCH=386 go1.10.7 build -o example.exe example.go
Code
Here's the code I'm trying to get working. I'm not doing anything with devices yet, but the goal would be to use the handle (DeviceHandle from rawInputDeviceList) to get information about the input device.
package main
import (
"fmt"
"syscall"
"unsafe"
)
// RAWINPUTDEVICELIST structure
type rawInputDeviceList struct {
DeviceHandle uintptr
Type uint32
}
var (
user32 = syscall.NewLazyDLL("user32.dll")
getRawInputDeviceListProc = user32.NewProc("GetRawInputDeviceList")
)
func main() {
dl := rawInputDeviceList{}
size := uint32(unsafe.Sizeof(dl))
// First I determine how many input devices are on the system, which
// gets assigned to `devCount`
var devCount uint32
_ = getRawInputDeviceList(nil, &devCount, size)
if devCount > 0 {
size = size * devCount
devices := make([]rawInputDeviceList, size) // <- This is definitely wrong
for i := 0; i < int(devCount); i++ {
devices[i] = rawInputDeviceList{}
}
// Here is where I get the "The parameter is incorrect." error:
err := getRawInputDeviceList(&devices, &devCount, size)
if err != nil {
fmt.Printf("Error: %v", err)
}
}
}
// Enumerates the raw input devices attached to the system.
func getRawInputDeviceList(
rawInputDeviceList *[]rawInputDeviceList, // <- This is probably wrong
numDevices *uint32,
size uint32,
) error {
_, _, err := getRawInputDeviceListProc.Call(
uintptr(unsafe.Pointer(rawInputDeviceList)),
uintptr(unsafe.Pointer(numDevices)),
uintptr(size))
if err != syscall.Errno(0) {
return err
}
return nil
}

First, the ERROR_INVALID_PARAMETER error is cause by the last parameter: cbSize, According to the document, it should always be set to size of RAWINPUTDEVICELIST.
Then you will pass the compiler but still get the runtime error. because you have passed a pointer of array.
The following code works for me:
package main
import (
"fmt"
"syscall"
"unsafe"
)
// RAWINPUTDEVICELIST structure
type rawInputDeviceList struct {
DeviceHandle uintptr
Type uint32
}
var (
user32 = syscall.NewLazyDLL("user32.dll")
getRawInputDeviceListProc = user32.NewProc("GetRawInputDeviceList")
)
func main() {
dl := rawInputDeviceList{}
size := uint32(unsafe.Sizeof(dl))
// First I determine how many input devices are on the system, which
// gets assigned to `devCount`
var devCount uint32
_ = getRawInputDeviceList(nil, &devCount, size)
if devCount > 0 {
devices := make([]rawInputDeviceList, size * devCount) // <- This is definitely wrong
for i := 0; i < int(devCount); i++ {
devices[i] = rawInputDeviceList{}
}
// Here is where I get the "The parameter is incorrect." error:
err := getRawInputDeviceList(&devices[0], &devCount, size)
if err != nil {
fmt.Printf("Error: %v", err)
}
for i := 0; i < int(devCount); i++ {
fmt.Printf("Type: %v", devices[i].Type)
}
}
}
// Enumerates the raw input devices attached to the system.
func getRawInputDeviceList(
rawInputDeviceList *rawInputDeviceList, // <- This is probably wrong
numDevices *uint32,
size uint32,
) error {
_, _, err := getRawInputDeviceListProc.Call(
uintptr(unsafe.Pointer(rawInputDeviceList)),
uintptr(unsafe.Pointer(numDevices)),
uintptr(size))
if err != syscall.Errno(0) {
return err
}
return nil
}

Related

"pointer to interface, not interface"

I am learning Go and decided to rewrite a MQTT orchestrator which I originally wrote in Python. The very basic part works fine:
package main
import (
"fmt"
"time"
"os"
MQTT "github.com/eclipse/paho.mqtt.golang"
log "github.com/sirupsen/logrus"
)
// definitions for a switch
type Switch struct {
topic string
state int
}
func allEvents(client MQTT.Client, msg MQTT.Message) {
log.WithFields(log.Fields{"topic": msg.Topic(), "payload": fmt.Sprintf("%s", msg.Payload())}).Info()
}
func initMQTT() MQTT.Client {
opts := MQTT.NewClientOptions()
opts.AddBroker("tcp://mqtt.example.com:1883")
opts.SetClientID("go-dispatcher")
opts.SetCleanSession(true)
client := MQTT.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
panic(token.Error())
}
log.Info("connected to MQTT broker")
return client
}
func main() {
// this is that part I want to modify later in the question
c := initMQTT()
if token := c.Subscribe("#", 0, allEvents); token.Wait() && token.Error() != nil {
fmt.Println(token.Error())
os.Exit(1)
}
time.Sleep(100000 * time.Hour)
}
Having used pointers in a distant past with C, I wanted to modify the program to pass, in the initialization part, the client by reference (more as a learning experience, the first code looks better to me)
package main
import (
"fmt"
"time"
"os"
MQTT "github.com/eclipse/paho.mqtt.golang"
log "github.com/sirupsen/logrus"
)
// definitions for a switch
type Switch struct {
topic string
state int
}
func allEvents(client MQTT.Client, msg MQTT.Message) {
log.WithFields(log.Fields{"topic": msg.Topic(), "payload": fmt.Sprintf("%s", msg.Payload())}).Info()
}
// this time we get a pointer and do not return anything
func initMQTT(client *MQTT.Client) {
opts := MQTT.NewClientOptions()
opts.AddBroker("tcp://mqtt.example.com:1883")
opts.SetClientID("go-dispatcher")
opts.SetCleanSession(true)
client = MQTT.NewClient(opts)
if token := *client.Connect(); token.Wait() && token.Error() != nil {
panic(token.Error())
}
log.Info("connected to MQTT broker")
}
func main() {
// the client is defined in main()
var c MQTT.Client
// and passed by reference so that the function modifies it
initMQTT(&c)
if token := c.Subscribe("#", 0, allEvents); token.Wait() && token.Error() != nil {
fmt.Println(token.Error())
os.Exit(1)
}
time.Sleep(100000 * time.Hour)
}
It fails to compile with
# command-line-arguments
.\main.go:29:9: cannot use mqtt.NewClient(opts) (type mqtt.Client) as type *mqtt.Client in assignment:
*mqtt.Client is pointer to interface, not interface
.\main.go:30:21: client.Connect undefined (type *mqtt.Client is pointer to interface, not interface)
Following advice form another question, I tried to remove & and * (blindly to start with, to tell the truth), and get a runtime error
time="2018-05-26T21:02:20+02:00" level=info msg="connected to MQTT broker"
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x604486]
goroutine 1 [running]:
main.main()
D:/Seafile/dev/Go/src/perso/domotique.dispatcher/main.go:39 +0x36
I though that since I defined c, I could just pass it as a reference but apparently the C-way is not the right one here? (it is usually in the examples I read)
This is a common misunderstanding. Because you've defined c as a value rather than a pointer type, you can't modify it without re-defining it.
The fact that you've passed its memory address does not enable you to modify it. This is different from a number of other languages.

json.Unmarshal() accepts a pointer to a pointer

I noticed, quite by accident, that I can successfully pass both a pointer to a struct, and a pointer to a pointer to a struct to json.Unmarshal(), and both work just fine:
package main
import (
"testing"
"encoding/json"
)
type Person struct {
Name string
Age int
}
func TestMarshaling(t *testing.T) {
foo := &Person{Name: "bob", Age: 23}
// marshal it to bytes
b, err := json.Marshal(foo)
if err != nil {
t.Error(err)
}
bar := &Person{} // pointer to new, empty struct
err = json.Unmarshal(b, bar) // unmarshal to bar, which is a *Person
if err != nil {
t.Error(err)
}
testBob(t, bar) // ok
bar = &Person{} // pointer to new, empty struct
err = json.Unmarshal(b, &bar) // wait a minute, passing in a **Person, yet it still works?
if err != nil {
t.Error(err)
}
testBob(t, bar) // ok
}
func testBob(t *testing.T, person *Person) {
if person.Name != "bob" || person.Age != 23 {
t.Error("not equal")
}
}
I was really surprised that the second one (unmarshal to **Person) worked.
What's going on in json.Unmarshal()? Is it dereferencing the pointers until it finds a struct?
The documentation offers:
To unmarshal JSON into a pointer, Unmarshal first handles the case of
the JSON being the JSON literal null. In that case, Unmarshal sets
the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into the
value pointed at by the pointer
It seems to be doing a bit more than that. What's really going on?
Fleshing out my question more: how does it know to automatically dereference my pointer to a pointer? The documentation says it will unmarshal "into the value pointed at by the pointer". Since the value of my pointer is in fact another pointer, and has no Name/Age fields, I expected it to stop there.
To be clear: I'm not saying there's a bug or misfeature in Unmarshal(); I'm trying to satisfy my astonishment that it works at all when given a ptr-to-ptr, and avoid any potential pitfalls in my use of it.
The json package has no reason to "stop at a pointer", since a pointer means nothing in json. It has to keep walking the tree in order to find a value to write. Since the json package is going to allow unmarshaling the same value into Type or *Type, it stands to reason that it should be able to unmarshal that into **Type, which is also a valid type in Go.
For a example, if Person were defined using pointers to differentiate between nil and zero values, and you were unmarshaling into a slice of []*Person, the json package needs to follow those pointers, and allocate values if necessary. The same applies if a field in Person were defined as a **string.
type Person struct {
Name **string
Age *int
}
type People []*Person
http://play.golang.org/p/vLq0nJPG5M
The json.Unmarshal implementation takes multiple indirection into account. Check the source here, in particular the decodeState.indirect method:
// indirect walks down v allocating pointers as needed,
// until it gets to a non-pointer.
// if it encounters an Unmarshaler, indirect stops and returns that.
// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.
func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
// If v is a named type and is addressable,
// start with its address, so that if the type has pointer methods,
// we find them.
if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
v = v.Addr()
}
for {
if v.Kind() == reflect.Interface && !v.IsNil() {
e := v.Elem()
if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
v = e
continue
}
}
if v.Kind() != reflect.Ptr {
break
}
//and so on
}
return nil, nil, v
The same method is called when unmarshaling arrays:
func (d *decodeState) array(v reflect.Value) {
u, ut, pv := d.indirect(v, false)
//...
That would have me believe that go can handle double indirection just fine. If nothing else, the json package source is a great example of what the reflect package is all about.
In short, values are checked, if the decoder is dealing with pointers, it will use reflection to work out how many levels of indirection there are, and determine what type the target has/is. The place to start from in the decode source is this: func (d *decodeState) unmarshal(v interface{}) (err error) {, from that point on, it's pretty self-explanatory.
As other answers have said, pointers are followed.
A little weird that this errors (nil pointer), but makes sense when you think about it.
package main
import (
"encoding/json"
"fmt"
"log"
)
type MyStruct struct {
A string `json:"a"`
}
func main() {
data := []byte(`{"a":"foo"}`)
var a *MyStruct
err := json.Unmarshal(data, a) // nil ptr
if err != nil {
log.Fatal(err)
}
fmt.Println(a)
}
But this doesn't error (pointer to nil pointer).
package main
import (
"encoding/json"
"fmt"
"log"
)
type MyStruct struct {
A string `json:"a"`
}
func main() {
data := []byte(`{"a":"foo"}`)
var a *MyStruct
err := json.Unmarshal(data, &a) // **MyStruct, ptr to nil ptr
if err != nil {
log.Fatal(err)
}
fmt.Println(a)
}
https://play.golang.org/p/eI8jqWZOmGW

Counting hard links to a file in Go

According to the man page for FileInfo, the following information is available when stat()ing a file in Go:
type FileInfo interface {
Name() string // base name of the file
Size() int64 // length in bytes for regular files; system-dependent for others
Mode() FileMode // file mode bits
ModTime() time.Time // modification time
IsDir() bool // abbreviation for Mode().IsDir()
Sys() interface{} // underlying data source (can return nil)
}
How can I retrieve the number of hard links to a specific file in Go?
UNIX (<sys/stat.h>) defines st_nlink ("reference count of hard links") as a return value from a stat() system call.
For example, on Linux,
package main
import (
"fmt"
"os"
"syscall"
)
func main() {
fi, err := os.Stat("filename")
if err != nil {
fmt.Println(err)
return
}
nlink := uint64(0)
if sys := fi.Sys(); sys != nil {
if stat, ok := sys.(*syscall.Stat_t); ok {
nlink = uint64(stat.Nlink)
}
}
fmt.Println(nlink)
}
Output:
1

function for converting a struct to map in Golang

I want to convert a struct to map in Golang. It would also be nice if I could use the JSON tags as keys in the created map (otherwise defaulting to field name).
Edit Dec 14, 2020
Since structs repo was archived, you can use mapstructure instead.
Edit TL;DR version, Jun 15, 2015
If you want the fast solution for converting a structure to map, see the accepted answer, upvote it and use that package.
Happy coding! :)
Original Post
So far I have this function, I am using the reflect package but I don't understand well how to use the package, please bear with me.
func ConvertToMap(model interface{}) bson.M {
ret := bson.M{}
modelReflect := reflect.ValueOf(model)
if modelReflect.Kind() == reflect.Ptr {
modelReflect = modelReflect.Elem()
}
modelRefType := modelReflect.Type()
fieldsCount := modelReflect.NumField()
var fieldData interface{}
for i := 0; i < fieldsCount; i++ {
field := modelReflect.Field(i)
switch field.Kind() {
case reflect.Struct:
fallthrough
case reflect.Ptr:
fieldData = ConvertToMap(field.Interface())
default:
fieldData = field.Interface()
}
ret[modelRefType.Field(i).Name] = fieldData
}
return ret
}
Also I looked at JSON package source code, because it should contain my needed implementation (or parts of it) but don't understand too much.
I also had need for something like this. I was using an internal package which was converting a struct to a map. I decided to open source it with other struct based high level functions. Have a look:
https://github.com/fatih/structs
It has support for:
Convert struct to a map
Extract the fields of a struct to a []string
Extract the values of a struct to a []values
Check if a struct is initialized or not
Check if a passed interface is a struct or a pointer to struct
You can see some examples here: http://godoc.org/github.com/fatih/structs#pkg-examples
For example converting a struct to a map is a simple:
type Server struct {
Name string
ID int32
Enabled bool
}
s := &Server{
Name: "gopher",
ID: 123456,
Enabled: true,
}
// => {"Name":"gopher", "ID":123456, "Enabled":true}
m := structs.Map(s)
The structs package has support for anonymous (embedded) fields and nested structs. The package provides to filter certain fields via field tags.
From struct to map[string]interface{}
package main
import (
"fmt"
"encoding/json"
)
type MyData struct {
One int
Two string
Three int
}
func main() {
in := &MyData{One: 1, Two: "second"}
var inInterface map[string]interface{}
inrec, _ := json.Marshal(in)
json.Unmarshal(inrec, &inInterface)
// iterate through inrecs
for field, val := range inInterface {
fmt.Println("KV Pair: ", field, val)
}
}
go playground here
Here is a function I've written in the past to convert a struct to a map, using tags as keys
// ToMap converts a struct to a map using the struct's tags.
//
// ToMap uses tags on struct fields to decide which fields to add to the
// returned map.
func ToMap(in interface{}, tag string) (map[string]interface{}, error){
out := make(map[string]interface{})
v := reflect.ValueOf(in)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
// we only accept structs
if v.Kind() != reflect.Struct {
return nil, fmt.Errorf("ToMap only accepts structs; got %T", v)
}
typ := v.Type()
for i := 0; i < v.NumField(); i++ {
// gets us a StructField
fi := typ.Field(i)
if tagv := fi.Tag.Get(tag); tagv != "" {
// set key of map to value in struct field
out[tagv] = v.Field(i).Interface()
}
}
return out, nil
}
Runnable example here.
Note, if you have multiple fields with the same tag value, then you will obviously not be able to store them all within a map. It might be prudent to return an error if that happens.
I like the importable package for the accepted answer, but it does not translate my json aliases. Most of my projects have a helper function/class that I import.
Here is a function that solves my specific problem.
// Converts a struct to a map while maintaining the json alias as keys
func StructToMap(obj interface{}) (newMap map[string]interface{}, err error) {
data, err := json.Marshal(obj) // Convert to a json string
if err != nil {
return
}
err = json.Unmarshal(data, &newMap) // Convert to a map
return
}
And in the main, this is how it would be called...
package main
import (
"fmt"
"encoding/json"
"github.com/fatih/structs"
)
type MyStructObject struct {
Email string `json:"email_address"`
}
func main() {
obj := &MyStructObject{Email: "test#test.com"}
// My solution
fmt.Println(StructToMap(obj)) // prints {"email_address": "test#test.com"}
// The currently accepted solution
fmt.Println(structs.Map(obj)) // prints {"Email": "test#test.com"}
}
package main
import (
"fmt"
"reflect"
)
type bill struct {
N1 int
N2 string
n3 string
}
func main() {
a := bill{4, "dhfthf", "fdgdf"}
v := reflect.ValueOf(a)
values := make(map[string]interface{}, v.NumField())
for i := 0; i < v.NumField(); i++ {
if v.Field(i).CanInterface() {
values[v.Type().Field(i).Name] = v.Field(i).Interface()
} else {
fmt.Printf("sorry you have a unexported field (lower case) value you are trying to sneak past. I will not allow it: %v\n", v.Type().Field(i).Name)
}
}
fmt.Println(values)
passObject(&values)
}
func passObject(v1 *map[string]interface{}) {
fmt.Println("yoyo")
}
I'm a bit late but I needed this kind of feature so I wrote this. Can resolve nested structs. By default, uses field names but can also use custom tags. A side effect is that if you set the tagTitle const to json, you could use the json tags you already have.
package main
import (
"fmt"
"reflect"
)
func StructToMap(val interface{}) map[string]interface{} {
//The name of the tag you will use for fields of struct
const tagTitle = "kelvin"
var data map[string]interface{} = make(map[string]interface{})
varType := reflect.TypeOf(val)
if varType.Kind() != reflect.Struct {
// Provided value is not an interface, do what you will with that here
fmt.Println("Not a struct")
return nil
}
value := reflect.ValueOf(val)
for i := 0; i < varType.NumField(); i++ {
if !value.Field(i).CanInterface() {
//Skip unexported fields
continue
}
tag, ok := varType.Field(i).Tag.Lookup(tagTitle)
var fieldName string
if ok && len(tag) > 0 {
fieldName = tag
} else {
fieldName = varType.Field(i).Name
}
if varType.Field(i).Type.Kind() != reflect.Struct {
data[fieldName] = value.Field(i).Interface()
} else {
data[fieldName] = StructToMap(value.Field(i).Interface())
}
}
return data
}
map := Structpb.AsMap()
// map is the map[string]interface{}

What is causing my HTTP server to fail with "exit status -1073741819"?

As an exercise I created a small HTTP server that generates random game mechanics, similar to this one. I wrote it on a Windows 7 (32-bit) system and it works flawlessly. However, when I run it on my home machine, Windows 7 (64-bit), it always fails with the same message: exit status -1073741819. I haven't managed to find anything on the web which references that status code, so I don't know how important it is.
Here's code for the server, with redundancy abridged:
package main
import (
"fmt"
"math/rand"
"time"
"net/http"
"html/template"
)
// Info about a game mechanic
type MechanicInfo struct { Name, Desc string }
// Print a mechanic as a string
func (m MechanicInfo) String() string {
return fmt.Sprintf("%s: %s", m.Name, m.Desc)
}
// A possible game mechanic
var (
UnkillableObjects = &MechanicInfo{"Avoiding Unkillable Objects",
"There are objects that the player cannot touch. These are different from normal enemies because they cannot be destroyed or moved."}
//...
Race = &MechanicInfo{"Race",
"The player must reach a place before the opponent does. Like \"Timed\" except the enemy as a \"timer\" can be slowed down by the player's actions, or there may be multiple enemies being raced against."}
)
// Slice containing all game mechanics
var GameMechanics []*MechanicInfo
// Pseudorandom number generator
var prng *rand.Rand
// Get a random mechanic
func RandMechanic() *MechanicInfo {
i := prng.Intn(len(GameMechanics))
return GameMechanics[i]
}
// Initialize the package
func init() {
prng = rand.New(rand.NewSource(time.Now().Unix()))
GameMechanics = make([]*MechanicInfo, 34)
GameMechanics[0] = UnkillableObjects
//...
GameMechanics[33] = Race
}
// serving
var index = template.Must(template.ParseFiles(
"templates/_base.html",
"templates/index.html",
))
func randMechHandler(w http.ResponseWriter, req *http.Request) {
mechanics := [3]*MechanicInfo{RandMechanic(), RandMechanic(), RandMechanic()}
if err := index.Execute(w, mechanics); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func main() {
http.HandleFunc("/", randMechHandler)
if err := http.ListenAndServe(":80", nil); err != nil {
panic(err)
}
}
In addition, the unabridged code, the _base.html template, and the index.html template.
What could be causing this issue? Is there a process for debugging a cryptic exit status like this?
When I ran it, I got the following two errors:
template: content:6: nil pointer evaluating *main.MechanicInfo.Name
http: multiple response.WriteHeader calls
The former was in the web browser, the latter in the console window where I launched your server.
The nil pointer problem is because your abridged program leaves GameMechanics[1:32] set to nil.
The second error is interesting. The only place in your program that any methods on your http.ResponseWriter get called is inside of index.Execute, which is not your code -- meaning maybe there is something wrong happening in html/template. I'm testing this with Go 1.0.2.
I put _base.html at the top of index.html and then changed index to this:
var index = template.Must(template.ParseFiles("templates/index.html"))
and the http.WriteHeaders warning went away.
Not really an answer, but a direction you could explore.
As a bonus, here's the more "Go way" of writing your program. Note that I simplified the use of the PRNG (you don't need to instantiate unless you want several going in parallel) and simplified the structure initializer:
package main
import (
"fmt"
"html/template"
"math/rand"
"net/http"
)
// Info about a game mechanic
type MechanicInfo struct{ Name, Desc string }
// Print a mechanic as a string
func (m MechanicInfo) String() string {
return fmt.Sprintf("%s: %s", m.Name, m.Desc)
}
// The game mechanics
var GameMechanics = [...]*MechanicInfo{
{"Avoiding Unkillable Objects",
"There are objects that the player cannot touch. These are different from normal enemies because they cannot be destroyed or moved."},
{"Race",
"The player must reach a place before the opponent does. Like \"Timed\" except the enemy as a \"timer\" can be slowed down by the player's actions, or there may be multiple enemies being raced against."},
}
// Get a random mechanic
func RandMechanic() *MechanicInfo {
i := rand.Intn(len(GameMechanics))
return GameMechanics[i]
}
var index = template.Must(template.ParseFiles("templates/index.html"))
func randMechHandler(w http.ResponseWriter, req *http.Request) {
mechanics := [3]*MechanicInfo{RandMechanic(), RandMechanic(), RandMechanic()}
if err := index.Execute(w, mechanics); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func main() {
http.HandleFunc("/", randMechHandler)
if err := http.ListenAndServe(":80", nil); err != nil {
panic(err)
}
}

Resources