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