mirror of
https://github.com/darlinghq/darling.git
synced 2024-11-24 12:49:44 +00:00
removefile-48
This commit is contained in:
parent
9b23a7dbbe
commit
7c4e4da0de
@ -52,6 +52,7 @@ enum {
|
||||
***/
|
||||
|
||||
#define __CHECKINT_INLINE static inline __attribute__((always_inline))
|
||||
#define __CHECKINT_UNLIKELY(X) __builtin_expect((X),0)
|
||||
|
||||
__CHECKINT_INLINE int32_t
|
||||
__checkint_is_mixed_sign32(int32_t x, int32_t y) {return ((x ^ y) < 0);}
|
||||
@ -74,7 +75,7 @@ __checkint_uint64_type_error(int32_t* err) {*err |= CHECKINT_TYPE_ERROR; return
|
||||
__CHECKINT_INLINE int32_t
|
||||
__checkint_int32_add(int64_t x, int64_t y, int32_t* err) {
|
||||
int64_t z = x + y;
|
||||
if (x < INT32_MIN || x > INT32_MAX || y < INT32_MIN || y > INT32_MAX) {
|
||||
if (__CHECKINT_UNLIKELY(x < INT32_MIN || x > INT32_MAX || y < INT32_MIN || y > INT32_MAX)) {
|
||||
*err |= CHECKINT_OVERFLOW_ERROR;
|
||||
}
|
||||
if (z > INT32_MAX || z < INT32_MIN) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
@ -84,8 +85,8 @@ __checkint_int32_add(int64_t x, int64_t y, int32_t* err) {
|
||||
__CHECKINT_INLINE uint32_t
|
||||
__checkint_uint32_add(int64_t x, int64_t y, int32_t* err) {
|
||||
int64_t z = x + y;
|
||||
if ((x & 0xffffffff00000000ull) || (y & 0xffffffff00000000ull)) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (z > UINT_MAX || z < 0) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (__CHECKINT_UNLIKELY((x & 0xffffffff00000000ull) || (y & 0xffffffff00000000ull))) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (__CHECKINT_UNLIKELY(z > UINT_MAX || z < 0)) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
return (uint32_t)z;
|
||||
}
|
||||
|
||||
@ -95,17 +96,17 @@ __checkint_int64_add_signed_signed(int64_t x, int64_t y, int32_t* err) {
|
||||
if (__checkint_is_mixed_sign64(x,y)) {
|
||||
/* else, both arguments negative */
|
||||
} else if (y < 0) {
|
||||
if (x < LLONG_MIN - y) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (__CHECKINT_UNLIKELY(x < LLONG_MIN - y)) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
/* else, both arguments positive */
|
||||
} else {
|
||||
if (LLONG_MAX - x < y) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (__CHECKINT_UNLIKELY(LLONG_MAX - x < y)) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
}
|
||||
return x + y;
|
||||
}
|
||||
|
||||
__CHECKINT_INLINE int64_t
|
||||
__checkint_int64_add_signed_unsigned(int64_t x, uint64_t y, int32_t* err) {
|
||||
if(((int64_t)(LLONG_MAX - y)) < x)
|
||||
if(__CHECKINT_UNLIKELY(((int64_t)(LLONG_MAX - y)) < x))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x + y;
|
||||
}
|
||||
@ -118,23 +119,23 @@ __checkint_int64_add_unsigned_signed(uint64_t x, int64_t y, int32_t* err) {
|
||||
__CHECKINT_INLINE int64_t
|
||||
__checkint_int64_add_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) {
|
||||
int64_t diff = LLONG_MAX - y;
|
||||
if(diff < 0 || ((uint64_t) diff) < x)
|
||||
if(__CHECKINT_UNLIKELY(diff < 0 || ((uint64_t) diff) < x))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x + y;
|
||||
}
|
||||
|
||||
__CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_add_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) {
|
||||
if((ULLONG_MAX - y) < x)
|
||||
if(__CHECKINT_UNLIKELY((ULLONG_MAX - y) < x))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x + y;
|
||||
}
|
||||
|
||||
__CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_add_signed_signed(int64_t x, int64_t y, int32_t* err) {
|
||||
if(((x < 0 && y >= 0) || (x >= 0 && y < 0)) && (x + y) < 0)
|
||||
if(__CHECKINT_UNLIKELY(((x < 0 && y >= 0) || (x >= 0 && y < 0)) && (x + y) < 0))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
else if(x < 0 && y < 0)
|
||||
else if(__CHECKINT_UNLIKELY(x < 0 && y < 0))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x + y;
|
||||
}
|
||||
@ -143,7 +144,7 @@ __CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_add_signed_unsigned(int64_t x, uint64_t y, int32_t* err) {
|
||||
if(x > 0)
|
||||
return __checkint_uint64_add_unsigned_unsigned(x, y, err);
|
||||
if((y < ((uint64_t)LLONG_MAX + 1)) && (((int64_t) (x + y)) < 0))
|
||||
if(__CHECKINT_UNLIKELY((y < ((uint64_t)LLONG_MAX + 1)) && (((int64_t) (x + y)) < 0)))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x + y;
|
||||
}
|
||||
@ -155,19 +156,19 @@ __checkint_uint64_add_unsigned_signed(uint64_t x, int64_t y, int32_t* err) {
|
||||
|
||||
__CHECKINT_INLINE int32_t
|
||||
__checkint_int32_sub(int64_t x, int64_t y, int32_t* err) {
|
||||
if (x < INT32_MIN || x > INT32_MAX || y < INT32_MIN || y > INT32_MAX) {
|
||||
if (__CHECKINT_UNLIKELY(x < INT32_MIN || x > INT32_MAX || y < INT32_MIN || y > INT32_MAX)) {
|
||||
*err |= CHECKINT_OVERFLOW_ERROR;
|
||||
}
|
||||
int64_t z = x - y;
|
||||
if (z > INT_MAX || z < INT_MIN) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (__CHECKINT_UNLIKELY(z > INT_MAX || z < INT_MIN)) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
return (int32_t)z;
|
||||
}
|
||||
|
||||
__CHECKINT_INLINE uint32_t
|
||||
__checkint_uint32_sub(int64_t x, int64_t y, int32_t* err) {
|
||||
int64_t z = x - y;
|
||||
if ((x & 0xffffffff00000000ull) || (y & 0xffffffff00000000ull)) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (z > UINT_MAX || z < 0) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (__CHECKINT_UNLIKELY((x & 0xffffffff00000000ull) || (y & 0xffffffff00000000ull))) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (__CHECKINT_UNLIKELY(z > UINT_MAX || z < 0)) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
return (uint32_t)z;
|
||||
}
|
||||
|
||||
@ -178,13 +179,13 @@ __checkint_int64_sub_signed_signed(int64_t x, int64_t y, int32_t* err) {
|
||||
/* Positive x subtract a negative y */
|
||||
if(x >= 0)
|
||||
{
|
||||
if(x > LLONG_MAX + y)
|
||||
if(__CHECKINT_UNLIKELY(x > LLONG_MAX + y))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
}
|
||||
/* Negative x subtract a positive y */
|
||||
else
|
||||
{
|
||||
if(x < LLONG_MIN + y)
|
||||
if(__CHECKINT_UNLIKELY(x < LLONG_MIN + y))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
}
|
||||
}
|
||||
@ -194,39 +195,39 @@ __checkint_int64_sub_signed_signed(int64_t x, int64_t y, int32_t* err) {
|
||||
|
||||
__CHECKINT_INLINE int64_t
|
||||
__checkint_int64_sub_signed_unsigned(int64_t x, uint64_t y, int32_t* err) {
|
||||
if(x < ((int64_t)(LLONG_MIN + y)))
|
||||
if(__CHECKINT_UNLIKELY(x < ((int64_t)(LLONG_MIN + y))))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x - y;
|
||||
}
|
||||
|
||||
__CHECKINT_INLINE int64_t
|
||||
__checkint_int64_sub_unsigned_signed(uint64_t x, int64_t y, int32_t* err) {
|
||||
if(x > ((uint64_t)(LLONG_MAX + y)) || y == LLONG_MIN)
|
||||
if(__CHECKINT_UNLIKELY(x > ((uint64_t)(LLONG_MAX + y)) || y == LLONG_MIN))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x - y;
|
||||
}
|
||||
|
||||
__CHECKINT_INLINE int64_t
|
||||
__checkint_int64_sub_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) {
|
||||
if(x > y && ((x - y) > LLONG_MAX))
|
||||
if(__CHECKINT_UNLIKELY(x > y && ((x - y) > LLONG_MAX)))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
else if(x < y && ((y - x - 1) > LLONG_MAX))
|
||||
else if(__CHECKINT_UNLIKELY(x < y && ((y - x - 1) > LLONG_MAX)))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x - y;
|
||||
}
|
||||
|
||||
__CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_sub_signed_signed(int64_t x, int64_t y, int32_t* err) {
|
||||
if(((x < 0 && y <= 0) || (x >= 0 && y > 0)) && (x - y) < 0)
|
||||
if(__CHECKINT_UNLIKELY(((x < 0 && y <= 0) || (x >= 0 && y > 0)) && (x - y) < 0))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
else if(x < 0 && y > 0)
|
||||
else if(__CHECKINT_UNLIKELY(x < 0 && y > 0))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x - y;
|
||||
}
|
||||
|
||||
__CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_sub_signed_unsigned(int64_t x, uint64_t y, int32_t* err) {
|
||||
if(y > ((uint64_t) LLONG_MAX + 1) || ((int64_t) y) > x)
|
||||
if(__CHECKINT_UNLIKELY(y > ((uint64_t) LLONG_MAX + 1) || ((int64_t) y) > x))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x - y;
|
||||
}
|
||||
@ -235,14 +236,14 @@ __CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_sub_unsigned_signed(uint64_t x, int64_t y, int32_t* err) {
|
||||
if(x <= LLONG_MAX)
|
||||
return __checkint_uint64_sub_signed_signed(x, y, err);
|
||||
else if (y == LLONG_MIN || -y > ULLONG_MAX - x)
|
||||
else if (__CHECKINT_UNLIKELY(y == LLONG_MIN || -y > ULLONG_MAX - x))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x - y;
|
||||
}
|
||||
|
||||
__CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_sub_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) {
|
||||
if(x < y)
|
||||
if(__CHECKINT_UNLIKELY(x < y))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x - y;
|
||||
}
|
||||
@ -250,18 +251,18 @@ __checkint_uint64_sub_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) {
|
||||
__CHECKINT_INLINE int32_t
|
||||
__checkint_int32_mul(int64_t x, int64_t y, int32_t* err) {
|
||||
int64_t z = x * y;
|
||||
if (x < INT32_MIN || x > INT32_MAX || y < INT32_MIN || y > INT32_MAX) {
|
||||
if (__CHECKINT_UNLIKELY(x < INT32_MIN || x > INT32_MAX || y < INT32_MIN || y > INT32_MAX)) {
|
||||
*err |= CHECKINT_OVERFLOW_ERROR;
|
||||
}
|
||||
if (z > INT_MAX || z < INT_MIN) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (__CHECKINT_UNLIKELY(z > INT_MAX || z < INT_MIN)) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
return (int32_t)z;
|
||||
}
|
||||
|
||||
__CHECKINT_INLINE uint32_t
|
||||
__checkint_uint32_mul(int64_t x, int64_t y, int32_t* err) {
|
||||
int64_t z = x * y;
|
||||
if ((x & 0xffffffff00000000ull) || (y & 0xffffffff00000000ull)) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (z > UINT_MAX || z < 0) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (__CHECKINT_UNLIKELY((x & 0xffffffff00000000ull) || (y & 0xffffffff00000000ull))) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
if (__CHECKINT_UNLIKELY(z > UINT_MAX || z < 0)) *err |= CHECKINT_OVERFLOW_ERROR;
|
||||
return (uint32_t)z;
|
||||
}
|
||||
|
||||
@ -273,14 +274,14 @@ __checkint_int64_mul_signed_signed(int64_t x, int64_t y, int32_t* err) {
|
||||
{
|
||||
if(x > 0)
|
||||
{
|
||||
if(LLONG_MAX/x < y)
|
||||
if(__CHECKINT_UNLIKELY(LLONG_MAX/x < y))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(x == LLONG_MIN || y == LLONG_MIN)
|
||||
if(__CHECKINT_UNLIKELY(x == LLONG_MIN || y == LLONG_MIN))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
if(LLONG_MAX/(-x) < (-y))
|
||||
if(__CHECKINT_UNLIKELY(LLONG_MAX/(-x) < (-y)))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
}
|
||||
}
|
||||
@ -288,11 +289,10 @@ __checkint_int64_mul_signed_signed(int64_t x, int64_t y, int32_t* err) {
|
||||
{
|
||||
if(x < 0)
|
||||
{
|
||||
if(x < LLONG_MIN/y)
|
||||
if(__CHECKINT_UNLIKELY(x < LLONG_MIN/y))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
}
|
||||
else
|
||||
if(y < LLONG_MIN/x)
|
||||
else if(__CHECKINT_UNLIKELY(y < LLONG_MIN/x))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
}
|
||||
return x * y;
|
||||
@ -302,7 +302,7 @@ __CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_mul_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) {
|
||||
if(x == 0) return 0;
|
||||
|
||||
if(ULLONG_MAX/x < y)
|
||||
if(__CHECKINT_UNLIKELY(ULLONG_MAX/x < y))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x * y;
|
||||
}
|
||||
@ -312,7 +312,7 @@ __CHECKINT_INLINE int64_t
|
||||
__checkint_int64_mul_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) {
|
||||
if(x == 0) return 0;
|
||||
|
||||
if(LLONG_MAX/x < y)
|
||||
if(__CHECKINT_UNLIKELY(LLONG_MAX/x < y))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x * y;
|
||||
}
|
||||
@ -324,7 +324,7 @@ __checkint_int64_mul_signed_unsigned(int64_t x, uint64_t y, int32_t* err) {
|
||||
if(x >= 0)
|
||||
return __checkint_int64_mul_unsigned_unsigned(x, y, err);
|
||||
else
|
||||
if(x < LLONG_MIN/y || x > LLONG_MAX/y)
|
||||
if(__CHECKINT_UNLIKELY(x < LLONG_MIN/y || x > LLONG_MAX/y))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x * y;
|
||||
}
|
||||
@ -336,7 +336,7 @@ __checkint_int64_mul_unsigned_signed(uint64_t x, int64_t y, int32_t* err) {
|
||||
|
||||
__CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_mul_signed_signed(int64_t x, int64_t y, int32_t* err) {
|
||||
if((x < 0 && y > 0) || (x > 0 && y < 0))
|
||||
if(__CHECKINT_UNLIKELY((x < 0 && y > 0) || (x > 0 && y < 0)))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
else if(x > 0 && y > 0)
|
||||
return __checkint_uint64_mul_unsigned_unsigned(x, y, err);
|
||||
@ -360,8 +360,10 @@ __checkint_uint64_mul_unsigned_signed(uint64_t x, int64_t y, int32_t* err) {
|
||||
|
||||
__CHECKINT_INLINE int32_t
|
||||
__checkint_int32_div_signed_signed(int32_t x, int32_t y, int32_t* err) {
|
||||
if((x == INT_MIN) && y == -1)
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
if(__CHECKINT_UNLIKELY((x == INT_MIN) && y == -1)) {
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return 0;
|
||||
}
|
||||
return x / y;
|
||||
}
|
||||
|
||||
@ -376,9 +378,9 @@ __CHECKINT_INLINE int32_t
|
||||
__checkint_int32_div_unsigned_signed(uint32_t x, int32_t y, int32_t* err) {
|
||||
if(x == ((uint32_t) INT_MAX + 1) && y == -1)
|
||||
return INT_MIN;
|
||||
if(x > ((uint32_t) INT_MAX + 1) && y == -1)
|
||||
if(__CHECKINT_UNLIKELY(x > ((uint32_t) INT_MAX + 1) && y == -1))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
else if(x > INT_MAX && y == 1)
|
||||
else if(__CHECKINT_UNLIKELY(x > INT_MAX && y == 1))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
if(x <= INT_MAX)
|
||||
return ((int32_t) x) / y;
|
||||
@ -390,7 +392,7 @@ __checkint_int32_div_unsigned_signed(uint32_t x, int32_t y, int32_t* err) {
|
||||
__CHECKINT_INLINE int32_t
|
||||
__checkint_int32_div_unsigned_unsigned(uint32_t x, uint32_t y, int32_t* err) {
|
||||
uint32_t result = x / y;
|
||||
if(result > INT_MAX)
|
||||
if(__CHECKINT_UNLIKELY(result > INT_MAX))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x / y;
|
||||
}
|
||||
@ -400,7 +402,7 @@ __checkint_uint32_div_signed_signed(int32_t x, int32_t y, int32_t* err) {
|
||||
int32_t result = x / y;
|
||||
if(x == INT_MIN && y == -1)
|
||||
return ((uint32_t) -x);
|
||||
if(result < 0)
|
||||
if(__CHECKINT_UNLIKELY(result < 0))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
if(x >= 0 && y > 0)
|
||||
return x / y;
|
||||
@ -414,7 +416,7 @@ __checkint_uint32_div_signed_signed(int32_t x, int32_t y, int32_t* err) {
|
||||
|
||||
__CHECKINT_INLINE uint32_t
|
||||
__checkint_uint32_div_signed_unsigned(int32_t x, uint32_t y, int32_t* err) {
|
||||
if(x < 0 && ((uint32_t) -x) >= y)
|
||||
if(__CHECKINT_UNLIKELY(x < 0 && ((uint32_t) -x) >= y))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
if(x >= 0)
|
||||
return x / y;
|
||||
@ -423,7 +425,7 @@ __checkint_uint32_div_signed_unsigned(int32_t x, uint32_t y, int32_t* err) {
|
||||
|
||||
__CHECKINT_INLINE uint32_t
|
||||
__checkint_uint32_div_unsigned_signed(uint32_t x, int32_t y, int32_t* err) {
|
||||
if(y < 0 && ((uint32_t) -y) <= x)
|
||||
if(__CHECKINT_UNLIKELY(y < 0 && ((uint32_t) -y) <= x))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
if(y > 0)
|
||||
return x / y;
|
||||
@ -437,8 +439,10 @@ __checkint_uint32_div_unsigned_unsigned(uint32_t x, uint32_t y, int32_t* err) {
|
||||
|
||||
__CHECKINT_INLINE int64_t
|
||||
__checkint_int64_div_signed_signed(int64_t x, int64_t y, int32_t* err) {
|
||||
if((x == LLONG_MIN) && y == -1)
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
if(__CHECKINT_UNLIKELY((x == LLONG_MIN) && y == -1)) {
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return 0;
|
||||
}
|
||||
return x / y;
|
||||
}
|
||||
|
||||
@ -453,9 +457,9 @@ __CHECKINT_INLINE int64_t
|
||||
__checkint_int64_div_unsigned_signed(uint64_t x, int64_t y, int32_t* err) {
|
||||
if(x == ((uint64_t) LLONG_MAX + 1) && y == -1)
|
||||
return LLONG_MIN;
|
||||
if(x > ((uint64_t) LLONG_MAX + 1) && y == -1)
|
||||
if(__CHECKINT_UNLIKELY(x > ((uint64_t) LLONG_MAX + 1) && y == -1))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
else if(x > LLONG_MAX && y == 1)
|
||||
else if(__CHECKINT_UNLIKELY(x > LLONG_MAX && y == 1))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
if(x <= LLONG_MAX)
|
||||
return ((int64_t) x) / y;
|
||||
@ -467,17 +471,17 @@ __checkint_int64_div_unsigned_signed(uint64_t x, int64_t y, int32_t* err) {
|
||||
__CHECKINT_INLINE int64_t
|
||||
__checkint_int64_div_unsigned_unsigned(uint64_t x, uint64_t y, int32_t* err) {
|
||||
uint64_t result = x / y;
|
||||
if(result > LLONG_MAX)
|
||||
if(__CHECKINT_UNLIKELY(result > LLONG_MAX))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
return x / y;
|
||||
}
|
||||
|
||||
__CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_div_signed_signed(int64_t x, int64_t y, int32_t* err) {
|
||||
int64_t result = x / y;
|
||||
int64_t result = x / y;
|
||||
if(x == LLONG_MIN && y == -1)
|
||||
return ((uint64_t)LLONG_MAX) + 1;
|
||||
if(result < 0)
|
||||
if(__CHECKINT_UNLIKELY(result < 0))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
if(x >= 0 && y > 0)
|
||||
return x / y;
|
||||
@ -491,7 +495,7 @@ __checkint_uint64_div_signed_signed(int64_t x, int64_t y, int32_t* err) {
|
||||
|
||||
__CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_div_signed_unsigned(int64_t x, uint64_t y, int32_t* err) {
|
||||
if(x < 0 && ((uint64_t) -x) >= y)
|
||||
if(__CHECKINT_UNLIKELY(x < 0 && ((uint64_t) -x) >= y))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
if(x >= 0)
|
||||
return x / y;
|
||||
@ -500,7 +504,7 @@ __checkint_uint64_div_signed_unsigned(int64_t x, uint64_t y, int32_t* err) {
|
||||
|
||||
__CHECKINT_INLINE uint64_t
|
||||
__checkint_uint64_div_unsigned_signed(uint64_t x, int64_t y, int32_t* err) {
|
||||
if(y < 0 && ((uint64_t) -y) <= x)
|
||||
if(__CHECKINT_UNLIKELY(y < 0 && ((uint64_t) -y) <= x))
|
||||
*err = *err | CHECKINT_OVERFLOW_ERROR;
|
||||
if(y > 0)
|
||||
return x / y;
|
||||
|
@ -1 +0,0 @@
|
||||
../checkint.h
|
@ -1 +0,0 @@
|
||||
../removefile.h
|
@ -1 +0,0 @@
|
||||
../removefile_priv.h
|
@ -1,4 +1,4 @@
|
||||
.\" Copyright (c) 2007 Apple Inc.
|
||||
.\" Copyright (c) 2015 Apple Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@ -24,7 +24,7 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd May 4, 2007
|
||||
.Dd Feb 26, 2015
|
||||
.Dt REMOVEFILE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -101,6 +101,11 @@ location is not deleted. If specified in conjunction with REMOVEFILE_RECURSIVE,
|
||||
then all of the contents of the directory at
|
||||
.Va path
|
||||
location will be deleted, but not the directory itself.
|
||||
.It Dv REMOVEFILE_CROSS_MOUNT
|
||||
By default, recursive traversals do not cross mount points. This option allows
|
||||
.Fn removefile
|
||||
to descend into directories that have a different device number than the file from which
|
||||
the descent began.
|
||||
.It Dv REMOVEFILE_SECURE_7_PASS
|
||||
Overwrite the file with 7 US DoD compliant passes (0xF6, 0x00, 0xFF, random, 0x00, 0xFF, random).
|
||||
.It Dv REMOVEFILE_SECURE_35_PASS
|
||||
@ -274,7 +279,6 @@ removefile("/tmp", s, REMOVEFILE_RECURSIVE | REMOVEFILE_KEEP_PARENT);
|
||||
removefile_state_free(s);
|
||||
.Ed
|
||||
.Sh "SEE ALSO"
|
||||
.Xr srm 1 ,
|
||||
.Xr unlink 1 ,
|
||||
.Xr sync 2 ,
|
||||
.Xr sync_volume_np 3
|
||||
|
@ -91,7 +91,7 @@ removefile_state_set(removefile_state_t state, uint32_t key, const void* value)
|
||||
|
||||
int
|
||||
removefile(const char* path, removefile_state_t state_param, removefile_flags_t flags) {
|
||||
int res = 0;
|
||||
int res = 0, error = 0;
|
||||
char* paths[] = { NULL, NULL };
|
||||
removefile_state_t state = state_param;
|
||||
|
||||
@ -113,9 +113,10 @@ removefile(const char* path, removefile_state_t state_param, removefile_flags_t
|
||||
paths[0] = strdup(path);
|
||||
if (paths[0]) {
|
||||
res = __removefile_tree_walker(paths, state);
|
||||
error = state->error_num;
|
||||
free(paths[0]);
|
||||
} else {
|
||||
errno = ENOMEM;
|
||||
error = ENOMEM;
|
||||
res = -1;
|
||||
}
|
||||
|
||||
@ -124,6 +125,10 @@ removefile(const char* path, removefile_state_t state_param, removefile_flags_t
|
||||
removefile_state_free(state);
|
||||
}
|
||||
|
||||
if (res) {
|
||||
errno = error;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
|
||||
* Copyright (c) 2015 Apple Computer, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __REMOVEFILE_H__
|
||||
@ -17,13 +17,14 @@ extern "C" {
|
||||
typedef uint32_t removefile_flags_t;
|
||||
|
||||
enum {
|
||||
REMOVEFILE_RECURSIVE = (1 << 0), // If path is a directory, recurse (depth first traversal)
|
||||
REMOVEFILE_KEEP_PARENT = (1 << 1), // Remove contents but not directory itself
|
||||
REMOVEFILE_SECURE_7_PASS = (1 << 2), // 7 pass DoD algorithm
|
||||
REMOVEFILE_SECURE_35_PASS = (1 << 3), // 35-pass Gutmann algorithm (overrides REMOVEFILE_SECURE_7_PASS)
|
||||
REMOVEFILE_SECURE_1_PASS = (1 << 4), // 1 pass single overwrite
|
||||
REMOVEFILE_SECURE_3_PASS = (1 << 5), // 3 pass overwrite
|
||||
REMOVEFILE_SECURE_1_PASS_ZERO = (1 << 6), // Single-pass overwrite, with 0 instead of random data
|
||||
REMOVEFILE_RECURSIVE = (1 << 0), // If path is a directory, recurse (depth first traversal)
|
||||
REMOVEFILE_KEEP_PARENT = (1 << 1), // Remove contents but not directory itself
|
||||
REMOVEFILE_SECURE_7_PASS = (1 << 2), // 7 pass DoD algorithm
|
||||
REMOVEFILE_SECURE_35_PASS = (1 << 3), // 35-pass Gutmann algorithm (overrides REMOVEFILE_SECURE_7_PASS)
|
||||
REMOVEFILE_SECURE_1_PASS = (1 << 4), // 1 pass single overwrite
|
||||
REMOVEFILE_SECURE_3_PASS = (1 << 5), // 3 pass overwrite
|
||||
REMOVEFILE_SECURE_1_PASS_ZERO = (1 << 6), // Single-pass overwrite, with 0 instead of random data
|
||||
REMOVEFILE_CROSS_MOUNT = (1 << 7), // Cross mountpoints when deleting recursively.
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
FCCE179913592780002CEE6D /* checkint.h in Headers */ = {isa = PBXBuildFile; fileRef = FCCE179013592780002CEE6D /* checkint.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
FCCE179A13592780002CEE6D /* removefile_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = FCCE179113592780002CEE6D /* removefile_priv.h */; settings = {ATTRIBUTES = (); }; };
|
||||
FCCE179A13592780002CEE6D /* removefile_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = FCCE179113592780002CEE6D /* removefile_priv.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
FCCE179B13592780002CEE6D /* removefile_random.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCE179213592780002CEE6D /* removefile_random.c */; };
|
||||
FCCE179C13592780002CEE6D /* removefile_rename_unlink.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCE179313592780002CEE6D /* removefile_rename_unlink.c */; };
|
||||
FCCE179D13592780002CEE6D /* removefile_sunlink.c in Sources */ = {isa = PBXBuildFile; fileRef = FCCE179413592780002CEE6D /* removefile_sunlink.c */; };
|
||||
@ -203,6 +203,8 @@
|
||||
FCCE1781135924CD002CEE6D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
SUPPORTS_TEXT_BASED_API = YES;
|
||||
TAPI_VERIFY_MODE = Pedantic;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@ -215,27 +217,20 @@
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "__DARWIN_NON_CANCELABLE=1";
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
IS_ZIPPERED = YES;
|
||||
LINK_WITH_STANDARD_LIBRARIES = NO;
|
||||
OTHER_LDFLAGS = (
|
||||
"-Wl,-umbrella,System",
|
||||
"-L/usr/lib/system",
|
||||
"-ldyld",
|
||||
"-lcompiler_rt",
|
||||
"-lsystem_kernel",
|
||||
"-lsystem_platform",
|
||||
"-lsystem$(SIM_SUFFIX)_kernel",
|
||||
"-lsystem$(SIM_SUFFIX)_platform",
|
||||
"-lsystem_malloc",
|
||||
"-lsystem_c",
|
||||
);
|
||||
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
|
||||
"-Wl,-umbrella,System",
|
||||
"-L/usr/lib/system",
|
||||
"-ldyld",
|
||||
"-lcompiler_rt",
|
||||
"-lsystem_sim_kernel",
|
||||
"-lsystem_sim_platform",
|
||||
"-lsystem_malloc",
|
||||
"-lsystem_sim_c",
|
||||
);
|
||||
"SIM_SUFFIX[sdk=iphonesimulator*]" = _sim;
|
||||
VERSION_INFO_PREFIX = "__attribute__((visibility(\"hidden\")))";
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
};
|
||||
name = Release;
|
||||
|
@ -60,3 +60,8 @@ void __removefile_randomize_buffer(unsigned char *buffer, size_t length, removef
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __APPLE__
|
||||
#ifndef AT_REMOVEDIR_DATALESS
|
||||
#define AT_REMOVEDIR_DATALESS 0x0100 /* Remove a dataless directory without materializing first */
|
||||
#endif
|
||||
#endif
|
||||
|
@ -93,6 +93,12 @@ __removefile_rename_unlink(const char *path, removefile_state_t state) {
|
||||
if (lstat(path, &statbuf) == -1)
|
||||
return -1;
|
||||
|
||||
#if __APPLE__
|
||||
if (S_ISDIR(statbuf.st_mode) && (statbuf.st_flags & SF_DATALESS) != 0) {
|
||||
return unlinkat(AT_FDCWD, path, AT_REMOVEDIR_DATALESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (S_ISDIR(statbuf.st_mode) && (empty_directory(path) == -1)) {
|
||||
/* Directory isn't empty (e.g. because it contains an immutable file).
|
||||
Attempting to remove it will fail, so avoid renaming it. */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* srm */
|
||||
/* Copyright (c) 2000 Matthew D. Gauthier
|
||||
* Portions copyright (c) 2007 Apple Inc. All rights reserved.
|
||||
* Portions copyright (c) 2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -31,6 +31,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
@ -39,7 +40,7 @@
|
||||
#include "removefile.h"
|
||||
#include "removefile_priv.h"
|
||||
|
||||
int
|
||||
static int
|
||||
__removefile_process_file(FTS* stream, FTSENT* current_file, removefile_state_t state) {
|
||||
int res = 0;
|
||||
char* path = current_file->fts_path;
|
||||
@ -82,7 +83,22 @@ __removefile_process_file(FTS* stream, FTSENT* current_file, removefile_state_t
|
||||
errno = EACCES;
|
||||
res = -1;
|
||||
} else {
|
||||
#if __APPLE__
|
||||
int is_dataless = (current_file->fts_statp->st_flags & SF_DATALESS) != 0;
|
||||
if (is_dataless) {
|
||||
int iopolicy = getiopolicy_np(IOPOL_TYPE_VFS_MATERIALIZE_DATALESS_FILES, IOPOL_SCOPE_THREAD);
|
||||
int non_materializing = iopolicy == IOPOL_MATERIALIZE_DATALESS_FILES_OFF;
|
||||
if (non_materializing || state->confirm_callback == NULL) {
|
||||
res = unlinkat(AT_FDCWD, path, AT_REMOVEDIR_DATALESS);
|
||||
} else {
|
||||
res = rmdir(path);
|
||||
}
|
||||
} else {
|
||||
res = rmdir(path);
|
||||
}
|
||||
#else
|
||||
res = rmdir(path);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (res == -1) state->error_num = errno;
|
||||
@ -117,6 +133,7 @@ __removefile_tree_walker(char **trees, removefile_state_t state) {
|
||||
FTSENT *current_file;
|
||||
FTS *stream;
|
||||
int rval = 0;
|
||||
int open_flags = 0;
|
||||
|
||||
removefile_callback_t cb_confirm = NULL;
|
||||
removefile_callback_t cb_status = NULL;
|
||||
@ -126,8 +143,22 @@ __removefile_tree_walker(char **trees, removefile_state_t state) {
|
||||
cb_status = state->status_callback;
|
||||
cb_error = state->error_callback;
|
||||
|
||||
stream = fts_open(trees, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
|
||||
if (stream == NULL) return -1;
|
||||
open_flags = FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV;
|
||||
|
||||
/*
|
||||
* Don't cross a mount point when deleting recursively by default.
|
||||
* This default was changed in 10.11, previous to which there was
|
||||
* no way to prevent removefile from crossing mount points.
|
||||
* see: rdar://problem/6799948
|
||||
*/
|
||||
if ((REMOVEFILE_CROSS_MOUNT & state->unlink_flags) != 0)
|
||||
open_flags &= ~FTS_XDEV;
|
||||
|
||||
stream = fts_open(trees, open_flags, NULL);
|
||||
if (stream == NULL) {
|
||||
state->error_num = errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((current_file = fts_read(stream)) != NULL) {
|
||||
int res = REMOVEFILE_PROCEED;
|
||||
@ -144,6 +175,16 @@ __removefile_tree_walker(char **trees, removefile_state_t state) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Setting FTS_XDEV skips the mountpoint on pre-order traversal,
|
||||
* but you have to manually hop over it on post-order or
|
||||
* removefile will return an error.
|
||||
*/
|
||||
if (current_file->fts_info == FTS_DP &&
|
||||
stream->fts_options & FTS_XDEV &&
|
||||
stream->fts_dev != current_file->fts_dev) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't process the file if a cancel has been requested
|
||||
if (__removefile_state_test_cancel(state)) break;
|
||||
|
||||
@ -209,7 +250,7 @@ __removefile_tree_walker(char **trees, removefile_state_t state) {
|
||||
}
|
||||
|
||||
if (__removefile_state_test_cancel(state)) {
|
||||
errno = ECANCELED;
|
||||
state->error_num = ECANCELED;
|
||||
rval = -1;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,16 @@
|
||||
#include "removefile.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
static struct timeval tv;
|
||||
static void start_timer(const char* str) {
|
||||
fprintf(stderr, "%s... ", str);
|
||||
@ -22,7 +27,7 @@ static void stop_timer() {
|
||||
} else {
|
||||
usec = tv2.tv_usec + (1000000 - tv.tv_usec);
|
||||
}
|
||||
fprintf(stderr, "%d.%03d\n", sec, usec);
|
||||
fprintf(stderr, "%ld.%03ld\n", sec, usec);
|
||||
}
|
||||
|
||||
|
||||
@ -46,7 +51,7 @@ static int removefile_status_callback(removefile_state_t state, const char * pat
|
||||
}
|
||||
|
||||
|
||||
int mkdirs() {
|
||||
void mkdirs() {
|
||||
start_timer("Creating directory structure");
|
||||
assert(mkdir("/tmp/removefile-test", 0755) == 0);
|
||||
assert(mkdir("/tmp/removefile-test/foo", 0755) == 0);
|
||||
@ -77,6 +82,15 @@ int main(int argc, char *argv[]) {
|
||||
pthread_t thread = NULL;
|
||||
int err = 0;
|
||||
|
||||
if (argc == 2) {
|
||||
/* pass in a directory with a mountpoint under it to test REMOVEFILE_CROSS_MOUNT */
|
||||
state = removefile_state_alloc();
|
||||
removefile_state_set(state, REMOVEFILE_STATE_ERROR_CALLBACK, removefile_error_callback);
|
||||
removefile_state_set(state, REMOVEFILE_STATE_ERROR_CONTEXT, (void*)4567);
|
||||
err = removefile(argv[1], state, REMOVEFILE_CROSS_MOUNT | REMOVEFILE_RECURSIVE);
|
||||
return err;
|
||||
}
|
||||
|
||||
mkdirs();
|
||||
start_timer("removefile(NULL)");
|
||||
assert(removefile("/tmp/removefile-test", NULL, REMOVEFILE_SECURE_1_PASS | REMOVEFILE_RECURSIVE) == 0);
|
||||
|
@ -1,15 +1,9 @@
|
||||
#include "<DEVELOPER_DIR>/Makefiles/CoreOS/Xcode/BSD.xcconfig"
|
||||
#include "<DEVELOPER_DIR>/AppleInternal/XcodeConfig/SimulatorSupport.xcconfig"
|
||||
|
||||
// Set INSTALL_PATH_ACTUAL to whatever INSTALL_PATH would normally be
|
||||
INSTALL_PATH_ACTUAL = /usr/lib/system
|
||||
INSTALL_PATH = /usr/lib/system
|
||||
|
||||
// Set INSTALL_PATH[sdk=macosx*] when SimulatorSupport.xcconfig is unavailable
|
||||
INSTALL_PATH[sdk=macosx*] = $(INSTALL_PATH_ACTUAL)
|
||||
|
||||
// Use $(INSTALL_PATH_PREFIX) instead of $(SDKROOT) as an unconditional prefix
|
||||
PUBLIC_HEADERS_FOLDER_PATH = $(INSTALL_PATH_PREFIX)/usr/include
|
||||
PRIVATE_HEADERS_FOLDER_PATH = $(INSTALL_PATH_PREFIX)/usr/local/include
|
||||
PUBLIC_HEADERS_FOLDER_PATH = /usr/include
|
||||
PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include
|
||||
|
||||
BUILD_VARIANTS = normal debug
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user