|
@@ -19,6 +19,75 @@
|
|
|
#define O_PATH_9P_UTIL 0
|
|
|
#endif
|
|
|
|
|
|
+#if !defined(CONFIG_LINUX)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Generates a Linux device number (a.k.a. dev_t) for given device major
|
|
|
+ * and minor numbers.
|
|
|
+ *
|
|
|
+ * To be more precise: it generates a device number in glibc's format
|
|
|
+ * (MMMM_Mmmm_mmmM_MMmm, 64 bits) actually, which is compatible with
|
|
|
+ * Linux's format (mmmM_MMmm, 32 bits), as described in <bits/sysmacros.h>.
|
|
|
+ */
|
|
|
+static inline uint64_t makedev_dotl(uint32_t dev_major, uint32_t dev_minor)
|
|
|
+{
|
|
|
+ uint64_t dev;
|
|
|
+
|
|
|
+ // from glibc sysmacros.h:
|
|
|
+ dev = (((uint64_t) (dev_major & 0x00000fffu)) << 8);
|
|
|
+ dev |= (((uint64_t) (dev_major & 0xfffff000u)) << 32);
|
|
|
+ dev |= (((uint64_t) (dev_minor & 0x000000ffu)) << 0);
|
|
|
+ dev |= (((uint64_t) (dev_minor & 0xffffff00u)) << 12);
|
|
|
+ return dev;
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
+/*
|
|
|
+ * Converts given device number from host's device number format to Linux
|
|
|
+ * device number format. As both the size of type dev_t and encoding of
|
|
|
+ * dev_t is system dependant, we have to convert them for Linux guests if
|
|
|
+ * host is not running Linux.
|
|
|
+ */
|
|
|
+static inline uint64_t host_dev_to_dotl_dev(dev_t dev)
|
|
|
+{
|
|
|
+#ifdef CONFIG_LINUX
|
|
|
+ return dev;
|
|
|
+#else
|
|
|
+ return makedev_dotl(major(dev), minor(dev));
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+/* Translates errno from host -> Linux if needed */
|
|
|
+static inline int errno_to_dotl(int err) {
|
|
|
+#if defined(CONFIG_LINUX)
|
|
|
+ /* nothing to translate (Linux -> Linux) */
|
|
|
+#elif defined(CONFIG_DARWIN)
|
|
|
+ /*
|
|
|
+ * translation mandatory for macOS hosts
|
|
|
+ *
|
|
|
+ * FIXME: Only most important errnos translated here yet, this should be
|
|
|
+ * extended to as many errnos being translated as possible in future.
|
|
|
+ */
|
|
|
+ if (err == ENAMETOOLONG) {
|
|
|
+ err = 36; /* ==ENAMETOOLONG on Linux */
|
|
|
+ } else if (err == ENOTEMPTY) {
|
|
|
+ err = 39; /* ==ENOTEMPTY on Linux */
|
|
|
+ } else if (err == ELOOP) {
|
|
|
+ err = 40; /* ==ELOOP on Linux */
|
|
|
+ } else if (err == ENOATTR) {
|
|
|
+ err = 61; /* ==ENODATA on Linux */
|
|
|
+ } else if (err == ENOTSUP) {
|
|
|
+ err = 95; /* ==EOPNOTSUPP on Linux */
|
|
|
+ } else if (err == EOPNOTSUPP) {
|
|
|
+ err = 95; /* ==EOPNOTSUPP on Linux */
|
|
|
+ }
|
|
|
+#else
|
|
|
+#error Missing errno translation to Linux for this host system
|
|
|
+#endif
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
#ifdef CONFIG_DARWIN
|
|
|
#define qemu_fgetxattr(...) fgetxattr(__VA_ARGS__, 0, 0)
|
|
|
#define qemu_lgetxattr(...) getxattr(__VA_ARGS__, 0, XATTR_NOFOLLOW)
|