LoginSignup
6
6

More than 3 years have passed since last update.

Linux: psコマンドで表示されるプロセスの名前を変更する

Last updated at Posted at 2017-01-01
  • 一部のシステムではsetproctitleという関数が使える
  • Linuxには標準ではsetproctitleは無い。argv[0]を書き換えるしかないので面倒
    • 元より長いコマンド名を書き込むとargv[1]以降と環境変数がある領域を破壊するので、あらかじめ別の場所にコピーする必要がある
  • util-linuxにLinux用のsetproctitle実装があるので、これをコピペすれば簡単にできる
    • ただしGPLだと思うので注意。

追記:探してみたらredisにも実装があった。RedisはBSDライセンス。

test.c
/*
 *  set process title for ps (from sendmail)
 *
 *  Clobbers argv of our main procedure so ps(1) will display the title.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

//#include "setproctitle.h"

#ifndef SPT_BUFSIZE
# define SPT_BUFSIZE     2048
#endif

extern char **environ;

static char **argv0;
static int argv_lth;

void initproctitle (int argc, char **argv)
{
  int i;
  char **envp = environ;

  /*
   * Move the environment so we can reuse the memory.
   * (Code borrowed from sendmail.)
   * WARNING: ugly assumptions on memory layout here;
   *          if this ever causes problems, #undef DO_PS_FIDDLING
   */
  for (i = 0; envp[i] != NULL; i++)
    continue;

  environ = malloc(sizeof(char *) * (i + 1));
  if (environ == NULL)
    return;

  for (i = 0; envp[i] != NULL; i++)
    if ((environ[i] = strdup(envp[i])) == NULL)
      return;
  environ[i] = NULL;

  argv0 = argv;
  if (i > 0)
    argv_lth = envp[i-1] + strlen(envp[i-1]) - argv0[0];
  else
    argv_lth = argv0[argc-1] + strlen(argv0[argc-1]) - argv0[0];
}

void setproctitle (const char *prog, const char *txt)
{
        int i;
        char buf[SPT_BUFSIZE];

        if (!argv0)
                return;

  if (strlen(prog) + strlen(txt) + 5 > SPT_BUFSIZE)
    return;

  sprintf(buf, "%s -- %s", prog, txt);

        i = strlen(buf);
        if (i > argv_lth - 2) {
                i = argv_lth - 2;
                buf[i] = '\0';
        }
  memset(argv0[0], '\0', argv_lth);       /* clear the memory area */
        strcpy(argv0[0], buf);

        argv0[1] = NULL;
}

// テスト用のmain関数
int main(int argc, char* argv[])
{
  initproctitle(argc, argv);
  setproctitle("hoge", "あいうえお");

  printf("Hello my pid = %d\n", getpid());
  sleep(10);

  return 0;
}

参考:

postgresのps_status.c プラットフォームごとに様々な方法でコマンド名変更を実現している

/*
 * Alternative ways of updating ps display:
 *
 * PS_USE_SETPROCTITLE
 *     use the function setproctitle(const char *, ...)
 *     (newer BSD systems)
 * PS_USE_PSTAT
 *     use the pstat(PSTAT_SETCMD, )
 *     (HPUX)
 * PS_USE_PS_STRINGS
 *     assign PS_STRINGS->ps_argvstr = "string"
 *     (some BSD systems)
 * PS_USE_CHANGE_ARGV
 *     assign argv[0] = "string"
 *     (some other BSD systems)
 * PS_USE_CLOBBER_ARGV
 *     write over the argv and environment area
 *     (Linux and most SysV-like systems)
 * PS_USE_WIN32
 *     push the string out as the name of a Windows event
 * PS_USE_NONE
 *     don't update ps display
 *     (This is the default, as it is safest.)
 */
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6