aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2012-03-30 16:11:26 +0100
committerRon Yorston <rmy@pobox.com>2012-03-30 16:11:26 +0100
commitf9f2117d5b7057f986850741b85bde5c30590b02 (patch)
tree5a069c443649f216bd1fe4474e80ebc37c72a38d
parent40b68b6ecaf47c6a68bfa4158a61ce41bffa8284 (diff)
downloadbusybox-w32-f9f2117d5b7057f986850741b85bde5c30590b02.tar.gz
busybox-w32-f9f2117d5b7057f986850741b85bde5c30590b02.tar.bz2
busybox-w32-f9f2117d5b7057f986850741b85bde5c30590b02.zip
Update mingw.c from latest git/compat
-rw-r--r--Config.in1
-rw-r--r--configs/mingw32_defconfig6
-rw-r--r--coreutils/cp.c5
-rw-r--r--coreutils/libcoreutils/cp_mv_stat.c5
-rw-r--r--include/mingw.h13
-rw-r--r--libbb/copy_file.c5
-rw-r--r--libbb/recursive_action.c5
-rw-r--r--win32/mingw.c115
8 files changed, 75 insertions, 80 deletions
diff --git a/Config.in b/Config.in
index cd51e2b45..1ed1bc0d4 100644
--- a/Config.in
+++ b/Config.in
@@ -20,6 +20,7 @@ config PLATFORM_POSIX
20 20
21config PLATFORM_MINGW32 21config PLATFORM_MINGW32
22 bool "MS Windows (MinGW port)" 22 bool "MS Windows (MinGW port)"
23 select LFS
23 24
24endchoice 25endchoice
25 26
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig
index 444b31145..cabb0b4f0 100644
--- a/configs/mingw32_defconfig
+++ b/configs/mingw32_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Busybox version: 1.20.0.git 3# Busybox version: 1.20.0.git
4# Fri Mar 23 12:07:27 2012 4# Tue Mar 27 11:53:57 2012
5# 5#
6CONFIG_HAVE_DOT_CONFIG=y 6CONFIG_HAVE_DOT_CONFIG=y
7# CONFIG_PLATFORM_POSIX is not set 7# CONFIG_PLATFORM_POSIX is not set
@@ -63,7 +63,7 @@ CONFIG_BUSYBOX_EXEC_PATH=""
63# CONFIG_BUILD_LIBBUSYBOX is not set 63# CONFIG_BUILD_LIBBUSYBOX is not set
64# CONFIG_FEATURE_INDIVIDUAL is not set 64# CONFIG_FEATURE_INDIVIDUAL is not set
65# CONFIG_FEATURE_SHARED_BUSYBOX is not set 65# CONFIG_FEATURE_SHARED_BUSYBOX is not set
66# CONFIG_LFS is not set 66CONFIG_LFS=y
67CONFIG_CROSS_COMPILER_PREFIX="i686-pc-mingw32-" 67CONFIG_CROSS_COMPILER_PREFIX="i686-pc-mingw32-"
68CONFIG_SYSROOT="" 68CONFIG_SYSROOT=""
69CONFIG_EXTRA_CFLAGS="-g -O0" 69CONFIG_EXTRA_CFLAGS="-g -O0"
@@ -187,7 +187,7 @@ CONFIG_FEATURE_DATE_COMPAT=y
187CONFIG_TEST=y 187CONFIG_TEST=y
188CONFIG_FEATURE_TEST_64=y 188CONFIG_FEATURE_TEST_64=y
189CONFIG_TOUCH=y 189CONFIG_TOUCH=y
190# CONFIG_FEATURE_TOUCH_SUSV3 is not set 190CONFIG_FEATURE_TOUCH_SUSV3=y
191CONFIG_TR=y 191CONFIG_TR=y
192CONFIG_FEATURE_TR_CLASSES=y 192CONFIG_FEATURE_TR_CLASSES=y
193CONFIG_FEATURE_TR_EQUIV=y 193CONFIG_FEATURE_TR_EQUIV=y
diff --git a/coreutils/cp.c b/coreutils/cp.c
index 45efaba72..de2e512be 100644
--- a/coreutils/cp.c
+++ b/coreutils/cp.c
@@ -148,13 +148,8 @@ int cp_main(int argc, char **argv)
148 last = argv[argc - 1]; 148 last = argv[argc - 1];
149 /* If there are only two arguments and... */ 149 /* If there are only two arguments and... */
150 if (argc == 2) { 150 if (argc == 2) {
151#if ENABLE_PLATFORM_MINGW32
152 /* stat can't be aliased, and MinGW uses lstat anyway */
153 s_flags = cp_mv_stat2(*argv, &source_stat, lstat);
154#else
155 s_flags = cp_mv_stat2(*argv, &source_stat, 151 s_flags = cp_mv_stat2(*argv, &source_stat,
156 (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); 152 (flags & FILEUTILS_DEREFERENCE) ? stat : lstat);
157#endif
158 if (s_flags < 0) 153 if (s_flags < 0)
159 return EXIT_FAILURE; 154 return EXIT_FAILURE;
160 d_flags = cp_mv_stat(last, &dest_stat); 155 d_flags = cp_mv_stat(last, &dest_stat);
diff --git a/coreutils/libcoreutils/cp_mv_stat.c b/coreutils/libcoreutils/cp_mv_stat.c
index 1af2ebb71..5ba07ecc3 100644
--- a/coreutils/libcoreutils/cp_mv_stat.c
+++ b/coreutils/libcoreutils/cp_mv_stat.c
@@ -46,10 +46,5 @@ int FAST_FUNC cp_mv_stat2(const char *fn, struct stat *fn_stat, stat_func sf)
46 46
47int FAST_FUNC cp_mv_stat(const char *fn, struct stat *fn_stat) 47int FAST_FUNC cp_mv_stat(const char *fn, struct stat *fn_stat)
48{ 48{
49#if ENABLE_PLATFORM_MINGW32
50 /* stat can't be aliased, and MinGW uses lstat anyway */
51 return cp_mv_stat2(fn, fn_stat, lstat);
52#else
53 return cp_mv_stat2(fn, fn_stat, stat); 49 return cp_mv_stat2(fn, fn_stat, stat);
54#endif
55} 50}
diff --git a/include/mingw.h b/include/mingw.h
index 138275588..fd0b09b15 100644
--- a/include/mingw.h
+++ b/include/mingw.h
@@ -234,19 +234,20 @@ typedef int nlink_t;
234NOIMPL(fchmod,int fildes UNUSED_PARAM, mode_t mode UNUSED_PARAM); 234NOIMPL(fchmod,int fildes UNUSED_PARAM, mode_t mode UNUSED_PARAM);
235NOIMPL(fchown,int fd UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM); 235NOIMPL(fchown,int fd UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM);
236int mingw_mkdir(const char *path, int mode); 236int mingw_mkdir(const char *path, int mode);
237#define mkdir mingw_mkdir
237 238
238/* Use mingw_lstat() instead of lstat()/stat() and 239/* Use mingw_lstat()/mingw_stat() instead of lstat()/stat() and
239 * mingw_fstat() instead of fstat() on Windows. 240 * mingw_fstat() instead of fstat() on Windows.
240 */ 241 */
242#define off_t off64_t
243#define lseek _lseeki64
244#define stat _stati64
241int mingw_lstat(const char *file_name, struct stat *buf); 245int mingw_lstat(const char *file_name, struct stat *buf);
246int mingw_stat(const char *file_name, struct stat *buf);
242int mingw_fstat(int fd, struct stat *buf); 247int mingw_fstat(int fd, struct stat *buf);
243
244#define mkdir mingw_mkdir
245#define stat(x,y) mingw_lstat(x,y)
246#define lseek _lseeki64
247#define fstat mingw_fstat 248#define fstat mingw_fstat
248#define lstat mingw_lstat 249#define lstat mingw_lstat
249#define _stati64 mingw_lstat 250#define _stati64(x,y) mingw_stat(x,y)
250 251
251/* 252/*
252 * sys/sysmacros.h 253 * sys/sysmacros.h
diff --git a/libbb/copy_file.c b/libbb/copy_file.c
index 48aaf481d..be65c4b47 100644
--- a/libbb/copy_file.c
+++ b/libbb/copy_file.c
@@ -85,12 +85,7 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags)
85/* Inverse of cp -d ("cp without -d") */ 85/* Inverse of cp -d ("cp without -d") */
86#define FLAGS_DEREF (flags & (FILEUTILS_DEREFERENCE + FILEUTILS_DEREFERENCE_L0)) 86#define FLAGS_DEREF (flags & (FILEUTILS_DEREFERENCE + FILEUTILS_DEREFERENCE_L0))
87 87
88#if ENABLE_PLATFORM_MINGW32
89 /* stat can't be aliased, and MinGW uses lstat anyway */
90 if (lstat(source, &source_stat) < 0) {
91#else
92 if ((FLAGS_DEREF ? stat : lstat)(source, &source_stat) < 0) { 88 if ((FLAGS_DEREF ? stat : lstat)(source, &source_stat) < 0) {
93#endif
94 /* This may be a dangling symlink. 89 /* This may be a dangling symlink.
95 * Making [sym]links to dangling symlinks works, so... */ 90 * Making [sym]links to dangling symlinks works, so... */
96 if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) 91 if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK))
diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c
index 560c93cad..b5cf7c0ab 100644
--- a/libbb/recursive_action.c
+++ b/libbb/recursive_action.c
@@ -73,12 +73,7 @@ int FAST_FUNC recursive_action(const char *fileName,
73 if (depth == 0) 73 if (depth == 0)
74 follow = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0; 74 follow = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0;
75 follow &= flags; 75 follow &= flags;
76#if ENABLE_PLATFORM_MINGW32
77 /* stat can't be aliased, and MinGW uses lstat anyway */
78 status = lstat(fileName, &statbuf);
79#else
80 status = (follow ? stat : lstat)(fileName, &statbuf); 76 status = (follow ? stat : lstat)(fileName, &statbuf);
81#endif
82 if (status < 0) { 77 if (status < 0) {
83#ifdef DEBUG_RECURS_ACTION 78#ifdef DEBUG_RECURS_ACTION
84 bb_error_msg("status=%d flags=%x", status, flags); 79 bb_error_msg("status=%d flags=%x", status, flags);
diff --git a/win32/mingw.c b/win32/mingw.c
index df413d18e..219ef96b8 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -130,7 +130,7 @@ int mingw_open (const char *filename, int oflags, ...)
130 errno = ENOSYS; 130 errno = ENOSYS;
131 return -1; 131 return -1;
132 } 132 }
133 if (!strcmp(filename, "/dev/null")) 133 if (filename && !strcmp(filename, "/dev/null"))
134 filename = "nul"; 134 filename = "nul";
135 fd = open(filename, oflags, mode); 135 fd = open(filename, oflags, mode);
136 if (fd < 0 && (oflags & O_CREAT) && errno == EACCES) { 136 if (fd < 0 && (oflags & O_CREAT) && errno == EACCES) {
@@ -142,11 +142,11 @@ int mingw_open (const char *filename, int oflags, ...)
142} 142}
143 143
144#undef fopen 144#undef fopen
145FILE *mingw_fopen (const char *filename, const char *mode) 145FILE *mingw_fopen (const char *filename, const char *otype)
146{ 146{
147 if (!strcmp(filename, "/dev/null")) 147 if (filename && !strcmp(filename, "/dev/null"))
148 filename = "nul"; 148 filename = "nul";
149 return fopen(filename, mode); 149 return fopen(filename, otype);
150} 150}
151 151
152#undef dup2 152#undef dup2
@@ -156,12 +156,20 @@ int mingw_dup2 (int fd, int fdto)
156 return ret != -1 ? fdto : -1; 156 return ret != -1 ? fdto : -1;
157} 157}
158 158
159static inline time_t filetime_to_time_t(const FILETIME *ft) 159/*
160 * The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC.
161 * Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch.
162 */
163static inline long long filetime_to_hnsec(const FILETIME *ft)
160{ 164{
161 long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime; 165 long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
162 winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */ 166 /* Windows to Unix Epoch conversion */
163 winTime /= 10000000; /* Nano to seconds resolution */ 167 return winTime - 116444736000000000LL;
164 return (time_t)winTime; 168}
169
170static inline time_t filetime_to_time_t(const FILETIME *ft)
171{
172 return (time_t)(filetime_to_hnsec(ft) / 10000000);
165} 173}
166 174
167static inline int file_attr_to_st_mode (DWORD attr) 175static inline int file_attr_to_st_mode (DWORD attr)
@@ -199,12 +207,16 @@ static inline int get_file_attr(const char *fname, WIN32_FILE_ATTRIBUTE_DATA *fd
199/* We keep the do_lstat code in a separate function to avoid recursion. 207/* We keep the do_lstat code in a separate function to avoid recursion.
200 * When a path ends with a slash, the stat will fail with ENOENT. In 208 * When a path ends with a slash, the stat will fail with ENOENT. In
201 * this case, we strip the trailing slashes and stat again. 209 * this case, we strip the trailing slashes and stat again.
210 *
211 * If follow is true then act like stat() and report on the link
212 * target. Otherwise report on the link itself.
202 */ 213 */
203static int do_lstat(const char *file_name, struct stat *buf) 214static int do_lstat(int follow, const char *file_name, struct stat *buf)
204{ 215{
216 int err;
205 WIN32_FILE_ATTRIBUTE_DATA fdata; 217 WIN32_FILE_ATTRIBUTE_DATA fdata;
206 218
207 if (!(errno = get_file_attr(file_name, &fdata))) { 219 if (!(err = get_file_attr(file_name, &fdata))) {
208 int len = strlen(file_name); 220 int len = strlen(file_name);
209 221
210 buf->st_ino = 0; 222 buf->st_ino = 0;
@@ -220,8 +232,28 @@ static int do_lstat(const char *file_name, struct stat *buf)
220 buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime)); 232 buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
221 buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime)); 233 buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
222 buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime)); 234 buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
235 if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
236 WIN32_FIND_DATAA findbuf;
237 HANDLE handle = FindFirstFileA(file_name, &findbuf);
238 if (handle != INVALID_HANDLE_VALUE) {
239 if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
240 (findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
241 if (follow) {
242 char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
243 buf->st_size = readlink(file_name, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
244 } else {
245 buf->st_mode = S_IFLNK;
246 }
247 buf->st_mode |= S_IREAD;
248 if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
249 buf->st_mode |= S_IWRITE;
250 }
251 FindClose(handle);
252 }
253 }
223 return 0; 254 return 0;
224 } 255 }
256 errno = err;
225 return -1; 257 return -1;
226} 258}
227 259
@@ -231,12 +263,12 @@ static int do_lstat(const char *file_name, struct stat *buf)
231 * complete. Note that Git stat()s are redirected to mingw_lstat() 263 * complete. Note that Git stat()s are redirected to mingw_lstat()
232 * too, since Windows doesn't really handle symlinks that well. 264 * too, since Windows doesn't really handle symlinks that well.
233 */ 265 */
234int mingw_lstat(const char *file_name, struct stat *buf) 266static int do_stat_internal(int follow, const char *file_name, struct stat *buf)
235{ 267{
236 int namelen; 268 int namelen;
237 static char alt_name[PATH_MAX]; 269 static char alt_name[PATH_MAX];
238 270
239 if (!do_lstat(file_name, buf)) 271 if (!do_lstat(follow, file_name, buf))
240 return 0; 272 return 0;
241 273
242 /* if file_name ended in a '/', Windows returned ENOENT; 274 /* if file_name ended in a '/', Windows returned ENOENT;
@@ -255,7 +287,16 @@ int mingw_lstat(const char *file_name, struct stat *buf)
255 287
256 memcpy(alt_name, file_name, namelen); 288 memcpy(alt_name, file_name, namelen);
257 alt_name[namelen] = 0; 289 alt_name[namelen] = 0;
258 return do_lstat(alt_name, buf); 290 return do_lstat(follow, alt_name, buf);
291}
292
293int mingw_lstat(const char *file_name, struct stat *buf)
294{
295 return do_stat_internal(0, file_name, buf);
296}
297int mingw_stat(const char *file_name, struct stat *buf)
298{
299 return do_stat_internal(1, file_name, buf);
259} 300}
260 301
261#undef fstat 302#undef fstat
@@ -374,43 +415,15 @@ int mkstemp(char *template)
374 return open(filename, O_RDWR | O_CREAT, 0600); 415 return open(filename, O_RDWR | O_CREAT, 0600);
375} 416}
376 417
377/* 418int gettimeofday(struct timeval *tv, void *tz UNUSED_PARAM)
378 * This is like mktime, but without normalization of tm_wday and tm_yday.
379 */
380static time_t tm_to_time_t(const struct tm *tm)
381{ 419{
382 static const int mdays[] = { 420 FILETIME ft;
383 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 421 long long hnsec;
384 };
385 int year = tm->tm_year - 70;
386 int month = tm->tm_mon;
387 int day = tm->tm_mday;
388 422
389 if (year < 0 || year > 129) /* algo only works for 1970-2099 */ 423 GetSystemTimeAsFileTime(&ft);
390 return -1; 424 hnsec = filetime_to_hnsec(&ft);
391 if (month < 0 || month > 11) /* array bounds */ 425 tv->tv_sec = hnsec / 10000000;
392 return -1; 426 tv->tv_usec = (hnsec % 10000000) / 10;
393 if (month < 2 || (year + 2) % 4)
394 day--;
395 return (year * 365 + (year + 1) / 4 + mdays[month] + day) * 24*60*60UL +
396 tm->tm_hour * 60*60 + tm->tm_min * 60 + tm->tm_sec;
397}
398
399int gettimeofday(struct timeval *tv, void *tz)
400{
401 SYSTEMTIME st;
402 struct tm tm;
403 GetSystemTime(&st);
404 tm.tm_year = st.wYear-1900;
405 tm.tm_mon = st.wMonth-1;
406 tm.tm_mday = st.wDay;
407 tm.tm_hour = st.wHour;
408 tm.tm_min = st.wMinute;
409 tm.tm_sec = st.wSecond;
410 tv->tv_sec = tm_to_time_t(&tm);
411 if (tv->tv_sec < 0)
412 return -1;
413 tv->tv_usec = st.wMilliseconds*1000;
414 return 0; 427 return 0;
415} 428}
416 429
@@ -482,7 +495,7 @@ int mingw_rename(const char *pold, const char *pnew)
482 return -1; 495 return -1;
483} 496}
484 497
485struct passwd *getpwuid(int uid) 498struct passwd *getpwuid(int uid UNUSED_PARAM)
486{ 499{
487 static char user_name[100]; 500 static char user_name[100];
488 static struct passwd p; 501 static struct passwd p;
@@ -622,7 +635,7 @@ sighandler_t mingw_signal(int sig, sighandler_t handler)
622 635
623int link(const char *oldpath, const char *newpath) 636int link(const char *oldpath, const char *newpath)
624{ 637{
625 typedef BOOL WINAPI (*T)(const char*, const char*, LPSECURITY_ATTRIBUTES); 638 typedef BOOL (WINAPI *T)(const char*, const char*, LPSECURITY_ATTRIBUTES);
626 static T create_hard_link = NULL; 639 static T create_hard_link = NULL;
627 if (!create_hard_link) { 640 if (!create_hard_link) {
628 create_hard_link = (T) GetProcAddress( 641 create_hard_link = (T) GetProcAddress(
@@ -702,7 +715,7 @@ int mingw_unlink(const char *pathname)
702 return unlink(pathname); 715 return unlink(pathname);
703} 716}
704 717
705char *strptime(const char *s, const char *format, struct tm *tm) 718char *strptime(const char *s UNUSED_PARAM, const char *format UNUSED_PARAM, struct tm *tm UNUSED_PARAM)
706{ 719{
707 return NULL; 720 return NULL;
708} 721}