Copyright 2018 The Prometheus Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

package procfs

import (
	
	
	
	
	
	
	
)
For the proc file format details, see https://elixir.bootlin.com/linux/v4.17/source/net/unix/af_unix.c#L2815 and https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/net.h#L48.
Inode and Path are optional.
NetUnixType is the type of the type field.
NetUnixFlags is the type of the flags field.
NetUnixState is the type of the state field.
NetUnixLine represents a line of /proc/net/unix.
NetUnix holds the data read from /proc/net/unix.
type NetUnix struct {
	Rows []*NetUnixLine
}
NewNetUnix returns data read from /proc/net/unix.
func () (*NetUnix, error) {
	,  := NewFS(DefaultMountPoint)
	if  != nil {
		return nil, 
	}

	return .NewNetUnix()
}
NewNetUnix returns data read from /proc/net/unix.
func ( FS) () (*NetUnix, error) {
	return NewNetUnixByPath(.proc.Path("net/unix"))
}
NewNetUnixByPath returns data read from /proc/net/unix by file path. It might returns an error with partial parsed data, if an error occur after some data parsed.
func ( string) (*NetUnix, error) {
	,  := os.Open()
	if  != nil {
		return nil, 
	}
	defer .Close()
	return NewNetUnixByReader()
}
NewNetUnixByReader returns data read from /proc/net/unix by a reader. It might returns an error with partial parsed data, if an error occur after some data parsed.
func ( io.Reader) (*NetUnix, error) {
	 := &NetUnix{
		Rows: make([]*NetUnixLine, 0, 32),
	}
Omit the header line.
	.Scan()
From the man page of proc(5), it does not contain an Inode field, but in actually it exists. This code works for both cases.
	 := strings.Contains(, "Inode")

	 := netUnixStaticFieldsCnt
	if  {
		++
	}
	for .Scan() {
		 := .Text()
		,  := .parseLine(, , )
		if  != nil {
			return , 
		}
		.Rows = append(.Rows, )
	}

	return , .Err()
}

func ( *NetUnix) ( string,  bool,  int) (*NetUnixLine, error) {
	 := strings.Fields()
	 := len()
	if  <  {
		return nil, fmt.Errorf(
			"Parse Unix domain failed: expect at least %d fields but got %d",
			, )
	}
	,  := .parseKernelPtr([netUnixKernelPtrIdx])
	if  != nil {
		return nil, fmt.Errorf("Parse Unix domain num(%s) failed: %s", [netUnixKernelPtrIdx], )
	}
	,  := .parseUsers([netUnixRefCountIdx])
	if  != nil {
		return nil, fmt.Errorf("Parse Unix domain ref count(%s) failed: %s", [netUnixRefCountIdx], )
	}
	,  := .parseFlags([netUnixFlagsIdx])
	if  != nil {
		return nil, fmt.Errorf("Parse Unix domain flags(%s) failed: %s", [netUnixFlagsIdx], )
	}
	,  := .parseType([netUnixTypeIdx])
	if  != nil {
		return nil, fmt.Errorf("Parse Unix domain type(%s) failed: %s", [netUnixTypeIdx], )
	}
	,  := .parseState([netUnixStateIdx])
	if  != nil {
		return nil, fmt.Errorf("Parse Unix domain state(%s) failed: %s", [netUnixStateIdx], )
	}
	var  uint64
	if  {
		 := [netUnixInodeIdx]
		,  = .parseInode()
		if  != nil {
			return nil, fmt.Errorf("Parse Unix domain inode(%s) failed: %s", , )
		}
	}

	 := &NetUnixLine{
		KernelPtr: ,
		RefCount:  ,
		Type:      ,
		Flags:     ,
		State:     ,
		Inode:     ,
	}
Path field is optional.
	if  >  {
		 := netUnixInodeIdx + 1
		if ! {
			--
		}
		.Path = []
	}

	return , nil
}

func ( NetUnix) ( string) (string, error) {
	if !strings.HasSuffix(, ":") {
		return "", errInvalidKernelPtrFmt
	}
	return [:len()-1], nil
}

func ( NetUnix) ( string) (uint64, error) {
	return strconv.ParseUint(, 16, 32)
}

func ( NetUnix) ( string) (NetUnixType, error) {
	,  := strconv.ParseUint(, 16, 16)
	if  != nil {
		return 0, 
	}
	return NetUnixType(), nil
}

func ( NetUnix) ( string) (NetUnixFlags, error) {
	,  := strconv.ParseUint(, 16, 32)
	if  != nil {
		return 0, 
	}
	return NetUnixFlags(), nil
}

func ( NetUnix) ( string) (NetUnixState, error) {
	,  := strconv.ParseInt(, 16, 8)
	if  != nil {
		return 0, 
	}
	return NetUnixState(), nil
}

func ( NetUnix) ( string) (uint64, error) {
	return strconv.ParseUint(, 10, 64)
}

func ( NetUnixType) () string {
	switch  {
	case netUnixTypeStream:
		return "stream"
	case netUnixTypeDgram:
		return "dgram"
	case netUnixTypeSeqpacket:
		return "seqpacket"
	}
	return "unknown"
}

func ( NetUnixFlags) () string {
	switch  {
	case netUnixFlagListen:
		return "listen"
	default:
		return "default"
	}
}

func ( NetUnixState) () string {
	switch  {
	case netUnixStateUnconnected:
		return "unconnected"
	case netUnixStateConnecting:
		return "connecting"
	case netUnixStateConnected:
		return "connected"
	case netUnixStateDisconnected:
		return "disconnected"
	}
	return "unknown"