diff --git a/CHANGES b/CHANGES index 64b9b55..048597f 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,9 @@ if _XOPEN_SOURCE is defined, which is needed for Solaris. OpenBSD sucks. I checked in a _really_ kludge now. Please do not use OpenBSD if you have a choice. Or Solaris, for that matter. + turns out the imult routines (which I never used) were incorrect. + Noted by Matthew Dempsky + open_* from open.h now open in large file mode 0.23: also recognize EPFNOSUPPORT as EAFNOSUPPORT (groan) diff --git a/mult/imult16.c b/mult/imult16.c index 98dfb39..adfdd3d 100644 --- a/mult/imult16.c +++ b/mult/imult16.c @@ -1,11 +1,8 @@ #include "safemult.h" int imult16(int16 a,int16 b,int16* c) { - int neg=(a<0); - uint16 d; - if (neg) a=-a; - if (b<0) { neg^=1; b=-b; } - if (umult16(a,b,&d)) return 0; - *c=(neg?-d:d); + int32 x=(int32)a*b; + if ((int16)x != x) return 0; + *c=x; return 1; } diff --git a/mult/imult32.c b/mult/imult32.c index 98067f1..1751960 100644 --- a/mult/imult32.c +++ b/mult/imult32.c @@ -1,11 +1,8 @@ #include "safemult.h" int imult32(int32 a,int32 b,int32* c) { - int neg=(a<0); - uint32 d; - if (neg) a=-a; - if (b<0) { neg^=1; b=-b; } - if (umult32(a,b,&d)) return 0; - *c=(neg?-d:d); + int64 x=(int64)a*b; + if ((int32)x != x) return 0; + *c=x; return 1; } diff --git a/mult/imult64.c b/mult/imult64.c index 39d40df..be59d66 100644 --- a/mult/imult64.c +++ b/mult/imult64.c @@ -5,7 +5,8 @@ int imult64(int64 a,int64 b,int64* c) { uint64 d; if (neg) a=-a; if (b<0) { neg^=1; b=-b; } - if (umult64(a,b,&d)) return 0; + if (!umult64(a,b,&d)) return 0; + if (d > 0x7fffffffffffffffULL + neg) return 0; *c=(neg?-d:d); return 1; } diff --git a/open/open_append.c b/open/open_append.c index 70512c8..80ae25d 100644 --- a/open/open_append.c +++ b/open/open_append.c @@ -1,3 +1,4 @@ +#define _FILE_OFFSET_BITS 64 #include #include #include "open.h" diff --git a/open/open_excl.c b/open/open_excl.c index 0ac42c3..426fbfa 100644 --- a/open/open_excl.c +++ b/open/open_excl.c @@ -1,3 +1,4 @@ +#define _FILE_OFFSET_BITS 64 #include #include #include "open.h" diff --git a/open/open_read.c b/open/open_read.c index 9aadf2f..a26d7b4 100644 --- a/open/open_read.c +++ b/open/open_read.c @@ -1,3 +1,4 @@ +#define _FILE_OFFSET_BITS 64 #include #include #include "open.h" diff --git a/open/open_rw.c b/open/open_rw.c index 84029d0..02089aa 100644 --- a/open/open_rw.c +++ b/open/open_rw.c @@ -1,3 +1,4 @@ +#define _FILE_OFFSET_BITS 64 #include #include #include "open.h" diff --git a/open/open_trunc.c b/open/open_trunc.c index 4c13770..0217852 100644 --- a/open/open_trunc.c +++ b/open/open_trunc.c @@ -1,3 +1,4 @@ +#define _FILE_OFFSET_BITS 64 #include #include #include "open.h" diff --git a/open/open_write.c b/open/open_write.c index 73781e6..9a5285c 100644 --- a/open/open_write.c +++ b/open/open_write.c @@ -1,3 +1,4 @@ +#define _FILE_OFFSET_BITS 64 #include #include #include "open.h" diff --git a/t.c b/t.c index edb26b2..0727611 100644 --- a/t.c +++ b/t.c @@ -21,6 +21,7 @@ #include #include "errmsg.h" #include "iob.h" +#include "safemult.h" #define rdtscl(low) \ __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") @@ -328,8 +329,25 @@ int main(int argc,char* argv[]) { write(1,tmp,x); } #endif +#if 0 printf("%d %d\n",strcmp("foo","bar"),str_diff("foo","bar")); printf("%d %d\n",strcmp("foo","üar"),str_diff("foo","üar")); return 0; +#endif + { + int16 a; + int32 b; + int64 c; + assert(imult16(4,10000,&a)==0); + assert(imult16(-4,10000,&a)==0); + assert(imult16(5,10,&a)==1 && a==50); + assert(imult16(-3,10000,&a)==1 && a==-30000); + + assert(imult32(0x40000000,2,&b)==0); + assert(imult32(0x3fffffff,2,&b)==1 && b==0x7ffffffe); + + assert(imult64(0x4000000000000000ll,2,&c)==0); + assert(imult64(0x3fffffffffffffffll,2,&c)==1 && c==0x7ffffffffffffffell); + } } diff --git a/test/mult.c b/test/mult.c new file mode 100644 index 0000000..6566e7f --- /dev/null +++ b/test/mult.c @@ -0,0 +1,26 @@ +#include +#include "safemult.h" + +int main() { + int16 a; + int32 b; + int64 c; + uint16 d; + uint32 e; + uint64 f; + + assert(imult16(4,10000,&a)==0); + assert(imult16(-4,10000,&a)==0); + assert(imult16(5,10,&a)==1 && a==50); + assert(imult16(-3,10000,&a)==1 && a==-30000); + + assert(imult32(0x40000000,2,&b)==0); + assert(imult32(-0x40000000,2,&b)==1 && b==-0x80000000); + assert(imult32(0x3fffffff,2,&b)==1 && b==0x7ffffffe); + + assert(imult64(0x4000000000000000ll,2,&c)==0); + assert(imult64(-0x4000000000000000ll,2,&c)==1 && c==-0x8000000000000000ll); + assert(imult64(0x3fffffffffffffffll,2,&c)==1 && c==0x7ffffffffffffffell); + + return 0; +}