hotspot/src/os/linux/vm/attachListener_linux.cpp
author trims
Thu, 27 May 2010 19:08:38 -0700
changeset 5547 f4b087cbb361
parent 5410 c4b979417733
child 6170 82aea418ab2d
permissions -rw-r--r--
6941466: Oracle rebranding changes for Hotspot repositories Summary: Change all the Sun copyrights to Oracle copyright Reviewed-by: ohair
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5410
diff changeset
     2
 * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5410
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5410
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5410
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_attachListener_linux.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
#include <unistd.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
#include <signal.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
#include <sys/types.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
#include <sys/socket.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
#include <sys/un.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
#include <sys/stat.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
// The attach mechanism on Linux uses a UNIX domain socket. An attach listener
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
// thread is created at startup or is created on-demand via a signal from
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
// the client tool. The attach listener creates a socket and binds it to a file
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
// in the filesystem. The attach listener then acts as a simple (single-
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
// threaded) server - tt waits for a client to connect, reads the request,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
// executes it, and returns the response to the client via the socket
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
// connection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
// As the socket is a UNIX domain socket it means that only clients on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
// local machine can connect. In addition there are two other aspects to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
// the security:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
// 1. The well known file that the socket is bound to has permission 400
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
// 2. When a client connect, the SO_PEERCRED socket option is used to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
//    obtain the credentials of client. We check that the effective uid
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
//    of the client matches this process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
// forward reference
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
class LinuxAttachOperation;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
class LinuxAttachListener: AllStatic {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  // the path to which we bind the UNIX domain socket
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  static char _path[PATH_MAX+1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  static bool _has_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  // the file descriptor for the listening socket
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  static int _listener;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  static void set_path(char* path) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
    if (path == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
      _has_path = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
      strncpy(_path, path, PATH_MAX);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
      _path[PATH_MAX] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
      _has_path = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  static void set_listener(int s)               { _listener = s; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  // reads a request from the given connected socket
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  static LinuxAttachOperation* read_request(int s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
    ATTACH_PROTOCOL_VER = 1                     // protocol version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    ATTACH_ERROR_BADVERSION     = 101           // error codes
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  // initialize the listener, returns 0 if okay
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  static int init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  static char* path()                   { return _path; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  static bool has_path()                { return _has_path; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  static int listener()                 { return _listener; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  // write the given buffer to a socket
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  static int write_fully(int s, char* buf, int len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  static LinuxAttachOperation* dequeue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
class LinuxAttachOperation: public AttachOperation {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
  // the connection to the client
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  int _socket;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  void complete(jint res, bufferedStream* st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  void set_socket(int s)                                { _socket = s; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  int socket() const                                    { return _socket; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  LinuxAttachOperation(char* name) : AttachOperation(name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    set_socket(-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
// statics
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
char LinuxAttachListener::_path[PATH_MAX+1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
bool LinuxAttachListener::_has_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
int LinuxAttachListener::_listener = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
// Supporting class to help split a buffer into individual components
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
class ArgumentIterator : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  char* _pos;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  char* _end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  ArgumentIterator(char* arg_buffer, size_t arg_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
    _pos = arg_buffer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
    _end = _pos + arg_size - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  char* next() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
    if (*_pos == '\0') {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
    char* res = _pos;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
    char* next_pos = strchr(_pos, '\0');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
    if (next_pos < _end)  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
      next_pos++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    _pos = next_pos;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
    return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
// atexit hook to stop listener and unlink the file that it is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
// bound too.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  static void listener_cleanup() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
    static int cleanup_done;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    if (!cleanup_done) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
      cleanup_done = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
      int s = LinuxAttachListener::listener();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
      if (s != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
        ::close(s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
      if (LinuxAttachListener::has_path()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
        ::unlink(LinuxAttachListener::path());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
// Initialization - create a listener socket and bind it to a file
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
int LinuxAttachListener::init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  char path[PATH_MAX+1];        // socket file
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  int listener;                 // listener socket (file descriptor)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  // register function to cleanup
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  ::atexit(listener_cleanup);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  // create the listener socket
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  if (listener == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  int res = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  struct sockaddr_un addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  addr.sun_family = AF_UNIX;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  // FIXME: Prior to b39 the tool-side API expected to find the well
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  // known file in the working directory. To allow this libjvm.so work with
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  // a pre-b39 SDK we create it in the working directory if
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  // +StartAttachListener is used is used. All unit tests for this feature
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  // currently used this flag. Once b39 SDK has been promoted we can remove
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  // this code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  if (StartAttachListener) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
    sprintf(path, ".java_pid%d", os::current_process_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
    strcpy(addr.sun_path, path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    ::unlink(path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
    res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  if (res == -1) {
5237
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 670
diff changeset
   195
    snprintf(path, PATH_MAX+1, "%s/.java_pid%d",
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 670
diff changeset
   196
             os::get_temp_directory(), os::current_process_id());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    strcpy(addr.sun_path, path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
    ::unlink(path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  if (res == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    RESTARTABLE(::close(listener), res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  set_path(path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  // put in listen mode and set permission
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  if ((::listen(listener, 5) == -1) || (::chmod(path, S_IREAD|S_IWRITE) == -1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    RESTARTABLE(::close(listener), res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
    ::unlink(path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
    set_path(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  set_listener(listener);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
// Given a socket that is connected to a peer we read the request and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
// create an AttachOperation. As the socket is blocking there is potential
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
// for a denial-of-service if the peer does not response. However this happens
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
// after the peer credentials have been checked and in the worst case it just
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
// means that the attach listener thread is blocked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
LinuxAttachOperation* LinuxAttachListener::read_request(int s) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  char ver_str[8];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  sprintf(ver_str, "%d", ATTACH_PROTOCOL_VER);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  // The request is a sequence of strings so we first figure out the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
  // expected count and the maximum possible length of the request.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  // The request is:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  //   <ver>0<cmd>0<arg>0<arg>0<arg>0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  // where <ver> is the protocol version (1), <cmd> is the command
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  // name ("load", "datadump", ...), and <arg> is an argument
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  int expected_str_count = 2 + AttachOperation::arg_count_max;
223
5c3b023117d9 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 1
diff changeset
   236
  const int max_len = (sizeof(ver_str) + 1) + (AttachOperation::name_length_max + 1) +
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
    AttachOperation::arg_count_max*(AttachOperation::arg_length_max + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  char buf[max_len];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  int str_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  // Read until all (expected) strings have been read, the buffer is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  // full, or EOF.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  int off = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  int left = max_len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
    int n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
    RESTARTABLE(read(s, buf+off, left), n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
    if (n == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
      return NULL;      // reset by peer or other error
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
    if (n == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
    for (int i=0; i<n; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
      if (buf[off+i] == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
        // EOS found
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
        str_count++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
        // The first string is <ver> so check it now to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
        // check for protocol mis-match
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
        if (str_count == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
          if ((strlen(buf) != strlen(ver_str)) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
              (atoi(buf) != ATTACH_PROTOCOL_VER)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
            char msg[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
            sprintf(msg, "%d\n", ATTACH_ERROR_BADVERSION);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
            write_fully(s, msg, strlen(msg));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
            return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
    off += n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
    left -= n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  } while (left > 0 && str_count < expected_str_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  if (str_count != expected_str_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    return NULL;        // incomplete request
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  // parse request
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  ArgumentIterator args(buf, (max_len)-left);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  // version already checked
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  char* v = args.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  char* name = args.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  if (name == NULL || strlen(name) > AttachOperation::name_length_max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  LinuxAttachOperation* op = new LinuxAttachOperation(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  for (int i=0; i<AttachOperation::arg_count_max; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    char* arg = args.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    if (arg == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
      op->set_arg(i, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
      if (strlen(arg) > AttachOperation::arg_length_max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
        delete op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
        return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
      op->set_arg(i, arg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  op->set_socket(s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  return op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
// Dequeue an operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
// In the Linux implementation there is only a single operation and clients
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
// cannot queue commands (except at the socket level).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
LinuxAttachOperation* LinuxAttachListener::dequeue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
    int s;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
    // wait for client to connect
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
    struct sockaddr addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    socklen_t len = sizeof(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    RESTARTABLE(::accept(listener(), &addr, &len), s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
    if (s == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
      return NULL;      // log a warning?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    // get the credentials of the peer and check the effective uid/guid
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
    // - check with jeff on this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
    struct ucred cred_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
    socklen_t optlen = sizeof(cred_info);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
    if (::getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void*)&cred_info, &optlen) == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
      int res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
      RESTARTABLE(::close(s), res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
    uid_t euid = geteuid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
    gid_t egid = getegid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
    if (cred_info.uid != euid || cred_info.gid != egid) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
      int res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
      RESTARTABLE(::close(s), res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
    // peer credential look okay so we read the request
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
    LinuxAttachOperation* op = read_request(s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
    if (op == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
      int res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
      RESTARTABLE(::close(s), res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
      return op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
// write the given buffer to the socket
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
int LinuxAttachListener::write_fully(int s, char* buf, int len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
    int n = ::write(s, buf, len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
    if (n == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
      if (errno != EINTR) return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
      buf += n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
      len -= n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  while (len > 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
// Complete an operation by sending the operation result and any result
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
// output to the client. At this time the socket is in blocking mode so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
// potentially we can block if there is a lot of data and the client is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
// non-responsive. For most operations this is a non-issue because the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
// default send buffer is sufficient to buffer everything. In the future
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
// if there are operations that involves a very big reply then it the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
// socket could be made non-blocking and a timeout could be used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
void LinuxAttachOperation::complete(jint result, bufferedStream* st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  ThreadBlockInVM tbivm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  // cleared by handle_special_suspend_equivalent_condition() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  // java_suspend_self() via check_and_wait_while_suspended()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  // write operation result
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  char msg[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  sprintf(msg, "%d\n", result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  int rc = LinuxAttachListener::write_fully(this->socket(), msg, strlen(msg));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  // write any result data
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  if (rc == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
    LinuxAttachListener::write_fully(this->socket(), (char*) st->base(), st->size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
    ::shutdown(this->socket(), 2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  // done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
  RESTARTABLE(::close(this->socket()), rc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  thread->check_and_wait_while_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  delete this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
// AttachListener functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
AttachOperation* AttachListener::dequeue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  ThreadBlockInVM tbivm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
  // cleared by handle_special_suspend_equivalent_condition() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  // java_suspend_self() via check_and_wait_while_suspended()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  AttachOperation* op = LinuxAttachListener::dequeue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  thread->check_and_wait_while_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  return op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
int AttachListener::pd_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  ThreadBlockInVM tbivm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  // cleared by handle_special_suspend_equivalent_condition() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  // java_suspend_self() via check_and_wait_while_suspended()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  int ret_code = LinuxAttachListener::init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  thread->check_and_wait_while_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  return ret_code;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
// Attach Listener is started lazily except in the case when
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
// +ReduseSignalUsage is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
bool AttachListener::init_at_startup() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  if (ReduceSignalUsage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
// If the file .attach_pid<pid> exists in the working directory
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
// or /tmp then this is the trigger to start the attach mechanism
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
bool AttachListener::is_init_trigger() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  if (init_at_startup() || is_initialized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
    return false;               // initialized at startup or already initialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  }
5410
c4b979417733 6944822: Fix for 6938627 exposes problem with hard-coded buffer sizes
coleenp
parents: 5237
diff changeset
   464
  char fn[PATH_MAX+1];
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  sprintf(fn, ".attach_pid%d", os::current_process_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  int ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  struct stat64 st;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
  RESTARTABLE(::stat64(fn, &st), ret);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  if (ret == -1) {
5237
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 670
diff changeset
   470
    snprintf(fn, sizeof(fn), "%s/.attach_pid%d",
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 670
diff changeset
   471
             os::get_temp_directory(), os::current_process_id());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
    RESTARTABLE(::stat64(fn, &st), ret);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  if (ret == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
    // simple check to avoid starting the attach mechanism when
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    // a bogus user creates the file
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
    if (st.st_uid == geteuid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
      init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
// if VM aborts then remove listener
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
void AttachListener::abort() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  listener_cleanup();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
void AttachListener::pd_data_dump() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  os::signal_notify(SIGQUIT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
AttachOperationFunctionInfo* AttachListener::pd_find_operation(const char* n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
jint AttachListener::pd_set_flag(AttachOperation* op, outputStream* out) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  out->print_cr("flag '%s' cannot be changed", op->arg(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
  return JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
void AttachListener::pd_detachall() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  // do nothing for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
}