<commit_before>package main

import (
	"io/ioutil"
	"os"
	"os/user"
	"path"
	"strconv"
	"strings"
	"syscall"
)

const (
	// The values in /proc/<pid>/stat
	statPid = iota
	statComm
	statState
	statPpid
	statPgrp
	statSession
	statTtyNr
	statTpgid
	statFlags
	statMinflt
	statCminflt
	statMajflt
	statCmajflt
	statUtime
	statStime
	statCutime
	statCstime
	statPriority
	statNice
	statNumThreads
	statItrealvalue
	statStartTime
	statVsize
	statRSS
	statRSSLimit
	statStartCode
	statEndCode
	statStartStack
	statKstKesp
	statKstKeip
	statSignal
	statBlocked
	statSigIgnore
	statSigCatch
	statWchan
	statNswap
	statCnswap
	statExitSignal
	statProcessor
	statRtPriority
	statPolicy
	statDelayActBlkioTicks
	statGuestTime
	statCguestTime
)

// Process represents an operating system process.
type Process struct {
	Pid     uint64
	User    *user.User
	Name    string // foo
	Command string // /usr/bin/foo --args

	// Alive is a flag used by ProcessMonitor to determine if it should remove
	// this process.
	Alive bool

	// Data from /proc/<pid>/stat
	Pgrp  uint64
	Utime uint64
	Stime uint64
	RSS   uint64

	UtimeDiff uint64
	StimeDiff uint64
}

// NewProcess returns a new Process if a process is currently running on
// the system with the passed in Pid.
func NewProcess(pid uint64) *Process {
	p := &Process{
		Pid: pid,
	}

	if err := p.Update(); err != nil {
		return nil
	}

	if err := p.parseCmdlineFile(); err != nil {
		return nil
	}

	return p
}

// Update updates Process from various files in /proc/<pid>. It returns an
// error if Process was unable to be updated (probably because the actual OS
// process is no longer running).
func (p *Process) Update() error {
	if err := p.statProcDir(); err != nil {
		return err
	}

	if err := p.parseStatFile(); err != nil {
		return err
	}

	return nil
}

// IsKernelThread returns whether or not Process is a kernel thread.
func (p *Process) IsKernelThread() bool {
	return p.Pgrp == 0
}

func (p *Process) statProcDir() error {
	path := path.Join("/proc", strconv.FormatUint(p.Pid, 10))

	var stat syscall.Stat_t
	if err := syscall.Stat(path, &stat); err != nil {
		return err
	}

	user, err := UserByUid(strconv.FormatUint(uint64(stat.Uid), 10))
	if err != nil {
		return err
	}
	p.User = user

	return nil
}

func (p *Process) parseStatFile() error {
	path := path.Join("/proc", strconv.FormatUint(p.Pid, 10), "stat")

	file, err := os.Open(path)
	if err != nil {
		return err
	}
	defer file.Close()

	data, err := ioutil.ReadAll(file)
	if err != nil {
		return err
	}

	line := string(data)
	values := strings.Split(line, " ")

	p.Pgrp, err = strconv.ParseUint(values[statPgrp], 10, 64)
	if err != nil {
		panic(err)
	}

	lastUtime := p.Utime
	p.Utime, err = strconv.ParseUint(values[statUtime], 10, 64)
	if err != nil {
		panic(err)
	}
	p.UtimeDiff = p.Utime - lastUtime

	lastStime := p.Stime<commit_msg>Use ReadFile to simplify function<commit_after>package main

import (
	"io/ioutil"
	"os/user"
	"path"
	"strconv"
	"strings"
	"syscall"
)

const (
	// The values in /proc/<pid>/stat
	statPid = iota
	statComm
	statState
	statPpid
	statPgrp
	statSession
	statTtyNr
	statTpgid
	statFlags
	statMinflt
	statCminflt
	statMajflt
	statCmajflt
	statUtime
	statStime
	statCutime
	statCstime
	statPriority
	statNice
	statNumThreads
	statItrealvalue
	statStartTime
	statVsize
	statRSS
	statRSSLimit
	statStartCode
	statEndCode
	statStartStack
	statKstKesp
	statKstKeip
	statSignal
	statBlocked
	statSigIgnore
	statSigCatch
	statWchan
	statNswap
	statCnswap
	statExitSignal
	statProcessor
	statRtPriority
	statPolicy
	statDelayActBlkioTicks
	statGuestTime
	statCguestTime
)

// Process represents an operating system process.
type Process struct {
	Pid     uint64
	User    *user.User
	Name    string // foo
	Command string // /usr/bin/foo --args

	// Alive is a flag used by ProcessMonitor to determine if it should remove
	// this process.
	Alive bool

	// Data from /proc/<pid>/stat
	Pgrp  uint64
	Utime uint64
	Stime uint64
	RSS   uint64

	UtimeDiff uint64
	StimeDiff uint64
}

// NewProcess returns a new Process if a process is currently running on
// the system with the passed in Pid.
func NewProcess(pid uint64) *Process {
	p := &Process{
		Pid: pid,
	}

	if err := p.Update(); err != nil {
		return nil
	}

	if err := p.parseCmdlineFile(); err != nil {
		return nil
	}

	return p
}

// Update updates Process from various files in /proc/<pid>. It returns an
// error if Process was unable to be updated (probably because the actual OS
// process is no longer running).
func (p *Process) Update() error {
	if err := p.statProcDir(); err != nil {
		return err
	}

	if err := p.parseStatFile(); err != nil {
		return err
	}

	return nil
}

// IsKernelThread returns whether or not Process is a kernel thread.
func (p *Process) IsKernelThread() bool {
	return p.Pgrp == 0
}

func (p *Process) statProcDir() error {
	path := path.Join("/proc", strconv.FormatUint(p.Pid, 10))

	var stat syscall.Stat_t
	if err := syscall.Stat(path, &stat); err != nil {
		return err
	}

	user, err := UserByUid(strconv.FormatUint(uint64(stat.Uid), 10))
	if err != nil {
		return err
	}
	p.User = user

	return nil
}

func (p *Process) parseStatFile() error {
	path := path.Join("/proc", strconv.FormatUint(p.Pid, 10), "stat")

	data, err := ioutil.ReadFile(path)
	if err != nil {
		return err
	}

	line := string(data)
	values := strings.Split(line, " ")

	p.Pgrp, err = strconv.ParseUint(values[statPgrp], 10, 64)
	if err != nil {
		panic(err)
	}

	lastUtime := p.Utime
	p.Utime, err = strconv.ParseUint(values[statUtime], 10, 64)
	if err != nil {
		panic(err)
	}
	p.UtimeDiff = p.Utime - lastUtime

	lastStime := p.Stime
{'fraction_non_alphanumeric': 0.10415561450044208, 'fraction_numerical': 0.011671087533156498, 'mean_word_length': 3.4817749603803487, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6830128', 'n_tokens_mistral': 2223, 'n_tokens_neox': 2111, 'n_words': 618}