1 #define __CRT__NO_INLINE
2 #include <sys/stat.h>
3 #include <stdlib.h>
4
5 /**
6 * Returns _path without trailing slash if any
7 *
8 * - if _path has no trailing slash, the function returns it
9 * - if _path has a trailing slash, but is of the form C:/, then it returns it
10 * - otherwise, the function creates a new string, which is a copy of _path
11 * without the trailing slash. It is then the responsibility of the caller
12 * to free it.
13 */
14
15 static char*
_mingw_no_trailing_slash(const char * _path)16 _mingw_no_trailing_slash (const char* _path)
17 {
18 int len;
19 char *p;
20
21 p = (char*)_path;
22
23 if (_path && *_path) {
24 len = strlen (_path);
25
26 /* Ignore X:\ */
27
28 if (len <= 1 || ((len == 2 || len == 3) && _path[1] == ':'))
29 return p;
30
31 /* Check UNC \\abc\<name>\ */
32 if ((_path[0] == '\\' || _path[0] == '/')
33 && (_path[1] == '\\' || _path[1] == '/'))
34 {
35 const char *r = &_path[2];
36 while (*r != 0 && *r != '\\' && *r != '/')
37 ++r;
38 if (*r != 0)
39 ++r;
40 if (*r == 0)
41 return p;
42 while (*r != 0 && *r != '\\' && *r != '/')
43 ++r;
44 if (*r != 0)
45 ++r;
46 if (*r == 0)
47 return p;
48 }
49
50 if (_path[len - 1] == '/' || _path[len - 1] == '\\')
51 {
52 p = (char*)malloc (len);
53 memcpy (p, _path, len - 1);
54 p[len - 1] = '\0';
55 }
56 }
57
58 return p;
59 }
60 /* FIXME: Relying on _USE_32BIT_TIME_T, which is a user-macro,
61 during CRT compilation is plainly broken. Need an appropriate
62 implementation to provide users the ability of compiling the
63 CRT only with 32-bit time_t behavior. */
64 #if defined(_USE_32BIT_TIME_T)
65 int __cdecl
stat(const char * _Filename,struct stat * _Stat)66 stat(const char *_Filename,struct stat *_Stat)
67 {
68 struct _stat32 st;
69 char *_path = _mingw_no_trailing_slash(_Filename);
70
71 int ret=_stat32(_path,&st);
72
73 if (_path != _Filename)
74 free (_path);
75
76 if (ret == -1) {
77 memset(_Stat,0,sizeof(struct stat));
78 return -1;
79 }
80 /* struct stat and struct _stat32
81 are the same for this case. */
82 memcpy(_Stat, &st, sizeof(struct _stat32));
83 return ret;
84 }
85 #else
86 int __cdecl
stat(const char * _Filename,struct stat * _Stat)87 stat(const char *_Filename,struct stat *_Stat)
88 {
89 struct _stat64 st;
90 char *_path = _mingw_no_trailing_slash(_Filename);
91
92 int ret=_stat64(_path,&st);
93
94 if (_path != _Filename)
95 free (_path);
96
97 if (ret == -1) {
98 memset(_Stat,0,sizeof(struct stat));
99 return -1;
100 }
101 /* struct stat and struct _stat64i32
102 are the same for this case. */
103 _Stat->st_dev=st.st_dev;
104 _Stat->st_ino=st.st_ino;
105 _Stat->st_mode=st.st_mode;
106 _Stat->st_nlink=st.st_nlink;
107 _Stat->st_uid=st.st_uid;
108 _Stat->st_gid=st.st_gid;
109 _Stat->st_rdev=st.st_rdev;
110 _Stat->st_size=(_off_t) st.st_size;
111 _Stat->st_atime=st.st_atime;
112 _Stat->st_mtime=st.st_mtime;
113 _Stat->st_ctime=st.st_ctime;
114 return ret;
115 }
116 #endif
117
118 /* Add __imp__fstat and __imp__stat symbols. */
119 int (*__MINGW_IMP_SYMBOL(stat))(const char *,struct stat *) = &stat;
120
121