From f725612b054c0098e846b912f4f0748e25760858 Mon Sep 17 00:00:00 2001 From: klausholstjacobsen Date: Fri, 28 Jul 2023 11:48:54 +0200 Subject: [PATCH] QNX 7.0 support for 2.76.1 and forward --- recipes/glib/all/conandata.yml | 64 ++ recipes/glib/all/conanfile.py | 30 +- .../patches/0002-2.76.x-qnx_meson_build.patch | 14 + .../patches/0002-2.77.0-qnx_meson_build.patch | 14 + .../patches/0003-2.76.x-glocalfile_c.patch | 20 + .../patches/0003-2.77.0-glocalfile_c.patch | 20 + recipes/glib/all/patches/0004-qnx700_h.patch | 115 ++++ recipes/glib/all/patches/0005-qnx700_c.patch | 575 ++++++++++++++++++ .../patches/0006-2.76.x-build_qnx700_c.patch | 13 + .../patches/0006-2.77.0-build_qnx700_c.patch | 13 + 10 files changed, 875 insertions(+), 3 deletions(-) create mode 100644 recipes/glib/all/patches/0002-2.76.x-qnx_meson_build.patch create mode 100644 recipes/glib/all/patches/0002-2.77.0-qnx_meson_build.patch create mode 100644 recipes/glib/all/patches/0003-2.76.x-glocalfile_c.patch create mode 100644 recipes/glib/all/patches/0003-2.77.0-glocalfile_c.patch create mode 100644 recipes/glib/all/patches/0004-qnx700_h.patch create mode 100644 recipes/glib/all/patches/0005-qnx700_c.patch create mode 100644 recipes/glib/all/patches/0006-2.76.x-build_qnx700_c.patch create mode 100644 recipes/glib/all/patches/0006-2.77.0-build_qnx700_c.patch diff --git a/recipes/glib/all/conandata.yml b/recipes/glib/all/conandata.yml index a457da4866ed6c..2a300a10929622 100644 --- a/recipes/glib/all/conandata.yml +++ b/recipes/glib/all/conandata.yml @@ -41,3 +41,67 @@ patches: patch_type: bugfix patch_description: fix for clang compilation patch_source: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2898 + "2.76.1": + - patch_file: "patches/0002-2.76.x-qnx_meson_build.patch" + patch_type: portability + patch_description: Adding qnx version to defines + - patch_file: "patches/0003-2.76.x-glocalfile_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir include header + - patch_file: "patches/0004-qnx700_h.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir header file + - patch_file: "patches/0005-qnx700_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir source file + - patch_file: "patches/0006-2.76.x-build_qnx700_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir build source + "2.76.2": + - patch_file: "patches/0002-2.76.x-qnx_meson_build.patch" + patch_type: portability + patch_description: Adding qnx version to defines + - patch_file: "patches/0003-2.76.x-glocalfile_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir include header + - patch_file: "patches/0004-qnx700_h.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir header file + - patch_file: "patches/0005-qnx700_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir source file + - patch_file: "patches/0006-2.76.x-build_qnx700_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir build source + "2.76.3": + - patch_file: "patches/0002-2.76.x-qnx_meson_build.patch" + patch_type: portability + patch_description: Adding qnx version to defines + - patch_file: "patches/0003-2.76.x-glocalfile_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir + - patch_file: "patches/0004-qnx700_h.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir + - patch_file: "patches/0005-qnx700_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir + - patch_file: "patches/0006-2.76.x-build_qnx700_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir + "2.77.0": + - patch_file: "patches/0002-2.77.0-qnx_meson_build.patch" + patch_type: portability + patch_description: Adding qnx version to defines + - patch_file: "patches/0003-2.77.0-glocalfile_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir + - patch_file: "patches/0004-qnx700_h.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir + - patch_file: "patches/0005-qnx700_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir + - patch_file: "patches/0006-2.77.0-build_qnx700_c.patch" + patch_type: portability + patch_description: Adding missing qnx 700 implementation of openat and fdopendir diff --git a/recipes/glib/all/conanfile.py b/recipes/glib/all/conanfile.py index 95fb7a1a6aec3d..f81be4a5ca99db 100644 --- a/recipes/glib/all/conanfile.py +++ b/recipes/glib/all/conanfile.py @@ -55,6 +55,10 @@ def config_options(self): if is_msvc(self): del self.options.with_elf + if self.settings.os == "Neutrino": + del self.options.with_elf + + def configure(self): if self.options.shared: self.options.rm_safe("fPIC") @@ -79,7 +83,7 @@ def requirements(self): self.requires("libselinux/3.3") if self.settings.os != "Linux": # for Linux, gettext is provided by libc - self.requires("libgettext/0.21", transitive_headers=True, transitive_libs=True) + self.requires("libgettext/0.22", transitive_headers=True, transitive_libs=True) if is_apple_os(self): self.requires("libiconv/1.17") @@ -103,10 +107,18 @@ def generate(self): tc.project_options["iconv"] = "external" # https://gitlab.gnome.org/GNOME/glib/issues/1557 tc.project_options["selinux"] = "enabled" if self.options.get_safe("with_selinux") else "disabled" tc.project_options["libmount"] = "enabled" if self.options.get_safe("with_mount") else "disabled" - if self.settings.os == "FreeBSD": + if self.settings.os == "FreeBSD" or self.settings.os == "Neutrino": tc.project_options["xattr"] = "false" tc.project_options["tests"] = "false" tc.project_options["libelf"] = "enabled" if self.options.get_safe("with_elf") else "disabled" + + if self.settings.os == "Neutrino": + tc.cross_build["host"]["system"] = "qnx" + tc.properties["qnx_version"] = self.settings.get_safe('os.version') + tc.c_args = ["-Wno-nonnull", "-Wno-format-nonliteral", "-Wno-unused-variable", "-Wno-unused-function", "-Wno-sign-compare", "-Wno-error=implicit-function-declaration", "-Wno-int-conversion"] + tc.c_link_args.append("-lm") + tc.c_link_args.append("-lsocket") + tc.generate() def _patch_sources(self): @@ -124,7 +136,7 @@ def _patch_sources(self): os.path.join(self.source_folder, "gio", "meson.build"), ]: replace_in_file(self, filename, "subdir('tests')", "#subdir('tests')") - if self.settings.os != "Linux": + if self.settings.os != "Linux" and self.settings.os != "Neutrino": # allow to find gettext replace_in_file(self, os.path.join(self.source_folder, "meson.build"), @@ -215,6 +227,18 @@ def package_info(self): self.cpp_info.components["gthread-2.0"].system_libs.append("pthread") self.cpp_info.components["gio-2.0"].system_libs.append("dl") + if self.settings.os == "Neutrino": + self.cpp_info.components["gmodule-export-2.0"].sharedlinkflags.append("-Wl,--export-dynamic") + self.cpp_info.components["gmodule-2.0"].sharedlinkflags.append("-Wl,--export-dynamic") + self.cpp_info.components["glib-2.0"].system_libs.append("m") + + if self.settings.os.version == "7.0": + self.cpp_info.components["gmodule-no-export-2.0"].system_libs.append("dl") + self.cpp_info.components["gio-2.0"].system_libs.append("dl") + elif self.settings.os.version == "7.1": + self.cpp_info.components["gmodule-no-export-2.0"].system_libs.append("c") + self.cpp_info.components["gio-2.0"].system_libs.append("c") + if self.settings.os == "Windows": self.cpp_info.components["glib-2.0"].system_libs += ["ws2_32", "ole32", "shell32", "user32", "advapi32"] self.cpp_info.components["gio-2.0"].system_libs.extend(["iphlpapi", "dnsapi", "shlwapi"]) diff --git a/recipes/glib/all/patches/0002-2.76.x-qnx_meson_build.patch b/recipes/glib/all/patches/0002-2.76.x-qnx_meson_build.patch new file mode 100644 index 00000000000000..522e75b41b5997 --- /dev/null +++ b/recipes/glib/all/patches/0002-2.76.x-qnx_meson_build.patch @@ -0,0 +1,14 @@ +--- meson_org.build 2023-07-28 08:17:35.282631200 +0200 ++++ meson.build 2023-07-28 08:35:13.238165100 +0200 +@@ -891,6 +891,11 @@ + + if host_system == 'qnx' + glib_conf.set('HAVE_QNX', 1) ++ if meson.get_external_property('qnx_version', '') == '7.0' ++ glib_conf.set('HAVE_QNX700', 1) ++ elif meson.get_external_property('qnx_version', '') == '7.1' ++ glib_conf.set('HAVE_QNX710', 1) ++ endif + endif + + # Check for futex(2) diff --git a/recipes/glib/all/patches/0002-2.77.0-qnx_meson_build.patch b/recipes/glib/all/patches/0002-2.77.0-qnx_meson_build.patch new file mode 100644 index 00000000000000..444a015e008993 --- /dev/null +++ b/recipes/glib/all/patches/0002-2.77.0-qnx_meson_build.patch @@ -0,0 +1,14 @@ +--- meson_org.build 2023-07-28 11:23:16.976552300 +0200 ++++ meson.build 2023-07-28 11:24:04.173300500 +0200 +@@ -905,6 +905,11 @@ + + if host_system == 'qnx' + glib_conf.set('HAVE_QNX', 1) ++ if meson.get_external_property('qnx_version', false) == '7.0' ++ glib_conf.set('HAVE_QNX700', 1) ++ elif meson.get_external_property('qnx_version', false) == '7.1' ++ glib_conf.set('HAVE_QNX710', 1) ++ endif + endif + + # Check for futex(2) diff --git a/recipes/glib/all/patches/0003-2.76.x-glocalfile_c.patch b/recipes/glib/all/patches/0003-2.76.x-glocalfile_c.patch new file mode 100644 index 00000000000000..9b4403782ac27d --- /dev/null +++ b/recipes/glib/all/patches/0003-2.76.x-glocalfile_c.patch @@ -0,0 +1,20 @@ +--- gio/glocalfile_org.c 2023-07-28 08:27:17.301625500 +0200 ++++ gio/glocalfile.c 2023-07-28 09:37:34.323776200 +0200 +@@ -22,12 +22,16 @@ + + #include "config.h" + ++#ifdef HAVE_QNX700 ++#include "qnx700.h" ++#endif ++ + #include + #include + #include + #include + #include +-#if G_OS_UNIX ++#ifdef G_OS_UNIX + #include + #include + #endif diff --git a/recipes/glib/all/patches/0003-2.77.0-glocalfile_c.patch b/recipes/glib/all/patches/0003-2.77.0-glocalfile_c.patch new file mode 100644 index 00000000000000..da7a54fbf0d222 --- /dev/null +++ b/recipes/glib/all/patches/0003-2.77.0-glocalfile_c.patch @@ -0,0 +1,20 @@ +--- gio/glocalfile_org.c 2023-07-28 11:24:23.429163000 +0200 ++++ gio/glocalfile.c 2023-07-28 11:24:52.849785800 +0200 +@@ -22,12 +22,16 @@ + + #include "config.h" + ++#ifdef HAVE_QNX700 ++#include "qnx700.h" ++#endif ++ + #include + #include + #include + #include + #include +-#if G_OS_UNIX ++#ifdef G_OS_UNIX + #include + #include + #endif diff --git a/recipes/glib/all/patches/0004-qnx700_h.patch b/recipes/glib/all/patches/0004-qnx700_h.patch new file mode 100644 index 00000000000000..1a3cda9b3770d5 --- /dev/null +++ b/recipes/glib/all/patches/0004-qnx700_h.patch @@ -0,0 +1,115 @@ +--- /dev/null 2023-07-28 07:48:39.050000000 +0200 ++++ gio/qnx700.h 2023-07-28 09:06:15.733401700 +0200 +@@ -0,0 +1,112 @@ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++# define REPLACE_FCHDIR 0 ++ ++#define EXPECTED_ERRNO(Errno) \ ++ ((Errno) == ENOTDIR || (Errno) == ENOENT \ ++ || (Errno) == EPERM || (Errno) == EACCES \ ++ || (Errno) == ENOSYS /* Solaris 8 */ \ ++ || (Errno) == EOPNOTSUPP /* FreeBSD */) ++ ++#define SAFER_ALLOCA_MAX (4096 - 64) ++ ++#define SAFER_ALLOCA(m) ((m) < SAFER_ALLOCA_MAX ? (m) : SAFER_ALLOCA_MAX) ++ ++#if defined PATH_MAX ++# define OPENAT_BUFFER_SIZE SAFER_ALLOCA (PATH_MAX) ++#elif defined _XOPEN_PATH_MAX ++# define OPENAT_BUFFER_SIZE SAFER_ALLOCA (_XOPEN_PATH_MAX) ++#else ++# define OPENAT_BUFFER_SIZE SAFER_ALLOCA (1024) ++#endif ++ ++#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) ++ ++#define INT_STRLEN_BOUND(t) \ ++ (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - _GL_SIGNED_TYPE_OR_EXPR (t)) \ ++ + _GL_SIGNED_TYPE_OR_EXPR (t)) ++ ++#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) ++ ++#if _GL_HAVE___TYPEOF__ ++# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t)) ++#else ++# define _GL_SIGNED_TYPE_OR_EXPR(t) 1 ++#endif ++ ++#if GNULIB_FCNTL_SAFER ++# include "fcntl--.h" ++#else ++# define GNULIB_FCNTL_SAFER 0 ++#endif ++ ++# define assure(E) assert (E) ++ ++#if (defined _WIN32 || defined __WIN32__ || \ ++ defined __MSDOS__ || defined __CYGWIN__ || \ ++ defined __EMX__ || defined __DJGPP__) ++ /* This internal macro assumes ASCII, but all hosts that support drive ++ letters use ASCII. */ ++# define _IS_DRIVE_LETTER(C) (((unsigned int) (C) | ('a' - 'A')) - 'a' \ ++ <= 'z' - 'a') ++# define FILE_SYSTEM_PREFIX_LEN(Filename) \ ++ (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0) ++# ifndef __CYGWIN__ ++# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1 ++# endif ++# define ISSLASH(C) ((C) == '/' || (C) == '\\') ++#else ++# define FILE_SYSTEM_PREFIX_LEN(Filename) 0 ++# define ISSLASH(C) ((C) == '/') ++#endif ++ ++#if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE ++# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)]) ++# else ++# define IS_ABSOLUTE_FILE_NAME(F) \ ++ (ISSLASH ((F)[0]) || FILE_SYSTEM_PREFIX_LEN (F) != 0) ++#endif ++ ++struct saved_cwd ++{ ++ int desc; ++ char *name; ++}; ++ ++struct cd_buf ++{ ++ int fd; ++}; ++ ++ ++DIR *fdopendir (int fd); ++DIR *fdopendir_with_dup (int fd, int older_dupfd, struct saved_cwd const *cwd); ++int save_cwd (struct saved_cwd *cwd); ++int restore_cwd (const struct saved_cwd *cwd); ++_Noreturn void openat_save_fail (int errnum); ++void free_cwd (struct saved_cwd *cwd); ++static DIR *fd_clone_opendir (int fd, struct saved_cwd const *cwd); ++char *openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file); ++_Noreturn void openat_restore_fail (int errnum); ++int fd_safer_flag (int fd, int flag); ++int dup_safer_flag (int fd, int flag); ++int chdir_long (char *dir); ++static void cdb_init (struct cd_buf *cdb); ++static int cdb_advance_fd (struct cd_buf *cdb, char const *dir); ++static void cdb_free (struct cd_buf const *cdb); ++static char *find_non_slash (char const *s); ++static int cdb_fchdir (struct cd_buf const *cdb); ++void *memrchr (void const *s, int c_in, size_t n); ++int openat (int fd, char const *file, int flags, ...); ++int openat_permissive (int fd, char const *file, int flags, mode_t mode, int *cwd_errno); diff --git a/recipes/glib/all/patches/0005-qnx700_c.patch b/recipes/glib/all/patches/0005-qnx700_c.patch new file mode 100644 index 00000000000000..a76e7e053315fe --- /dev/null +++ b/recipes/glib/all/patches/0005-qnx700_c.patch @@ -0,0 +1,575 @@ +--- /dev/null 2023-07-28 07:48:39.050000000 +0200 ++++ gio/qnx700.c 2023-07-28 07:55:24.432860700 +0200 +@@ -0,0 +1,572 @@ ++#include "qnx700.h" ++ ++int openat_permissive (int fd, char const *file, int flags, mode_t mode, int *cwd_errno) ++{ ++ struct saved_cwd saved_cwd; ++ int saved_errno; ++ int err; ++ gboolean save_ok; ++ ++ if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) ++ return open (file, flags, mode); ++ ++ { ++ char buf[OPENAT_BUFFER_SIZE]; ++ char *proc_file = openat_proc_name (buf, fd, file); ++ if (proc_file) ++ { ++ int open_result = open (proc_file, flags, mode); ++ int open_errno = errno; ++ if (proc_file != buf) ++ free (proc_file); ++ /* If the syscall succeeds, or if it fails with an unexpected ++ errno value, then return right away. Otherwise, fall through ++ and resort to using save_cwd/restore_cwd. */ ++ if (0 <= open_result || ! EXPECTED_ERRNO (open_errno)) ++ { ++ errno = open_errno; ++ return open_result; ++ } ++ } ++ } ++ ++ save_ok = (save_cwd (&saved_cwd) == 0); ++ if (! save_ok) ++ { ++ if (! cwd_errno) ++ openat_save_fail (errno); ++ *cwd_errno = errno; ++ } ++ if (0 <= fd && fd == saved_cwd.desc) ++ { ++ /* If saving the working directory collides with the user's ++ requested fd, then the user's fd must have been closed to ++ begin with. */ ++ free_cwd (&saved_cwd); ++ errno = EBADF; ++ return -1; ++ } ++ ++ err = fchdir (fd); ++ saved_errno = errno; ++ ++ if (! err) ++ { ++ err = open (file, flags, mode); ++ saved_errno = errno; ++ if (save_ok && restore_cwd (&saved_cwd) != 0) ++ { ++ if (! cwd_errno) ++ { ++ /* Don't write a message to just-created fd 2. */ ++ saved_errno = errno; ++ if (err == STDERR_FILENO) ++ close (err); ++ openat_restore_fail (saved_errno); ++ } ++ *cwd_errno = errno; ++ } ++ } ++ ++ free_cwd (&saved_cwd); ++ errno = saved_errno; ++ return err; ++} ++ ++int openat (int fd, char const *file, int flags, ...) ++{ ++ mode_t mode = 0; ++ ++ if (flags & O_CREAT) ++ { ++ va_list arg; ++ va_start (arg, flags); ++ ++ /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4 ++ creates crashing code when 'mode_t' is smaller than 'int'. */ ++ mode = va_arg (arg, mode_t); ++ ++ va_end (arg); ++ } ++ ++ return openat_permissive (fd, file, flags, mode, NULL); ++} ++ ++void *memrchr (void const *s, int c_in, size_t n) ++{ ++ typedef unsigned long int longword; ++ ++ const unsigned char *char_ptr; ++ const longword *longword_ptr; ++ longword repeated_one; ++ longword repeated_c; ++ unsigned char c; ++ ++ c = (unsigned char) c_in; ++ ++ for (char_ptr = (const unsigned char *) s + n; ++ n > 0 && (size_t) char_ptr % sizeof (longword) != 0; ++ --n) ++ if (*--char_ptr == c) ++ return (void *) char_ptr; ++ ++ longword_ptr = (const longword *) char_ptr; ++ ++ repeated_one = 0x01010101; ++ repeated_c = c | (c << 8); ++ repeated_c |= repeated_c << 16; ++ if (0xffffffffU < (longword) -1) ++ { ++ repeated_one |= repeated_one << 31 << 1; ++ repeated_c |= repeated_c << 31 << 1; ++ if (8 < sizeof (longword)) ++ { ++ size_t i; ++ ++ for (i = 64; i < sizeof (longword) * 8; i *= 2) ++ { ++ repeated_one |= repeated_one << i; ++ repeated_c |= repeated_c << i; ++ } ++ } ++ } ++ ++ while (n >= sizeof (longword)) ++ { ++ longword longword1 = *--longword_ptr ^ repeated_c; ++ ++ if ((((longword1 - repeated_one) & ~longword1) ++ & (repeated_one << 7)) != 0) ++ { ++ longword_ptr++; ++ break; ++ } ++ n -= sizeof (longword); ++ } ++ ++ char_ptr = (const unsigned char *) longword_ptr; ++ while (n-- > 0) ++ { ++ if (*--char_ptr == c) ++ return (void *) char_ptr; ++ } ++ ++ return NULL; ++} ++ ++static int cdb_fchdir (struct cd_buf const *cdb) ++{ ++ return fchdir (cdb->fd); ++} ++ ++static char *find_non_slash (char const *s) ++{ ++ size_t n_slash = strspn (s, "/"); ++ return (char *) s + n_slash; ++} ++ ++static void cdb_free (struct cd_buf const *cdb) ++{ ++ if (0 <= cdb->fd) ++ { ++ gboolean close_fail = close (cdb->fd); ++ assure (! close_fail); ++ } ++} ++ ++static int cdb_advance_fd (struct cd_buf *cdb, char const *dir) ++{ ++ int new_fd = openat (cdb->fd, dir, ++ O_NOCTTY | O_NONBLOCK); ++ if (new_fd < 0) ++ return -1; ++ ++ cdb_free (cdb); ++ cdb->fd = new_fd; ++ ++ return 0; ++} ++ ++static void cdb_init (struct cd_buf *cdb) ++{ ++ cdb->fd = AT_FDCWD; ++} ++ ++int chdir_long (char *dir) ++{ ++ int e = chdir (dir); ++ if (e == 0 || errno != ENAMETOOLONG) ++ return e; ++ ++ { ++ size_t len = strlen (dir); ++ char *dir_end = dir + len; ++ struct cd_buf cdb; ++ size_t n_leading_slash; ++ ++ cdb_init (&cdb); ++ ++ /* If DIR is the empty string, then the chdir above ++ must have failed and set errno to ENOENT. */ ++ assure (0 < len); ++ assure (PATH_MAX <= len); ++ ++ /* Count leading slashes. */ ++ n_leading_slash = strspn (dir, "/"); ++ ++ /* Handle any leading slashes as well as any name that matches ++ the regular expression, m!^//hostname[/]*! . Handling this ++ prefix separately usually results in a single additional ++ cdb_advance_fd call, but it's worthwhile, since it makes the ++ code in the following loop cleaner. */ ++ if (n_leading_slash == 2) ++ { ++ int err; ++ /* Find next slash. ++ We already know that dir[2] is neither a slash nor '\0'. */ ++ char *slash = memchr (dir + 3, '/', dir_end - (dir + 3)); ++ if (slash == NULL) ++ { ++ errno = ENAMETOOLONG; ++ return -1; ++ } ++ *slash = '\0'; ++ err = cdb_advance_fd (&cdb, dir); ++ *slash = '/'; ++ if (err != 0) ++ goto Fail; ++ dir = find_non_slash (slash + 1); ++ } ++ else if (n_leading_slash) ++ { ++ if (cdb_advance_fd (&cdb, "/") != 0) ++ goto Fail; ++ dir += n_leading_slash; ++ } ++ ++ assure (*dir != '/'); ++ assure (dir <= dir_end); ++ ++ while (PATH_MAX <= dir_end - dir) ++ { ++ int err; ++ /* Find a slash that is PATH_MAX or fewer bytes away from dir. ++ I.e. see if there is a slash that will give us a name of ++ length PATH_MAX-1 or less. */ ++ char *slash = memrchr (dir, '/', PATH_MAX); ++ if (slash == NULL) ++ { ++ errno = ENAMETOOLONG; ++ return -1; ++ } ++ ++ *slash = '\0'; ++ assure (slash - dir < PATH_MAX); ++ err = cdb_advance_fd (&cdb, dir); ++ *slash = '/'; ++ if (err != 0) ++ goto Fail; ++ ++ dir = find_non_slash (slash + 1); ++ } ++ ++ if (dir < dir_end) ++ { ++ if (cdb_advance_fd (&cdb, dir) != 0) ++ goto Fail; ++ } ++ ++ if (cdb_fchdir (&cdb) != 0) ++ goto Fail; ++ ++ cdb_free (&cdb); ++ return 0; ++ ++ Fail: ++ { ++ int saved_errno = errno; ++ cdb_free (&cdb); ++ errno = saved_errno; ++ return -1; ++ } ++ } ++} ++ ++int dup_safer_flag (int fd, int flag) ++{ ++ return fcntl (fd, (flag & O_CLOEXEC) ? F_DUPFD_CLOEXEC : F_DUPFD, ++ STDERR_FILENO + 1); ++} ++ ++int fd_safer_flag (int fd, int flag) ++{ ++ if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) ++ { ++ int f = dup_safer_flag (fd, flag); ++ int e = errno; ++ close (fd); ++ errno = e; ++ fd = f; ++ } ++ ++ return fd; ++} ++ ++_Noreturn void openat_restore_fail (int errnum) ++{ ++ abort (); ++} ++ ++char *openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file) ++{ ++ char *result = buf; ++ int dirlen; ++ ++ /* Make sure the caller gets ENOENT when appropriate. */ ++ if (!*file) ++ { ++ buf[0] = '\0'; ++ return buf; ++ } ++ ++#ifndef __KLIBC__ ++# define PROC_SELF_FD_FORMAT "/proc/self/fd/%d/" ++ { ++ enum { ++ PROC_SELF_FD_DIR_SIZE_BOUND ++ = (sizeof PROC_SELF_FD_FORMAT - (sizeof "%d" - 1) ++ + INT_STRLEN_BOUND (int)) ++ }; ++ ++ static int proc_status = 0; ++ if (! proc_status) ++ { ++ /* Set PROC_STATUS to a positive value if /proc/self/fd is ++ reliable, and a negative value otherwise. Solaris 10 ++ /proc/self/fd mishandles "..", and any file name might expand ++ to ".." after symbolic link expansion, so avoid /proc/self/fd ++ if it mishandles "..". Solaris 10 has openat, but this ++ problem is exhibited on code that built on Solaris 8 and ++ running on Solaris 10. */ ++ ++ int proc_self_fd = open ("/proc/self/fd", ++ O_NOCTTY | O_NONBLOCK); ++ if (proc_self_fd < 0) ++ proc_status = -1; ++ else ++ { ++ /* Detect whether /proc/self/fd/%i/../fd exists, where %i is the ++ number of a file descriptor open on /proc/self/fd. On Linux, ++ that name resolves to /proc/self/fd, which was opened above. ++ However, on Solaris, it may resolve to /proc/self/fd/fd, which ++ cannot exist, since all names in /proc/self/fd are numeric. */ ++ char dotdot_buf[PROC_SELF_FD_DIR_SIZE_BOUND + sizeof "../fd" - 1]; ++ sprintf (dotdot_buf, PROC_SELF_FD_FORMAT "../fd", proc_self_fd); ++ proc_status = access (dotdot_buf, F_OK) ? -1 : 1; ++ close (proc_self_fd); ++ } ++ } ++ ++ if (proc_status < 0) ++ return NULL; ++ else ++ { ++ size_t bufsize = PROC_SELF_FD_DIR_SIZE_BOUND + strlen (file); ++ if (OPENAT_BUFFER_SIZE < bufsize) ++ { ++ result = malloc (bufsize); ++ if (! result) ++ return NULL; ++ } ++ ++ dirlen = sprintf (result, PROC_SELF_FD_FORMAT, fd); ++ } ++ } ++#else ++ /* OS/2 kLIBC provides a function to retrieve a path from a fd. */ ++ { ++ char dir[_MAX_PATH]; ++ size_t bufsize; ++ ++ if (__libc_Back_ioFHToPath (fd, dir, sizeof dir)) ++ return NULL; ++ ++ dirlen = strlen (dir); ++ bufsize = dirlen + 1 + strlen (file) + 1; /* 1 for '/', 1 for null */ ++ if (OPENAT_BUFFER_SIZE < bufsize) ++ { ++ result = malloc (bufsize); ++ if (! result) ++ return NULL; ++ } ++ ++ strcpy (result, dir); ++ result[dirlen++] = '/'; ++ } ++#endif ++ ++ strcpy (result + dirlen, file); ++ return result; ++} ++ ++DIR *fdopendir (int fd) ++{ ++ DIR *dir = fdopendir_with_dup (fd, -1, NULL); ++ ++ if (! REPLACE_FCHDIR && ! dir) ++ { ++ int saved_errno = errno; ++ if (EXPECTED_ERRNO (saved_errno)) ++ { ++ struct saved_cwd cwd; ++ if (save_cwd (&cwd) != 0) ++ openat_save_fail (errno); ++ dir = fdopendir_with_dup (fd, -1, &cwd); ++ saved_errno = errno; ++ free_cwd (&cwd); ++ errno = saved_errno; ++ } ++ } ++ ++ return dir; ++} ++ ++/* Like fdopendir, except that if OLDER_DUPFD is not -1, it is known ++ to be a dup of FD which is less than FD - 1 and which will be ++ closed by the caller and not otherwise used by the caller. This ++ function makes sure that FD is closed and all file descriptors less ++ than FD are open, and then calls fd_clone_opendir on a dup of FD. ++ That way, barring race conditions, fd_clone_opendir returns a ++ stream whose file descriptor is FD. ++ ++ If REPLACE_FCHDIR or CWD is null, use opendir ("/proc/self/fd/...", ++ falling back on fchdir metadata. Otherwise, CWD is a saved version ++ of the working directory; use fchdir/opendir(".")/restore_cwd(CWD). */ ++DIR *fdopendir_with_dup (int fd, int older_dupfd, struct saved_cwd const *cwd) ++{ ++ int dupfd = dup (fd); ++ if (dupfd < 0 && errno == EMFILE) ++ dupfd = older_dupfd; ++ if (dupfd < 0) ++ return NULL; ++ else ++ { ++ DIR *dir; ++ int saved_errno; ++ if (dupfd < fd - 1 && dupfd != older_dupfd) ++ { ++ dir = fdopendir_with_dup (fd, dupfd, cwd); ++ saved_errno = errno; ++ } ++ else ++ { ++ close (fd); ++ dir = fd_clone_opendir (dupfd, cwd); ++ saved_errno = errno; ++ if (! dir) ++ { ++ int fd1 = dup (dupfd); ++ if (fd1 != fd) ++ openat_save_fail (fd1 < 0 ? errno : EBADF); ++ } ++ } ++ ++ if (dupfd != older_dupfd) ++ close (dupfd); ++ errno = saved_errno; ++ return dir; ++ } ++} ++ ++/* Like fdopendir, except the result controls a clone of FD. It is ++ the caller's responsibility both to close FD and (if the result is ++ not null) to closedir the result. */ ++static DIR *fd_clone_opendir (int fd, struct saved_cwd const *cwd) ++{ ++ if (REPLACE_FCHDIR || ! cwd) ++ { ++ DIR *dir = NULL; ++ int saved_errno = EOPNOTSUPP; ++ char buf[OPENAT_BUFFER_SIZE]; ++ char *proc_file = openat_proc_name (buf, fd, "."); ++ if (proc_file) ++ { ++ dir = opendir (proc_file); ++ saved_errno = errno; ++ if (proc_file != buf) ++ free (proc_file); ++ } ++# if REPLACE_FCHDIR ++ if (! dir && EXPECTED_ERRNO (saved_errno)) ++ { ++ char const *name = _gl_directory_name (fd); ++ DIR *dp = name ? opendir (name) : NULL; ++ ++ /* The caller has done an elaborate dance to arrange for opendir to ++ consume just the right file descriptor. If dirfd returns -1, ++ though, we're on a system like mingw where opendir does not ++ consume a file descriptor. Consume it via 'dup' instead. */ ++ if (dp && dirfd (dp) < 0) ++ dup (fd); ++ ++ return dp; ++ } ++# endif ++ errno = saved_errno; ++ return dir; ++ } ++ else ++ { ++ if (fchdir (fd) != 0) ++ return NULL; ++ else ++ { ++ DIR *dir = opendir ("."); ++ int saved_errno = errno; ++ if (restore_cwd (cwd) != 0) ++ openat_restore_fail (errno); ++ errno = saved_errno; ++ return dir; ++ } ++ } ++} ++ ++int save_cwd (struct saved_cwd *cwd) ++{ ++ cwd->name = NULL; ++ ++ cwd->desc = open (".", O_CLOEXEC); ++ if (!GNULIB_FCNTL_SAFER) ++ cwd->desc = fd_safer_flag (cwd->desc, O_CLOEXEC); ++ if (cwd->desc < 0) ++ { ++ cwd->name = getcwd (NULL, 0); ++ return cwd->name ? 0 : -1; ++ } ++ ++ return 0; ++} ++ ++/* Change to recorded location, CWD, in directory hierarchy. ++ Upon failure, return -1 (errno is set by chdir or fchdir). ++ Upon success, return zero. */ ++ ++int restore_cwd (const struct saved_cwd *cwd) ++{ ++ if (0 <= cwd->desc) ++ return fchdir (cwd->desc); ++ else ++ return chdir_long (cwd->name); ++} ++ ++void free_cwd (struct saved_cwd *cwd) ++{ ++ if (cwd->desc >= 0) ++ close (cwd->desc); ++ free (cwd->name); ++} ++ ++_Noreturn void openat_save_fail (int errnum) ++{ ++ abort (); ++} diff --git a/recipes/glib/all/patches/0006-2.76.x-build_qnx700_c.patch b/recipes/glib/all/patches/0006-2.76.x-build_qnx700_c.patch new file mode 100644 index 00000000000000..20f996e2d12ac6 --- /dev/null +++ b/recipes/glib/all/patches/0006-2.76.x-build_qnx700_c.patch @@ -0,0 +1,13 @@ +--- gio/meson.build 2023-07-28 11:26:04.858363400 +0200 ++++ gio/meson.build 2023-07-28 11:26:19.363678200 +0200 +@@ -619,6 +619,10 @@ + gio_sources += portal_sources + gio_sources += local_sources + ++if host_system == 'qnx' ++ gio_sources += 'qnx700.c' ++endif ++ + MISSING_STUFF = ''' + # This is read by gobject-introspection/misc/ and gtk-doc + gio-public-headers.txt: Makefile \ No newline at end of file diff --git a/recipes/glib/all/patches/0006-2.77.0-build_qnx700_c.patch b/recipes/glib/all/patches/0006-2.77.0-build_qnx700_c.patch new file mode 100644 index 00000000000000..df50d030136092 --- /dev/null +++ b/recipes/glib/all/patches/0006-2.77.0-build_qnx700_c.patch @@ -0,0 +1,13 @@ +--- gio/meson.build 2023-07-28 11:26:04.858363400 +0200 ++++ gio/meson.build 2023-08-28 09:49:55.139735000 +0200 +@@ -617,6 +617,10 @@ + gio_sources += portal_sources + gio_sources += local_sources + ++if host_system == 'qnx' ++ gio_sources += 'qnx700.c' ++endif ++ + MISSING_STUFF = ''' + # This is read by gobject-introspection/misc/ and gtk-doc + gio-public-headers.txt: Makefile \ No newline at end of file