From: Linux <li...@in...> - 2012-02-09 11:30:05
|
I coded a small utility in "C" using the Code::Blocks IDE on 32 Bit Linux for distribution. The utility searches, identifies and can delete files with identical content. I also want to distribute a Windows version of the utility but can't get it to compile and work on Windows 7 using the Mingw 4.6.3 with the Code::Blocks IDE for Windows. Under Windows, the complier rejects these declarations and functions: struct stat64 lst; stat64(path, &lst); Using 'stat' instead of 'stat64' will complile without errors but 'opendir()' returns 0. readir() and closedir() also fail; The code compiles and works as it should on 32 and 64 bit Linux. I can not find the MinGW specific sources for the functions stat(), stat64(), opendir(), readdir(), closedir() and other functions. ' ------------------------------------------ #define _LARGEFILE64_SOURCE #define _FILE_OFFSET_BITS 64 #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> #define _MAX_PATH 260 #define SLASH '/' void read_dirs(char *); int main(int argc, char* argv[]) { char *topdir; char defaultdir[2]="."; if (argc != 2) { printf("Argument not supplied - using current directory.\n"); topdir=defaultdir; } else topdir=argv[1]; printf("Directory scan of %s\n",topdir); read_dirs(topdir); printf("done.\n"); exit(0); } void read_dirs(char *dir) { char path[_MAX_PATH]; struct dirent *entry; DIR *d; struct stat lst; /*should be 'struct stat64 lst*/ int rec_no = 0; d = opendir(dir); if( d == NULL ) { return; } while ( (entry = readdir(d)) ) { if( strcmp( entry->d_name, "." ) == 0 || strcmp( entry->d_name, ".." ) == 0 ) { continue; } sprintf(path,"%s/%s", dir, entry->d_name); if (stat(path, &lst) < 0) /* should be stat64*/ continue; if ( S_ISDIR(lst.st_mode) ) { chdir(entry->d_name); read_dirs("."); chdir(".."); } else { getcwd(path, _MAX_PATH); printf("%6d %12lld %s%c%s\n", rec_no, lst.st_size, path, SLASH, entry->d_name); rec_no++; } } closedir(d); } ----------------------------------- Thanks in advance for your assistance. Hans |
From: Keith M. <kei...@us...> - 2012-02-09 13:50:41
|
On 9 February 2012 11:29, Linux <linux@...> wrote: > Under Windows, the complier rejects these declarations and functions: > > struct stat64 lst; > stat64(path, &lst); In the windows world, you must prefix underscores: struct __stat64 lst; _stat64( path, &lst ); > Using 'stat' instead of 'stat64' will complile without errors but > 'opendir()' returns 0. readir() and closedir() also fail; WJFFM. $ cat dtree.c #include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <string.h> #if HAVE_DIRENT_D_TYPE_DT_DIR # define D_TYPE_IS_DT_DIR(ent) ((ent)->d_type == DT_DIR) #else # include <sys/types.h> # include <sys/stat.h> # include <unistd.h> static __inline__ int D_TYPE_IS_DT_DIR( const struct dirent* ent ) { struct stat info; if( stat( ent->d_name, &info ) == 0 ) return S_ISDIR( info.st_mode ); return 0; } #endif void walkcwd( int level ) { const char *cwdname = "."; const char *parent = ".."; DIR *cwd = opendir( cwdname ); if( cwd != NULL) { struct dirent *ent; while( (ent = readdir( cwd )) != NULL ) { printf( "%*s%s\n", level, "", ent->d_name ); if( (D_TYPE_IS_DT_DIR( ent )) && ! (strcmp( ent->d_name, cwdname ) == 0) && ! (strcmp( ent->d_name, parent ) == 0) ) { chdir( ent->d_name ); walkcwd( 2 + level ); chdir( parent ); } } closedir( cwd ); } } int main(){ walkcwd( 2 ); return 0; } $ gcc -o dtree dtree.c $ ./dtree ...displays tree from $PWD... Also, with current CVS snapshot of mingwrt, (not yet released): $ gcc -o dtree -DHAVE_DIRENT_D_TYPE_DT_DIR=1 dtree.c $ ./dtree works equally well using the DT_DIR attribute from dirent.h directly, without using stat() at all. > #define _LARGEFILE64_SOURCE > #define _FILE_OFFSET_BITS 64 These have no effect on windows. > #include <unistd.h> > #include <stdio.h> > #include <stdlib.h> > #include <dirent.h> > #include <string.h> > #include <sys/stat.h> Conspicuously absent: 'man 2 stat' on my Linux box says that you also need, (since you are also supporting Linux hosts): #include <sys/types.h> > #define _MAX_PATH 260 You should let the system headers define this. -- Regards, Keith. |
From: Keith M. <kei...@us...> - 2012-02-09 14:17:13
|
To further qualify my earlier reply: On 9 February 2012 11:29, Linux <linux@...> wrote: > I also want to distribute a Windows version of the utility but can't get > it to compile and work on Windows 7 using the Mingw 4.6.3 The most recent release, from this project, is MinGW GCC-4.6.2; this is what I have used, to build my example. > with the Code::Blocks IDE for Windows. While this may be your preference, it shouldn't be relevant to the distributed code. I prefer to use only vim. > I can not find the MinGW specific sources for the functions stat(), > stat64() ... nor will you, because these come directly from Microsoft; (there is no stat64() anyway; it is _stat64()). > ... opendir(), readdir(), closedir() and other functions. These three, and others related to them, are implemented in mingwex/dirent.c, in the mingwrt source distribution, or in CVS: http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/mingw/include/dirent.h?cvsroot=src http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/mingw/mingwex/dirent.c?cvsroot=src -- Regards, Keith. |
From: Keith M. <kei...@us...> - 2012-02-10 11:06:00
|
Please keep replies on-list; I've taken the liberty of forwarding this: ---------- Forwarded message ---------- On Thu, 2012-02-09 at 14:17 +0000, Keith Marshall wrote: > To further qualify my earlier reply: > > On 9 February 2012 11:29, Linux <linux@...> wrote: > > I also want to distribute a Windows version of the utility but can't get > > it to compile and work on Windows 7 using the Mingw 4.6.3 > > The most recent release, from this project, is MinGW GCC-4.6.2; > this is what I have used, to build my example. > > > with the Code::Blocks IDE for Windows. > > While this may be your preference, it shouldn't be relevant to the > distributed code. I prefer to use only vim. > > > I can not find the MinGW specific sources for the functions stat(), > > stat64() ... > > nor will you, because these come directly from Microsoft; (there is > no stat64() anyway; it is _stat64()). > > > ... opendir(), readdir(), closedir() and other functions. > > These three, and others related to them, are implemented in > mingwex/dirent.c, in the mingwrt source distribution, or in CVS: > http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/mingw/include/dirent.h?cvsroot=src > http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/mingw/mingwex/dirent.c?cvsroot=src > Thanks for the information. The code lists directory and files names. It does not list the file sizes. Apparently the current MinGW library does not support'stat64' or '_stat64' functions needed to read 64 bit filesize information from structure 'stat' or 'stat64' ->st_size member. How can I use with MinGW _stat64 and if necessary, _findfirst64, _findnext64, _findclose, etc. and thereby avoid porting about 10,000 lines of Linux code to Visual Studio 10 and paying $ 1000's for a license to give away the finial software for free? Hans |
From: Keith M. <kei...@us...> - 2012-02-10 11:12:42
|
On 10 February 2012 07:30, Linux <linux@...> wrote: > Thanks for the information. The code lists directory and files names. It > does not list the file sizes. No, it doesn't. That information isn't directly available in struct dirent, so to get it, your best bet may well be stat()/_stat64(). > Apparently the current MinGW library does not support'stat64' or > '_stat64' functions needed to read 64 bit filesize information from > structure 'stat' or 'stat64' ->st_size member. Wrong assumption; it most certainly does! > How can I use with MinGW _stat64 and if necessary, _findfirst64, > _findnext64, _findclose, etc. and thereby avoid porting about 10,000 > lines of Linux code to Visual Studio 10 and paying $ 1000's for a > license to give away the finial software for free? Sigh... I really shouldn't need to hold your hand like this. Consult MSDN; check the header files directly, e..g. /mingw/include/sys/stat.h tells you that, for struct __stat64 and _stat64(), you must specify: #define __MSVCRT_VERSION__ 0x0601 /* or greater */ (thus entering into a contract that you accept that your application will not be supported on systems which don't provide at least this level of msvcrt.dll compatibility). This patch: $ hg diff diff -r 1174018ec3d8 dtree.c --- a/dtree.c Fri Feb 10 10:07:46 2012 +0000 +++ b/dtree.c Fri Feb 10 10:08:45 2012 +0000 @@ -1,3 +1,5 @@ +#define __MSVCRT_VERSION__ 0x0601 + #include <stdio.h> #include <stdlib.h> #include <dirent.h> @@ -14,8 +16,8 @@ static __inline__ int D_TYPE_IS_DT_DIR( const struct dirent* ent ) { - struct stat info; - if( stat( ent->d_name, &info ) == 0 ) + struct __stat64 info; + if( _stat64( ent->d_name, &info ) == 0 ) return S_ISDIR( info.st_mode ); return 0; } makes my previous example WJFFM, using struct __stat64. -- Regards, Keith. |
From: Eli Z. <el...@gn...> - 2012-02-10 19:08:17
|
> Date: Fri, 10 Feb 2012 11:12:36 +0000 > From: Keith Marshall <kei...@us...> > > /mingw/include/sys/stat.h tells you that, for struct __stat64 and > _stat64(), you must specify: > > #define __MSVCRT_VERSION__ 0x0601 /* or greater */ > > (thus entering into a contract that you accept that your application > will not be supported on systems which don't provide at least this > level of msvcrt.dll compatibility). Could you please tell how this works in practice? Will the resulting executable simply refuse to run if msvcrt.dll at least that new is present, or will they run and sometimes crash due to incompatibilities? (If this is documented somewhere, please just point me to that document.) TIA |
From: LRN <lr...@gm...> - 2012-02-10 19:57:49
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 10.02.2012 23:07, Eli Zaretskii wrote: >> Date: Fri, 10 Feb 2012 11:12:36 +0000 From: Keith Marshall >> <kei...@us...> >> >> /mingw/include/sys/stat.h tells you that, for struct __stat64 >> and _stat64(), you must specify: >> >> #define __MSVCRT_VERSION__ 0x0601 /* or greater */ >> >> (thus entering into a contract that you accept that your >> application will not be supported on systems which don't provide >> at least this level of msvcrt.dll compatibility). > > Could you please tell how this works in practice? Will the > resulting executable simply refuse to run if msvcrt.dll at least > that new is present, or will they run and sometimes crash due to > incompatibilities? > > (If this is documented somewhere, please just point me to that > document.) > My guess is that it will say something like "Procedure entry point for foo was not found in msvcrt.dll". -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJPNXaxAAoJEOs4Jb6SI2CwZYkH/jiBrA+8PWx12LERupgPw54C arxf+sba1qmfKdp7b9S7YxcGCofwL9z+7pljYbEd13/76bw4gJ0rPV8NqBXEV+Zy uQHGV75HF4PNAErJcoPKseiKK9+v5Q5+iOEImbvP8n6u33XRwSp9IubQP8v7TSE8 Si3XI5UIEiZKH44B/O82W2FmR8Q5CKUj4vgKAtqsE2ayUwrJ3rXtTWSz3MW6LcGp 8RsC6zj7m5mwO8TYMsPkOtGNkmrfKSU51YqFTYO3CU2F/7IF8Z3RjLj17J1PbhlD NEOddgxgO3biBWGqVvRJzrNPdge7n0UPjeLfc2EVkoqekR2tpR1QTeBMxi85IDs= =eahi -----END PGP SIGNATURE----- |
From: Eli Z. <el...@gn...> - 2012-02-10 19:33:46
|
> Date: Fri, 10 Feb 2012 21:07:31 +0200 > From: Eli Zaretskii <el...@gn...> > > Could you please tell how this works in practice? Will the resulting > executable simply refuse to run if msvcrt.dll at least that new is > present, [...] Sorry, I meant "is NOT present", of course. |
From: Earnie B. <ea...@us...> - 2012-02-10 20:04:14
|
On Fri, Feb 10, 2012 at 2:33 PM, Eli Zaretskii <el...@gn...> wrote: >> Date: Fri, 10 Feb 2012 21:07:31 +0200 >> From: Eli Zaretskii <el...@gn...> >> >> Could you please tell how this works in practice? Will the resulting >> executable simply refuse to run if msvcrt.dll at least that new is >> present, [...] > > Sorry, I meant "is NOT present", of course. > It will abort when the function used isn't present but called into action. The executable may work up to a point of use of the function that isn't supported for the version of Windows the user is using. -- Earnie -- https://sites.google.com/site/earnieboyd |
From: Eli Z. <el...@gn...> - 2012-02-10 20:34:45
|
> Date: Fri, 10 Feb 2012 15:04:07 -0500 > From: Earnie Boyd <ea...@us...> > > It will abort when the function used isn't present but called into > action. The executable may work up to a point of use of the function > that isn't supported for the version of Windows the user is using. Thanks. Do you happen to know when was MSVCRT version 6.10 introduced? That is, if a program was compiled with __MSVCRT_VERSION__ >= 0x0601, on what Windows versions will it not be guaranteed to work well? |
From: Roger P. <rog...@gm...> - 2012-08-05 03:14:32
|
>> #define _LARGEFILE64_SOURCE >> #define _FILE_OFFSET_BITS 64 I was thinking the other day that it would be quite nice if these *did* have an effect, viz: today to compile mplayer in windows, you must first apply (IIRC) this patch to the compiler: http://oss.netfarm.it/mplayer/misc/mingwrt_file64.diff to be able to compile and work with large files "out of the box." Thanks. (and sorry if this was a repeat :P ) -roger- |
From: Hans <li...@in...> - 2012-08-05 10:30:31
|
On 05/08/12 13:14, Roger Pack wrote: >>> #define _LARGEFILE64_SOURCE >>> #define _FILE_OFFSET_BITS 64 > > I was thinking the other day that it would be quite nice if these > *did* have an effect, viz: > today to compile mplayer in windows, you must first apply (IIRC) this > patch to the compiler: > http://oss.netfarm.it/mplayer/misc/mingwrt_file64.diff > to be able to compile and work with large files "out of the box." > Thanks. (and sorry if this was a repeat :P ) > -roger- > -------snipp ----------- #define _LARGEFILE64_SOURCE #define _FILE_OFFSET_BITS 64 where defined to be able to use the same code for large file access under Linux 32 & 64 bit and Windows 32 bit. You can download the complete source from http://www.linux.interworld.net.au Hans |