Comment #0 by Jesse.K.Phillips+D — 2010-11-11T21:34:53Z
The structure created by D for stat is not the same size as the one in C, and there appears to be no communication of data between C and D. Assigns a value to st_mode and calls a C function which prints the value and assigns its own. At which point D prints the value (the same one it assigned). Running 32bit Linux.
Output:
D size: 100
D Assigning 65
C Size: 88
C Found: 0
C Assign: 45
D Found 65
import core.sys.posix.sys.stat;
import std.stdio;
extern(C) void modStat(stat_t* data);
void main() {
stat_t stbuf;
writeln("D size: ", stbuf.sizeof);
writeln("D Assigning ", 65);
stbuf.st_mode = 65;
modStat(&stbuf);
writeln("D Found ", stbuf.st_mode);
}
--------------- cstat.c
#include <sys/stat.h>
#include <stdio.h>
void modStat(struct stat *stbuf) {
struct stat rrr;
printf("C Size: %d\n", sizeof(rrr));
printf("C Found: %d\n", stbuf->st_mode);
printf("C Assign: %d\n", 45);
stbuf->st_mode = 45;
}
Compiled with: gcc -g -c cstat.c && dmd -gc stat.d cstat.o
Comment #1 by Jesse.K.Phillips+D — 2010-11-11T21:48:11Z
I did try to compare the Structures, and only one thing came out as being different (after I discovered __USE_FILE_OFFSET64 was supposed to always be set). The struct has a if(false) which seems to have the missing code that I need, and adds quite a bit.
http://dsource.org/projects/druntime/browser/trunk/src/core/sys/posix/sys/stat.d?rev=300#L112
This is what stat looks like with some trimming: gcc -E -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse -pthread -lfuse -lrt -ldl stat.h
struct stat
{
__dev_t st_dev;
unsigned short int __pad1;
__ino_t __st_ino;
__mode_t st_mode;
__nlink_t st_nlink;
__uid_t st_uid;
__gid_t st_gid;
__dev_t st_rdev;
unsigned short int __pad2;
__off64_t st_size;
__blksize_t st_blksize;
__blkcnt64_t st_blocks;
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
__ino64_t st_ino;
};
Comment #2 by ibuclaw — 2010-12-30T09:40:34Z
This should really be set to true for all glibc systems.
However, the current implementation is buggy:
timespec st_atim;
timespec st_mtim;
timespec st_ctim;
alias st_atim.tv_sec st_atime;
alias st_mtim.tv_sec st_mtime;
alias st_ctim.tv_sec st_ctime;
The three aliases aren't actually usable, because:
Error: struct core.sys.posix.sys.stat.stat_t 'tv_sec' is not a member
Error: struct core.sys.posix.sys.stat.stat_t member tv_sec is not accessible
Error: this for tv_sec needs to be type timespec not type stat_t
Regards
Comment #3 by ibuclaw — 2011-01-03T06:47:56Z
Created attachment 859
patch for 5206
Patch against my tree. Updates stat_t for version(linux), adds definition of __WORDSIZE (needs review, probably better to define it on a per-architecture basis), and removes all except the alias to fstat64 in std.file.
Can someone pick this up and clean/apply? :)
Comment #4 by sohgo — 2011-01-31T19:08:36Z
(In reply to comment #3)
> Created an attachment (id=859) [details]
> patch for 5206
I have tested Jesse's patch on FreeBSD 8.1(i386 and amd64) and run his program.
The outputs were following.
8.1(i386):
D size: 96
D Assigning 65
C Size: 96
C Found: 65
C Assign; 45
D Found 45
8.1(amd64):
D size: 120
D Assigning 65
C Size: 120
C Found: 65
C Assign; 45
D Found 45
Comment #5 by ibuclaw — 2011-01-31T22:51:45Z
Created attachment 891
patch for 5206
Note, have since updated stat_t implementation for Linux.
struct_stat64 in std.file is still present and should be removed. :o)
Comment #9 by jfanatiker — 2012-04-08T13:00:33Z
Is someone working on this? If not, I am going to fix it.
I happened to implement this struct on my own, because I relied on the online API documentation where lots of C wrappers are not documented, so I did not realized that they exist. Anyway I implemented a simple unit test for my own stat struct which compares the size of the struct in D with the size of the struct in C by means of a simple C function that returns the size of the struct in C. Would there be any problem if I did something like this in the druntime code?