Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.
  • 一部のシステムでは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.)
 */
aosho235
1981年生まれ。駅すぱあとの会社で新規サービスを開発しています。好きなレイヤーはOS~ミドルウェア。好きなことは開発を楽にするためのツールやフレームワークの整備、自分自身が便利と思うものを作ること。新しいものを追うより、自分が自信を持って使える技術で効率的に開発するのが好き。そのため使うライブラリやサービスの挙動は仔細に把握しておきたいものです。
https://aosho235.com/
val
経路検索システム「駅すぱあと」をはじめ、全国のデータと高い信頼性をベースにさまざまなサービスを展開。
https://www.val.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away