| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #pragma once |
| |
| #ifndef _WIN32 |
| #define ARROW_HAVE_SIGACTION 1 |
| #endif |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #if ARROW_HAVE_SIGACTION |
| #include <signal.h> // Needed for struct sigaction |
| #endif |
| |
| #include "arrow/io/interfaces.h" |
| #include "arrow/status.h" |
| #include "arrow/type_fwd.h" |
| #include "arrow/util/macros.h" |
| #include "arrow/util/windows_fixup.h" |
| |
| namespace arrow { |
| |
| class Buffer; |
| |
| namespace io { |
| |
| // Output stream that just writes to stdout. |
| class ARROW_EXPORT StdoutStream : public OutputStream { |
| public: |
| StdoutStream(); |
| ~StdoutStream() override {} |
| |
| Status Close() override; |
| bool closed() const override; |
| |
| Result<int64_t> Tell() const override; |
| |
| Status Write(const void* data, int64_t nbytes) override; |
| |
| private: |
| int64_t pos_; |
| }; |
| |
| // Output stream that just writes to stderr. |
| class ARROW_EXPORT StderrStream : public OutputStream { |
| public: |
| StderrStream(); |
| ~StderrStream() override {} |
| |
| Status Close() override; |
| bool closed() const override; |
| |
| Result<int64_t> Tell() const override; |
| |
| Status Write(const void* data, int64_t nbytes) override; |
| |
| private: |
| int64_t pos_; |
| }; |
| |
| // Input stream that just reads from stdin. |
| class ARROW_EXPORT StdinStream : public InputStream { |
| public: |
| StdinStream(); |
| ~StdinStream() override {} |
| |
| Status Close() override; |
| bool closed() const override; |
| |
| Result<int64_t> Tell() const override; |
| |
| Result<int64_t> Read(int64_t nbytes, void* out) override; |
| |
| Result<std::shared_ptr<Buffer>> Read(int64_t nbytes) override; |
| |
| private: |
| int64_t pos_; |
| }; |
| |
| } // namespace io |
| |
| namespace internal { |
| |
| // NOTE: 8-bit path strings on Windows are encoded using UTF-8. |
| // Using MBCS would fail encoding some paths. |
| |
| #if defined(_WIN32) |
| using NativePathString = std::wstring; |
| #else |
| using NativePathString = std::string; |
| #endif |
| |
| class ARROW_EXPORT PlatformFilename { |
| public: |
| struct Impl; |
| |
| ~PlatformFilename(); |
| PlatformFilename(); |
| PlatformFilename(const PlatformFilename&); |
| PlatformFilename(PlatformFilename&&); |
| PlatformFilename& operator=(const PlatformFilename&); |
| PlatformFilename& operator=(PlatformFilename&&); |
| explicit PlatformFilename(const NativePathString& path); |
| explicit PlatformFilename(const NativePathString::value_type* path); |
| |
| const NativePathString& ToNative() const; |
| std::string ToString() const; |
| |
| PlatformFilename Parent() const; |
| |
| // These functions can fail for character encoding reasons. |
| static Result<PlatformFilename> FromString(const std::string& file_name); |
| Result<PlatformFilename> Join(const std::string& child_name) const; |
| |
| PlatformFilename Join(const PlatformFilename& child_name) const; |
| |
| bool operator==(const PlatformFilename& other) const; |
| bool operator!=(const PlatformFilename& other) const; |
| |
| // Made public to avoid the proliferation of friend declarations. |
| const Impl* impl() const { return impl_.get(); } |
| |
| private: |
| std::unique_ptr<Impl> impl_; |
| |
| explicit PlatformFilename(Impl impl); |
| }; |
| |
| /// Create a directory if it doesn't exist. |
| /// |
| /// Return whether the directory was created. |
| ARROW_EXPORT |
| Result<bool> CreateDir(const PlatformFilename& dir_path); |
| |
| /// Create a directory and its parents if it doesn't exist. |
| /// |
| /// Return whether the directory was created. |
| ARROW_EXPORT |
| Result<bool> CreateDirTree(const PlatformFilename& dir_path); |
| |
| /// Delete a directory's contents (but not the directory itself) if it exists. |
| /// |
| /// Return whether the directory existed. |
| ARROW_EXPORT |
| Result<bool> DeleteDirContents(const PlatformFilename& dir_path, |
| bool allow_not_found = true); |
| |
| /// Delete a directory tree if it exists. |
| /// |
| /// Return whether the directory existed. |
| ARROW_EXPORT |
| Result<bool> DeleteDirTree(const PlatformFilename& dir_path, bool allow_not_found = true); |
| |
| // Non-recursively list the contents of the given directory. |
| // The returned names are the children's base names, not including dir_path. |
| ARROW_EXPORT |
| Result<std::vector<PlatformFilename>> ListDir(const PlatformFilename& dir_path); |
| |
| /// Delete a file if it exists. |
| /// |
| /// Return whether the file existed. |
| ARROW_EXPORT |
| Result<bool> DeleteFile(const PlatformFilename& file_path, bool allow_not_found = true); |
| |
| /// Return whether a file exists. |
| ARROW_EXPORT |
| Result<bool> FileExists(const PlatformFilename& path); |
| |
| /// Open a file for reading and return a file descriptor. |
| ARROW_EXPORT |
| Result<int> FileOpenReadable(const PlatformFilename& file_name); |
| |
| /// Open a file for writing and return a file descriptor. |
| ARROW_EXPORT |
| Result<int> FileOpenWritable(const PlatformFilename& file_name, bool write_only = true, |
| bool truncate = true, bool append = false); |
| |
| /// Read from current file position. Return number of bytes read. |
| ARROW_EXPORT |
| Result<int64_t> FileRead(int fd, uint8_t* buffer, int64_t nbytes); |
| /// Read from given file position. Return number of bytes read. |
| ARROW_EXPORT |
| Result<int64_t> FileReadAt(int fd, uint8_t* buffer, int64_t position, int64_t nbytes); |
| |
| ARROW_EXPORT |
| Status FileWrite(int fd, const uint8_t* buffer, const int64_t nbytes); |
| ARROW_EXPORT |
| Status FileTruncate(int fd, const int64_t size); |
| |
| ARROW_EXPORT |
| Status FileSeek(int fd, int64_t pos); |
| ARROW_EXPORT |
| Status FileSeek(int fd, int64_t pos, int whence); |
| ARROW_EXPORT |
| Result<int64_t> FileTell(int fd); |
| ARROW_EXPORT |
| Result<int64_t> FileGetSize(int fd); |
| |
| ARROW_EXPORT |
| Status FileClose(int fd); |
| |
| struct Pipe { |
| int rfd; |
| int wfd; |
| }; |
| |
| ARROW_EXPORT |
| Result<Pipe> CreatePipe(); |
| |
| ARROW_EXPORT |
| int64_t GetPageSize(); |
| |
| struct MemoryRegion { |
| void* addr; |
| size_t size; |
| }; |
| |
| ARROW_EXPORT |
| Status MemoryMapRemap(void* addr, size_t old_size, size_t new_size, int fildes, |
| void** new_addr); |
| ARROW_EXPORT |
| Status MemoryAdviseWillNeed(const std::vector<MemoryRegion>& regions); |
| |
| ARROW_EXPORT |
| Result<std::string> GetEnvVar(const char* name); |
| ARROW_EXPORT |
| Result<std::string> GetEnvVar(const std::string& name); |
| ARROW_EXPORT |
| Result<NativePathString> GetEnvVarNative(const char* name); |
| ARROW_EXPORT |
| Result<NativePathString> GetEnvVarNative(const std::string& name); |
| |
| ARROW_EXPORT |
| Status SetEnvVar(const char* name, const char* value); |
| ARROW_EXPORT |
| Status SetEnvVar(const std::string& name, const std::string& value); |
| ARROW_EXPORT |
| Status DelEnvVar(const char* name); |
| ARROW_EXPORT |
| Status DelEnvVar(const std::string& name); |
| |
| ARROW_EXPORT |
| std::string ErrnoMessage(int errnum); |
| #if _WIN32 |
| ARROW_EXPORT |
| std::string WinErrorMessage(int errnum); |
| #endif |
| |
| ARROW_EXPORT |
| std::shared_ptr<StatusDetail> StatusDetailFromErrno(int errnum); |
| #if _WIN32 |
| ARROW_EXPORT |
| std::shared_ptr<StatusDetail> StatusDetailFromWinError(int errnum); |
| #endif |
| ARROW_EXPORT |
| std::shared_ptr<StatusDetail> StatusDetailFromSignal(int signum); |
| |
| template <typename... Args> |
| Status StatusFromErrno(int errnum, StatusCode code, Args&&... args) { |
| return Status::FromDetailAndArgs(code, StatusDetailFromErrno(errnum), |
| std::forward<Args>(args)...); |
| } |
| |
| template <typename... Args> |
| Status IOErrorFromErrno(int errnum, Args&&... args) { |
| return StatusFromErrno(errnum, StatusCode::IOError, std::forward<Args>(args)...); |
| } |
| |
| #if _WIN32 |
| template <typename... Args> |
| Status StatusFromWinError(int errnum, StatusCode code, Args&&... args) { |
| return Status::FromDetailAndArgs(code, StatusDetailFromWinError(errnum), |
| std::forward<Args>(args)...); |
| } |
| |
| template <typename... Args> |
| Status IOErrorFromWinError(int errnum, Args&&... args) { |
| return StatusFromWinError(errnum, StatusCode::IOError, std::forward<Args>(args)...); |
| } |
| #endif |
| |
| template <typename... Args> |
| Status StatusFromSignal(int signum, StatusCode code, Args&&... args) { |
| return Status::FromDetailAndArgs(code, StatusDetailFromSignal(signum), |
| std::forward<Args>(args)...); |
| } |
| |
| template <typename... Args> |
| Status CancelledFromSignal(int signum, Args&&... args) { |
| return StatusFromSignal(signum, StatusCode::Cancelled, std::forward<Args>(args)...); |
| } |
| |
| ARROW_EXPORT |
| int ErrnoFromStatus(const Status&); |
| |
| // Always returns 0 on non-Windows platforms (for Python). |
| ARROW_EXPORT |
| int WinErrorFromStatus(const Status&); |
| |
| ARROW_EXPORT |
| int SignalFromStatus(const Status&); |
| |
| class ARROW_EXPORT TemporaryDir { |
| public: |
| ~TemporaryDir(); |
| |
| /// '/'-terminated path to the temporary dir |
| const PlatformFilename& path() { return path_; } |
| |
| /// Create a temporary subdirectory in the system temporary dir, |
| /// named starting with `prefix`. |
| static Result<std::unique_ptr<TemporaryDir>> Make(const std::string& prefix); |
| |
| private: |
| PlatformFilename path_; |
| |
| explicit TemporaryDir(PlatformFilename&&); |
| }; |
| |
| class ARROW_EXPORT SignalHandler { |
| public: |
| typedef void (*Callback)(int); |
| |
| SignalHandler(); |
| explicit SignalHandler(Callback cb); |
| #if ARROW_HAVE_SIGACTION |
| explicit SignalHandler(const struct sigaction& sa); |
| #endif |
| |
| Callback callback() const; |
| #if ARROW_HAVE_SIGACTION |
| const struct sigaction& action() const; |
| #endif |
| |
| protected: |
| #if ARROW_HAVE_SIGACTION |
| // Storing the full sigaction allows to restore the entire signal handling |
| // configuration. |
| struct sigaction sa_; |
| #else |
| Callback cb_; |
| #endif |
| }; |
| |
| /// \brief Return the current handler for the given signal number. |
| ARROW_EXPORT |
| Result<SignalHandler> GetSignalHandler(int signum); |
| |
| /// \brief Set a new handler for the given signal number. |
| /// |
| /// The old signal handler is returned. |
| ARROW_EXPORT |
| Result<SignalHandler> SetSignalHandler(int signum, const SignalHandler& handler); |
| |
| /// \brief Reinstate the signal handler |
| /// |
| /// For use in signal handlers. This is needed on platforms without sigaction() |
| /// such as Windows, as the default signal handler is restored there as |
| /// soon as a signal is raised. |
| ARROW_EXPORT |
| void ReinstateSignalHandler(int signum, SignalHandler::Callback handler); |
| |
| /// \brief Send a signal to the current process |
| /// |
| /// The thread which will receive the signal is unspecified. |
| ARROW_EXPORT |
| Status SendSignal(int signum); |
| |
| /// \brief Send a signal to the given thread |
| /// |
| /// This function isn't supported on Windows. |
| ARROW_EXPORT |
| Status SendSignalToThread(int signum, uint64_t thread_id); |
| |
| /// \brief Get an unpredictable random seed |
| /// |
| /// This function may be slightly costly, so should only be used to initialize |
| /// a PRNG, not to generate a large amount of random numbers. |
| /// It is better to use this function rather than std::random_device, unless |
| /// absolutely necessary (e.g. to generate a cryptographic secret). |
| ARROW_EXPORT |
| int64_t GetRandomSeed(); |
| |
| } // namespace internal |
| } // namespace arrow |