diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h index 2cc9a5dbfb..c3526144c9 100644 --- a/hw/9pfs/9p-util.h +++ b/hw/9pfs/9p-util.h @@ -58,6 +58,36 @@ static inline uint64_t host_dev_to_dotl_dev(dev_t 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) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 4a296a0b94..0cd0c14c2a 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -1054,6 +1054,8 @@ static void coroutine_fn pdu_complete(V9fsPDU *pdu, ssize_t len) } len += ret; id = P9_RERROR; + } else { + err = errno_to_dotl(err); } ret = pdu_marshal(pdu, len, "d", err);