Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support QNX platform. #116

Closed
thun-res opened this issue Apr 20, 2021 · 13 comments
Closed

Support QNX platform. #116

thun-res opened this issue Apr 20, 2021 · 13 comments
Assignees
Labels
available on master Fix is done on master branch, issue closed on next release enhancement New feature or request POSIX POSIX type backend is affected
Milestone

Comments

@thun-res
Copy link

platform: qnx700, aarch64, c++11 support (POSIX support)

"Operating system currently not supported!"
And It looks like the 'struct dirent' has no 'd_type'
I try to modify:

filesystem.hpp:

...
#elif defined(__QNX__)
#define GHC_OS_QNX
#else
#error "Operating system currently not supported!"
#endif
...

...
      void copyToDirEntry()
        {
            _dir_entry._symlink_status.permissions(perms::unknown);
#ifdef GHC_OS_QNX
            _dir_entry._status.type(file_type::none);
            _dir_entry._status.permissions(perms::unknown);
            _dir_entry._symlink_status.type(file_type::unknown);
#else
            switch (_entry->d_type) {
            case DT_BLK:
                _dir_entry._symlink_status.type(file_type::block);
                break;
            case DT_CHR:
                _dir_entry._symlink_status.type(file_type::character);
                break;
            case DT_DIR:
                _dir_entry._symlink_status.type(file_type::directory);
                break;
            case DT_FIFO:
                _dir_entry._symlink_status.type(file_type::fifo);
                break;
            case DT_LNK:
                _dir_entry._symlink_status.type(file_type::symlink);
                break;
            case DT_REG:
                _dir_entry._symlink_status.type(file_type::regular);
                break;
            case DT_SOCK:
                _dir_entry._symlink_status.type(file_type::socket);
                break;
            default:
                _dir_entry._symlink_status.type(file_type::unknown);
                break;
            }
            if (_entry->d_type != DT_LNK) {
                _dir_entry._status = _dir_entry._symlink_status;
            } else {
                _dir_entry._status.type(file_type::none);
                _dir_entry._status.permissions(perms::unknown);
            }
#endif
            _dir_entry._file_size = static_cast<uintmax_t>(-1);
            _dir_entry._hard_link_count = static_cast<uintmax_t>(-1);
            _dir_entry._last_write_time = 0;
        }
...

I don’t know if the changes are correct, but the compilation passed.

thanks.

@gulrak gulrak added the enhancement New feature or request label Apr 20, 2021
@gulrak gulrak self-assigned this Apr 20, 2021
@gulrak
Copy link
Owner

gulrak commented Apr 20, 2021

Thank you! That looks like it should work, I'll look into it.

@thun-res
Copy link
Author

I tested it briefly and found it crashed(when I create dir it throw)...

@gulrak
Copy link
Owner

gulrak commented Apr 26, 2021

Sadly, contrary to what I expected, I couldn't get access to a QNX installation and didn't want do register and apply for a 30 days evaluation, as that wouldn't allow me to further support it after 30 days, so I currently have no way to check it myself.

@thun-res
Copy link
Author

Thanks for trying my suggestion, I have solved it now.

