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: " + 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: " + 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: " + 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 }