8201247: Various cleanups in the attach framework
Reviewed-by: goetz, cjplummer
This commit is contained in:
parent
9fb40e61cb
commit
024d4eb8f4
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,12 +30,12 @@
|
||||
#include "services/attachListener.hpp"
|
||||
#include "services/dtraceAttacher.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef UNIX_PATH_MAX
|
||||
#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path)
|
||||
@ -145,10 +145,10 @@ class ArgumentIterator : public StackObj {
|
||||
}
|
||||
char* next() {
|
||||
if (*_pos == '\0') {
|
||||
// advance the iterator if possible (null arguments)
|
||||
if (_pos < _end) {
|
||||
_pos += 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
char* res = _pos;
|
||||
@ -233,10 +233,10 @@ int AixAttachListener::init() {
|
||||
// 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) & ~(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)), res);
|
||||
if (res == 0) {
|
||||
res = ::rename(initial_path, path);
|
||||
}
|
||||
RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
|
||||
if (res == 0) {
|
||||
res = ::rename(initial_path, path);
|
||||
}
|
||||
}
|
||||
if (res == -1) {
|
||||
::close(listener);
|
||||
@ -284,10 +284,12 @@ AixAttachOperation* AixAttachListener::read_request(int s) {
|
||||
// Don't block on interrupts because this will
|
||||
// hang in the clean-up when shutting down.
|
||||
n = read(s, buf+off, left);
|
||||
assert(n <= left, "buffer was too small, impossible!");
|
||||
buf[max_len - 1] = '\0';
|
||||
if (n == -1) {
|
||||
return NULL; // reset by peer or other error
|
||||
}
|
||||
if (n == 0) { // end of file reached
|
||||
if (n == 0) {
|
||||
break;
|
||||
}
|
||||
for (int i=0; i<n; i++) {
|
||||
@ -362,7 +364,7 @@ AixAttachOperation* AixAttachListener::dequeue() {
|
||||
socklen_t len = sizeof(addr);
|
||||
memset(&addr, 0, len);
|
||||
// We must prevent accept blocking on the socket if it has been shut down.
|
||||
// Therefore we allow interrups and check whether we have been shut down already.
|
||||
// Therefore we allow interrupts and check whether we have been shut down already.
|
||||
if (AixAttachListener::is_shutdown()) {
|
||||
return NULL;
|
||||
}
|
||||
@ -371,19 +373,11 @@ AixAttachOperation* AixAttachListener::dequeue() {
|
||||
return NULL; // log a warning?
|
||||
}
|
||||
|
||||
// Added timeouts for read and write. If we get no request within the
|
||||
// next AttachListenerTimeout milliseconds we just finish the connection.
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = AttachListenerTimeout * 1000;
|
||||
::setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv));
|
||||
::setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));
|
||||
|
||||
// get the credentials of the peer and check the effective uid/guid
|
||||
// - check with jeff on this.
|
||||
struct peercred_struct cred_info;
|
||||
socklen_t optlen = sizeof(cred_info);
|
||||
if (::getsockopt(s, SOL_SOCKET, SO_PEERID, (void*)&cred_info, &optlen) == -1) {
|
||||
log_debug(attach)("Failed to get socket option SO_PEERID");
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
@ -391,6 +385,7 @@ AixAttachOperation* AixAttachListener::dequeue() {
|
||||
gid_t egid = getegid();
|
||||
|
||||
if (cred_info.euid != euid || cred_info.egid != egid) {
|
||||
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", cred_info.euid, cred_info.egid, euid, egid);
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
@ -532,10 +527,10 @@ bool AttachListener::is_init_trigger() {
|
||||
if (init_at_startup() || is_initialized()) {
|
||||
return false; // initialized at startup or already initialized
|
||||
}
|
||||
char fn[PATH_MAX+1];
|
||||
sprintf(fn, ".attach_pid%d", os::current_process_id());
|
||||
char fn[PATH_MAX + 1];
|
||||
int ret;
|
||||
struct stat64 st;
|
||||
sprintf(fn, ".attach_pid%d", os::current_process_id());
|
||||
RESTARTABLE(::stat64(fn, &st), ret);
|
||||
if (ret == -1) {
|
||||
log_trace(attach)("Failed to find attach file: %s, trying alternate", fn);
|
||||
@ -551,7 +546,7 @@ bool AttachListener::is_init_trigger() {
|
||||
// a bogus user creates the file
|
||||
if (st.st_uid == geteuid()) {
|
||||
init();
|
||||
log_trace(attach)("Attach trigerred by %s", fn);
|
||||
log_trace(attach)("Attach triggered by %s", fn);
|
||||
return true;
|
||||
} else {
|
||||
log_debug(attach)("File %s has wrong user id %d (vs %d). Attach is not triggered", fn, st.st_uid, geteuid());
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -51,10 +51,6 @@
|
||||
product(bool, AllowExtshm, false, \
|
||||
"Allow VM to run with EXTSHM=ON.") \
|
||||
\
|
||||
product(intx, AttachListenerTimeout, 1000, \
|
||||
"Timeout in ms the attach listener waits for a request") \
|
||||
range(0, 2147483) \
|
||||
\
|
||||
/* Maximum expected size of the data segment. That correlates with the */ \
|
||||
/* to the maximum C Heap consumption we expect. */ \
|
||||
/* We need to know this because we need to leave "breathing space" for the */ \
|
||||
|
@ -137,6 +137,10 @@ class ArgumentIterator : public StackObj {
|
||||
}
|
||||
char* next() {
|
||||
if (*_pos == '\0') {
|
||||
// advance the iterator if possible (null arguments)
|
||||
if (_pos < _end) {
|
||||
_pos += 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
char* res = _pos;
|
||||
@ -195,6 +199,7 @@ int BsdAttachListener::init() {
|
||||
|
||||
// bind socket
|
||||
struct sockaddr_un addr;
|
||||
memset((void *)&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, initial_path);
|
||||
::unlink(initial_path);
|
||||
@ -260,6 +265,8 @@ BsdAttachOperation* BsdAttachListener::read_request(int s) {
|
||||
do {
|
||||
int n;
|
||||
RESTARTABLE(read(s, buf+off, left), n);
|
||||
assert(n <= left, "buffer was too small, impossible!");
|
||||
buf[max_len - 1] = '\0';
|
||||
if (n == -1) {
|
||||
return NULL; // reset by peer or other error
|
||||
}
|
||||
@ -342,10 +349,10 @@ BsdAttachOperation* BsdAttachListener::dequeue() {
|
||||
}
|
||||
|
||||
// get the credentials of the peer and check the effective uid/guid
|
||||
// - check with jeff on this.
|
||||
uid_t puid;
|
||||
gid_t pgid;
|
||||
if (::getpeereid(s, &puid, &pgid) != 0) {
|
||||
log_debug(attach)("Failed to get peer id");
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
@ -353,6 +360,7 @@ BsdAttachOperation* BsdAttachListener::dequeue() {
|
||||
gid_t egid = getegid();
|
||||
|
||||
if (puid != euid || pgid != egid) {
|
||||
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", puid, pgid, euid, egid);
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
@ -438,7 +446,6 @@ AttachOperation* AttachListener::dequeue() {
|
||||
return op;
|
||||
}
|
||||
|
||||
|
||||
// Performs initialization at vm startup
|
||||
// For BSD we remove any stale .java_pid file which could cause
|
||||
// an attaching process to think we are ready to receive on the
|
||||
@ -497,7 +504,6 @@ bool AttachListener::is_init_trigger() {
|
||||
char fn[PATH_MAX + 1];
|
||||
int ret;
|
||||
struct stat st;
|
||||
|
||||
snprintf(fn, PATH_MAX + 1, "%s/.attach_pid%d",
|
||||
os::get_temp_directory(), os::current_process_id());
|
||||
RESTARTABLE(::stat(fn, &st), ret);
|
||||
@ -509,7 +515,7 @@ bool AttachListener::is_init_trigger() {
|
||||
// a bogus user creates the file
|
||||
if (st.st_uid == geteuid()) {
|
||||
init();
|
||||
log_trace(attach)("Attach trigerred by %s", fn);
|
||||
log_trace(attach)("Attach triggered by %s", fn);
|
||||
return true;
|
||||
} else {
|
||||
log_debug(attach)("File %s has wrong user id %d (vs %d). Attach is not triggered", fn, st.st_uid, geteuid());
|
||||
|
@ -138,6 +138,10 @@ class ArgumentIterator : public StackObj {
|
||||
}
|
||||
char* next() {
|
||||
if (*_pos == '\0') {
|
||||
// advance the iterator if possible (null arguments)
|
||||
if (_pos < _end) {
|
||||
_pos += 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
char* res = _pos;
|
||||
@ -196,6 +200,7 @@ int LinuxAttachListener::init() {
|
||||
|
||||
// bind socket
|
||||
struct sockaddr_un addr;
|
||||
memset((void *)&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, initial_path);
|
||||
::unlink(initial_path);
|
||||
@ -208,10 +213,10 @@ int LinuxAttachListener::init() {
|
||||
// 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);
|
||||
}
|
||||
RESTARTABLE(::chmod(initial_path, S_IREAD|S_IWRITE), res);
|
||||
if (res == 0) {
|
||||
res = ::rename(initial_path, path);
|
||||
}
|
||||
}
|
||||
if (res == -1) {
|
||||
::close(listener);
|
||||
@ -340,10 +345,10 @@ LinuxAttachOperation* LinuxAttachListener::dequeue() {
|
||||
}
|
||||
|
||||
// get the credentials of the peer and check the effective uid/guid
|
||||
// - check with jeff on this.
|
||||
struct ucred cred_info;
|
||||
socklen_t optlen = sizeof(cred_info);
|
||||
if (::getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void*)&cred_info, &optlen) == -1) {
|
||||
log_debug(attach)("Failed to get socket option SO_PEERCRED");
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
@ -351,6 +356,7 @@ LinuxAttachOperation* LinuxAttachListener::dequeue() {
|
||||
gid_t egid = getegid();
|
||||
|
||||
if (cred_info.uid != euid || cred_info.gid != egid) {
|
||||
log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", cred_info.uid, cred_info.gid, euid, egid);
|
||||
::close(s);
|
||||
continue;
|
||||
}
|
||||
@ -436,7 +442,6 @@ AttachOperation* AttachListener::dequeue() {
|
||||
return op;
|
||||
}
|
||||
|
||||
|
||||
// Performs initialization at vm startup
|
||||
// For Linux we remove any stale .java_pid file which could cause
|
||||
// an attaching process to think we are ready to receive on the
|
||||
@ -492,10 +497,10 @@ bool AttachListener::is_init_trigger() {
|
||||
if (init_at_startup() || is_initialized()) {
|
||||
return false; // initialized at startup or already initialized
|
||||
}
|
||||
char fn[PATH_MAX+1];
|
||||
sprintf(fn, ".attach_pid%d", os::current_process_id());
|
||||
char fn[PATH_MAX + 1];
|
||||
int ret;
|
||||
struct stat64 st;
|
||||
sprintf(fn, ".attach_pid%d", os::current_process_id());
|
||||
RESTARTABLE(::stat64(fn, &st), ret);
|
||||
if (ret == -1) {
|
||||
log_trace(attach)("Failed to find attach file: %s, trying alternate", fn);
|
||||
@ -511,10 +516,10 @@ bool AttachListener::is_init_trigger() {
|
||||
// a bogus user creates the file
|
||||
if (st.st_uid == geteuid()) {
|
||||
init();
|
||||
log_trace(attach)("Attach trigerred by %s", fn);
|
||||
log_trace(attach)("Attach triggered by %s", fn);
|
||||
return true;
|
||||
} else {
|
||||
log_debug(attach)("File %s has wrong user id %d (vs %d). Attach is not trigerred", fn, st.st_uid, geteuid());
|
||||
log_debug(attach)("File %s has wrong user id %d (vs %d). Attach is not triggered", fn, st.st_uid, geteuid());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -186,6 +186,10 @@ class ArgumentIterator : public StackObj {
|
||||
}
|
||||
char* next() {
|
||||
if (*_pos == '\0') {
|
||||
// advance the iterator if possible (null arguments)
|
||||
if (_pos < _end) {
|
||||
_pos += 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
char* res = _pos;
|
||||
@ -644,10 +648,10 @@ bool AttachListener::is_init_trigger() {
|
||||
if (init_at_startup() || is_initialized()) {
|
||||
return false; // initialized at startup or already initialized
|
||||
}
|
||||
char fn[PATH_MAX+1];
|
||||
sprintf(fn, ".attach_pid%d", os::current_process_id());
|
||||
char fn[PATH_MAX + 1];
|
||||
int ret;
|
||||
struct stat64 st;
|
||||
sprintf(fn, ".attach_pid%d", os::current_process_id());
|
||||
RESTARTABLE(::stat64(fn, &st), ret);
|
||||
if (ret == -1) {
|
||||
log_trace(attach)("Failed to find attach file: %s, trying alternate", fn);
|
||||
@ -663,7 +667,10 @@ bool AttachListener::is_init_trigger() {
|
||||
// a bogus user creates the file
|
||||
if (st.st_uid == geteuid()) {
|
||||
init();
|
||||
log_trace(attach)("Attach triggered by %s", fn);
|
||||
return true;
|
||||
} else {
|
||||
log_debug(attach)("File %s has wrong user id %d (vs %d). Attach is not triggered", fn, st.st_uid, geteuid());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -131,12 +131,12 @@ class Win32AttachOperation: public AttachOperation {
|
||||
pipe_name_max = 256 // maximum pipe name
|
||||
};
|
||||
|
||||
char _pipe[pipe_name_max+1];
|
||||
char _pipe[pipe_name_max + 1];
|
||||
|
||||
const char* pipe() const { return _pipe; }
|
||||
void set_pipe(const char* pipe) {
|
||||
assert(strlen(pipe) <= pipe_name_max, "execeds maximum length of pipe name");
|
||||
strcpy(_pipe, pipe);
|
||||
assert(strlen(pipe) <= pipe_name_max, "exceeds maximum length of pipe name");
|
||||
os::snprintf(_pipe, sizeof(_pipe), "%s", pipe);
|
||||
}
|
||||
|
||||
HANDLE open_pipe();
|
||||
@ -329,12 +329,20 @@ void Win32AttachOperation::complete(jint result, bufferedStream* result_stream)
|
||||
|
||||
fSuccess = write_pipe(hPipe, msg, (int)strlen(msg));
|
||||
if (fSuccess) {
|
||||
write_pipe(hPipe, (char*) result_stream->base(), (int)(result_stream->size()));
|
||||
fSuccess = write_pipe(hPipe, (char*)result_stream->base(), (int)(result_stream->size()));
|
||||
}
|
||||
|
||||
// Need to flush buffers
|
||||
FlushFileBuffers(hPipe);
|
||||
CloseHandle(hPipe);
|
||||
|
||||
if (fSuccess) {
|
||||
log_debug(attach)("wrote result of attach operation %s to pipe %s", name(), pipe());
|
||||
} else {
|
||||
log_error(attach)("failure writing result of operation %s to pipe %s", name(), pipe());
|
||||
}
|
||||
} else {
|
||||
log_error(attach)("could not open pipe %s to send result of operation %s", pipe(), name());
|
||||
}
|
||||
|
||||
DWORD res = ::WaitForSingleObject(Win32AttachListener::mutex(), INFINITE);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2018, SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,8 +34,6 @@ import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
|
||||
// Based on linux/classes/sun/tools/attach/VirtualMachineImpl.java.
|
||||
|
||||
/*
|
||||
* Aix implementation of HotSpotVirtualMachine
|
||||
*/
|
||||
@ -140,7 +138,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
||||
* Execute the given command in the target VM.
|
||||
*/
|
||||
InputStream execute(String cmd, Object ... args) throws AgentLoadException, IOException {
|
||||
assert args.length <= 3; // includes null
|
||||
assert args.length <= 3; // includes null
|
||||
|
||||
// did we detach?
|
||||
synchronized (this) {
|
||||
@ -261,7 +259,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
||||
}
|
||||
}
|
||||
|
||||
// On Solaris/Linux/Aix a simple handshake is used to start the attach mechanism
|
||||
// On Aix a simple handshake is used to start the attach mechanism
|
||||
// if not already started. The client creates a .attach_pid<pid> file in the
|
||||
// target VM's working directory (or temp directory), and the SIGQUIT handler
|
||||
// checks for the file.
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2018, SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,27 +24,18 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
/*
|
||||
* Based on 'LinuxVirtualMachine.c'. Non-relevant code has been removed and all
|
||||
* occurrences of the string "Linux" have been replaced by "Aix".
|
||||
*/
|
||||
|
||||
#include "sun_tools_attach_VirtualMachineImpl.h"
|
||||
|
||||
@ -67,15 +58,6 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_socket
|
||||
if (fd == -1) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "socket");
|
||||
}
|
||||
/* added time out values */
|
||||
else {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 2 * 60;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv));
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));
|
||||
}
|
||||
return (jint)fd;
|
||||
}
|
||||
|
||||
@ -125,23 +107,6 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_connect
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Structure and callback function used to send a QUIT signal to all
|
||||
* children of a given process
|
||||
*/
|
||||
typedef struct {
|
||||
pid_t ppid;
|
||||
} SendQuitContext;
|
||||
|
||||
static void SendQuitCallback(const pid_t pid, void* user_data) {
|
||||
SendQuitContext* context = (SendQuitContext*)user_data;
|
||||
pid_t parent = getParent(pid);
|
||||
if (parent == context->ppid) {
|
||||
kill(pid, SIGQUIT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_VirtualMachineImpl
|
||||
* Method: sendQuitTo
|
||||
@ -169,7 +134,7 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
struct stat64 sb;
|
||||
uid_t uid, gid;
|
||||
int res;
|
||||
/* added missing initialization of the stat64 buffer */
|
||||
|
||||
memset(&sb, 0, sizeof(struct stat64));
|
||||
|
||||
/*
|
||||
@ -189,21 +154,21 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
char msg[100];
|
||||
jboolean isError = JNI_FALSE;
|
||||
if (sb.st_uid != uid) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);
|
||||
isError = JNI_TRUE;
|
||||
} else if (sb.st_gid != gid) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
|
||||
isError = JNI_TRUE;
|
||||
} else if ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file should only be readable and writable by the owner but has 0%03o access", sb.st_mode & 0777);
|
||||
isError = JNI_TRUE;
|
||||
}
|
||||
if (isError) {
|
||||
char buf[256];
|
||||
jio_snprintf(buf, sizeof(buf)-1, "well-known file %s is not secure: %s", p, msg);
|
||||
snprintf(buf, sizeof(buf), "well-known file %s is not secure: %s", p, msg);
|
||||
JNU_ThrowIOException(env, buf);
|
||||
}
|
||||
} else {
|
||||
@ -229,11 +194,7 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_close
|
||||
(JNIEnv *env, jclass cls, jint fd)
|
||||
{
|
||||
int res;
|
||||
/* Fixed deadlock when this call of close by the client is not seen by the attach server
|
||||
* which has accepted the (very short) connection already and is waiting for the request. But read don't get a byte,
|
||||
* because the close is lost without shutdown.
|
||||
*/
|
||||
shutdown(fd, 2);
|
||||
shutdown(fd, SHUT_RDWR);
|
||||
RESTARTABLE(close(fd), res);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -105,7 +105,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
||||
} finally {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the file owner/permission to avoid attaching to
|
||||
// bogus process
|
||||
@ -274,7 +274,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
||||
return new File(root, ".java_pid" + ns_pid);
|
||||
}
|
||||
|
||||
// On Solaris/Linux a simple handshake is used to start the attach mechanism
|
||||
// On Linux a simple handshake is used to start the attach mechanism
|
||||
// if not already started. The client creates a .attach_pid<pid> file in the
|
||||
// target VM's working directory (or temp directory), and the SIGQUIT handler
|
||||
// checks for the file.
|
||||
@ -356,8 +356,6 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
||||
|
||||
//-- native methods
|
||||
|
||||
static native void sendQuitToChildrenOf(int pid) throws IOException;
|
||||
|
||||
static native void sendQuitTo(int pid) throws IOException;
|
||||
|
||||
static native void checkPermissions(String path) throws IOException;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,23 +23,18 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "sun_tools_attach_VirtualMachineImpl.h"
|
||||
|
||||
@ -54,85 +49,6 @@
|
||||
*/
|
||||
DEF_STATIC_JNI_OnLoad
|
||||
|
||||
/*
|
||||
* Defines a callback that is invoked for each process
|
||||
*/
|
||||
typedef void (*ProcessCallback)(const pid_t pid, void* user_data);
|
||||
|
||||
/*
|
||||
* Invokes the callback function for each process
|
||||
*/
|
||||
static void forEachProcess(ProcessCallback f, void* user_data) {
|
||||
DIR* dir;
|
||||
struct dirent* ptr;
|
||||
|
||||
/*
|
||||
* To locate the children we scan /proc looking for files that have a
|
||||
* position integer as a filename.
|
||||
*/
|
||||
if ((dir = opendir("/proc")) == NULL) {
|
||||
return;
|
||||
}
|
||||
while ((ptr = readdir(dir)) != NULL) {
|
||||
pid_t pid;
|
||||
|
||||
/* skip current/parent directories */
|
||||
if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip files that aren't numbers */
|
||||
pid = (pid_t)atoi(ptr->d_name);
|
||||
if ((int)pid <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* invoke the callback */
|
||||
(*f)(pid, user_data);
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the parent pid of a given pid, or -1 if not found
|
||||
*/
|
||||
static pid_t getParent(pid_t pid) {
|
||||
char state;
|
||||
FILE* fp;
|
||||
char stat[2048];
|
||||
int statlen;
|
||||
char fn[32];
|
||||
int i, p;
|
||||
char* s;
|
||||
|
||||
/*
|
||||
* try to open /proc/%d/stat
|
||||
*/
|
||||
sprintf(fn, "/proc/%d/stat", pid);
|
||||
fp = fopen(fn, "r");
|
||||
if (fp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The format is: pid (command) state ppid ...
|
||||
* As the command could be anything we must find the right most
|
||||
* ")" and then skip the white spaces that follow it.
|
||||
*/
|
||||
statlen = fread(stat, 1, 2047, fp);
|
||||
stat[statlen] = '\0';
|
||||
fclose(fp);
|
||||
s = strrchr(stat, ')');
|
||||
if (s == NULL) {
|
||||
return -1;
|
||||
}
|
||||
do s++; while (isspace(*s));
|
||||
i = sscanf(s, "%c %d", &state, &p);
|
||||
return (pid_t)p;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_VirtualMachineImpl
|
||||
* Method: socket
|
||||
@ -194,39 +110,6 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_connect
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Structure and callback function used to send a QUIT signal to all
|
||||
* children of a given process
|
||||
*/
|
||||
typedef struct {
|
||||
pid_t ppid;
|
||||
} SendQuitContext;
|
||||
|
||||
static void SendQuitCallback(const pid_t pid, void* user_data) {
|
||||
SendQuitContext* context = (SendQuitContext*)user_data;
|
||||
pid_t parent = getParent(pid);
|
||||
if (parent == context->ppid) {
|
||||
kill(pid, SIGQUIT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_VirtualMachineImpl
|
||||
* Method: sendQuitToChildrenOf
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_sendQuitToChildrenOf
|
||||
(JNIEnv *env, jclass cls, jint pid)
|
||||
{
|
||||
SendQuitContext context;
|
||||
context.ppid = (pid_t)pid;
|
||||
|
||||
/*
|
||||
* Iterate over all children of 'pid' and send a QUIT signal to each.
|
||||
*/
|
||||
forEachProcess(SendQuitCallback, (void*)&context);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_VirtualMachineImpl
|
||||
* Method: sendQuitTo
|
||||
@ -255,6 +138,8 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
uid_t uid, gid;
|
||||
int res;
|
||||
|
||||
memset(&sb, 0, sizeof(struct stat64));
|
||||
|
||||
/*
|
||||
* Check that the path is owned by the effective uid/gid of this
|
||||
* process. Also check that group/other access is not allowed.
|
||||
@ -272,21 +157,21 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
char msg[100];
|
||||
jboolean isError = JNI_FALSE;
|
||||
if (sb.st_uid != uid) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);
|
||||
isError = JNI_TRUE;
|
||||
} else if (sb.st_gid != gid) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
|
||||
isError = JNI_TRUE;
|
||||
} else if ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file should only be readable and writable by the owner but has 0%03o access", sb.st_mode & 0777);
|
||||
isError = JNI_TRUE;
|
||||
}
|
||||
if (isError) {
|
||||
char buf[256];
|
||||
jio_snprintf(buf, sizeof(buf)-1, "well-known file %s is not secure: %s", p, msg);
|
||||
snprintf(buf, sizeof(buf), "well-known file %s is not secure: %s", p, msg);
|
||||
JNU_ThrowIOException(env, buf);
|
||||
}
|
||||
} else {
|
||||
@ -312,6 +197,7 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_close
|
||||
(JNIEnv *env, jclass cls, jint fd)
|
||||
{
|
||||
int res;
|
||||
shutdown(fd, SHUT_RDWR);
|
||||
RESTARTABLE(close(fd), res);
|
||||
}
|
||||
|
||||
@ -366,8 +252,8 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_write
|
||||
|
||||
RESTARTABLE(write(fd, buf, len), n);
|
||||
if (n > 0) {
|
||||
off += n;
|
||||
remaining -= n;
|
||||
off += n;
|
||||
remaining -= n;
|
||||
} else {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "write");
|
||||
return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -281,8 +281,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
||||
}
|
||||
|
||||
private File createAttachFile(int pid) throws IOException {
|
||||
String fn = ".attach_pid" + pid;
|
||||
File f = new File(tmpdir, fn);
|
||||
File f = new File(tmpdir, ".attach_pid" + pid);
|
||||
createAttachFile0(f.getPath());
|
||||
return f;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,24 +23,20 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syslimits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sun_tools_attach_VirtualMachineImpl.h"
|
||||
|
||||
@ -144,6 +140,8 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
uid_t uid, gid;
|
||||
int res;
|
||||
|
||||
memset(&sb, 0, sizeof(struct stat));
|
||||
|
||||
/*
|
||||
* Check that the path is owned by the effective uid/gid of this
|
||||
* process. Also check that group/other access is not allowed.
|
||||
@ -161,21 +159,21 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
char msg[100];
|
||||
jboolean isError = JNI_FALSE;
|
||||
if (sb.st_uid != uid) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);
|
||||
isError = JNI_TRUE;
|
||||
} else if (sb.st_gid != gid) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
|
||||
isError = JNI_TRUE;
|
||||
} else if ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file should only be readable and writable by the owner but has 0%03o access", sb.st_mode & 0777);
|
||||
isError = JNI_TRUE;
|
||||
}
|
||||
if (isError) {
|
||||
char buf[256];
|
||||
jio_snprintf(buf, sizeof(buf)-1, "well-known file %s is not secure: %s", p, msg);
|
||||
snprintf(buf, sizeof(buf), "well-known file %s is not secure: %s", p, msg);
|
||||
JNU_ThrowIOException(env, buf);
|
||||
}
|
||||
} else {
|
||||
@ -201,6 +199,7 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_close
|
||||
(JNIEnv *env, jclass cls, jint fd)
|
||||
{
|
||||
int res;
|
||||
shutdown(fd, SHUT_RDWR);
|
||||
RESTARTABLE(close(fd), res);
|
||||
}
|
||||
|
||||
@ -255,8 +254,8 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_write
|
||||
|
||||
RESTARTABLE(write(fd, buf, len), n);
|
||||
if (n > 0) {
|
||||
off += n;
|
||||
remaining -= n;
|
||||
off += n;
|
||||
remaining -= n;
|
||||
} else {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "write");
|
||||
return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -225,7 +225,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
||||
return fd;
|
||||
}
|
||||
|
||||
// On Solaris/Linux a simple handshake is used to start the attach mechanism
|
||||
// On Solaris a simple handshake is used to start the attach mechanism
|
||||
// if not already started. The client creates a .attach_pid<pid> file in the
|
||||
// target VM's working directory (or temporary directory), and the SIGQUIT
|
||||
// handler checks for the file.
|
||||
|
@ -22,20 +22,19 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <door.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <door.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sun_tools_attach_VirtualMachineImpl.h"
|
||||
|
||||
@ -105,6 +104,8 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
uid_t uid, gid;
|
||||
int res;
|
||||
|
||||
memset(&sb, 0, sizeof(struct stat64));
|
||||
|
||||
/*
|
||||
* Check that the path is owned by the effective uid/gid of this
|
||||
* process. Also check that group/other access is not allowed.
|
||||
@ -122,21 +123,21 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
|
||||
char msg[100];
|
||||
jboolean isError = JNI_FALSE;
|
||||
if (sb.st_uid != uid) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);
|
||||
isError = JNI_TRUE;
|
||||
} else if (sb.st_gid != gid) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
|
||||
isError = JNI_TRUE;
|
||||
} else if ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) {
|
||||
jio_snprintf(msg, sizeof(msg)-1,
|
||||
snprintf(msg, sizeof(msg),
|
||||
"file should only be readable and writable by the owner but has 0%03o access", sb.st_mode & 0777);
|
||||
isError = JNI_TRUE;
|
||||
}
|
||||
if (isError) {
|
||||
char buf[256];
|
||||
jio_snprintf(buf, sizeof(buf)-1, "well-known file %s is not secure: %s", p, msg);
|
||||
snprintf(buf, sizeof(buf), "well-known file %s is not secure: %s", p, msg);
|
||||
JNU_ThrowIOException(env, buf);
|
||||
}
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,16 +22,15 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "jni_util.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <Sddl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
|
||||
#include "sun_tools_attach_VirtualMachineImpl.h"
|
||||
|
||||
|
||||
/* kernel32 */
|
||||
typedef HINSTANCE (WINAPI* GetModuleHandleFunc) (LPCTSTR);
|
||||
typedef FARPROC (WINAPI* GetProcAddressFunc)(HMODULE, LPCSTR);
|
||||
@ -303,9 +302,7 @@ JNIEXPORT jlong JNICALL Java_sun_tools_attach_VirtualMachineImpl_createPipe
|
||||
LocalFree(sa.lpSecurityDescriptor);
|
||||
|
||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||
char msg[256];
|
||||
_snprintf(msg, sizeof(msg), "CreateNamedPipe failed: %d", GetLastError());
|
||||
JNU_ThrowIOExceptionWithLastError(env, msg);
|
||||
JNU_ThrowIOExceptionWithLastError(env, "CreateNamedPipe failed");
|
||||
}
|
||||
return (jlong)hPipe;
|
||||
}
|
||||
@ -318,7 +315,7 @@ JNIEXPORT jlong JNICALL Java_sun_tools_attach_VirtualMachineImpl_createPipe
|
||||
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_closePipe
|
||||
(JNIEnv *env, jclass cls, jlong hPipe)
|
||||
{
|
||||
CloseHandle( (HANDLE)hPipe );
|
||||
CloseHandle((HANDLE)hPipe);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -430,7 +427,7 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_enqueue
|
||||
if ((*env)->ExceptionOccurred(env)) return;
|
||||
}
|
||||
}
|
||||
for (i=argsLen; i<MAX_ARGS; i++) {
|
||||
for (i = argsLen; i < MAX_ARGS; i++) {
|
||||
data.arg[i][0] = '\0';
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user