1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  package org.newsclub.net.unix;
19  
20  import java.io.IOException;
21  import java.nio.channels.AsynchronousCloseException;
22  import java.nio.channels.ClosedByInterruptException;
23  import java.nio.channels.ClosedChannelException;
24  import java.nio.channels.NotYetBoundException;
25  import java.nio.channels.NotYetConnectedException;
26  import java.nio.channels.spi.AbstractInterruptibleChannel;
27  import java.util.Objects;
28  
29  
30  
31  
32  
33  
34  final class InterruptibleChannelUtil {
35    
36  
37  
38    @FunctionalInterface
39    interface EndMethod {
40      void end(boolean completed) throws AsynchronousCloseException;
41    }
42  
43    
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55    static void endInterruptable(AFSomeSocketChannel channel, EndMethod end, boolean complete,
56        Exception exception) throws AsynchronousCloseException {
57      if (!complete) {
58        if (exception instanceof ClosedChannelException) {
59          
60          complete = true;
61        }
62      }
63      try {
64        end.end(complete);
65      } catch (AsynchronousCloseException e) {
66        throw closeAndThrow(channel, e);
67      }
68    }
69  
70    private static <T extends Exception> T closeAndThrow(AFSomeSocketChannel channel, T exc) {
71      Objects.requireNonNull(exc);
72      if (channel.isOpen()) {
73        try {
74          channel.close();
75        } catch (IOException e2) {
76          exc.addSuppressed(e2);
77        }
78      }
79      return exc;
80    }
81  
82    static IOException ioExceptionOrThrowRuntimeException(Exception exception) {
83      if (exception instanceof IOException) {
84        return (IOException) exception;
85      } else if (exception instanceof RuntimeException) {
86        throw (RuntimeException) exception;
87      } else {
88        throw new IllegalStateException(exception);
89      }
90    }
91  
92    
93  
94  
95  
96  
97  
98  
99  
100 
101   @SuppressWarnings("PMD.CognitiveComplexity")
102   static Exception handleException(AFSomeSocketChannel channel, IOException e) {
103     if (e instanceof NotConnectedSocketException) {
104       return (NotYetConnectedException) new NotYetConnectedException().initCause(e);
105     } else if (e instanceof NotBoundSocketException) {
106       return (NotYetBoundException) new NotYetBoundException().initCause(e);
107     }
108 
109     if (e instanceof InvalidArgumentSocketException) {
110       if (channel instanceof AFServerSocketChannel<?>) {
111         AFServerSocketChannel<?> sc = (AFServerSocketChannel<?>) channel;
112         if (!sc.socket().isBound()) {
113           return (NotYetBoundException) new NotYetBoundException().initCause(e);
114         }
115       } else if (channel instanceof AFSocketChannel<?>) {
116         if (!((AFSocketChannel<?>) channel).socket().isConnected()) {
117           return (NotYetConnectedException) new NotYetConnectedException().initCause(e);
118         }
119       }
120     }
121 
122     if (e instanceof SocketClosedException || e instanceof ClosedChannelException
123         || e instanceof BrokenPipeSocketException) {
124       Thread t = Thread.currentThread();
125 
126       if (e instanceof SocketClosedByInterruptException
127           || e instanceof ClosedByInterruptException) {
128         if (!t.isInterrupted()) {
129           t.interrupt();
130         }
131       }
132 
133       if (!(e instanceof ClosedChannelException)) {
134         
135         if (t.isInterrupted()) {
136           e = (ClosedByInterruptException) new ClosedByInterruptException().initCause(e);
137         } else if (e instanceof BrokenPipeSocketException) {
138           e = (AsynchronousCloseException) new AsynchronousCloseException().initCause(e);
139         } else {
140           e = (ClosedChannelException) new ClosedChannelException().initCause(e);
141         }
142       }
143 
144       return closeAndThrow(channel, e);
145     } else {
146       return e;
147     }
148   }
149 }