...
#define GHC_OS_WEB
#include <wasi/api.h>
#elif defined(__QNX__)
#define GHC_OS_QNX
#else
#error "Operating system currently not supported!"
#endif
...
...
        void copyToDirEntry()
        {
            _dir_entry._symlink_status.permissions(perms::unknown);
#ifdef GHC_OS_QNX
            struct stat buffer;
            int reval = ::stat(_dir_entry._path.c_str(), &buffer);
            if (reval == 0) {
                if (S_ISDIR(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::directory);
                } else if (S_ISREG(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::regular);
                } else if (S_ISLNK(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::symlink);
                } else if (S_ISCHR(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::character);
                } else if (S_ISFIFO(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::fifo);
                } else if (S_ISBLK(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::block);
                } else if (S_ISSOCK(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::socket);
                } else {
                    _dir_entry._symlink_status.type(file_type::unknown);
                }
                _dir_entry._status = _dir_entry._symlink_status;
            } else {
                _dir_entry._status.type(file_type::none);
                _dir_entry._symlink_status.type(file_type::unknown);
            }
#else
            switch (_entry->d_type) {
            case DT_BLK:
                _dir_entry._symlink_status.type(file_type::block);
                break;
            case DT_CHR:
                _dir_entry._symlink_status.type(file_type::character);
                break;
            case DT_DIR:
                _dir_entry._symlink_status.type(file_type::directory);
                break;
            case DT_FIFO:
                _dir_entry._symlink_status.type(file_type::fifo);
                break;
            case DT_LNK:
                _dir_entry._symlink_status.type(file_type::symlink);
                break;
            case DT_REG:
                _dir_entry._symlink_status.type(file_type::regular);
                break;
            case DT_SOCK:
                _dir_entry._symlink_status.type(file_type::socket);
                break;
            default:
                _dir_entry._symlink_status.type(file_type::unknown);
                break;
            }
            if (_entry->d_type != DT_LNK) {
                _dir_entry._status = _dir_entry._symlink_status;
            } else {
                _dir_entry._status.type(file_type::none);
                _dir_entry._status.permissions(perms::unknown);
            }
#endif
            _dir_entry._file_size = static_cast<uintmax_t>(-1);
            _dir_entry._hard_link_count = static_cast<uintmax_t>(-1);
            _dir_entry._last_write_time = 0;
        }
        path _base;
        directory_options _options;
        DIR* _dir;
        struct ::dirent* _entry;
        directory_entry _dir_entry;
        std::error_code _ec;
    };
...

I have tested and it works, you can add this.

@thun-res
Copy link
Author

#ifdef GHC_OS_QNX
            struct stat buffer;
            int reval = ::stat(_dir_entry._path.c_str(), &buffer);
            bool is_link = false;
            if (reval == 0) {
                if (S_ISDIR(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::directory);
                } else if (S_ISREG(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::regular);
                } else if (S_ISLNK(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::symlink);
                    is_link = true;
                } else if (S_ISCHR(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::character);
                } else if (S_ISFIFO(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::fifo);
                } else if (S_ISBLK(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::block);
                } else if (S_ISSOCK(buffer.st_mode)) {
                    _dir_entry._symlink_status.type(file_type::socket);
                } else {
                    _dir_entry._symlink_status.type(file_type::unknown);
                }
                if (is_link) {
                    _dir_entry._status.type(file_type::none);
                    _dir_entry._status.permissions(perms::unknown);
                } else {
                    _dir_entry._status = _dir_entry._symlink_status;
                }
            } else {
                _dir_entry._status.type(file_type::unknown);
                _dir_entry._symlink_status.type(file_type::unknown);
                _dir_entry._status.permissions(perms::unknown);
            }
#else
            switch (_entry->d_type) {
            case DT_BLK:
                _dir_entry._symlink_status.type(file_type::block);
                break;
            case DT_CHR:
                _dir_entry._symlink_status.type(file_type::character);
                break;
            case DT_DIR:
                _dir_entry._symlink_status.type(file_type::directory);
                break;
            case DT_FIFO:
                _dir_entry._symlink_status.type(file_type::fifo);
                break;
            case DT_LNK:
                _dir_entry._symlink_status.type(file_type::symlink);
                break;
            case DT_REG:
                _dir_entry._symlink_status.type(file_type::regular);
                break;
            case DT_SOCK:
                _dir_entry._symlink_status.type(file_type::socket);
                break;
            default:
                _dir_entry._symlink_status.type(file_type::unknown);
                break;
            }
            if (_entry->d_type != DT_LNK) {
                _dir_entry._status = _dir_entry._symlink_status;
            } else {
                _dir_entry._status.type(file_type::none);
                _dir_entry._status.permissions(perms::unknown);
            }
