github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/system/proc.go (about)

     1  package system
     2  
     3  import (
     4  	"io/ioutil"
     5  	"path/filepath"
     6  	"strconv"
     7  	"strings"
     8  )
     9  
    10  // look in /proc to find the process start time so that we can verify
    11  // that this pid has started after ourself
    12  func GetProcessStartTime(pid int) (string, error) {
    13  	data, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat"))
    14  	if err != nil {
    15  		return "", err
    16  	}
    17  	return parseStartTime(string(data))
    18  }
    19  
    20  func parseStartTime(stat string) (string, error) {
    21  	// the starttime is located at pos 22
    22  	// from the man page
    23  	//
    24  	// starttime %llu (was %lu before Linux 2.6)
    25  	// (22)  The  time the process started after system boot.  In kernels before Linux 2.6, this
    26  	// value was expressed in jiffies.  Since Linux 2.6, the value is expressed in  clock  ticks
    27  	// (divide by sysconf(_SC_CLK_TCK)).
    28  	//
    29  	// NOTE:
    30  	// pos 2 could contain space and is inside `(` and `)`:
    31  	// (2) comm  %s
    32  	// The filename of the executable, in parentheses.
    33  	// This is visible whether or not the executable is
    34  	// swapped out.
    35  	//
    36  	// the following is an example:
    37  	// 89653 (gunicorn: maste) S 89630 89653 89653 0 -1 4194560 29689 28896 0 3 146 32 76 19 20 0 1 0 2971844 52965376 3920 18446744073709551615 1 1 0 0 0 0 0 16781312 137447943 0 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0
    38  
    39  	// get parts after last `)`:
    40  	s := strings.Split(stat, ")")
    41  	parts := strings.Split(strings.TrimSpace(s[len(s)-1]), " ")
    42  	return parts[22-3], nil // starts at 3 (after the filename pos `2`)
    43  }