1// Licensed to Elasticsearch B.V. under one or more contributor
2// license agreements. See the NOTICE file distributed with
3// this work for additional information regarding copyright
4// ownership. Elasticsearch B.V. licenses this file to you under
5// the Apache License, Version 2.0 (the "License"); you may
6// not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9//     http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18// +build darwin,amd64,cgo
19
20package darwin
21
22// #include <unistd.h>
23// #include <uuid/uuid.h>
24import "C"
25
26import (
27	"unsafe"
28
29	"github.com/pkg/errors"
30)
31
32// MachineID returns the Hardware UUID also accessible via
33// About this Mac -> System Report and as the field
34// IOPlatformUUID in the output of "ioreg -d2 -c IOPlatformExpertDevice".
35func MachineID() (string, error) {
36	return getHostUUID()
37}
38
39func getHostUUID() (string, error) {
40	var uuidC C.uuid_t
41	var id [unsafe.Sizeof(uuidC)]C.uchar
42	wait := C.struct_timespec{5, 0} // 5 seconds
43
44	ret, err := C.gethostuuid(&id[0], &wait)
45	if ret != 0 {
46		if err != nil {
47			return "", errors.Wrapf(err, "gethostuuid failed with %v", ret)
48		}
49
50		return "", errors.Errorf("gethostuuid failed with %v", ret)
51	}
52
53	var uuidStringC C.uuid_string_t
54	var uuid [unsafe.Sizeof(uuidStringC)]C.char
55	_, err = C.uuid_unparse_upper(&id[0], &uuid[0])
56	if err != nil {
57		return "", errors.Wrap(err, "uuid_unparse_upper failed")
58	}
59
60	return C.GoString(&uuid[0]), nil
61}
62