LCOV - code coverage report
Current view: top level - core/filesystem - SPFilesystemNativePosix.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 81 98 82.7 %
Date: 2024-05-12 00:16:13 Functions: 15 17 88.2 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2016-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #include "SPFilesystem.h"
      25             : 
      26             : #ifndef WIN32
      27             : 
      28             : #include <sys/time.h>
      29             : #include <unistd.h>
      30             : #include <sys/types.h>
      31             : #include <sys/stat.h>
      32             : #include <errno.h>
      33             : #include <dirent.h>
      34             : #include <utime.h>
      35             : 
      36             : namespace STAPPLER_VERSIONIZED stappler::filesystem::native {
      37             : 
      38             : template <>
      39           0 : memory::PoolInterface::StringType nativeToPosix<memory::PoolInterface>(StringView path) {
      40           0 :         return path.str<memory::PoolInterface>();
      41             : }
      42             : 
      43             : template <>
      44          25 : memory::PoolInterface::StringType posixToNative<memory::PoolInterface>(StringView path) {
      45          25 :         return path.str<memory::PoolInterface>();
      46             : }
      47             : 
      48             : template <>
      49           0 : memory::StandartInterface::StringType nativeToPosix<memory::StandartInterface>(StringView path) {
      50           0 :         return path.str<memory::StandartInterface>();
      51             : }
      52             : 
      53             : template <>
      54         750 : memory::StandartInterface::StringType posixToNative<memory::StandartInterface>(StringView path) {
      55         750 :         return path.str<memory::StandartInterface>();
      56             : }
      57             : 
      58             : template <>
      59         200 : memory::PoolInterface::StringType getcwd_fn<memory::PoolInterface>() {
      60         200 :         char cwd[1024] = { 0 };
      61         200 :         if (getcwd(cwd, 1024 - 1) != NULL) {
      62         200 :                 return memory::PoolInterface::StringType((const char *)cwd);
      63             :         }
      64           0 :         return memory::PoolInterface::StringType();
      65             : }
      66             : 
      67             : template <>
      68        3209 : memory::StandartInterface::StringType getcwd_fn<memory::StandartInterface>() {
      69        3209 :         char cwd[1024] = { 0 };
      70        3209 :         if (getcwd(cwd, 1024 - 1) != NULL) {
      71        3209 :                 return memory::StandartInterface::StringType((const char *)cwd);
      72             :         }
      73           0 :         return memory::StandartInterface::StringType();
      74             : }
      75             : 
      76             : #define SP_TERMINATED_DATA(view) (view.terminated()?view.data():view.str<memory::StandartInterface>().data())
      77             : 
      78        2245 : bool remove_fn(StringView path) {
      79        2245 :         return ::remove(SP_TERMINATED_DATA(path)) == 0;
      80             : }
      81             : 
      82         200 : bool unlink_fn(StringView path) {
      83         200 :         return ::unlink(SP_TERMINATED_DATA(path)) == 0;
      84             : }
      85             : 
      86         475 : bool mkdir_fn(StringView path) {
      87         475 :     mode_t process_mask = ::umask(0);
      88         475 :         bool ret = ::mkdir(SP_TERMINATED_DATA(path), (mode_t)(S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) == 0;
      89         475 :     ::umask(process_mask);
      90         475 :     return ret;
      91             : }
      92             : 
      93        1463 : bool access_fn(StringView path, Access mode) {
      94        1463 :         int m = 0;
      95        1463 :         switch (mode) {
      96           0 :         case Access::Execute: m = X_OK; break;
      97        1463 :         case Access::Exists: m = F_OK; break;
      98           0 :         case Access::Read: m = R_OK; break;
      99           0 :         case Access::Write: m = W_OK; break;
     100             :         }
     101        1463 :         return ::access(SP_TERMINATED_DATA(path), m) == 0;
     102             : }
     103             : 
     104        1700 : bool stat_fn(StringView path, Stat &stat) {
     105             :         struct stat s;
     106        1700 :         if(::stat(SP_TERMINATED_DATA(path), &s) == 0 ) {
     107        1475 :                 stat.size = size_t(s.st_size);
     108        1475 :                 stat.isDir = (s.st_mode & S_IFDIR);
     109             : #if LINUX || ANDROID
     110        1475 :                 stat.atime = Time::microseconds(s.st_atime * 1000000 + s.st_atim.tv_nsec / 1000);
     111        1475 :                 stat.ctime = Time::microseconds(s.st_ctime * 1000000 + s.st_ctim.tv_nsec / 1000);
     112        1475 :                 stat.mtime = Time::microseconds(s.st_mtime * 1000000 + s.st_mtim.tv_nsec / 1000);
     113             : #else
     114             :                 // some fruit systems just made by assholes
     115             :                 stat.atime = Time::seconds(s.st_atime);
     116             :                 stat.ctime = Time::seconds(s.st_ctime);
     117             :                 stat.mtime = Time::seconds(s.st_mtime);
     118             : #endif
     119        1475 :                 return true;
     120             :         } else {
     121         225 :                 return false;
     122             :         }
     123             : }
     124             : 
     125          50 : bool touch_fn(StringView path) {
     126          50 :         return utime(SP_TERMINATED_DATA(path), NULL) == 0;
     127             : }
     128             : 
     129       17975 : void ftw_fn(StringView path, const Callback<void(StringView path, bool isFile)> &callback, int depth, bool dirFirst) {
     130       17975 :         auto dp = opendir(SP_TERMINATED_DATA(path));
     131       17975 :         if (dp == NULL) {
     132       17525 :                 if (access(SP_TERMINATED_DATA(path), F_OK) != -1) {
     133       17500 :                         callback(path, true);
     134             :                 }
     135             :         } else {
     136         450 :                 if (dirFirst) {
     137         225 :                         callback(path, false);
     138             :                 }
     139         450 :                 if (depth < 0 || depth > 0) {
     140             :                         struct dirent *entry;
     141       18450 :                         while ((entry = readdir(dp))) {
     142       18200 :                                 if (strcmp(entry->d_name, "..") != 0 && strcmp(entry->d_name, ".") != 0) {
     143       17700 :                                         auto newPath = filepath::merge<memory::StandartInterface>(path, entry->d_name);
     144       17700 :                                         ftw_fn(newPath, callback, depth - 1, dirFirst);
     145       17700 :                                 }
     146             :                         }
     147             :                 }
     148         450 :                 if (!dirFirst) {
     149         225 :                         callback(path, false);
     150             :                 }
     151         450 :                 closedir(dp);
     152             :         }
     153       17975 : }
     154         593 : bool ftw_b_fn(StringView path, const Callback<bool(StringView path, bool isFile)> &callback, int depth, bool dirFirst) {
     155         593 :         auto dp = opendir(SP_TERMINATED_DATA(path));
     156         593 :         if (dp == NULL) {
     157         412 :                 if (access(SP_TERMINATED_DATA(path), F_OK) != -1) {
     158         389 :                         return callback(path, true);
     159             :                 }
     160             :         } else {
     161         181 :                 if (dirFirst) {
     162           0 :                         if (!callback(path, false)) {
     163           0 :                                 closedir(dp);
     164           0 :                                 return false;
     165             :                         }
     166             :                 }
     167         181 :                 if (depth < 0 || depth > 0) {
     168             :                         struct dirent *entry;
     169        1061 :                         while ((entry = readdir(dp))) {
     170         880 :                                 if (strcmp(entry->d_name, "..") != 0 && strcmp(entry->d_name, ".") != 0) {
     171         518 :                                         auto newPath = filepath::merge<memory::StandartInterface>(path, entry->d_name);
     172         518 :                                         if (!ftw_b_fn(newPath, callback, depth - 1, dirFirst)) {
     173           0 :                                                 closedir(dp);
     174           0 :                                                 return false;
     175             :                                         }
     176         518 :                                 }
     177             :                         }
     178             :                 }
     179         181 :                 if (!dirFirst) {
     180         181 :                         if (!callback(path, false)) {
     181           0 :                                 closedir(dp);
     182           0 :                                 return false;
     183             :                         }
     184             :                 }
     185         181 :                 closedir(dp);
     186             :         }
     187         204 :         return true;
     188             : }
     189             : 
     190         225 : bool rename_fn(StringView source, StringView dest) {
     191         225 :         return rename(SP_TERMINATED_DATA(source), SP_TERMINATED_DATA(dest)) == 0;
     192             : }
     193             : 
     194       24334 : FILE *fopen_fn(StringView path, StringView mode) {
     195       24334 :         return fopen(SP_TERMINATED_DATA(path), SP_TERMINATED_DATA(mode));
     196             : }
     197             : 
     198         275 : bool write_fn(StringView path, const unsigned char *data, size_t len) {
     199         275 :         std::ofstream f(SP_TERMINATED_DATA(path));
     200         275 :         if (f.is_open()) {
     201         275 :                 f.write((const char *)data, len);
     202         275 :                 f.close();
     203         275 :                 return true;
     204             :         }
     205           0 :         return false;
     206         275 : }
     207             : 
     208             : #undef SP_TERMINATED_DATA
     209             : 
     210             : }
     211             : 
     212             : #endif

Generated by: LCOV version 1.14