13 #include <sys/types.h>
26 # include <shellapi.h>
27 # include <shobjidl.h>
30 # if defined(__APPLE__)
31 # include <CoreFoundation/CoreFoundation.h>
32 # include <objc/message.h>
33 # include <objc/runtime.h>
36 # include <sys/param.h>
37 # include <sys/wait.h>
50 void *buf,
size_t len, FILE *
file,
size_t file_offset,
int compression_level)
52 fseek(
file, file_offset, SEEK_SET);
54 ZSTD_CCtx *ctx = ZSTD_createCCtx();
55 ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, compression_level);
59 size_t out_len = ZSTD_CStreamOutSize();
61 size_t total_written = 0;
65 ZSTD_outBuffer
output = {out_buf, out_len, 0};
66 size_t ret = ZSTD_compressStream2(ctx, &
output, &
input, ZSTD_e_continue);
67 if (ZSTD_isError(
ret)) {
73 total_written +=
output.pos;
79 ZSTD_outBuffer
output = {out_buf, out_len, 0};
81 if (ZSTD_isError(
ret)) {
87 total_written +=
output.pos;
93 return ZSTD_isError(
ret) ? 0 : total_written;
98 fseek(
file, file_offset, SEEK_SET);
100 ZSTD_DCtx *ctx = ZSTD_createDCtx();
102 size_t in_len = ZSTD_DStreamInSize();
104 ZSTD_inBuffer
input = {in_buf, in_len, 0};
111 input.size = fread(in_buf, 1, in_len,
file);
112 if (
input.size == 0) {
121 if (ZSTD_isError(
ret)) {
130 return ZSTD_isError(
ret) ? 0 :
output.pos;
137 return header[0] == 0x1f && header[1] == 0x8b && header[2] == 0x08;
158 if (
magic == 0xFD2FB528) {
161 if ((
magic >> 4) == 0x184D2A5) {
174 else if (errno != ENOENT) {
186 writable =
BLI_access(parent, X_OK | W_OK) == 0;
222 static void callLocalErrorCallBack(
const char *
err)
227 FILE *
BLI_fopen(
const char *filepath,
const char *mode)
231 return ufopen(filepath, mode);
234 void BLI_get_short_name(
char short_name[256],
const char *filepath)
236 wchar_t short_name_16[256];
241 GetShortPathNameW(filepath_16, short_name_16, 256);
243 for (i = 0; i < 256; i++) {
244 short_name[i] = (char)short_name_16[i];
250 void *
BLI_gzopen(
const char *filepath,
const char *mode)
257 if (mode[0] ==
'w') {
268 # if ZLIB_VERNUM >= 0x1270
271 gzfile = gzopen_w(filepath_16, mode);
276 char short_name[256];
277 BLI_get_short_name(short_name, filepath);
278 gzfile = gzopen(short_name, mode);
292 int BLI_access(
const char *filepath,
int mode)
296 return uaccess(filepath, mode);
299 static bool delete_soft(
const wchar_t *path_16,
const char **error_message)
306 HRESULT hr = CoInitializeEx(
NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
312 hr = CoCreateInstance(
313 &CLSID_FileOperation,
NULL, CLSCTX_ALL, &IID_IFileOperation, (
void **)&pfo);
320 hr = pfo->lpVtbl->SetOperationFlags(pfo, FOF_ALLOWUNDO | FOF_SILENT | FOF_WANTNUKEWARNING);
323 hr = SHCreateItemFromParsingName(path_16,
NULL, &IID_IShellItem, (
void **)&psi);
326 hr = pfo->lpVtbl->DeleteItem(pfo, psi,
NULL);
329 hr = pfo->lpVtbl->PerformOperations(pfo);
332 *error_message =
"Failed to prepare delete operation";
336 *error_message =
"Failed to prepare delete operation";
338 psi->lpVtbl->Release(psi);
341 *error_message =
"Failed to parse path";
345 *error_message =
"Failed to set operation flags";
347 pfo->lpVtbl->Release(pfo);
350 *error_message =
"Failed to create FileOperation instance";
355 *error_message =
"Failed to initialize COM";
361 static bool delete_unique(
const char *path,
const bool dir)
368 err = !RemoveDirectoryW(path_16);
370 printf(
"Unable to remove directory\n");
374 err = !DeleteFileW(path_16);
376 callLocalErrorCallBack(
"Unable to delete file");
385 static bool delete_recursive(
const char *dir)
389 uint filelist_num, i;
406 if (delete_recursive(
path)) {
411 if (delete_unique(fl->
path,
false)) {
418 if (!
err && delete_unique(dir,
true)) {
437 err = delete_unique(
file, dir);
463 int BLI_move(
const char *
file,
const char *to)
482 err = !MoveFileW(file_16, str_16);
487 callLocalErrorCallBack(
"Unable to move file");
488 printf(
" Move from '%s' to '%s' failed\n",
file,
str);
514 err = !CopyFileW(file_16, str_16,
false);
519 callLocalErrorCallBack(
"Unable to copy file!");
520 printf(
" Copy from '%s' to '%s' failed\n",
file,
str);
527 int BLI_create_symlink(
const char *
file,
const char *to)
530 callLocalErrorCallBack(
"Linking files is unsupported on Windows");
554 if (isalpha(tmp[0]) && (tmp[1] ==
':') && tmp[2] ==
'\0') {
577 printf(
"Unable to create directory %s\n",
dirname);
619 size_t len = strlen(dir) + strlen(
file) + 1;
624 else if (*alloc_len <
len) {
662 char *from_path =
NULL, *to_path =
NULL;
664 size_t from_alloc_len = -1, to_alloc_len = -1;
665 int i, n = 0,
ret = 0;
683 if (callback_file !=
NULL) {
692 n = scandir(startfrom, &dirlist,
NULL, alphasort);
700 if (callback_dir_pre !=
NULL) {
701 ret = callback_dir_pre(
from, to);
714 for (i = 0; i < n; i++) {
733 lstat(filepath, &st_dir);
734 is_dir =
S_ISDIR(st_dir.st_mode);
737 is_dir = (
dirent->d_type == DT_DIR);
743 from_path, to_path, callback_dir_pre, callback_file, callback_dir_post);
745 else if (callback_file !=
NULL) {
746 ret = callback_file(from_path, to_path);
760 if (callback_dir_post !=
NULL) {
761 ret = callback_dir_post(
from, to);
768 if (dirlist !=
NULL) {
769 for (i = 0; i < n; i++) {
774 if (from_path !=
NULL) {
777 if (to_path !=
NULL) {
817 Class NSAutoreleasePoolClass = objc_getClass(
"NSAutoreleasePool");
818 SEL allocSel = sel_registerName(
"alloc");
819 SEL initSel = sel_registerName(
"init");
820 id poolAlloc = ((
id(*)(Class, SEL))objc_msgSend)(NSAutoreleasePoolClass, allocSel);
821 id pool = ((
id(*)(
id, SEL))objc_msgSend)(poolAlloc, initSel);
823 Class NSStringClass = objc_getClass(
"NSString");
824 SEL stringWithUTF8StringSel = sel_registerName(
"stringWithUTF8String:");
826 id(*)(Class, SEL,
const char *))objc_msgSend)(NSStringClass, stringWithUTF8StringSel,
file);
828 Class NSFileManagerClass = objc_getClass(
"NSFileManager");
829 SEL defaultManagerSel = sel_registerName(
"defaultManager");
830 id fileManager = ((
id(*)(Class, SEL))objc_msgSend)(NSFileManagerClass, defaultManagerSel);
832 Class NSURLClass = objc_getClass(
"NSURL");
833 SEL fileURLWithPathSel = sel_registerName(
"fileURLWithPath:");
834 id nsurl = ((
id(*)(Class, SEL,
id))objc_msgSend)(NSURLClass, fileURLWithPathSel, pathString);
836 SEL trashItemAtURLSel = sel_registerName(
"trashItemAtURL:resultingItemURL:error:");
837 BOOL deleteSuccessful = ((
838 BOOL(*)(
id, SEL,
id,
id,
id))objc_msgSend)(fileManager, trashItemAtURLSel, nsurl, nil, nil);
840 if (deleteSuccessful) {
844 *error_message =
"The Cocoa API call to delete file or directory failed";
847 SEL drainSel = sel_registerName(
"drain");
848 ((
void (*)(
id, SEL))objc_msgSend)(
pool, drainSel);
856 const char *process_failed;
858 char *xdg_current_desktop = getenv(
"XDG_CURRENT_DESKTOP");
859 char *xdg_session_desktop = getenv(
"XDG_SESSION_DESKTOP");
861 if ((xdg_current_desktop !=
NULL &&
STREQ(xdg_current_desktop,
"KDE")) ||
862 (xdg_session_desktop !=
NULL &&
STREQ(xdg_session_desktop,
"KDE"))) {
863 args[0] =
"kioclient5";
868 process_failed =
"kioclient5 reported failure";
875 process_failed =
"gio reported failure";
884 waitpid(pid, &wstatus, 0);
886 if (!WIFEXITED(wstatus)) {
888 "Blender may not support moving files or directories to trash on your system.";
891 if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus)) {
892 *error_message = process_failed;
899 execvp(args[0], (
char **)args);
901 *error_message =
"Forking process failed.";
910 return fopen(filepath, mode);
917 return gzopen(filepath, mode);
924 return open(filepath,
oflag, pmode);
931 return access(filepath, mode);
959 struct stat st_a, st_b;
961 if (lstat(path_a, &st_a)) {
965 if (lstat(path_b, &st_b)) {
969 return st_a.st_dev == st_b.st_dev && st_a.st_ino == st_b.st_ino;
977 if (chown(
file,
st->st_uid,
st->st_gid)) {
982 if (chmod(
file,
st->st_mode)) {
997 fprintf(stderr,
"%s: '%s' is the same as '%s'\n", __func__,
from, to);
1007 if (mkdir(to,
st.st_mode)) {
1013 if (chown(to,
st.st_uid,
st.st_gid)) {
1023 FILE *from_stream, *to_stream;
1029 fprintf(stderr,
"%s: '%s' is the same as '%s'\n", __func__,
from, to);
1038 if (S_ISLNK(
st.st_mode)) {
1045 if ((
st.st_size + 1) <
sizeof(buf)) {
1050 link_buffer =
MEM_callocN(
st.st_size + 2,
"copy_single_file link_buffer");
1054 link_len = readlink(
from, link_buffer,
st.st_size + 1);
1065 link_buffer[link_len] =
'\0';
1067 if (symlink(link_buffer, to)) {
1081 if (S_ISCHR(
st.st_mode) || S_ISBLK(
st.st_mode) || S_ISFIFO(
st.st_mode) || S_ISSOCK(
st.st_mode)) {
1083 if (mknod(to,
st.st_mode,
st.st_rdev)) {
1095 fprintf(stderr,
"Copying of this kind of files isn't supported yet\n");
1099 from_stream = fopen(
from,
"rb");
1105 to_stream = fopen(to,
"wb");
1108 fclose(from_stream);
1112 while ((
len = fread(buf, 1,
sizeof(buf), from_stream)) > 0) {
1113 fwrite(buf, 1,
len, to_stream);
1117 fclose(from_stream);
1128 static int move_callback_pre(
const char *
from,
const char *to)
1139 static int move_single_file(
const char *
from,
const char *to)
1152 int BLI_move(
const char *
file,
const char *to)
1168 if (!stat(to, &
st)) {
1171 const char *filename;
1185 len = strlen(to) + strlen(filename) + 1;
1205 if (actual_to != to) {
1213 int BLI_create_symlink(
const char *
file,
const char *to)
1215 return symlink(to,
file);
1280 return rename(
from, to);
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
unsigned int BLI_filelist_dir_contents(const char *dir, struct direntry **r_filelist)
bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_filelist_free(struct direntry *filelist, unsigned int nrentries)
Some types for dealing with directories.
void BLI_kdtree_nd_() free(KDTree *tree)
const char * BLI_path_basename(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
void BLI_split_dirfile(const char *string, char *dir, char *file, size_t dirlen, size_t filelen)
#define FILENAME_IS_CURRPAR(_n)
void BLI_path_slash_rstrip(char *string) ATTR_NONNULL()
size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path_first,...) ATTR_NONNULL(1
int BLI_path_slash_ensure(char *string) ATTR_NONNULL()
void BLI_path_slash_native(char *path) ATTR_NONNULL()
const char * BLI_path_slash_rfind(const char *string) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
void BLI_join_dirfile(char *__restrict dst, size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Compatibility-like things for windows.
const char * dirname(char *path)
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
ATTR_WARN_UNUSED_RESULT const BMFlagLayer const short oflag
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SyclQueue void void size_t num_bytes void
static int set_permissions(const char *file, const struct stat *st)
FILE * BLI_fopen(const char *filepath, const char *mode)
int BLI_delete_soft(const char *file, const char **error_message)
int BLI_access(const char *filepath, int mode)
static bool check_the_same(const char *path_a, const char *path_b)
size_t BLI_file_unzstd_to_mem_at_pos(void *buf, size_t len, FILE *file, size_t file_offset)
int(* RecursiveOp_Callback)(const char *from, const char *to)
static const char * check_destination(const char *file, const char *to)
bool BLI_file_magic_is_gzip(const char header[4])
int BLI_copy(const char *file, const char *to)
bool BLI_dir_create_recursive(const char *dirname)
int BLI_open(const char *filepath, int oflag, int pmode)
static char * strip_last_slash(const char *dir)
bool BLI_file_is_writable(const char *filepath)
bool BLI_file_magic_is_zstd(const char header[4])
static int copy_single_file(const char *from, const char *to)
static int delete_single_file(const char *from, const char *UNUSED(to))
static void join_dirfile_alloc(char **dst, size_t *alloc_len, const char *dir, const char *file)
bool BLI_file_touch(const char *file)
static int recursive_operation(const char *startfrom, const char *startto, RecursiveOp_Callback callback_dir_pre, RecursiveOp_Callback callback_file, RecursiveOp_Callback callback_dir_post)
size_t BLI_file_zstd_from_mem_at_pos(void *buf, size_t len, FILE *file, size_t file_offset, int compression_level)
void * BLI_gzopen(const char *filepath, const char *mode)
static int delete_callback_post(const char *from, const char *UNUSED(to))
int BLI_rename(const char *from, const char *to)
static int delete_soft(const char *file, const char **error_message)
@ RecursiveOp_Callback_StopRecurs
@ RecursiveOp_Callback_OK
@ RecursiveOp_Callback_Error
static int copy_callback_pre(const char *from, const char *to)
int BLI_delete(const char *file, bool dir, bool recursive)
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_global KernelShaderEvalInput * input
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
bool remove(void *owner, const AttributeIDRef &attribute_id)
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
static int magic(const Tex *tex, const float texvec[3], TexResult *texres)
int umkdir(const char *pathname)
FILE * ufopen(const char *filename, const char *mode)
int uopen(const char *filename, int oflag, int pmode)
int uaccess(const char *filename, int mode)
int urename(const char *oldname, const char *newname)
#define UTF16_ENCODE(in8str)
#define UTF16_UN_ENCODE(in8str)