0

Java seems unable to inherit anonymous pipes from the WinAPI, I am using my own library and can not figure out what the issue is.

Library source on the current commit.

The anon test:

package net.gudenau.lib.pipes.test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import net.gudenau.lib.pipes.AnonymousPipeHandle;
import net.gudenau.lib.pipes.PipeHandle;
import net.gudenau.lib.pipes.Pipes;

public class AnonymousPipe{
    public static void main(String[] args){
        try(PipeHandle client = Pipes.findPipe()){
            InputStream inputStream = client.getInputStream();
            OutputStream outputStream = client.getOutputStream();

            byte[] data = "This is from the anon pipe!".getBytes(StandardCharsets.UTF_16);
            outputStream.write(data.length);
            outputStream.write(data);
            data = new byte[inputStream.read()];
            inputStream.read(data);
            System.out.printf("Server says: %s\n", new String(data, StandardCharsets.UTF_16));
        }catch(IOException e){
            e.printStackTrace();
            System.exit(0);
        }
    }

    static void test(){
        File path = new File(System.getProperty("java.home") + File.separator + "bin");
        File executable;
        if(System.getProperty("os.name").toLowerCase().contains("windows")){
            executable = new File(path, "javaw.exe");
        }else{
            executable = new File(path, "java");
        }

        ProcessBuilder processBuilder = new ProcessBuilder(
            executable.getAbsolutePath(),
            "-Dfile.encoding=UTF-8",
            "-classpath",
            System.getProperty("java.class.path"),
            "net.gudenau.lib.pipes.test.AnonymousPipe"
        );
        processBuilder.inheritIO();

        try(AnonymousPipeHandle pipe = Pipes.createPipe()){
            pipe.setupHandleShare(processBuilder);
            Process process = processBuilder.start();
            pipe.clientConnected();

            InputStream inputStream = pipe.getInputStream();
            OutputStream outputStream = pipe.getOutputStream();

            byte[] data = new byte[inputStream.read()];
            inputStream.read(data);
            String message = new String(data, StandardCharsets.UTF_16);
            System.out.printf("Client says: %s\n", new String(data, StandardCharsets.UTF_16));
            data = message.toUpperCase().getBytes(StandardCharsets.UTF_16);
            outputStream.write(data.length);
            outputStream.write(data);

            try{
                process.waitFor();
            }catch(InterruptedException ignored){}
        }catch(IOException e){
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

As far as I can tell I am doing all of this correctly.

I am creating the anon pipe with CreatePipe using a SECURITY_ATTRIBUTES with bInheritHandle set to true.

Then after the client side is created I close the "client" side handles.

What am I missing?

Edit: I spaced and missed the errors. The test method throws The specified procedure could not be found., at least according to Windows which makes no sense to me.

The other process throws The handle is invalid., again according to Windows.

Output:

Client says: the quick brown fox jumps over the lazy dog
Server says: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
java.io.IOException: The specified procedure could not be found.

    at net.gudenau.lib.pipes.impl.windows.WindowsPipeInputStream.read(WindowsPipeInputStream.java:34)
    at java.base/java.io.InputStream.read(InputStream.java:106)
    at net.gudenau.lib.pipes.impl.windows.WindowsPipeInputStream.read(WindowsPipeInputStream.java:16)
    at net.gudenau.lib.pipes.test.AnonymousPipe.test(AnonymousPipe.java:57)
    at net.gudenau.lib.pipes.test.PipeTest.main(PipeTest.java:6)
java.io.IOException: The handle is invalid.

    at net.gudenau.lib.pipes.impl.windows.WindowsPipeOutputStream.write(WindowsPipeOutputStream.java:35)
    at java.base/java.io.OutputStream.write(OutputStream.java:77)
    at net.gudenau.lib.pipes.impl.windows.WindowsPipeOutputStream.write(WindowsPipeOutputStream.java:15)
    at net.gudenau.lib.pipes.test.AnonymousPipe.main(AnonymousPipe.java:19)

Process finished with exit code -1
gudenau
  • 500
  • 5
  • 19

1 Answers1

-1

I remember reading here that handles from one process are invalid in another process and that Java windows anonymous pipes only worked between threads. That would explain an invalid handle.

Micromuncher
  • 903
  • 7
  • 19
  • [Pipe Handle Inheritance](https://learn.microsoft.com/en-us/windows/desktop/ipc/pipe-handle-inheritance) disagrees with the initial statement. – IInspectable Aug 07 '18 at 01:06
  • handles of course per process value and have sense only in process context. but inheritance - this is when handle duplicated to child process from parent with same value. what you mean under *only worked between threads* i at all don't understand. – RbMm Aug 07 '18 at 06:53
  • my point is that if the child process has a different pid (that it should), then an anonymous pipe's handle is invalid unless you fix it up with duplicatehandle ( http://forums.codeguru.com/showthread.php?55501-Anonymous-pipes-between-unrelated-processes ) – Micromuncher Aug 07 '18 at 20:18
  • Now that is something that I might be able to use, I will look into that. – gudenau Aug 07 '18 at 20:26
  • DuplicateHandle says the handle is invalid. How odd. – gudenau Aug 07 '18 at 20:52