tdf#154546 skip dispatch when presenter controller is not set
[LibreOffice.git] / sal / osl / unx / uunxapi.cxx
blobd1fc6c4f9d3f46242dba93a6040e1745cc39aae6
1 /* -*- Mode: ObjC; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <string_view>
24 #include <config_features.h>
26 #include "uunxapi.hxx"
27 #include "system.hxx"
28 #include "unixerrnostring.hxx"
29 #include <limits.h>
30 #include <rtl/ustring.hxx>
31 #include <osl/thread.h>
32 #include <sal/log.hxx>
34 #ifdef ANDROID
35 #include <osl/detail/android-bootstrap.h>
36 #endif
38 OString osl::OUStringToOString(std::u16string_view s)
40 return rtl::OUStringToOString(s, osl_getThreadTextEncoding());
43 #if HAVE_FEATURE_MACOSX_SANDBOX
45 #include <Foundation/Foundation.h>
46 #include <Security/Security.h>
47 #include <mach-o/dyld.h>
49 static NSUserDefaults *userDefaults = NULL;
50 static bool isSandboxed = false;
52 static void do_once()
54 SecCodeRef code;
55 OSStatus rc = SecCodeCopySelf(kSecCSDefaultFlags, &code);
57 SecStaticCodeRef staticCode;
58 if (rc == errSecSuccess)
59 rc = SecCodeCopyStaticCode(code, kSecCSDefaultFlags, &staticCode);
61 CFDictionaryRef signingInformation;
62 if (rc == errSecSuccess)
63 rc = SecCodeCopySigningInformation(staticCode, kSecCSRequirementInformation, &signingInformation);
65 CFDictionaryRef entitlements = NULL;
66 if (rc == errSecSuccess)
67 entitlements = (CFDictionaryRef) CFDictionaryGetValue(signingInformation, kSecCodeInfoEntitlementsDict);
69 if (entitlements != NULL)
70 if (CFDictionaryGetValue(entitlements, CFSTR("com.apple.security.app-sandbox")) != NULL)
71 isSandboxed = true;
73 if (isSandboxed)
74 userDefaults = [NSUserDefaults standardUserDefaults];
77 typedef struct {
78 NSURL *scopeURL;
79 NSAutoreleasePool *pool;
80 } accessFilePathState;
82 static accessFilePathState *
83 prepare_to_access_file_path( const char *cpFilePath )
85 static pthread_once_t once = PTHREAD_ONCE_INIT;
86 pthread_once(&once, &do_once);
87 NSURL *fileURL = nil;
88 NSData *data = nil;
89 BOOL stale;
90 accessFilePathState *state;
92 if (!isSandboxed)
93 return NULL;
95 // If malloc() fails we are screwed anyway
96 state = (accessFilePathState*) malloc(sizeof(accessFilePathState));
98 state->pool = [[NSAutoreleasePool alloc] init];
99 state->scopeURL = nil;
101 if (userDefaults != nil)
102 fileURL = [NSURL fileURLWithPath:[NSString stringWithUTF8String:cpFilePath]];
104 if (fileURL != nil)
105 data = [userDefaults dataForKey:[@"bookmarkFor:" stringByAppendingString:[fileURL absoluteString]]];
107 if (data != nil)
108 state->scopeURL = [NSURL URLByResolvingBookmarkData:data
109 options:NSURLBookmarkResolutionWithSecurityScope
110 relativeToURL:nil
111 bookmarkDataIsStale:&stale
112 error:nil];
113 if (state->scopeURL != nil)
114 [state->scopeURL startAccessingSecurityScopedResource];
116 return state;
119 static void
120 done_accessing_file_path( const char * /*cpFilePath*/, accessFilePathState *state )
122 if (!isSandboxed)
123 return;
125 int saved_errno = errno;
127 if (state->scopeURL != nil)
128 [state->scopeURL stopAccessingSecurityScopedResource];
129 [state->pool release];
130 free(state);
132 errno = saved_errno;
135 #else
137 typedef void accessFilePathState;
139 #define prepare_to_access_file_path( cpFilePath ) nullptr
141 #define done_accessing_file_path( cpFilePath, state ) ((void) cpFilePath, (void) state)
143 #endif
145 #ifdef MACOSX
147 * Helper function for resolving Mac native alias files (not the same as unix alias files)
148 * and to return the resolved alias as OString
150 static OString macxp_resolveAliasAndConvert(OString const & p)
152 char path[PATH_MAX];
153 if (p.getLength() < PATH_MAX)
155 strcpy(path, p.getStr());
156 macxp_resolveAlias(path, PATH_MAX);
157 return path;
159 return p;
161 #endif /* MACOSX */
163 int osl::access(const OString& pstrPath, int mode)
165 OString fn = pstrPath;
166 #ifdef ANDROID
167 if (fn == "/assets" || fn.startsWith("/assets/"))
169 struct stat stat;
170 if (lo_apk_lstat(fn.getStr(), &stat) == -1)
171 return -1;
172 if (mode & W_OK)
174 errno = EACCES;
175 return -1;
177 return 0;
179 #endif
181 #ifdef MACOSX
182 fn = macxp_resolveAliasAndConvert(fn);
183 #endif
185 accessFilePathState *state = prepare_to_access_file_path(fn.getStr());
187 int result = ::access(fn.getStr(), mode);
188 int saved_errno = errno;
189 if (result == -1)
190 SAL_INFO("sal.file", "access(" << fn << ",0" << std::oct << mode << std::dec << "): " << UnixErrnoString(saved_errno));
191 else
192 SAL_INFO("sal.file", "access(" << fn << ",0" << std::oct << mode << std::dec << "): OK");
194 done_accessing_file_path(fn.getStr(), state);
196 errno = saved_errno;
198 return result;
201 namespace {
203 OString toOString(OString const & s) { return s; }
205 OString toOString(std::u16string_view s) { return osl::OUStringToOString(s); }
207 template<typename T> T fromOString(OString const &) = delete;
209 template<> OString fromOString(OString const & s) { return s; }
211 template<> OUString fromOString(OString const & s)
212 { return OStringToOUString(s, osl_getThreadTextEncoding()); }
214 template<typename T> bool realpath_(const T& pstrFileName, T& ppstrResolvedName)
216 OString fn = toOString(pstrFileName);
217 #if defined ANDROID || defined(EMSCRIPTEN)
218 #if defined ANDROID
219 if (fn == "/assets" || fn.startsWith("/assets/"))
220 #else
221 if (fn == "/instdir" || fn.startsWith("/instdir/"))
222 #endif
224 if (osl::access(fn, F_OK) == -1)
225 return false;
227 ppstrResolvedName = pstrFileName;
229 return true;
231 #endif // ANDROID || EMSCRIPTEN
233 #ifdef MACOSX
234 fn = macxp_resolveAliasAndConvert(fn);
235 #endif
237 accessFilePathState *state = prepare_to_access_file_path(fn.getStr());
239 char rp[PATH_MAX];
240 bool bRet = realpath(fn.getStr(), rp);
241 int saved_errno = errno;
242 if (!bRet)
243 SAL_INFO("sal.file", "realpath(" << fn << "): " << UnixErrnoString(saved_errno));
244 else
245 SAL_INFO("sal.file", "realpath(" << fn << "): OK");
247 done_accessing_file_path(fn.getStr(), state);
249 if (bRet)
251 ppstrResolvedName = fromOString<T>(OString(rp));
254 errno = saved_errno;
256 return bRet;
261 bool osl::realpath(const OUString& pustrFileName, OUString& ppustrResolvedName)
263 return realpath_(pustrFileName, ppustrResolvedName);
266 bool osl::realpath(const OString& pstrFileName, OString& ppstrResolvedName)
268 return realpath_(pstrFileName, ppstrResolvedName);
271 int stat_c(const char* cpPath, struct stat* buf)
273 #ifdef ANDROID
274 if (strncmp(cpPath, "/assets", sizeof("/assets")-1) == 0 &&
275 (cpPath[sizeof("/assets")-1] == '\0' ||
276 cpPath[sizeof("/assets")-1] == '/'))
277 return lo_apk_lstat(cpPath, buf);
278 #endif
280 accessFilePathState *state = prepare_to_access_file_path(cpPath);
282 int result = stat(cpPath, buf);
283 int saved_errno = errno;
284 if (result == -1)
285 SAL_INFO("sal.file", "stat(" << cpPath << "): " << UnixErrnoString(saved_errno));
286 else
287 SAL_INFO("sal.file", "stat(" << cpPath << "): OK");
289 done_accessing_file_path(cpPath, state);
291 errno = saved_errno;
293 return result;
296 int lstat_c(const char* cpPath, struct stat* buf)
298 #ifdef ANDROID
299 if (strncmp(cpPath, "/assets", sizeof("/assets")-1) == 0 &&
300 (cpPath[sizeof("/assets")-1] == '\0' ||
301 cpPath[sizeof("/assets")-1] == '/'))
302 return lo_apk_lstat(cpPath, buf);
303 #endif
305 accessFilePathState *state = prepare_to_access_file_path(cpPath);
307 int result = lstat(cpPath, buf);
308 int saved_errno = errno;
309 if (result == -1)
310 SAL_INFO("sal.file", "lstat(" << cpPath << "): " << UnixErrnoString(saved_errno));
311 else
312 SAL_INFO("sal.file", "lstat(" << cpPath << "): OK");
314 done_accessing_file_path(cpPath, state);
316 errno = saved_errno;
318 return result;
321 namespace {
323 template<typename T> int lstat_(const T& pstrPath, struct stat& buf)
325 OString fn = toOString(pstrPath);
327 #ifdef MACOSX
328 fn = macxp_resolveAliasAndConvert(fn);
329 #endif
331 return lstat_c(fn.getStr(), &buf);
336 int osl::lstat(const OUString& pustrPath, struct stat& buf)
338 return lstat_(pustrPath, buf);
341 int osl::lstat(const OString& pstrPath, struct stat& buf)
343 return lstat_(pstrPath, buf);
346 int osl::mkdir(const OString& path, mode_t mode)
348 accessFilePathState *state = prepare_to_access_file_path(path.getStr());
350 int result = ::mkdir(path.getStr(), mode);
351 int saved_errno = errno;
352 if (result == -1)
353 SAL_INFO("sal.file", "mkdir(" << path << ",0" << std::oct << mode << std::dec << "): " << UnixErrnoString(saved_errno));
354 else
355 SAL_INFO("sal.file", "mkdir(" << path << ",0" << std::oct << mode << std::dec << "): OK");
357 done_accessing_file_path(path.getStr(), state);
359 errno = saved_errno;
361 return result;
364 int open_c(const OString& path, int oflag, int mode)
366 accessFilePathState *state = prepare_to_access_file_path(path.getStr());
368 int result = open(path.getStr(), oflag, mode);
369 int saved_errno = errno;
370 if (result == -1)
371 SAL_INFO("sal.file", "open(" << path << ",0" << std::oct << oflag << ",0" << mode << std::dec << "): " << UnixErrnoString(saved_errno));
372 else
373 SAL_INFO("sal.file", "open(" << path << ",0" << std::oct << oflag << ",0" << mode << std::dec << ") => " << result);
375 #if HAVE_FEATURE_MACOSX_SANDBOX
376 if (isSandboxed && result != -1 && (oflag & O_CREAT) && (oflag & O_EXCL))
378 // A new file was created. Check if it is outside the sandbox.
379 // (In that case it must be one the user selected as export or
380 // save destination in a file dialog, otherwise we wouldn't
381 // have been able to create it.) Create and store a security
382 // scoped bookmark for it so that we can access the file in
383 // the future, too. (For the "Recent Files" functionality.)
384 const char *sandbox = [NSHomeDirectory() UTF8String];
385 if (!(strncmp(sandbox, path.getStr(), strlen(sandbox)) == 0 &&
386 path[strlen(sandbox)] == '/'))
388 auto cpPath = path.getStr();
389 NSURL *url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:cpPath]];
390 NSData *data = [url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
391 includingResourceValuesForKeys:nil
392 relativeToURL:nil
393 error:nil];
394 if (data != NULL)
396 [userDefaults setObject:data
397 forKey:[@"bookmarkFor:" stringByAppendingString:[url absoluteString]]];
401 #endif
403 done_accessing_file_path(path.getStr(), state);
405 errno = saved_errno;
407 return result;
410 int utime_c(const char *cpPath, struct utimbuf *times)
412 accessFilePathState *state = prepare_to_access_file_path(cpPath);
414 int result = utime(cpPath, times);
416 done_accessing_file_path(cpPath, state);
418 return result;
421 int ftruncate_with_name(int fd, sal_uInt64 uSize, const OString& path)
423 /* When sandboxed on macOS, ftruncate(), even if it takes an
424 * already open file descriptor which was returned from an open()
425 * call already checked by the sandbox, still requires a security
426 * scope bookmark for the file to be active in case the file is
427 * one that the sandbox doesn't otherwise allow access to. Luckily
428 * LibreOffice usually calls ftruncate() through the helpful C++
429 * abstraction layer that keeps the pathname around.
432 OString fn(path);
434 #ifdef MACOSX
435 fn = macxp_resolveAliasAndConvert(fn);
436 #endif
438 accessFilePathState *state = prepare_to_access_file_path(fn.getStr());
440 int result = ftruncate(fd, uSize);
441 int saved_errno = errno;
442 if (result < 0)
443 SAL_INFO("sal.file", "ftruncate(" << fd << "," << uSize << "): " << UnixErrnoString(saved_errno));
444 else
445 SAL_INFO("sal.file", "ftruncate(" << fd << "," << uSize << "): OK");
447 done_accessing_file_path(fn.getStr(), state);
449 errno = saved_errno;
451 return result;
455 std::string UnixErrnoString(int nErrno)
457 // Errnos from <asm-generic/errno-base.h> and <asm-generic/errno.h> on Linux and <sys/errno.h>
458 // on macOS.
459 switch (nErrno)
461 case EPERM:
462 return "EPERM";
463 case ENOENT:
464 return "ENOENT";
465 case ESRCH:
466 return "ESRCH";
467 case EINTR:
468 return "EINTR";
469 case EIO:
470 return "EIO";
471 case ENXIO:
472 return "ENXIO";
473 case E2BIG:
474 return "E2BIG";
475 case ENOEXEC:
476 return "ENOEXEC";
477 case EBADF:
478 return "EBADF";
479 case ECHILD:
480 return "ECHILD";
481 case EAGAIN:
482 return "EAGAIN";
483 case ENOMEM:
484 return "ENOMEM";
485 case EACCES:
486 return "EACCES";
487 case EFAULT:
488 return "EFAULT";
489 #ifdef ENOTBLK
490 case ENOTBLK:
491 return "ENOTBLK";
492 #endif
493 case EBUSY:
494 return "EBUSY";
495 case EEXIST:
496 return "EEXIST";
497 case EXDEV:
498 return "EXDEV";
499 case ENODEV:
500 return "ENODEV";
501 case ENOTDIR:
502 return "ENOTDIR";
503 case EISDIR:
504 return "EISDIR";
505 case EINVAL:
506 return "EINVAL";
507 case ENFILE:
508 return "ENFILE";
509 case EMFILE:
510 return "EMFILE";
511 case ENOTTY:
512 return "ENOTTY";
513 case ETXTBSY:
514 return "ETXTBSY";
515 case EFBIG:
516 return "EFBIG";
517 case ENOSPC:
518 return "ENOSPC";
519 case ESPIPE:
520 return "ESPIPE";
521 case EROFS:
522 return "EROFS";
523 case EMLINK:
524 return "EMLINK";
525 case EPIPE:
526 return "EPIPE";
527 case EDOM:
528 return "EDOM";
529 case ERANGE:
530 return "ERANGE";
531 case EDEADLK:
532 return "EDEADLK";
533 case ENAMETOOLONG:
534 return "ENAMETOOLONG";
535 case ENOLCK:
536 return "ENOLCK";
537 case ENOSYS:
538 return "ENOSYS";
539 case ENOTEMPTY:
540 return "ENOTEMPTY";
541 case ELOOP:
542 return "ELOOP";
543 case ENOMSG:
544 return "ENOMSG";
545 case EIDRM:
546 return "EIDRM";
547 #ifdef ECHRNG
548 case ECHRNG:
549 return "ECHRNG";
550 #endif
551 #ifdef EL2NSYNC
552 case EL2NSYNC:
553 return "EL2NSYNC";
554 #endif
555 #ifdef EL3HLT
556 case EL3HLT:
557 return "EL3HLT";
558 #endif
559 #ifdef EL3RST
560 case EL3RST:
561 return "EL3RST";
562 #endif
563 #ifdef ELNRNG
564 case ELNRNG:
565 return "ELNRNG";
566 #endif
567 #ifdef EUNATCH
568 case EUNATCH:
569 return "EUNATCH";
570 #endif
571 #ifdef ENOCSI
572 case ENOCSI:
573 return "ENOCSI";
574 #endif
575 #ifdef EL2HLT
576 case EL2HLT:
577 return "EL2HLT";
578 #endif
579 #ifdef EBADE
580 case EBADE:
581 return "EBADE";
582 #endif
583 #ifdef EBADR
584 case EBADR:
585 return "EBADR";
586 #endif
587 #ifdef EXFULL
588 case EXFULL:
589 return "EXFULL";
590 #endif
591 #ifdef ENOANO
592 case ENOANO:
593 return "ENOANO";
594 #endif
595 #ifdef EBADRQC
596 case EBADRQC:
597 return "EBADRQC";
598 #endif
599 #ifdef EBADSLT
600 case EBADSLT:
601 return "EBADSLT";
602 #endif
603 #ifdef EBFONT
604 case EBFONT:
605 return "EBFONT";
606 #endif
607 case ENOSTR:
608 return "ENOSTR";
609 case ENODATA:
610 return "ENODATA";
611 case ETIME:
612 return "ETIME";
613 case ENOSR:
614 return "ENOSR";
615 #ifdef ENONET
616 case ENONET:
617 return "ENONET";
618 #endif
619 #ifdef ENOPKG
620 case ENOPKG:
621 return "ENOPKG";
622 #endif
623 #ifdef EREMOTE
624 case EREMOTE:
625 return "EREMOTE";
626 #endif
627 case ENOLINK:
628 return "ENOLINK";
629 #ifdef EADV
630 case EADV:
631 return "EADV";
632 #endif
633 #ifdef ESRMNT
634 case ESRMNT:
635 return "ESRMNT";
636 #endif
637 #ifdef ECOMM
638 case ECOMM:
639 return "ECOMM";
640 #endif
641 case EPROTO:
642 return "EPROTO";
643 case EMULTIHOP:
644 return "EMULTIHOP";
645 #ifdef EDOTDOT
646 case EDOTDOT:
647 return "EDOTDOT";
648 #endif
649 case EBADMSG:
650 return "EBADMSG";
651 case EOVERFLOW:
652 return "EOVERFLOW";
653 #ifdef ENOTUNIQ
654 case ENOTUNIQ:
655 return "ENOTUNIQ";
656 #endif
657 #ifdef EBADFD
658 case EBADFD:
659 return "EBADFD";
660 #endif
661 #ifdef EREMCHG
662 case EREMCHG:
663 return "EREMCHG";
664 #endif
665 #ifdef ELIBACC
666 case ELIBACC:
667 return "ELIBACC";
668 #endif
669 #ifdef ELIBBAD
670 case ELIBBAD:
671 return "ELIBBAD";
672 #endif
673 #ifdef ELIBSCN
674 case ELIBSCN:
675 return "ELIBSCN";
676 #endif
677 #ifdef ELIBMAX
678 case ELIBMAX:
679 return "ELIBMAX";
680 #endif
681 #ifdef ELIBEXEC
682 case ELIBEXEC:
683 return "ELIBEXEC";
684 #endif
685 case EILSEQ:
686 return "EILSEQ";
687 #ifdef ERESTART
688 case ERESTART:
689 return "ERESTART";
690 #endif
691 #ifdef ESTRPIPE
692 case ESTRPIPE:
693 return "ESTRPIPE";
694 #endif
695 #ifdef EUSERS
696 case EUSERS:
697 return "EUSERS";
698 #endif
699 case ENOTSOCK:
700 return "ENOTSOCK";
701 case EDESTADDRREQ:
702 return "EDESTADDRREQ";
703 case EMSGSIZE:
704 return "EMSGSIZE";
705 case EPROTOTYPE:
706 return "EPROTOTYPE";
707 case ENOPROTOOPT:
708 return "ENOPROTOOPT";
709 case EPROTONOSUPPORT:
710 return "EPROTONOSUPPORT";
711 #ifdef ESOCKTNOSUPPORT
712 case ESOCKTNOSUPPORT:
713 return "ESOCKTNOSUPPORT";
714 #endif
715 #ifdef EOPNOTSUPP
716 case EOPNOTSUPP:
717 return "EOPNOTSUPP";
718 #endif
719 case EPFNOSUPPORT:
720 return "EPFNOSUPPORT";
721 case EAFNOSUPPORT:
722 return "EAFNOSUPPORT";
723 case EADDRINUSE:
724 return "EADDRINUSE";
725 case EADDRNOTAVAIL:
726 return "EADDRNOTAVAIL";
727 case ENETDOWN:
728 return "ENETDOWN";
729 case ENETUNREACH:
730 return "ENETUNREACH";
731 case ENETRESET:
732 return "ENETRESET";
733 case ECONNABORTED:
734 return "ECONNABORTED";
735 case ECONNRESET:
736 return "ECONNRESET";
737 case ENOBUFS:
738 return "ENOBUFS";
739 case EISCONN:
740 return "EISCONN";
741 case ENOTCONN:
742 return "ENOTCONN";
743 #ifdef ESHUTDOWN
744 case ESHUTDOWN:
745 return "ESHUTDOWN";
746 #endif
747 #ifdef ETOOMANYREFS
748 case ETOOMANYREFS:
749 return "ETOOMANYREFS";
750 #endif
751 case ETIMEDOUT:
752 return "ETIMEDOUT";
753 case ECONNREFUSED:
754 return "ECONNREFUSED";
755 #ifdef EHOSTDOWN
756 case EHOSTDOWN:
757 return "EHOSTDOWN";
758 #endif
759 case EHOSTUNREACH:
760 return "EHOSTUNREACH";
761 case EALREADY:
762 return "EALREADY";
763 case EINPROGRESS:
764 return "EINPROGRESS";
765 case ESTALE:
766 return "ESTALE";
767 #ifdef EUCLEAN
768 case EUCLEAN:
769 return "EUCLEAN";
770 #endif
771 #ifdef ENOTNAM
772 case ENOTNAM:
773 return "ENOTNAM";
774 #endif
775 #ifdef ENAVAIL
776 case ENAVAIL:
777 return "ENAVAIL";
778 #endif
779 #ifdef EISNAM
780 case EISNAM:
781 return "EISNAM";
782 #endif
783 #ifdef EREMOTEIO
784 case EREMOTEIO:
785 return "EREMOTEIO";
786 #endif
787 case EDQUOT:
788 return "EDQUOT";
789 #ifdef ENOMEDIUM
790 case ENOMEDIUM:
791 return "ENOMEDIUM";
792 #endif
793 #ifdef EMEDIUMTYPE
794 case EMEDIUMTYPE:
795 return "EMEDIUMTYPE";
796 #endif
797 case ECANCELED:
798 return "ECANCELED";
799 #ifdef ENOKEY
800 case ENOKEY:
801 return "ENOKEY";
802 #endif
803 #ifdef EKEYEXPIRED
804 case EKEYEXPIRED:
805 return "EKEYEXPIRED";
806 #endif
807 #ifdef EKEYREVOKED
808 case EKEYREVOKED:
809 return "EKEYREVOKED";
810 #endif
811 #ifdef EKEYREJECTED
812 case EKEYREJECTED:
813 return "EKEYREJECTED";
814 #endif
815 #ifdef EOWNERDEAD
816 case EOWNERDEAD:
817 return "EOWNERDEAD";
818 #endif
819 #ifdef ENOTRECOVERABLE
820 case ENOTRECOVERABLE:
821 return "ENOTRECOVERABLE";
822 #endif
823 #ifdef ERFKILL
824 case ERFKILL:
825 return "ERFKILL";
826 #endif
827 #ifdef EHWPOISON
828 case EHWPOISON:
829 return "EHWPOISON";
830 #endif
831 #ifdef EPROCLIM
832 case EPROCLIM:
833 return "EPROCLIM";
834 #endif
835 #ifdef EBADRPC
836 case EBADRPC:
837 return "EBADRPC";
838 #endif
839 #ifdef ERPCMISMATCH
840 case ERPCMISMATCH:
841 return "ERPCMISMATCH";
842 #endif
843 #ifdef EPROGUNAVAIL
844 case EPROGUNAVAIL:
845 return "EPROGUNAVAIL";
846 #endif
847 #ifdef EPROGMISMATCH
848 case EPROGMISMATCH:
849 return "EPROGMISMATCH";
850 #endif
851 #ifdef EPROCUNAVAIL
852 case EPROCUNAVAIL:
853 return "EPROCUNAVAIL";
854 #endif
855 #ifdef EFTYPE
856 case EFTYPE:
857 return "EFTYPE";
858 #endif
859 #ifdef EAUTH
860 case EAUTH:
861 return "EAUTH";
862 #endif
863 #ifdef ENEEDAUTH
864 case ENEEDAUTH:
865 return "ENEEDAUTH";
866 #endif
867 #ifdef EPWROFF
868 case EPWROFF:
869 return "EPWROFF";
870 #endif
871 #ifdef EDEVERR
872 case EDEVERR:
873 return "EDEVERR";
874 #endif
875 #ifdef EBADEXEC
876 case EBADEXEC:
877 return "EBADEXEC";
878 #endif
879 #ifdef EBADARCH
880 case EBADARCH:
881 return "EBADARCH";
882 #endif
883 #ifdef ESHLIBVERS
884 case ESHLIBVERS:
885 return "ESHLIBVERS";
886 #endif
887 #ifdef EBADMACHO
888 case EBADMACHO:
889 return "EBADMACHO";
890 #endif
891 #ifdef ENOATTR
892 case ENOATTR:
893 return "ENOATTR";
894 #endif
895 #ifdef EQFULL
896 case EQFULL:
897 return "EQFULL";
898 #endif
899 default:
900 char* str = strerror(nErrno);
901 return std::to_string(nErrno) + " (" + std::string(str) + ")";
905 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */