1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package io.netty.channel.unix;
17  
18  import io.netty.util.internal.EmptyArrays;
19  
20  import java.io.FileNotFoundException;
21  import java.io.IOException;
22  import java.net.ConnectException;
23  import java.net.NoRouteToHostException;
24  import java.nio.channels.AlreadyConnectedException;
25  import java.nio.channels.ClosedChannelException;
26  import java.nio.channels.ConnectionPendingException;
27  import java.nio.channels.NotYetConnectedException;
28  
29  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errnoEAGAIN;
30  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errnoEBADF;
31  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errnoECONNRESET;
32  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errnoEINPROGRESS;
33  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errnoENOENT;
34  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errnoENOTCONN;
35  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errnoEPIPE;
36  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errnoEWOULDBLOCK;
37  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errorEALREADY;
38  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errorECONNREFUSED;
39  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errorEHOSTUNREACH;
40  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errorEISCONN;
41  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.errorENETUNREACH;
42  import static io.netty.channel.unix.ErrorsStaticallyReferencedJniMethods.strError;
43  
44  
45  
46  
47  
48  public final class Errors {
49      
50      public static final int ERRNO_ENOENT_NEGATIVE = -errnoENOENT();
51      public static final int ERRNO_ENOTCONN_NEGATIVE = -errnoENOTCONN();
52      public static final int ERRNO_EBADF_NEGATIVE = -errnoEBADF();
53      public static final int ERRNO_EPIPE_NEGATIVE = -errnoEPIPE();
54      public static final int ERRNO_ECONNRESET_NEGATIVE = -errnoECONNRESET();
55      public static final int ERRNO_EAGAIN_NEGATIVE = -errnoEAGAIN();
56      public static final int ERRNO_EWOULDBLOCK_NEGATIVE = -errnoEWOULDBLOCK();
57      public static final int ERRNO_EINPROGRESS_NEGATIVE = -errnoEINPROGRESS();
58      public static final int ERROR_ECONNREFUSED_NEGATIVE = -errorECONNREFUSED();
59      public static final int ERROR_EISCONN_NEGATIVE = -errorEISCONN();
60      public static final int ERROR_EALREADY_NEGATIVE = -errorEALREADY();
61      public static final int ERROR_ENETUNREACH_NEGATIVE = -errorENETUNREACH();
62      public static final int ERROR_EHOSTUNREACH_NEGATIVE = -errorEHOSTUNREACH();
63  
64      
65  
66  
67  
68  
69  
70  
71  
72      private static final String[] ERRORS = new String[2048];
73  
74      
75  
76  
77      public static final class NativeIoException extends IOException {
78          private static final long serialVersionUID = 8222160204268655526L;
79          private final int expectedErr;
80          private final boolean fillInStackTrace;
81  
82          public NativeIoException(String method, int expectedErr) {
83              this(method, expectedErr, true);
84          }
85  
86          public NativeIoException(String method, int expectedErr, boolean fillInStackTrace) {
87              super(method + "(..) failed with error(" + expectedErr + "): " + errnoString(-expectedErr));
88              this.expectedErr = expectedErr;
89              this.fillInStackTrace = fillInStackTrace;
90          }
91  
92          public int expectedErr() {
93              return expectedErr;
94          }
95  
96          @Override
97          public synchronized Throwable fillInStackTrace() {
98              if (fillInStackTrace) {
99                  return super.fillInStackTrace();
100             }
101             return this;
102         }
103     }
104 
105     static final class NativeConnectException extends ConnectException {
106         private static final long serialVersionUID = -5532328671712318161L;
107         private final int expectedErr;
108         NativeConnectException(String method, int expectedErr) {
109             super(method + "(..) failed with error(" + expectedErr + "):" + errnoString(-expectedErr));
110             this.expectedErr = expectedErr;
111         }
112 
113         int expectedErr() {
114             return expectedErr;
115         }
116     }
117 
118     static {
119         for (int i = 0; i < ERRORS.length; i++) {
120             
121             ERRORS[i] = strError(i);
122         }
123     }
124 
125     public static boolean handleConnectErrno(String method, int err) throws IOException {
126         if (err == ERRNO_EINPROGRESS_NEGATIVE || err == ERROR_EALREADY_NEGATIVE) {
127             
128             
129             return false;
130         }
131         throw newConnectException0(method, err);
132     }
133 
134     
135 
136 
137 
138 
139 
140     @Deprecated
141     public static void throwConnectException(String method, int err) throws IOException {
142         if (err == ERROR_EALREADY_NEGATIVE) {
143             throw new ConnectionPendingException();
144         }
145         throw newConnectException0(method, err);
146     }
147 
148     private static String errnoString(int err) {
149         
150         if (err < ERRORS.length - 1) {
151             return ERRORS[err];
152         }
153         return strError(err);
154     }
155 
156     private static IOException newConnectException0(String method, int err) {
157         if (err == ERROR_ENETUNREACH_NEGATIVE || err == ERROR_EHOSTUNREACH_NEGATIVE) {
158             return new NoRouteToHostException();
159         }
160         if (err == ERROR_EISCONN_NEGATIVE) {
161             throw new AlreadyConnectedException();
162         }
163         if (err == ERRNO_ENOENT_NEGATIVE) {
164             return new FileNotFoundException();
165         }
166         return new ConnectException(method + "(..) failed with error(" + err + "): " + errnoString(-err));
167     }
168 
169     public static NativeIoException newConnectionResetException(String method, int errnoNegative) {
170         NativeIoException exception = new NativeIoException(method, errnoNegative, false);
171         exception.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE);
172         return exception;
173     }
174 
175     public static NativeIoException newIOException(String method, int err) {
176         return new NativeIoException(method, err);
177     }
178 
179     @Deprecated
180     public static int ioResult(String method, int err, NativeIoException resetCause,
181                                ClosedChannelException closedCause) throws IOException {
182         
183         if (err == ERRNO_EAGAIN_NEGATIVE || err == ERRNO_EWOULDBLOCK_NEGATIVE) {
184             return 0;
185         }
186         if (err == resetCause.expectedErr()) {
187             throw resetCause;
188         }
189         if (err == ERRNO_EBADF_NEGATIVE) {
190             throw closedCause;
191         }
192         if (err == ERRNO_ENOTCONN_NEGATIVE) {
193             throw new NotYetConnectedException();
194         }
195         if (err == ERRNO_ENOENT_NEGATIVE) {
196             throw new FileNotFoundException();
197         }
198 
199         
200         
201         throw newIOException(method, err);
202     }
203 
204     public static int ioResult(String method, int err) throws IOException {
205         
206         if (err == ERRNO_EAGAIN_NEGATIVE || err == ERRNO_EWOULDBLOCK_NEGATIVE) {
207             return 0;
208         }
209         if (err == ERRNO_EBADF_NEGATIVE) {
210             throw new ClosedChannelException();
211         }
212         if (err == ERRNO_ENOTCONN_NEGATIVE) {
213             throw new NotYetConnectedException();
214         }
215         if (err == ERRNO_ENOENT_NEGATIVE) {
216             throw new FileNotFoundException();
217         }
218 
219         throw new NativeIoException(method, err, false);
220     }
221 
222     private Errors() { }
223 }