#endif

gulrak added a commit that referenced this issue May 24, 2021
@gulrak gulrak added this to the v1.5.6 milestone May 24, 2021
@gulrak gulrak added the POSIX POSIX type backend is affected label May 24, 2021
@gulrak
Copy link
Owner

gulrak commented May 24, 2021

Sorry for the delay! The reason I didn't simply use your solution was, that I wanted the way to support systems without dirent.d_type the same way as filesystems reporting DT_UNKNOWN as type and I had thought my default: would be handling those correctly but it didn't. As I couldn't test myself I postponed work on it a bit.

I used a macro to select no-d_type support to allow easier integration for other systems that might need it.

@gulrak
Copy link
Owner

gulrak commented May 24, 2021

This is now part of release v1.5.6

@gulrak gulrak closed this as completed May 24, 2021
@gulrak gulrak added the available on master Fix is done on master branch, issue closed on next release label May 24, 2021
@district10
Copy link

platform: qnx700, aarch64, c++14 support (POSIX support)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14")
set(CMAKE_CXX_EXTENSIONS ON)

Got error:

// using the most recent ghc_filesystem/1.5.6
filesystem.hpp:178:22: fatal error: langinfo.h: No such file or directory

@district10
Copy link

2021/09/04: works totally fine on QNX. 😢 Sorry for the disruption.

@GarfiledXu
Copy link

latest version, compiled on android arm-64 pass
complied on qnx 700 arm fail!
complie output:
inc/include/ghc/filesystem.hpp:164:22: fatal error: langinfo.h: No such file or directory
i can't find this header : laninfo.h
if i try to note this include, will ouput error info:
/ghc/filesystem.hpp:2467:43: error: '::nl_langinfo' has not been declared
_simple_insensitive(::nl_langin

@facontidavide
Copy link

facontidavide commented Sep 12, 2023

Similar problem with QNX 7.1.0 (x86_64):

/home/davide/qnx710/host/linux/x86_64/usr/bin/x86_64-pc-nto-qnx7.1.0-ld: CMakeFiles/fs_dir.dir/dir.cpp.o: in function `ghc::filesystem::u8arguments::u8arguments(int&, char**&)':
dir.cpp:(.text._ZN3ghc10filesystem11u8argumentsC2ERiRPPc[_ZN3ghc10filesystem11u8argumentsC5ERiRPPc]+0x66): undefined reference to `nl_langinfo(int)'
collect2: error: ld returned 1 exit status
examples/CMakeFiles/fs_dir.dir/build.make:96: recipe for target 'examples/fs_dir' failed

@gulrak
Copy link
Owner

gulrak commented Sep 16, 2023

This is better kept at #169 as comments at an old issue get lost fast, but as written there, I need help or PRs to fix that.

There is no free QNX dev environment to test and debug this myself, at least I couldn't find a legal one, and I'm not willing to buy a license I don't need for myself, so QNX support sadly is not an official feature but one backed by help of others, I can't check it by CI and I can't do it myself.

@district10
Copy link

I worked on QNX years ago (and ghc_filesystem worked). This patch may be useful: https://gist.github.com/district10/9937754bdcdd5321a56430f491088de9

Specially, add these to your CMakeLists.txt may resolve your problem: (I still have no idea why. It's tricky.)

add_definitions(-D_QNX_SOURCE)
add_definitions(-D_XOPEN_SOURCE=500)

Or this:

if (CMAKE_SYSTEM_NAME STREQUAL "QNX")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++")
    set(CMAKE_CXX_EXTENSIONS ON)
endif()

You may read -stdlib=XXX, -std=xxx here: https://www.qnx.com/developers/docs/7.0.0/#com.qnx.doc.neutrino.utilities/topic/q/qcc.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
available on master Fix is done on master branch, issue closed on next release enhancement New feature or request POSIX POSIX type backend is affected
Projects
None yet
Development

No branches or pull requests

5 participants