blob: d5404a6d7284b452472947610c01a35620d4deb7 [file] [log] [blame]
khenaidood948f772021-08-11 17:49:24 -04001// 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
Abhay Kumara2ae5992025-11-10 14:02:24 +000014//go:build (linux || darwin) && !appengine
15// +build linux darwin
16// +build !appengine
khenaidood948f772021-08-11 17:49:24 -040017
18package util
19
20import (
21 "bytes"
22 "os"
Abhay Kumara2ae5992025-11-10 14:02:24 +000023 "strconv"
24 "strings"
khenaidood948f772021-08-11 17:49:24 -040025 "syscall"
26)
27
Abhay Kumara2ae5992025-11-10 14:02:24 +000028// SysReadFile is a simplified os.ReadFile that invokes syscall.Read directly.
khenaidood948f772021-08-11 17:49:24 -040029// 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
Abhay Kumara2ae5992025-11-10 14:02:24 +000040 // Go's os.ReadFile implementation to poll forever.
khenaidood948f772021-08-11 17:49:24 -040041 //
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}
Abhay Kumara2ae5992025-11-10 14:02:24 +000053
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}