Top


定義場所(file name)

hotspot/src/os/linux/vm/attachListener_linux.cpp

説明(description)

// Initialization - create a listener socket and bind it to a file

名前(function name)

int LinuxAttachListener::init() {

本体部(body)

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      char path[UNIX_PATH_MAX];          // socket file
      char initial_path[UNIX_PATH_MAX];  // socket file during setup
      int listener;                      // listener socket (file descriptor)

  {- -------------------------------------------
  (1) atexit() を呼んで, listener_cleanup() 関数が終了時に呼ばれるようにしておく.
      ---------------------------------------- -}

      // register function to cleanup
      ::atexit(listener_cleanup);

  {- -------------------------------------------
  (1) 通信用の unix domain socket のファイル名を生成する.

      (ファイル名は "${TMP_DIR}/.java_pid${PID}".
       ただし, 生成作業中だけは, 一時的に最後に ".tmp" を付けた名前にしておく)
      (ファイル名の生成に失敗したらここでリターン)
      ---------------------------------------- -}

      int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
                       os::get_temp_directory(), os::current_process_id());
      if (n < (int)UNIX_PATH_MAX) {
        n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path);
      }
      if (n >= (int)UNIX_PATH_MAX) {
        return -1;
      }

  {- -------------------------------------------
  (1) 通信用の unix domain socket を作成する.
      (失敗したらここでリターン)
      ---------------------------------------- -}

      // create the listener socket
      listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
      if (listener == -1) {
        return -1;
      }

  {- -------------------------------------------
  (1) 通信用の unix domain socket を bind する.
      (失敗したらここでリターン)
      ---------------------------------------- -}

      // bind socket
      struct sockaddr_un addr;
      addr.sun_family = AF_UNIX;
      strcpy(addr.sun_path, initial_path);
      ::unlink(initial_path);
      int res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
      if (res == -1) {
        RESTARTABLE(::close(listener), res);
        return -1;
      }

  {- -------------------------------------------
  (1) 通信用の unix domain socket を listen する.
      その後, chmod() でアクセス権限を変更し, rename() で ".tmp" を含まないファイル名に変更する.

      (なお, この操作のどこかで失敗したらその時点でリターンする. 
       その場合, ファイルも unlink() で削除する)
      ---------------------------------------- -}

      // put in listen mode, set permissions, and rename into place
      res = ::listen(listener, 5);
      if (res == 0) {
          RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
          if (res == 0) {
              res = ::rename(initial_path, path);
          }
      }
      if (res == -1) {
        RESTARTABLE(::close(listener), res);
        ::unlink(initial_path);
        return -1;
      }

  {- -------------------------------------------
  (1) 
      ---------------------------------------- -}

      set_path(path);
      set_listener(listener);

  {- -------------------------------------------
  (1) リターン
      ---------------------------------------- -}

      return 0;
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.