Setting the process name (as seen on `ps`) in Go

The following (rightfully) does not work:

package main

import (
        "os"
        "time"
)

func main() {
        os.Args[0] = "custom name"
        println("sleeping")
        time.Sleep(1000 * time.Second)
        println("done")
}

Some languages ​​provide this function by setting the process name as a built-in function (for example, in Ruby it is only a matter of assignment $0 ) or as a third-party library ( Python ).

I am looking for a solution that works, at least on Linux.

+5
source share
3 answers

, . , ( ) , . syscall / , Go. , :

argv [0]

func SetProcessName(name string) error {
    argv0str := (*reflect.StringHeader)(unsafe.Pointer(&os.Args[0]))
    argv0 := (*[1 << 30]byte)(unsafe.Pointer(argv0str.Data))[:argv0str.Len]

    n := copy(argv0, name)
    if n < len(argv0) {
            argv0[n] = 0
    }

    return nil
}

Go argv ( ), , .

, Linux.

PR_SET_NAME

func SetProcessName(name string) error {
    bytes := append([]byte(name), 0)
    ptr := unsafe.Pointer(&bytes[0])
    if _, _, errno := syscall.RawSyscall6(syscall.SYS_PRCTL, syscall.PR_SET_NAME, uintptr(ptr), 0, 0, 0, 0); errno != 0 {
            return syscall.Errno(errno)
    }
    return nil
}

16 .

, , Linux, , PR_GET_NAME . - Linux VM.

+8

Linux, prctl PR_SET_NAME.

, Go. C , Go.

+4

, " " - . , Ruby Go? os.Args " ", , . Go. getters/seters , /, .

, - , .

To work with process properties that are different from those available via the os package, you need to use the platform syscall in a certain way. But then build restrictions (discussed here ) can help handle things correctly on different platforms.

0
source

All Articles