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