]> git.sven.stormbind.net Git - sven/jattach.git/blobdiff - src/windows/jattach.c
Update upstream source from tag 'upstream/2.2'
[sven/jattach.git] / src / windows / jattach.c
index 1318a94541a2ef6706bde4d361cc81c4d28385f3..f25f1d6f049f1f2acac970e02850736e0104d82b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Andrei Pangin
+ * Copyright jattach authors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -85,10 +85,19 @@ static LPVOID allocate_data(HANDLE hProcess, char* pipeName, int argc, char** ar
     strcpy(data.strJvm, "jvm");
     strcpy(data.strEnqueue, "_JVM_EnqueueOperation");
     strcpy(data.pipeName, pipeName);
+    data.args[0][0] = data.args[1][0] = data.args[2][0] = data.args[3][0] = 0;
 
+    // jcmd has 2 arguments maximum; merge excessive arguments into one
+    int cmd_args = argc >= 2 && strcmp(argv[0], "jcmd") == 0 ? 2 : argc >= 4 ? 4 : argc;
+
+    size_t n = 0;
     int i;
-    for (i = 0; i < 4; i++) {
-        strcpy(data.args[i], i < argc ? argv[i] : "");
+    for (i = 0; i < argc; i++) {
+        if (i < cmd_args) {
+            n = snprintf(data.args[i], sizeof(data.args[i]), "%s", argv[i]);
+        } else if (n < sizeof(data.args[cmd_args - 1])) {
+            n += snprintf(data.args[cmd_args - 1] + n, sizeof(data.args[cmd_args - 1]) - n, " %s", argv[i]);
+        }
     }
 
     LPVOID remoteData = VirtualAllocEx(hProcess, NULL, sizeof(CallData), MEM_COMMIT, PAGE_READWRITE);
@@ -203,7 +212,7 @@ static int inject_thread(int pid, char* pipeName, int argc, char** argv) {
 }
 
 // JVM response is read from the pipe and mirrored to stdout
-static int read_response(HANDLE hPipe) {
+static int read_response(HANDLE hPipe, int print_output) {
     ConnectNamedPipe(hPipe, NULL);
 
     char buf[8192];
@@ -217,14 +226,19 @@ static int read_response(HANDLE hPipe) {
     buf[bytesRead] = 0;
     int result = atoi(buf);
 
-    do {
-        fwrite(buf, 1, bytesRead, stdout);
-    } while (ReadFile(hPipe, buf, sizeof(buf), &bytesRead, NULL));
+    if (print_output) {
+        // Mirror JVM response to stdout
+        printf("JVM response code = ");
+        do {
+            fwrite(buf, 1, bytesRead, stdout);
+        } while (ReadFile(hPipe, buf, sizeof(buf), &bytesRead, NULL));
+         printf("\n");
+     }
 
     return result;
 }
 
-int jattach(int pid, int argc, char** argv) {
+int jattach(int pid, int argc, char** argv, int print_output) {
     // When attaching as an Administrator, make sure the target process can connect to our pipe,
     // i.e. allow read-write access to everyone. For the complete format description, see
     // https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format
@@ -236,7 +250,7 @@ int jattach(int pid, int argc, char** argv) {
     sprintf(pipeName, "\\\\.\\pipe\\javatool%d", GetTickCount());
     HANDLE hPipe = CreateNamedPipe(pipeName, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
                                    1, 4096, 8192, NMPWAIT_USE_DEFAULT_WAIT, &sec);
-    if (hPipe == NULL) {
+    if (hPipe == INVALID_HANDLE_VALUE) {
         print_error("Could not create pipe", GetLastError());
         LocalFree(sec.lpSecurityDescriptor);
         return 1;
@@ -249,11 +263,7 @@ int jattach(int pid, int argc, char** argv) {
         return 1;
     }
 
-    printf("Response code = ");
-    fflush(stdout);
-
-    int result = read_response(hPipe);
-    printf("\n");
+    int result = read_response(hPipe, print_output);
     CloseHandle(hPipe);
 
     return result;
@@ -264,7 +274,6 @@ int jattach(int pid, int argc, char** argv) {
 int main(int argc, char** argv) {
     if (argc < 3) {
         printf("jattach " JATTACH_VERSION " built on " __DATE__ "\n"
-               "Copyright 2021 Andrei Pangin\n"
                "\n"
                "Usage: jattach <pid> <cmd> [args ...]\n"
                "\n"
@@ -281,7 +290,7 @@ int main(int argc, char** argv) {
         return 1;
     }
 
-    return jattach(pid, argc - 2, argv + 2);
+    return jattach(pid, argc - 2, argv + 2, 1);
 }
 
 #endif // JATTACH_VERSION