1//! The `rustix` `Errno` type.
2//!
3//! This type holds an OS error code, which conceptually corresponds to an
4//! `errno` value.
5//!
6//! # Safety
7//!
8//! Linux uses error codes in `-4095..0`; we use rustc attributes to describe
9//! this restricted range of values.
10#![allow(unsafe_code)]
11#![cfg_attr(not(rustc_attrs), allow(unused_unsafe))]
12
13use super::super::c;
14use crate::backend::fd::RawFd;
15use crate::backend::reg::{RetNumber, RetReg};
16use crate::io;
17use linux_raw_sys::errno;
18
19/// The error type for `rustix` APIs.
20///
21/// This is similar to `std::io::Error`, but only holds an OS error code,
22/// and no extra error value.
23#[repr(transparent)]
24#[doc(alias = "errno")]
25#[derive(Eq, PartialEq, Hash, Copy, Clone)]
26// Linux returns negated error codes, and we leave them in negated form, so
27// error codes are in `-4095..0`.
28#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_start(0xf001))]
29#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_end(0xffff))]
30pub struct Errno(u16);
31
32impl Errno {
33 /// Extract an `Errno` value from a `std::io::Error`.
34 ///
35 /// This isn't a `From` conversion because it's expected to be relatively
36 /// uncommon.
37 #[cfg(feature = "std")]
38 #[inline]
39 pub fn from_io_error(io_err: &std::io::Error) -> Option<Self> {
40 io_err.raw_os_error().and_then(|raw| {
41 // `std::io::Error` could theoretically have arbitrary "OS error"
42 // values, so check that they're in Linux's range.
43 if (1..4096).contains(&raw) {
44 Some(Self::from_errno(raw as u32))
45 } else {
46 None
47 }
48 })
49 }
50
51 /// Extract the raw OS error number from this error.
52 #[inline]
53 pub const fn raw_os_error(self) -> i32 {
54 (self.0 as i16 as i32).wrapping_neg()
55 }
56
57 /// Construct an `Errno` from a raw OS error number.
58 #[inline]
59 pub const fn from_raw_os_error(raw: i32) -> Self {
60 Self::from_errno(raw as u32)
61 }
62
63 /// Convert from a C `errno` value (which is positive) to an `Errno`.
64 const fn from_errno(raw: u32) -> Self {
65 // We store error values in negated form, so that we don't have to
66 // negate them after every syscall.
67 let encoded = raw.wrapping_neg() as u16;
68
69 // TODO: Use Range::contains, once that's `const`.
70 const_assert!(encoded >= 0xf001);
71
72 // SAFETY: Linux syscalls return negated error values in the range
73 // `-4095..0`, which we just asserted.
74 unsafe { Self(encoded) }
75 }
76}
77
78/// Check for an error from the result of a syscall which encodes a
79/// `c::c_int` on success.
80#[inline]
81pub(in crate::backend) fn try_decode_c_int<Num: RetNumber>(
82 raw: RetReg<Num>,
83) -> io::Result<c::c_int> {
84 if raw.is_in_range(-4095..0) {
85 // SAFETY: `raw` must be in `-4095..0`, and we just checked that raw is
86 // in that range.
87 return Err(unsafe { Errno(raw.decode_error_code()) });
88 }
89
90 Ok(raw.decode_c_int())
91}
92
93/// Check for an error from the result of a syscall which encodes a
94/// `c::c_uint` on success.
95#[inline]
96pub(in crate::backend) fn try_decode_c_uint<Num: RetNumber>(
97 raw: RetReg<Num>,
98) -> io::Result<c::c_uint> {
99 if raw.is_in_range(-4095..0) {
100 // SAFETY: `raw` must be in `-4095..0`, and we just checked that raw is
101 // in that range.
102 return Err(unsafe { Errno(raw.decode_error_code()) });
103 }
104
105 Ok(raw.decode_c_uint())
106}
107
108/// Check for an error from the result of a syscall which encodes a `usize` on
109/// success.
110#[inline]
111pub(in crate::backend) fn try_decode_usize<Num: RetNumber>(raw: RetReg<Num>) -> io::Result<usize> {
112 if raw.is_in_range(-4095..0) {
113 // SAFETY: `raw` must be in `-4095..0`, and we just checked that raw is
114 // in that range.
115 return Err(unsafe { Errno(raw.decode_error_code()) });
116 }
117
118 Ok(raw.decode_usize())
119}
120
121/// Check for an error from the result of a syscall which encodes a
122/// `*mut c_void` on success.
123#[inline]
124pub(in crate::backend) fn try_decode_void_star<Num: RetNumber>(
125 raw: RetReg<Num>,
126) -> io::Result<*mut c::c_void> {
127 if raw.is_in_range(-4095..0) {
128 // SAFETY: `raw` must be in `-4095..0`, and we just checked that raw is
129 // in that range.
130 return Err(unsafe { Errno(raw.decode_error_code()) });
131 }
132
133 Ok(raw.decode_void_star())
134}
135
136/// Check for an error from the result of a syscall which encodes a
137/// `u64` on success.
138#[cfg(target_pointer_width = "64")]
139#[inline]
140pub(in crate::backend) fn try_decode_u64<Num: RetNumber>(raw: RetReg<Num>) -> io::Result<u64> {
141 if raw.is_in_range(-4095..0) {
142 // SAFETY: `raw` must be in `-4095..0`, and we just checked that raw is
143 // in that range.
144 return Err(unsafe { Errno(raw.decode_error_code()) });
145 }
146
147 Ok(raw.decode_u64())
148}
149
150/// Check for an error from the result of a syscall which encodes a file
151/// descriptor on success.
152///
153/// # Safety
154///
155/// This must only be used with syscalls which return file descriptors on
156/// success.
157#[inline]
158pub(in crate::backend) unsafe fn try_decode_raw_fd<Num: RetNumber>(
159 raw: RetReg<Num>,
160) -> io::Result<RawFd> {
161 // Instead of using `check_result` here, we just check for negative, since
162 // this function is only used for system calls which return file
163 // descriptors, and this produces smaller code.
164 if raw.is_negative() {
165 debug_assert!(raw.is_in_range(-4095..0));
166
167 // Tell the optimizer that we know the value is in the error range.
168 // This helps it avoid unnecessary integer conversions.
169 #[cfg(core_intrinsics)]
170 {
171 core::intrinsics::assume(raw.is_in_range(-4095..0));
172 }
173
174 return Err(Errno(raw.decode_error_code()));
175 }
176
177 Ok(raw.decode_raw_fd())
178}
179
180/// Check for an error from the result of a syscall which encodes no value on
181/// success. On success, return the unconsumed `raw` value.
182///
183/// # Safety
184///
185/// This must only be used with syscalls which return no value on success.
186#[inline]
187pub(in crate::backend) unsafe fn try_decode_void<Num: RetNumber>(
188 raw: RetReg<Num>,
189) -> io::Result<()> {
190 // Instead of using `check_result` here, we just check for zero, since this
191 // function is only used for system calls which have no other return value,
192 // and this produces smaller code.
193 if raw.is_nonzero() {
194 debug_assert!(raw.is_in_range(-4095..0));
195
196 // Tell the optimizer that we know the value is in the error range.
197 // This helps it avoid unnecessary integer conversions.
198 #[cfg(core_intrinsics)]
199 {
200 core::intrinsics::assume(raw.is_in_range(-4095..0));
201 }
202
203 return Err(Errno(raw.decode_error_code()));
204 }
205
206 raw.decode_void();
207
208 Ok(())
209}
210
211/// Check for an error from the result of a syscall which does not return on
212/// success. On success, return the unconsumed `raw` value.
213///
214/// # Safety
215///
216/// This must only be used with syscalls which do not return on success.
217#[cfg(feature = "runtime")]
218#[inline]
219pub(in crate::backend) unsafe fn try_decode_error<Num: RetNumber>(raw: RetReg<Num>) -> io::Errno {
220 debug_assert!(raw.is_in_range(-4095..0));
221
222 // Tell the optimizer that we know the value is in the error range.
223 // This helps it avoid unnecessary integer conversions.
224 #[cfg(core_intrinsics)]
225 {
226 core::intrinsics::assume(raw.is_in_range(-4095..0));
227 }
228
229 Errno(raw.decode_error_code())
230}
231
232/// Return the contained `usize` value.
233#[cfg(not(debug_assertions))]
234#[inline]
235pub(in crate::backend) fn decode_usize_infallible<Num: RetNumber>(raw: RetReg<Num>) -> usize {
236 raw.decode_usize()
237}
238
239/// Return the contained `c_int` value.
240#[cfg(not(debug_assertions))]
241#[inline]
242pub(in crate::backend) fn decode_c_uint_infallible<Num: RetNumber>(raw: RetReg<Num>) -> c::c_uint {
243 raw.decode_c_uint()
244}
245
246impl Errno {
247 /// `EACCES`
248 #[doc(alias = "ACCES")]
249 pub const ACCESS: Self = Self::from_errno(errno::EACCES);
250 /// `EADDRINUSE`
251 pub const ADDRINUSE: Self = Self::from_errno(errno::EADDRINUSE);
252 /// `EADDRNOTAVAIL`
253 pub const ADDRNOTAVAIL: Self = Self::from_errno(errno::EADDRNOTAVAIL);
254 /// `EADV`
255 pub const ADV: Self = Self::from_errno(errno::EADV);
256 /// `EAFNOSUPPORT`
257 pub const AFNOSUPPORT: Self = Self::from_errno(errno::EAFNOSUPPORT);
258 /// `EAGAIN`
259 pub const AGAIN: Self = Self::from_errno(errno::EAGAIN);
260 /// `EALREADY`
261 pub const ALREADY: Self = Self::from_errno(errno::EALREADY);
262 /// `EBADE`
263 pub const BADE: Self = Self::from_errno(errno::EBADE);
264 /// `EBADF`
265 pub const BADF: Self = Self::from_errno(errno::EBADF);
266 /// `EBADFD`
267 pub const BADFD: Self = Self::from_errno(errno::EBADFD);
268 /// `EBADMSG`
269 pub const BADMSG: Self = Self::from_errno(errno::EBADMSG);
270 /// `EBADR`
271 pub const BADR: Self = Self::from_errno(errno::EBADR);
272 /// `EBADRQC`
273 pub const BADRQC: Self = Self::from_errno(errno::EBADRQC);
274 /// `EBADSLT`
275 pub const BADSLT: Self = Self::from_errno(errno::EBADSLT);
276 /// `EBFONT`
277 pub const BFONT: Self = Self::from_errno(errno::EBFONT);
278 /// `EBUSY`
279 pub const BUSY: Self = Self::from_errno(errno::EBUSY);
280 /// `ECANCELED`
281 pub const CANCELED: Self = Self::from_errno(errno::ECANCELED);
282 /// `ECHILD`
283 pub const CHILD: Self = Self::from_errno(errno::ECHILD);
284 /// `ECHRNG`
285 pub const CHRNG: Self = Self::from_errno(errno::ECHRNG);
286 /// `ECOMM`
287 pub const COMM: Self = Self::from_errno(errno::ECOMM);
288 /// `ECONNABORTED`
289 pub const CONNABORTED: Self = Self::from_errno(errno::ECONNABORTED);
290 /// `ECONNREFUSED`
291 pub const CONNREFUSED: Self = Self::from_errno(errno::ECONNREFUSED);
292 /// `ECONNRESET`
293 pub const CONNRESET: Self = Self::from_errno(errno::ECONNRESET);
294 /// `EDEADLK`
295 pub const DEADLK: Self = Self::from_errno(errno::EDEADLK);
296 /// `EDEADLOCK`
297 pub const DEADLOCK: Self = Self::from_errno(errno::EDEADLOCK);
298 /// `EDESTADDRREQ`
299 pub const DESTADDRREQ: Self = Self::from_errno(errno::EDESTADDRREQ);
300 /// `EDOM`
301 pub const DOM: Self = Self::from_errno(errno::EDOM);
302 /// `EDOTDOT`
303 pub const DOTDOT: Self = Self::from_errno(errno::EDOTDOT);
304 /// `EDQUOT`
305 pub const DQUOT: Self = Self::from_errno(errno::EDQUOT);
306 /// `EEXIST`
307 pub const EXIST: Self = Self::from_errno(errno::EEXIST);
308 /// `EFAULT`
309 pub const FAULT: Self = Self::from_errno(errno::EFAULT);
310 /// `EFBIG`
311 pub const FBIG: Self = Self::from_errno(errno::EFBIG);
312 /// `EHOSTDOWN`
313 pub const HOSTDOWN: Self = Self::from_errno(errno::EHOSTDOWN);
314 /// `EHOSTUNREACH`
315 pub const HOSTUNREACH: Self = Self::from_errno(errno::EHOSTUNREACH);
316 /// `EHWPOISON`
317 pub const HWPOISON: Self = Self::from_errno(errno::EHWPOISON);
318 /// `EIDRM`
319 pub const IDRM: Self = Self::from_errno(errno::EIDRM);
320 /// `EILSEQ`
321 pub const ILSEQ: Self = Self::from_errno(errno::EILSEQ);
322 /// `EINPROGRESS`
323 pub const INPROGRESS: Self = Self::from_errno(errno::EINPROGRESS);
324 /// `EINTR`.
325 ///
326 /// For a convenient way to retry system calls that exit with `INTR`, use
327 /// [`retry_on_intr`].
328 ///
329 /// [`retry_on_intr`]: io::retry_on_intr
330 pub const INTR: Self = Self::from_errno(errno::EINTR);
331 /// `EINVAL`
332 pub const INVAL: Self = Self::from_errno(errno::EINVAL);
333 /// `EIO`
334 pub const IO: Self = Self::from_errno(errno::EIO);
335 /// `EISCONN`
336 pub const ISCONN: Self = Self::from_errno(errno::EISCONN);
337 /// `EISDIR`
338 pub const ISDIR: Self = Self::from_errno(errno::EISDIR);
339 /// `EISNAM`
340 pub const ISNAM: Self = Self::from_errno(errno::EISNAM);
341 /// `EKEYEXPIRED`
342 pub const KEYEXPIRED: Self = Self::from_errno(errno::EKEYEXPIRED);
343 /// `EKEYREJECTED`
344 pub const KEYREJECTED: Self = Self::from_errno(errno::EKEYREJECTED);
345 /// `EKEYREVOKED`
346 pub const KEYREVOKED: Self = Self::from_errno(errno::EKEYREVOKED);
347 /// `EL2HLT`
348 pub const L2HLT: Self = Self::from_errno(errno::EL2HLT);
349 /// `EL2NSYNC`
350 pub const L2NSYNC: Self = Self::from_errno(errno::EL2NSYNC);
351 /// `EL3HLT`
352 pub const L3HLT: Self = Self::from_errno(errno::EL3HLT);
353 /// `EL3RST`
354 pub const L3RST: Self = Self::from_errno(errno::EL3RST);
355 /// `ELIBACC`
356 pub const LIBACC: Self = Self::from_errno(errno::ELIBACC);
357 /// `ELIBBAD`
358 pub const LIBBAD: Self = Self::from_errno(errno::ELIBBAD);
359 /// `ELIBEXEC`
360 pub const LIBEXEC: Self = Self::from_errno(errno::ELIBEXEC);
361 /// `ELIBMAX`
362 pub const LIBMAX: Self = Self::from_errno(errno::ELIBMAX);
363 /// `ELIBSCN`
364 pub const LIBSCN: Self = Self::from_errno(errno::ELIBSCN);
365 /// `ELNRNG`
366 pub const LNRNG: Self = Self::from_errno(errno::ELNRNG);
367 /// `ELOOP`
368 pub const LOOP: Self = Self::from_errno(errno::ELOOP);
369 /// `EMEDIUMTYPE`
370 pub const MEDIUMTYPE: Self = Self::from_errno(errno::EMEDIUMTYPE);
371 /// `EMFILE`
372 pub const MFILE: Self = Self::from_errno(errno::EMFILE);
373 /// `EMLINK`
374 pub const MLINK: Self = Self::from_errno(errno::EMLINK);
375 /// `EMSGSIZE`
376 pub const MSGSIZE: Self = Self::from_errno(errno::EMSGSIZE);
377 /// `EMULTIHOP`
378 pub const MULTIHOP: Self = Self::from_errno(errno::EMULTIHOP);
379 /// `ENAMETOOLONG`
380 pub const NAMETOOLONG: Self = Self::from_errno(errno::ENAMETOOLONG);
381 /// `ENAVAIL`
382 pub const NAVAIL: Self = Self::from_errno(errno::ENAVAIL);
383 /// `ENETDOWN`
384 pub const NETDOWN: Self = Self::from_errno(errno::ENETDOWN);
385 /// `ENETRESET`
386 pub const NETRESET: Self = Self::from_errno(errno::ENETRESET);
387 /// `ENETUNREACH`
388 pub const NETUNREACH: Self = Self::from_errno(errno::ENETUNREACH);
389 /// `ENFILE`
390 pub const NFILE: Self = Self::from_errno(errno::ENFILE);
391 /// `ENOANO`
392 pub const NOANO: Self = Self::from_errno(errno::ENOANO);
393 /// `ENOBUFS`
394 pub const NOBUFS: Self = Self::from_errno(errno::ENOBUFS);
395 /// `ENOCSI`
396 pub const NOCSI: Self = Self::from_errno(errno::ENOCSI);
397 /// `ENODATA`
398 #[doc(alias = "NOATTR")]
399 pub const NODATA: Self = Self::from_errno(errno::ENODATA);
400 /// `ENODEV`
401 pub const NODEV: Self = Self::from_errno(errno::ENODEV);
402 /// `ENOENT`
403 pub const NOENT: Self = Self::from_errno(errno::ENOENT);
404 /// `ENOEXEC`
405 pub const NOEXEC: Self = Self::from_errno(errno::ENOEXEC);
406 /// `ENOKEY`
407 pub const NOKEY: Self = Self::from_errno(errno::ENOKEY);
408 /// `ENOLCK`
409 pub const NOLCK: Self = Self::from_errno(errno::ENOLCK);
410 /// `ENOLINK`
411 pub const NOLINK: Self = Self::from_errno(errno::ENOLINK);
412 /// `ENOMEDIUM`
413 pub const NOMEDIUM: Self = Self::from_errno(errno::ENOMEDIUM);
414 /// `ENOMEM`
415 pub const NOMEM: Self = Self::from_errno(errno::ENOMEM);
416 /// `ENOMSG`
417 pub const NOMSG: Self = Self::from_errno(errno::ENOMSG);
418 /// `ENONET`
419 pub const NONET: Self = Self::from_errno(errno::ENONET);
420 /// `ENOPKG`
421 pub const NOPKG: Self = Self::from_errno(errno::ENOPKG);
422 /// `ENOPROTOOPT`
423 pub const NOPROTOOPT: Self = Self::from_errno(errno::ENOPROTOOPT);
424 /// `ENOSPC`
425 pub const NOSPC: Self = Self::from_errno(errno::ENOSPC);
426 /// `ENOSR`
427 pub const NOSR: Self = Self::from_errno(errno::ENOSR);
428 /// `ENOSTR`
429 pub const NOSTR: Self = Self::from_errno(errno::ENOSTR);
430 /// `ENOSYS`
431 pub const NOSYS: Self = Self::from_errno(errno::ENOSYS);
432 /// `ENOTBLK`
433 pub const NOTBLK: Self = Self::from_errno(errno::ENOTBLK);
434 /// `ENOTCONN`
435 pub const NOTCONN: Self = Self::from_errno(errno::ENOTCONN);
436 /// `ENOTDIR`
437 pub const NOTDIR: Self = Self::from_errno(errno::ENOTDIR);
438 /// `ENOTEMPTY`
439 pub const NOTEMPTY: Self = Self::from_errno(errno::ENOTEMPTY);
440 /// `ENOTNAM`
441 pub const NOTNAM: Self = Self::from_errno(errno::ENOTNAM);
442 /// `ENOTRECOVERABLE`
443 pub const NOTRECOVERABLE: Self = Self::from_errno(errno::ENOTRECOVERABLE);
444 /// `ENOTSOCK`
445 pub const NOTSOCK: Self = Self::from_errno(errno::ENOTSOCK);
446 /// `ENOTSUP`
447 // On Linux, `ENOTSUP` has the same value as `EOPNOTSUPP`.
448 pub const NOTSUP: Self = Self::from_errno(errno::EOPNOTSUPP);
449 /// `ENOTTY`
450 pub const NOTTY: Self = Self::from_errno(errno::ENOTTY);
451 /// `ENOTUNIQ`
452 pub const NOTUNIQ: Self = Self::from_errno(errno::ENOTUNIQ);
453 /// `ENXIO`
454 pub const NXIO: Self = Self::from_errno(errno::ENXIO);
455 /// `EOPNOTSUPP`
456 pub const OPNOTSUPP: Self = Self::from_errno(errno::EOPNOTSUPP);
457 /// `EOVERFLOW`
458 pub const OVERFLOW: Self = Self::from_errno(errno::EOVERFLOW);
459 /// `EOWNERDEAD`
460 pub const OWNERDEAD: Self = Self::from_errno(errno::EOWNERDEAD);
461 /// `EPERM`
462 pub const PERM: Self = Self::from_errno(errno::EPERM);
463 /// `EPFNOSUPPORT`
464 pub const PFNOSUPPORT: Self = Self::from_errno(errno::EPFNOSUPPORT);
465 /// `EPIPE`
466 pub const PIPE: Self = Self::from_errno(errno::EPIPE);
467 /// `EPROTO`
468 pub const PROTO: Self = Self::from_errno(errno::EPROTO);
469 /// `EPROTONOSUPPORT`
470 pub const PROTONOSUPPORT: Self = Self::from_errno(errno::EPROTONOSUPPORT);
471 /// `EPROTOTYPE`
472 pub const PROTOTYPE: Self = Self::from_errno(errno::EPROTOTYPE);
473 /// `ERANGE`
474 pub const RANGE: Self = Self::from_errno(errno::ERANGE);
475 /// `EREMCHG`
476 pub const REMCHG: Self = Self::from_errno(errno::EREMCHG);
477 /// `EREMOTE`
478 pub const REMOTE: Self = Self::from_errno(errno::EREMOTE);
479 /// `EREMOTEIO`
480 pub const REMOTEIO: Self = Self::from_errno(errno::EREMOTEIO);
481 /// `ERESTART`
482 pub const RESTART: Self = Self::from_errno(errno::ERESTART);
483 /// `ERFKILL`
484 pub const RFKILL: Self = Self::from_errno(errno::ERFKILL);
485 /// `EROFS`
486 pub const ROFS: Self = Self::from_errno(errno::EROFS);
487 /// `ESHUTDOWN`
488 pub const SHUTDOWN: Self = Self::from_errno(errno::ESHUTDOWN);
489 /// `ESOCKTNOSUPPORT`
490 pub const SOCKTNOSUPPORT: Self = Self::from_errno(errno::ESOCKTNOSUPPORT);
491 /// `ESPIPE`
492 pub const SPIPE: Self = Self::from_errno(errno::ESPIPE);
493 /// `ESRCH`
494 pub const SRCH: Self = Self::from_errno(errno::ESRCH);
495 /// `ESRMNT`
496 pub const SRMNT: Self = Self::from_errno(errno::ESRMNT);
497 /// `ESTALE`
498 pub const STALE: Self = Self::from_errno(errno::ESTALE);
499 /// `ESTRPIPE`
500 pub const STRPIPE: Self = Self::from_errno(errno::ESTRPIPE);
501 /// `ETIME`
502 pub const TIME: Self = Self::from_errno(errno::ETIME);
503 /// `ETIMEDOUT`
504 pub const TIMEDOUT: Self = Self::from_errno(errno::ETIMEDOUT);
505 /// `E2BIG`
506 #[doc(alias = "2BIG")]
507 pub const TOOBIG: Self = Self::from_errno(errno::E2BIG);
508 /// `ETOOMANYREFS`
509 pub const TOOMANYREFS: Self = Self::from_errno(errno::ETOOMANYREFS);
510 /// `ETXTBSY`
511 pub const TXTBSY: Self = Self::from_errno(errno::ETXTBSY);
512 /// `EUCLEAN`
513 pub const UCLEAN: Self = Self::from_errno(errno::EUCLEAN);
514 /// `EUNATCH`
515 pub const UNATCH: Self = Self::from_errno(errno::EUNATCH);
516 /// `EUSERS`
517 pub const USERS: Self = Self::from_errno(errno::EUSERS);
518 /// `EWOULDBLOCK`
519 pub const WOULDBLOCK: Self = Self::from_errno(errno::EWOULDBLOCK);
520 /// `EXDEV`
521 pub const XDEV: Self = Self::from_errno(errno::EXDEV);
522 /// `EXFULL`
523 pub const XFULL: Self = Self::from_errno(errno::EXFULL);
524}
525