blob: d5404a6d7284b452472947610c01a35620d4deb7 [file] [log] [blame]
Abhay Kumara61c5222025-11-10 07:32:50 +00001// Copyright 2018 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14//go:build (linux || darwin) && !appengine
15// +build linux darwin
16// +build !appengine
17
18package util
19
20import (
21 "bytes"
22 "os"
23 "strconv"
24 "strings"
25 "syscall"
26)
27
28// SysReadFile is a simplified os.ReadFile that invokes syscall.Read directly.
29// https://github.com/prometheus/node_exporter/pull/728/files
30//
31// Note that this function will not read files larger than 128 bytes.
32func SysReadFile(file string) (string, error) {
33 f, err := os.Open(file)
34 if err != nil {
35 return "", err
36 }
37 defer f.Close()
38
39 // On some machines, hwmon drivers are broken and return EAGAIN. This causes
40 // Go's os.ReadFile implementation to poll forever.
41 //
42 // Since we either want to read data or bail immediately, do the simplest
43 // possible read using syscall directly.
44 const sysFileBufferSize = 128
45 b := make([]byte, sysFileBufferSize)
46 n, err := syscall.Read(int(f.Fd()), b)
47 if err != nil {
48 return "", err
49 }
50
51 return string(bytes.TrimSpace(b[:n])), nil
52}
53
54// SysReadUintFromFile reads a file using SysReadFile and attempts to parse a uint64 from it.
55func SysReadUintFromFile(path string) (uint64, error) {
56 data, err := SysReadFile(path)
57 if err != nil {
58 return 0, err
59 }
60 return strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
61}
62
63// SysReadIntFromFile reads a file using SysReadFile and attempts to parse a int64 from it.
64func SysReadIntFromFile(path string) (int64, error) {
65 data, err := SysReadFile(path)
66 if err != nil {
67 return 0, err
68 }
69 return strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64)
70}