removefile-48

This commit is contained in:
Ariel Abreu 2020-06-16 14:46:49 -04:00
parent 9b23a7dbbe
commit 7c4e4da0de
No known key found for this signature in database
GPG Key ID: F4D43CC7053EA2B3
13 changed files with 169 additions and 103 deletions

View File

@ -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;

View File

@ -1 +0,0 @@
../checkint.h

View File

@ -1 +0,0 @@
../removefile.h

View File

@ -1 +0,0 @@
../removefile_priv.h

View File

@ -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

View File

@ -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;
}

View File

@ -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.
};
/*

View File

@ -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;

View File

@ -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

View File

@ -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. */

View File

@ -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;
}

View File

@ -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);

View File

@ -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