File indexing completed on 2023-09-24 04:04:48
0001 /* 0002 This file is part of the KDE libraries 0003 Copyright (C) 2004 Jarosław Staniek <staniek@kde.org> 0004 Copyright (C) 2009 Christian Ehrlicher <ch.ehrlicher@gmx.de> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License version 2 as published by the Free Software Foundation. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 */ 0020 0021 // needed for _wstat64 0022 #define __MSVCRT_VERSION__ 0x601 0023 0024 #include "kde_file.h" 0025 0026 #include <QFile> 0027 #include <errno.h> 0028 0029 #include <sys/utime.h> 0030 #include <sys/stat.h> 0031 #include <wchar.h> 0032 #define CONV(x) ((wchar_t*)x.utf16()) 0033 0034 /** @internal, from kdewin32 lib */ 0035 static int kdewin_fix_mode_string(char *fixed_mode, const char *mode) 0036 { 0037 if (strlen(mode) < 1 || strlen(mode) > 3) { 0038 errno = EINVAL; 0039 return 1; 0040 } 0041 0042 strncpy(fixed_mode, mode, 3); 0043 if (fixed_mode[0] == 'b' || fixed_mode[1] == 'b' || fixed_mode[0] == 't' || fixed_mode[1] == 't') { 0044 return 0; 0045 } 0046 /* no 't' or 'b': append 'b' */ 0047 if (fixed_mode[1] == '+') { 0048 fixed_mode[1] = 'b'; 0049 fixed_mode[2] = '+'; 0050 fixed_mode[3] = 0; 0051 } else { 0052 fixed_mode[1] = 'b'; 0053 fixed_mode[2] = 0; 0054 } 0055 return 0; 0056 } 0057 0058 /** @internal */ 0059 static int kdewin_fix_flags(int flags) 0060 { 0061 if ((flags & O_TEXT) == 0 && (flags & O_BINARY) == 0) { 0062 return flags | O_BINARY; 0063 } 0064 return flags; 0065 } 0066 0067 namespace KDE 0068 { 0069 int access(const QString &path, int mode) 0070 { 0071 int x_mode = 0; 0072 // X_OK gives an assert on msvc2005 and up - use stat() instead 0073 if ((mode & X_OK) == X_OK) { 0074 KDE_struct_stat st; 0075 if (KDE::stat(path, &st) != 0) { 0076 return 1; 0077 } 0078 if ((st.st_mode & S_IXUSR) != S_IXUSR) { 0079 return 1; 0080 } 0081 } 0082 mode &= ~X_OK; 0083 return _waccess(CONV(path), mode); 0084 } 0085 0086 int chmod(const QString &path, mode_t mode) 0087 { 0088 return _wchmod(CONV(path), mode); 0089 } 0090 0091 FILE *fopen(const QString &pathname, const char *mode) 0092 { 0093 return _wfopen(CONV(pathname), CONV(QString::fromLatin1(mode))); 0094 } 0095 0096 int lstat(const QString &path, KDE_struct_stat *buf) 0097 { 0098 return KDE::stat(path, buf); 0099 } 0100 0101 int mkdir(const QString &pathname, mode_t) 0102 { 0103 return _wmkdir(CONV(pathname)); 0104 } 0105 0106 int open(const QString &pathname, int flags, mode_t mode) 0107 { 0108 return _wopen(CONV(pathname), kdewin_fix_flags(flags), mode); 0109 } 0110 0111 int rename(const QString &in, const QString &out) 0112 { 0113 // better than :waccess/_wunlink/_wrename 0114 #ifndef _WIN32_WCE 0115 bool ok = (MoveFileExW(CONV(in), CONV(out), 0116 MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) != 0); 0117 #else 0118 bool ok = (MoveFileW(CONV(in), CONV(out)) != 0); 0119 #endif 0120 return ok ? 0 : -1; 0121 } 0122 0123 int stat(const QString &path, KDE_struct_stat *buf) 0124 { 0125 int result; 0126 #ifdef Q_CC_MSVC 0127 #ifndef _WIN32_WCE 0128 struct _stat64 s64; 0129 #else 0130 struct stat st; 0131 #endif 0132 #else 0133 struct __stat64 s64; 0134 #endif 0135 const int len = path.length(); 0136 if ((len == 2 || len == 3) && path[1] == QLatin1Char(':') && path[0].isLetter()) { 0137 /* 1) */ 0138 QString newPath(path); 0139 if (len == 2) { 0140 newPath += QLatin1Char('\\'); 0141 } 0142 #ifndef _WIN32_WCE 0143 result = _wstat64(CONV(newPath), &s64); 0144 #else 0145 result = wstat(CONV(newPath), &st); 0146 #endif 0147 } else if (len > 1 && (path.endsWith(QLatin1Char('\\')) || path.endsWith(QLatin1Char('/')))) { 0148 /* 2) */ 0149 const QString newPath = path.left(len - 1); 0150 #ifndef _WIN32_WCE 0151 result = _wstat64(CONV(newPath), &s64); 0152 #else 0153 result = wstat(CONV(newPath), &st); 0154 #endif 0155 } else { 0156 //TODO: is stat("/") ok? 0157 #ifndef _WIN32_WCE 0158 result = _wstat64(CONV(path), &s64); 0159 #else 0160 result = wstat(CONV(path), &st); 0161 #endif 0162 } 0163 if (result != 0) { 0164 return result; 0165 } 0166 // KDE5: fixme! 0167 #ifndef _WIN32_WCE 0168 buf->st_dev = s64.st_dev; 0169 buf->st_ino = s64.st_ino; 0170 buf->st_mode = s64.st_mode; 0171 buf->st_nlink = s64.st_nlink; 0172 #else 0173 buf->st_dev = st.st_dev; 0174 buf->st_ino = st.st_ino; 0175 buf->st_mode = st.st_mode; 0176 buf->st_nlink = st.st_nlink; 0177 #endif 0178 buf->st_uid = -2; // be in sync with Qt4 0179 buf->st_gid = -2; // be in sync with Qt4 0180 #ifndef _WIN32_WCE 0181 buf->st_rdev = s64.st_rdev; 0182 buf->st_size = s64.st_size; 0183 buf->st_atime = s64.st_atime; 0184 buf->st_mtime = s64.st_mtime; 0185 buf->st_ctime = s64.st_ctime; 0186 #else 0187 buf->st_rdev = st.st_rdev; 0188 buf->st_size = st.st_size; 0189 buf->st_atime = st.st_atime; 0190 buf->st_mtime = st.st_mtime; 0191 buf->st_ctime = st.st_ctime; 0192 #endif 0193 return result; 0194 } 0195 int utime(const QString &filename, struct utimbuf *buf) 0196 { 0197 #ifndef _WIN32_WCE 0198 return _wutime(CONV(filename), (struct _utimbuf *)buf); 0199 #else 0200 return _wutime(CONV(filename), (struct utimbuf *)buf); 0201 #endif 0202 } 0203 };