tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / sal / osl / unx / uunxapi.cxx
blob37db3c98731530297213ed23c1bf60f6c8e2cfa7
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 #include <sys/stat.h>
35 #include <unistd.h>
36 #include <fcntl.h>
37 #include <utime.h>
39 #ifdef ANDROID
40 #include <osl/detail/android-bootstrap.h>
41 #endif
43 OString osl::OUStringToOString(std::u16string_view s)
45 return rtl::OUStringToOString(s, osl_getThreadTextEncoding());
48 #if HAVE_FEATURE_MACOSX_SANDBOX
50 #include <Foundation/Foundation.h>
51 #include <Security/Security.h>
52 #include <mach-o/dyld.h>
54 static NSUserDefaults *userDefaults = NULL;
55 static bool isSandboxed = false;
57 static void do_once()
59 SecCodeRef code;
60 OSStatus rc = SecCodeCopySelf(kSecCSDefaultFlags, &code);
62 SecStaticCodeRef staticCode;
63 if (rc == errSecSuccess)
64 rc = SecCodeCopyStaticCode(code, kSecCSDefaultFlags, &staticCode);
66 CFDictionaryRef signingInformation;
67 if (rc == errSecSuccess)
68 rc = SecCodeCopySigningInformation(staticCode, kSecCSRequirementInformation, &signingInformation);
70 CFDictionaryRef entitlements = NULL;
71 if (rc == errSecSuccess)
72 entitlements = (CFDictionaryRef) CFDictionaryGetValue(signingInformation, kSecCodeInfoEntitlementsDict);
74 if (entitlements != NULL)
75 if (CFDictionaryGetValue(entitlements, CFSTR("com.apple.security.app-sandbox")) != NULL)
76 isSandboxed = true;
78 if (isSandboxed)
79 userDefaults = [NSUserDefaults standardUserDefaults];
82 typedef struct {
83 NSURL *scopeURL;
84 NSAutoreleasePool *pool;
85 } accessFilePathState;
87 static accessFilePathState *
88 prepare_to_access_file_path( const char *cpFilePath )
90 static pthread_once_t once = PTHREAD_ONCE_INIT;
91 pthread_once(&once, &do_once);
92 NSURL *fileURL = nil;
93 NSData *data = nil;
94 BOOL stale;
95 accessFilePathState *state;
97 if (!isSandboxed)
98 return NULL;
100 // If malloc() fails we are screwed anyway
101 state = (accessFilePathState*) malloc(sizeof(accessFilePathState));
103 state->pool = [[NSAutoreleasePool alloc] init];
104 state->scopeURL = nil;
106 if (userDefaults != nil)
107 fileURL = [NSURL fileURLWithPath:[NSString stringWithUTF8String:cpFilePath]];
109 if (fileURL != nil)
110 data = [userDefaults dataForKey:[@"bookmarkFor:" stringByAppendingString:[fileURL absoluteString]]];
112 if (data != nil)
113 state->scopeURL = [NSURL URLByResolvingBookmarkData:data
114 options:NSURLBookmarkResolutionWithSecurityScope
115 relativeToURL:nil
116 bookmarkDataIsStale:&stale
117 error:nil];
118 if (state->scopeURL != nil)
119 [state->scopeURL startAccessingSecurityScopedResource];
121 return state;
124 static void
125 done_accessing_file_path( const char * /*cpFilePath*/, accessFilePathState *state )
127 if (!isSandboxed)
128 return;
130 int saved_errno = errno;
132 if (state->scopeURL != nil)
133 [state->scopeURL stopAccessingSecurityScopedResource];
134 [state->pool release];
135 free(state);
137 errno = saved_errno;
140 #else
142 typedef void accessFilePathState;
144 #define prepare_to_access_file_path( cpFilePath ) nullptr
146 #define done_accessing_file_path( cpFilePath, state ) ((void) cpFilePath, (void) state)
148 #endif
150 #ifdef MACOSX
152 * Helper function for resolving Mac native alias files (not the same as unix alias files)
153 * and to return the resolved alias as OString
155 static OString macxp_resolveAliasAndConvert(OString const & p)
157 char path[PATH_MAX];
158 if (p.getLength() < PATH_MAX)
160 strcpy(path, p.getStr());
161 macxp_resolveAlias(path, PATH_MAX);
162 return path;
164 return p;
166 #endif /* MACOSX */
168 int osl::access(const OString& pstrPath, int mode)
170 OString fn = pstrPath;
171 #ifdef ANDROID
172 if (fn == "/assets" || fn.startsWith("/assets/"))
174 struct stat stat;
175 if (lo_apk_lstat(fn.getStr(), &stat) == -1)
176 return -1;
177 if (mode & W_OK)
179 errno = EACCES;
180 return -1;
182 return 0;
184 #endif
186 #ifdef MACOSX
187 fn = macxp_resolveAliasAndConvert(fn);
188 #endif
190 accessFilePathState *state = prepare_to_access_file_path(fn.getStr());
192 int result = ::access(fn.getStr(), mode);
193 int saved_errno = errno;
194 if (result == -1)
195 SAL_INFO("sal.file", "access(" << fn << ",0" << std::oct << mode << std::dec << "): " << UnixErrnoString(saved_errno));
196 else
197 SAL_INFO("sal.file", "access(" << fn << ",0" << std::oct << mode << std::dec << "): OK");
199 done_accessing_file_path(fn.getStr(), state);
201 errno = saved_errno;
203 return result;
206 namespace {
208 OString toOString(OString const & s) { return s; }
210 OString toOString(std::u16string_view s) { return osl::OUStringToOString(s); }
212 template<typename T> T fromOString(OString const &) = delete;
214 template<> OString fromOString(OString const & s) { return s; }
216 template<> OUString fromOString(OString const & s)
217 { return OStringToOUString(s, osl_getThreadTextEncoding()); }
219 template<typename T> bool realpath_(const T& pstrFileName, T& ppstrResolvedName)
221 OString fn = toOString(pstrFileName);
222 #if defined ANDROID || defined(EMSCRIPTEN)
223 #if defined ANDROID
224 if (fn == "/assets" || fn.startsWith("/assets/"))
225 #else
226 if (fn == "/instdir" || fn.startsWith("/instdir/"))
227 #endif
229 if (osl::access(fn, F_OK) == -1)
230 return false;
232 ppstrResolvedName = pstrFileName;
234 return true;
236 #endif // ANDROID || EMSCRIPTEN
238 #ifdef MACOSX
239 fn = macxp_resolveAliasAndConvert(fn);
240 #endif
242 accessFilePathState *state = prepare_to_access_file_path(fn.getStr());
244 char rp[PATH_MAX];
245 bool bRet = realpath(fn.getStr(), rp);
246 int saved_errno = errno;
247 if (!bRet)
248 SAL_INFO("sal.file", "realpath(" << fn << "): " << UnixErrnoString(saved_errno));
249 else
250 SAL_INFO("sal.file", "realpath(" << fn << "): OK");
252 done_accessing_file_path(fn.getStr(), state);
254 if (bRet)
256 ppstrResolvedName = fromOString<T>(OString(rp));
259 errno = saved_errno;
261 return bRet;
266 bool osl::realpath(const OUString& pustrFileName, OUString& ppustrResolvedName)
268 return realpath_(pustrFileName, ppustrResolvedName);
271 bool osl::realpath(const OString& pstrFileName, OString& ppstrResolvedName)
273 return realpath_(pstrFileName, ppstrResolvedName);
276 int stat_c(const char* cpPath, struct stat* buf)
278 #ifdef ANDROID
279 if (strncmp(cpPath, "/assets", sizeof("/assets")-1) == 0 &&
280 (cpPath[sizeof("/assets")-1] == '\0' ||
281 cpPath[sizeof("/assets")-1] == '/'))
282 return lo_apk_lstat(cpPath, buf);
283 #endif
285 accessFilePathState *state = prepare_to_access_file_path(cpPath);
287 int result = stat(cpPath, buf);
288 int saved_errno = errno;
289 if (result == -1)
290 SAL_INFO("sal.file", "stat(" << cpPath << "): " << UnixErrnoString(saved_errno));
291 else
292 SAL_INFO("sal.file", "stat(" << cpPath << "): OK");
294 done_accessing_file_path(cpPath, state);
296 errno = saved_errno;
298 return result;
301 int lstat_c(const char* cpPath, struct stat* buf)
303 #ifdef ANDROID
304 if (strncmp(cpPath, "/assets", sizeof("/assets")-1) == 0 &&
305 (cpPath[sizeof("/assets")-1] == '\0' ||
306 cpPath[sizeof("/assets")-1] == '/'))
307 return lo_apk_lstat(cpPath, buf);
308 #endif
310 accessFilePathState *state = prepare_to_access_file_path(cpPath);
312 int result = lstat(cpPath, buf);
313 int saved_errno = errno;
314 if (result == -1)
315 SAL_INFO("sal.file", "lstat(" << cpPath << "): " << UnixErrnoString(saved_errno));
316 else
317 SAL_INFO("sal.file", "lstat(" << cpPath << "): OK");
319 done_accessing_file_path(cpPath, state);
321 errno = saved_errno;
323 return result;
326 namespace {
328 template<typename T> int lstat_(const T& pstrPath, struct stat& buf)
330 OString fn = toOString(pstrPath);
332 #ifdef MACOSX
333 fn = macxp_resolveAliasAndConvert(fn);
334 #endif
336 return lstat_c(fn.getStr(), &buf);
341 int osl::lstat(const OUString& pustrPath, struct stat& buf)
343 return lstat_(pustrPath, buf);
346 int osl::lstat(const OString& pstrPath, struct stat& buf)
348 return lstat_(pstrPath, buf);
351 int osl::mkdir(const OString& path, mode_t mode)
353 accessFilePathState *state = prepare_to_access_file_path(path.getStr());
355 int result = ::mkdir(path.getStr(), mode);
356 int saved_errno = errno;
357 if (result == -1)
358 SAL_INFO("sal.file", "mkdir(" << path << ",0" << std::oct << mode << std::dec << "): " << UnixErrnoString(saved_errno));
359 else
360 SAL_INFO("sal.file", "mkdir(" << path << ",0" << std::oct << mode << std::dec << "): OK");
362 done_accessing_file_path(path.getStr(), state);
364 errno = saved_errno;
366 return result;
369 int open_c(const OString& path, int oflag, int mode)
371 accessFilePathState *state = prepare_to_access_file_path(path.getStr());
373 int result = open(path.getStr(), oflag, mode);
374 int saved_errno = errno;
375 if (result == -1)
376 SAL_INFO("sal.file", "open(" << path << ",0" << std::oct << oflag << ",0" << mode << std::dec << "): " << UnixErrnoString(saved_errno));
377 else
378 SAL_INFO("sal.file", "open(" << path << ",0" << std::oct << oflag << ",0" << mode << std::dec << ") => " << result);
380 #if HAVE_FEATURE_MACOSX_SANDBOX
381 if (isSandboxed && result != -1 && (oflag & O_CREAT) && (oflag & O_EXCL))
383 // A new file was created. Check if it is outside the sandbox.
384 // (In that case it must be one the user selected as export or
385 // save destination in a file dialog, otherwise we wouldn't
386 // have been able to create it.) Create and store a security
387 // scoped bookmark for it so that we can access the file in
388 // the future, too. (For the "Recent Files" functionality.)
389 const char *sandbox = [NSHomeDirectory() UTF8String];
390 if (!(strncmp(sandbox, path.getStr(), strlen(sandbox)) == 0 &&
391 path[strlen(sandbox)] == '/'))
393 auto cpPath = path.getStr();
394 NSURL *url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:cpPath]];
395 NSData *data = [url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
396 includingResourceValuesForKeys:nil
397 relativeToURL:nil
398 error:nil];
399 if (data != NULL)
401 [userDefaults setObject:data
402 forKey:[@"bookmarkFor:" stringByAppendingString:[url absoluteString]]];
406 #endif
408 done_accessing_file_path(path.getStr(), state);
410 errno = saved_errno;
412 return result;
415 int utime_c(const char *cpPath, struct utimbuf *times)
417 accessFilePathState *state = prepare_to_access_file_path(cpPath);
419 int result = utime(cpPath, times);
421 done_accessing_file_path(cpPath, state);
423 return result;
426 int ftruncate_with_name(int fd, sal_uInt64 uSize, const OString& path)
428 /* When sandboxed on macOS, ftruncate(), even if it takes an
429 * already open file descriptor which was returned from an open()
430 * call already checked by the sandbox, still requires a security
431 * scope bookmark for the file to be active in case the file is
432 * one that the sandbox doesn't otherwise allow access to. Luckily
433 * LibreOffice usually calls ftruncate() through the helpful C++
434 * abstraction layer that keeps the pathname around.
437 OString fn(path);
439 #ifdef MACOSX
440 fn = macxp_resolveAliasAndConvert(fn);
441 #endif
443 accessFilePathState *state = prepare_to_access_file_path(fn.getStr());
445 int result = ftruncate(fd, uSize);
446 int saved_errno = errno;
447 if (result < 0)
448 SAL_INFO("sal.file", "ftruncate(" << fd << "," << uSize << "): " << UnixErrnoString(saved_errno));
449 else
450 SAL_INFO("sal.file", "ftruncate(" << fd << "," << uSize << "): OK");
452 done_accessing_file_path(fn.getStr(), state);
454 errno = saved_errno;
456 return result;
460 std::string UnixErrnoString(int nErrno)
462 // Errnos from <asm-generic/errno-base.h> and <asm-generic/errno.h> on Linux and <sys/errno.h>
463 // on macOS.
464 switch (nErrno)
466 case EPERM:
467 return "EPERM";
468 case ENOENT:
469 return "ENOENT";
470 case ESRCH:
471 return "ESRCH";
472 case EINTR:
473 return "EINTR";
474 case EIO:
475 return "EIO";
476 case ENXIO:
477 return "ENXIO";
478 case E2BIG:
479 return "E2BIG";
480 case ENOEXEC:
481 return "ENOEXEC";
482 case EBADF:
483 return "EBADF";
484 case ECHILD:
485 return "ECHILD";
486 case EAGAIN:
487 return "EAGAIN";
488 case ENOMEM:
489 return "ENOMEM";
490 case EACCES:
491 return "EACCES";
492 case EFAULT:
493 return "EFAULT";
494 #ifdef ENOTBLK
495 case ENOTBLK:
496 return "ENOTBLK";
497 #endif
498 case EBUSY:
499 return "EBUSY";
500 case EEXIST:
501 return "EEXIST";
502 case EXDEV:
503 return "EXDEV";
504 case ENODEV:
505 return "ENODEV";
506 case ENOTDIR:
507 return "ENOTDIR";
508 case EISDIR:
509 return "EISDIR";
510 case EINVAL:
511 return "EINVAL";
512 case ENFILE:
513 return "ENFILE";
514 case EMFILE:
515 return "EMFILE";
516 case ENOTTY:
517 return "ENOTTY";
518 case ETXTBSY:
519 return "ETXTBSY";
520 case EFBIG:
521 return "EFBIG";
522 case ENOSPC:
523 return "ENOSPC";
524 case ESPIPE:
525 return "ESPIPE";
526 case EROFS:
527 return "EROFS";
528 case EMLINK:
529 return "EMLINK";
530 case EPIPE:
531 return "EPIPE";
532 case EDOM:
533 return "EDOM";
534 case ERANGE:
535 return "ERANGE";
536 case EDEADLK:
537 return "EDEADLK";
538 case ENAMETOOLONG:
539 return "ENAMETOOLONG";
540 case ENOLCK:
541 return "ENOLCK";
542 case ENOSYS:
543 return "ENOSYS";
544 case ENOTEMPTY:
545 return "ENOTEMPTY";
546 case ELOOP:
547 return "ELOOP";
548 case ENOMSG:
549 return "ENOMSG";
550 case EIDRM:
551 return "EIDRM";
552 #ifdef ECHRNG
553 case ECHRNG:
554 return "ECHRNG";
555 #endif
556 #ifdef EL2NSYNC
557 case EL2NSYNC:
558 return "EL2NSYNC";
559 #endif
560 #ifdef EL3HLT
561 case EL3HLT:
562 return "EL3HLT";
563 #endif
564 #ifdef EL3RST
565 case EL3RST:
566 return "EL3RST";
567 #endif
568 #ifdef ELNRNG
569 case ELNRNG:
570 return "ELNRNG";
571 #endif
572 #ifdef EUNATCH
573 case EUNATCH:
574 return "EUNATCH";
575 #endif
576 #ifdef ENOCSI
577 case ENOCSI:
578 return "ENOCSI";
579 #endif
580 #ifdef EL2HLT
581 case EL2HLT:
582 return "EL2HLT";
583 #endif
584 #ifdef EBADE
585 case EBADE:
586 return "EBADE";
587 #endif
588 #ifdef EBADR
589 case EBADR:
590 return "EBADR";
591 #endif
592 #ifdef EXFULL
593 case EXFULL:
594 return "EXFULL";
595 #endif
596 #ifdef ENOANO
597 case ENOANO:
598 return "ENOANO";
599 #endif
600 #ifdef EBADRQC
601 case EBADRQC:
602 return "EBADRQC";
603 #endif
604 #ifdef EBADSLT
605 case EBADSLT:
606 return "EBADSLT";
607 #endif
608 #ifdef EBFONT
609 case EBFONT:
610 return "EBFONT";
611 #endif
612 #if defined __clang__
613 #if __has_warning("-Wdeprecated-pragma")
614 #pragma clang diagnostic push
615 #pragma clang diagnostic ignored "-Wdeprecated-pragma"
616 #endif
617 #endif
618 case ENOSTR:
619 #if defined __clang__
620 #if __has_warning("-Wdeprecated-pragma")
621 #pragma clang diagnostic push
622 #endif
623 #endif
624 return "ENOSTR";
625 #if defined __clang__
626 #if __has_warning("-Wdeprecated-pragma")
627 #pragma clang diagnostic push
628 #pragma clang diagnostic ignored "-Wdeprecated-pragma"
629 #endif
630 #endif
631 case ENODATA:
632 #if defined __clang__
633 #if __has_warning("-Wdeprecated-pragma")
634 #pragma clang diagnostic push
635 #endif
636 #endif
637 return "ENODATA";
638 #if defined __clang__
639 #if __has_warning("-Wdeprecated-pragma")
640 #pragma clang diagnostic push
641 #pragma clang diagnostic ignored "-Wdeprecated-pragma"
642 #endif
643 #endif
644 case ETIME:
645 #if defined __clang__
646 #if __has_warning("-Wdeprecated-pragma")
647 #pragma clang diagnostic push
648 #endif
649 #endif
650 return "ETIME";
651 #if defined __clang__
652 #if __has_warning("-Wdeprecated-pragma")
653 #pragma clang diagnostic push
654 #pragma clang diagnostic ignored "-Wdeprecated-pragma"
655 #endif
656 #endif
657 case ENOSR:
658 #if defined __clang__
659 #if __has_warning("-Wdeprecated-pragma")
660 #pragma clang diagnostic push
661 #endif
662 #endif
663 return "ENOSR";
664 #ifdef ENONET
665 case ENONET:
666 return "ENONET";
667 #endif
668 #ifdef ENOPKG
669 case ENOPKG:
670 return "ENOPKG";
671 #endif
672 #ifdef EREMOTE
673 case EREMOTE:
674 return "EREMOTE";
675 #endif
676 case ENOLINK:
677 return "ENOLINK";
678 #ifdef EADV
679 case EADV:
680 return "EADV";
681 #endif
682 #ifdef ESRMNT
683 case ESRMNT:
684 return "ESRMNT";
685 #endif
686 #ifdef ECOMM
687 case ECOMM:
688 return "ECOMM";
689 #endif
690 case EPROTO:
691 return "EPROTO";
692 case EMULTIHOP:
693 return "EMULTIHOP";
694 #ifdef EDOTDOT
695 case EDOTDOT:
696 return "EDOTDOT";
697 #endif
698 case EBADMSG:
699 return "EBADMSG";
700 case EOVERFLOW:
701 return "EOVERFLOW";
702 #ifdef ENOTUNIQ
703 case ENOTUNIQ:
704 return "ENOTUNIQ";
705 #endif
706 #ifdef EBADFD
707 case EBADFD:
708 return "EBADFD";
709 #endif
710 #ifdef EREMCHG
711 case EREMCHG:
712 return "EREMCHG";
713 #endif
714 #ifdef ELIBACC
715 case ELIBACC:
716 return "ELIBACC";
717 #endif
718 #ifdef ELIBBAD
719 case ELIBBAD:
720 return "ELIBBAD";
721 #endif
722 #ifdef ELIBSCN
723 case ELIBSCN:
724 return "ELIBSCN";
725 #endif
726 #ifdef ELIBMAX
727 case ELIBMAX:
728 return "ELIBMAX";
729 #endif
730 #ifdef ELIBEXEC
731 case ELIBEXEC:
732 return "ELIBEXEC";
733 #endif
734 case EILSEQ:
735 return "EILSEQ";
736 #ifdef ERESTART
737 case ERESTART:
738 return "ERESTART";
739 #endif
740 #ifdef ESTRPIPE
741 case ESTRPIPE:
742 return "ESTRPIPE";
743 #endif
744 #ifdef EUSERS
745 case EUSERS:
746 return "EUSERS";
747 #endif
748 case ENOTSOCK:
749 return "ENOTSOCK";
750 case EDESTADDRREQ:
751 return "EDESTADDRREQ";
752 case EMSGSIZE:
753 return "EMSGSIZE";
754 case EPROTOTYPE:
755 return "EPROTOTYPE";
756 case ENOPROTOOPT:
757 return "ENOPROTOOPT";
758 case EPROTONOSUPPORT:
759 return "EPROTONOSUPPORT";
760 #ifdef ESOCKTNOSUPPORT
761 case ESOCKTNOSUPPORT:
762 return "ESOCKTNOSUPPORT";
763 #endif
764 #ifdef EOPNOTSUPP
765 case EOPNOTSUPP:
766 return "EOPNOTSUPP";
767 #endif
768 case EPFNOSUPPORT:
769 return "EPFNOSUPPORT";
770 case EAFNOSUPPORT:
771 return "EAFNOSUPPORT";
772 case EADDRINUSE:
773 return "EADDRINUSE";
774 case EADDRNOTAVAIL:
775 return "EADDRNOTAVAIL";
776 case ENETDOWN:
777 return "ENETDOWN";
778 case ENETUNREACH:
779 return "ENETUNREACH";
780 case ENETRESET:
781 return "ENETRESET";
782 case ECONNABORTED:
783 return "ECONNABORTED";
784 case ECONNRESET:
785 return "ECONNRESET";
786 case ENOBUFS:
787 return "ENOBUFS";
788 case EISCONN:
789 return "EISCONN";
790 case ENOTCONN:
791 return "ENOTCONN";
792 #ifdef ESHUTDOWN
793 case ESHUTDOWN:
794 return "ESHUTDOWN";
795 #endif
796 #ifdef ETOOMANYREFS
797 case ETOOMANYREFS:
798 return "ETOOMANYREFS";
799 #endif
800 case ETIMEDOUT:
801 return "ETIMEDOUT";
802 case ECONNREFUSED:
803 return "ECONNREFUSED";
804 #ifdef EHOSTDOWN
805 case EHOSTDOWN:
806 return "EHOSTDOWN";
807 #endif
808 case EHOSTUNREACH:
809 return "EHOSTUNREACH";
810 case EALREADY:
811 return "EALREADY";
812 case EINPROGRESS:
813 return "EINPROGRESS";
814 case ESTALE:
815 return "ESTALE";
816 #ifdef EUCLEAN
817 case EUCLEAN:
818 return "EUCLEAN";
819 #endif
820 #ifdef ENOTNAM
821 case ENOTNAM:
822 return "ENOTNAM";
823 #endif
824 #ifdef ENAVAIL
825 case ENAVAIL:
826 return "ENAVAIL";
827 #endif
828 #ifdef EISNAM
829 case EISNAM:
830 return "EISNAM";
831 #endif
832 #ifdef EREMOTEIO
833 case EREMOTEIO:
834 return "EREMOTEIO";
835 #endif
836 case EDQUOT:
837 return "EDQUOT";
838 #ifdef ENOMEDIUM
839 case ENOMEDIUM:
840 return "ENOMEDIUM";
841 #endif
842 #ifdef EMEDIUMTYPE
843 case EMEDIUMTYPE:
844 return "EMEDIUMTYPE";
845 #endif
846 case ECANCELED:
847 return "ECANCELED";
848 #ifdef ENOKEY
849 case ENOKEY:
850 return "ENOKEY";
851 #endif
852 #ifdef EKEYEXPIRED
853 case EKEYEXPIRED:
854 return "EKEYEXPIRED";
855 #endif
856 #ifdef EKEYREVOKED
857 case EKEYREVOKED:
858 return "EKEYREVOKED";
859 #endif
860 #ifdef EKEYREJECTED
861 case EKEYREJECTED:
862 return "EKEYREJECTED";
863 #endif
864 #ifdef EOWNERDEAD
865 case EOWNERDEAD:
866 return "EOWNERDEAD";
867 #endif
868 #ifdef ENOTRECOVERABLE
869 case ENOTRECOVERABLE:
870 return "ENOTRECOVERABLE";
871 #endif
872 #ifdef ERFKILL
873 case ERFKILL:
874 return "ERFKILL";
875 #endif
876 #ifdef EHWPOISON
877 case EHWPOISON:
878 return "EHWPOISON";
879 #endif
880 #ifdef EPROCLIM
881 case EPROCLIM:
882 return "EPROCLIM";
883 #endif
884 #ifdef EBADRPC
885 case EBADRPC:
886 return "EBADRPC";
887 #endif
888 #ifdef ERPCMISMATCH
889 case ERPCMISMATCH:
890 return "ERPCMISMATCH";
891 #endif
892 #ifdef EPROGUNAVAIL
893 case EPROGUNAVAIL:
894 return "EPROGUNAVAIL";
895 #endif
896 #ifdef EPROGMISMATCH
897 case EPROGMISMATCH:
898 return "EPROGMISMATCH";
899 #endif
900 #ifdef EPROCUNAVAIL
901 case EPROCUNAVAIL:
902 return "EPROCUNAVAIL";
903 #endif
904 #ifdef EFTYPE
905 case EFTYPE:
906 return "EFTYPE";
907 #endif
908 #ifdef EAUTH
909 case EAUTH:
910 return "EAUTH";
911 #endif
912 #ifdef ENEEDAUTH
913 case ENEEDAUTH:
914 return "ENEEDAUTH";
915 #endif
916 #ifdef EPWROFF
917 case EPWROFF:
918 return "EPWROFF";
919 #endif
920 #ifdef EDEVERR
921 case EDEVERR:
922 return "EDEVERR";
923 #endif
924 #ifdef EBADEXEC
925 case EBADEXEC:
926 return "EBADEXEC";
927 #endif
928 #ifdef EBADARCH
929 case EBADARCH:
930 return "EBADARCH";
931 #endif
932 #ifdef ESHLIBVERS
933 case ESHLIBVERS:
934 return "ESHLIBVERS";
935 #endif
936 #ifdef EBADMACHO
937 case EBADMACHO:
938 return "EBADMACHO";
939 #endif
940 #ifdef ENOATTR
941 case ENOATTR:
942 return "ENOATTR";
943 #endif
944 #ifdef EQFULL
945 case EQFULL:
946 return "EQFULL";
947 #endif
948 default:
949 char* str = strerror(nErrno);
950 return std::to_string(nErrno) + " (" + std::string(str) + ")";
954 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */