--- a/hotspot/src/os/linux/vm/attachListener_linux.cpp Thu Jul 15 13:48:01 2010 -0700
+++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp Sat Jul 17 21:49:23 2010 -0700
@@ -32,11 +32,15 @@
#include <sys/un.h>
#include <sys/stat.h>
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path)
+#endif
+
// The attach mechanism on Linux uses a UNIX domain socket. An attach listener
// thread is created at startup or is created on-demand via a signal from
// the client tool. The attach listener creates a socket and binds it to a file
// in the filesystem. The attach listener then acts as a simple (single-
-// threaded) server - tt waits for a client to connect, reads the request,
+// threaded) server - it waits for a client to connect, reads the request,
// executes it, and returns the response to the client via the socket
// connection.
//
@@ -54,7 +58,7 @@
class LinuxAttachListener: AllStatic {
private:
// the path to which we bind the UNIX domain socket
- static char _path[PATH_MAX+1];
+ static char _path[UNIX_PATH_MAX];
static bool _has_path;
// the file descriptor for the listening socket
@@ -64,8 +68,8 @@
if (path == NULL) {
_has_path = false;
} else {
- strncpy(_path, path, PATH_MAX);
- _path[PATH_MAX] = '\0';
+ strncpy(_path, path, UNIX_PATH_MAX);
+ _path[UNIX_PATH_MAX-1] = '\0';
_has_path = true;
}
}
@@ -113,7 +117,7 @@
};
// statics
-char LinuxAttachListener::_path[PATH_MAX+1];
+char LinuxAttachListener::_path[UNIX_PATH_MAX];
bool LinuxAttachListener::_has_path;
int LinuxAttachListener::_listener = -1;
@@ -163,54 +167,53 @@
// Initialization - create a listener socket and bind it to a file
int LinuxAttachListener::init() {
- char path[PATH_MAX+1]; // socket file
- int listener; // listener socket (file descriptor)
+ char path[UNIX_PATH_MAX]; // socket file
+ char initial_path[UNIX_PATH_MAX]; // socket file during setup
+ int listener; // listener socket (file descriptor)
// register function to cleanup
::atexit(listener_cleanup);
+ 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;
+ }
+
// create the listener socket
listener = ::socket(PF_UNIX, SOCK_STREAM, 0);
if (listener == -1) {
return -1;
}
- int res = -1;
+ // bind socket
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
-
- // FIXME: Prior to b39 the tool-side API expected to find the well
- // known file in the working directory. To allow this libjvm.so work with
- // a pre-b39 SDK we create it in the working directory if
- // +StartAttachListener is used is used. All unit tests for this feature
- // currently used this flag. Once b39 SDK has been promoted we can remove
- // this code.
- if (StartAttachListener) {
- sprintf(path, ".java_pid%d", os::current_process_id());
- strcpy(addr.sun_path, path);
- ::unlink(path);
- res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
- }
- if (res == -1) {
- snprintf(path, PATH_MAX+1, "%s/.java_pid%d",
- os::get_temp_directory(), os::current_process_id());
- strcpy(addr.sun_path, path);
- ::unlink(path);
- res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
- }
+ 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;
}
- set_path(path);
- // put in listen mode and set permission
- if ((::listen(listener, 5) == -1) || (::chmod(path, S_IREAD|S_IWRITE) == -1)) {
+ // 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(path);
- set_path(NULL);
+ ::unlink(initial_path);
return -1;
}
+ set_path(path);
set_listener(listener);
return 0;
--- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Thu Jul 15 13:48:01 2010 -0700
+++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Sat Jul 17 21:49:23 2010 -0700
@@ -364,6 +364,7 @@
// Create the door
int SolarisAttachListener::create_door() {
char door_path[PATH_MAX+1];
+ char initial_path[PATH_MAX+1];
int fd, res;
// register exit function
@@ -375,36 +376,46 @@
return -1;
}
+ // create initial file to attach door descriptor
snprintf(door_path, sizeof(door_path), "%s/.java_pid%d",
os::get_temp_directory(), os::current_process_id());
- RESTARTABLE(::creat(door_path, S_IRUSR | S_IWUSR), fd);
-
+ snprintf(initial_path, sizeof(initial_path), "%s.tmp", door_path);
+ RESTARTABLE(::creat(initial_path, S_IRUSR | S_IWUSR), fd);
if (fd == -1) {
- debug_only(warning("attempt to create %s failed", door_path));
+ debug_only(warning("attempt to create %s failed", initial_path));
+ ::door_revoke(dd);
return -1;
}
assert(fd >= 0, "bad file descriptor");
- set_door_path(door_path);
RESTARTABLE(::close(fd), res);
// attach the door descriptor to the file
- if ((res = ::fattach(dd, door_path)) == -1) {
+ if ((res = ::fattach(dd, initial_path)) == -1) {
// if busy then detach and try again
if (errno == EBUSY) {
- ::fdetach(door_path);
- res = ::fattach(dd, door_path);
+ ::fdetach(initial_path);
+ res = ::fattach(dd, initial_path);
}
if (res == -1) {
::door_revoke(dd);
dd = -1;
}
}
+
+ // rename file so that clients can attach
+ if (dd >= 0) {
+ if (::rename(initial_path, door_path) == -1) {
+ RESTARTABLE(::close(dd), res);
+ ::fdetach(initial_path);
+ dd = -1;
+ }
+ }
if (dd >= 0) {
set_door_descriptor(dd);
+ set_door_path(door_path);
} else {
- // unable to create door or attach it to the file
- ::unlink(door_path);
- set_door_path(NULL);
+ // unable to create door, attach it to file, or rename file into place
+ ::unlink(initial_path);
return -1;
}