Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib/intern/BLI_bfile.c')
-rw-r--r--source/blender/blenlib/intern/BLI_bfile.c192
1 files changed, 134 insertions, 58 deletions
diff --git a/source/blender/blenlib/intern/BLI_bfile.c b/source/blender/blenlib/intern/BLI_bfile.c
index b5dd764d6c6..dc593e23bdc 100644
--- a/source/blender/blenlib/intern/BLI_bfile.c
+++ b/source/blender/blenlib/intern/BLI_bfile.c
@@ -1,4 +1,5 @@
-/*
+/* -*- indent-tabs-mode:t; tab-width:4; -*-
+ *
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -62,17 +63,19 @@
/* Declaration of internal functions */
-void chomp(char* line);
-void expand_envvars(char* src, char* dst);
-void fill_paths(BFILE *bfile, const char *path);
-char* find_in_pathlist(char* filename, char* pathlist);
-void init_vars_from_file(const char* path);
-void setup_temp();
+static void chomp(char* line);
+static void expand_envvars(char* src, char* dst);
+static void fill_paths(BFILE *bfile, const char *path, const char *relpath);
+static char* find_in_pathlist(char* filename, char* pathlist);
+static void init_vars_from_file(const char* path);
+static void free_paths(BFILE* bfile);
+static void setup_temp();
+
/*** Exported functions ***/
BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags,
- BEnvVarFam envvars)
+ const char *relpath)
{
BFILE *bfile;
@@ -88,50 +91,85 @@ BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags,
a BCF_AT_END | BCF_WRITE
a+ BCF_AT_END | BCF_WRITE | BCF_READ
*/
- if(strchr(mode, 'r'))
+ if (strchr(mode, 'r'))
bfile->classf |= BCF_READ;
- if(strchr(mode, 'w'))
+ if (strchr(mode, 'w'))
bfile->classf |= (BCF_DISCARD | BCF_WRITE);
- if(strchr(mode, 'a'))
+ if (strchr(mode, 'a'))
bfile->classf |= (BCF_AT_END | BCF_WRITE);
- if(strchr(mode, '+'))
+ if (strchr(mode, '+'))
bfile->classf |= (BCF_READ | BCF_WRITE);
- fill_paths(bfile, path);
+ fill_paths(bfile, path, relpath);
bfile->stream = fopen(bfile->tpath, mode);
- // detect failed fopen
+ if (!(bfile->stream)) {
+ free_paths(bfile);
+ MEM_freeN(bfile);
+ return NULL;
+ }
+
bfile->fd = fileno(bfile->stream);
+
return bfile;
}
BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags,
- BEnvVarFam envvars)
+ const char *relpath)
{
BFILE *bfile;
+ char fopen_mode[3];
bfile = MEM_mallocN(sizeof(BFILE), "bfile-open");
bfile->classf = BCF_OPEN;
bfile->uflags = bflags;
/* Easy mapping for open() */
- if(flags & O_RDONLY)
+ if (flags & O_RDONLY)
bfile->classf |= BCF_READ;
- if(flags & O_WRONLY)
+ if (flags & O_WRONLY)
bfile->classf |= BCF_WRITE;
- if(flags & O_RDWR)
+ if (flags & O_RDWR)
bfile->classf |= (BCF_READ | BCF_WRITE);
- if(flags & O_APPEND)
+ if (flags & O_APPEND)
bfile->classf |= BCF_AT_END;
- if(flags & O_TRUNC)
+ if (flags & O_TRUNC)
bfile->classf |= BCF_DISCARD;
- fill_paths(bfile, pathname);
+ fill_paths(bfile, pathname, relpath);
bfile->fd = open(bfile->tpath, flags);
- // detect failed open
-// bfile->stream = fdopen(bfile->fd, XXX); /* MSWindows _fdopen? */
+ if (bfile->fd == -1) {
+ free_paths(bfile);
+ MEM_freeN(bfile);
+ return NULL;
+ }
+
+ fopen_mode[0] = 'r';
+ fopen_mode[1] = '\0';
+ fopen_mode[2] = '\0';
+ if (bfile->classf & BCF_DISCARD) {
+ fopen_mode[0] = 'w';
+ if (bfile->classf & BCF_READ) {
+ fopen_mode[1] = '+';
+ }
+ } else if (bfile->classf & BCF_AT_END) {
+ fopen_mode[0] = 'a';
+ if (bfile->classf & BCF_READ) {
+ fopen_mode[1] = '+';
+ }
+ } else if (bfile->classf & BCF_WRITE) {
+ fopen_mode[1] = '+';
+ }
+
+ bfile->stream = fdopen(bfile->fd, fopen_mode); /* MSWindows _fdopen? */
+ if (!(bfile->stream)) {
+ free_paths(bfile);
+ MEM_freeN(bfile);
+ return NULL;
+ }
+
return bfile;
}
@@ -171,12 +209,15 @@ ssize_t BLI_bfile_read(BFILE *f, void *buf, size_t count) {
size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb,
- BFILE *f)
+ BFILE *f)
{
size_t ret;
+ if (f == NULL)
+ return 0;
+
ret = fwrite(ptr, size, nmemb, f->stream);
- if (ret < 0) {
+ if (ret <= 0) {
f->error = 1;
}
@@ -187,8 +228,11 @@ size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb,
size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f) {
size_t ret;
+ if (f == NULL)
+ return 0;
+
ret = fread(ptr, size, nmemb, f->stream);
- if ((ret < 0) && ferror(f->stream)) {
+ if ((ret <= 0) && ferror(f->stream)) {
f->error = 1;
}
@@ -197,21 +241,23 @@ size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f) {
void BLI_bfile_close(BFILE *bfile) {
- if((bfile->classf | BCF_WRITE) &&
- !(bfile->uflags | BFILE_RAW)) {
+ if ((bfile->classf | BCF_WRITE) &&
+ !(bfile->uflags | BFILE_RAW)) {
+ int error;
/* Make sure data is on disk */
+ error = fsync(bfile->fd);
+ /* fsync the directory too? */
/* Move to final name if no errors */
+ if (!(bfile->error) && !error) {
+ rename(bfile->tpath, bfile->fpath);
+ }
}
/* Normal close */
/* Cleanup */
- if(bfile->fpath) {
- MEM_freeN(bfile->fpath);
- }
- if(bfile->tpath) {
- MEM_freeN(bfile->tpath);
- }
+ free_paths(bfile);
+ MEM_freeN(bfile);
}
@@ -240,7 +286,7 @@ void BLI_bfile_init_vars() {
/* Is this unpack&run? */
sprintf(temp, "%s/%d/environment", dirname(bprogname), BLENDER_VERSION);
- if(BLI_exist(temp)) {
+ if (BLI_exist(temp)) {
BLI_setenv_if_new("BLENDER_SHARE", dirname(bprogname));
} else {
BLI_setenv_if_new("BLENDER_SHARE", (const char*)GHOST_getSystemDir());
@@ -255,12 +301,12 @@ void BLI_bfile_init_vars() {
temp[3] = '\0';
BLI_setenv("BLENDER_VERSION_PREV", temp);
/* 2nd line, read previous session path if needed */
- if(!getenv("BLENDER_TEMP")) {
+ if (!getenv("BLENDER_TEMP")) {
if ((fgets(temp, MAXPATHLEN, fp) != NULL)) {
/* Clean any \n */
chomp(temp);
/* Check the dir is still there or generate new one */
- if(!BLI_exist(temp)) {
+ if (!BLI_exist(temp)) {
setup_temp();
}
} else {
@@ -274,7 +320,15 @@ void BLI_bfile_init_vars() {
setup_temp();
}
- if(fp) {
+ if (fp) {
+ fclose(fp);
+ }
+
+ /* Loaded session info (or created), so time to store current data */
+ // TODO use own fuctions to get safe saving
+ fp = fopen(file, "w");
+ if (fp) {
+ fprintf(fp, "%s\n%s\n", getenv("BLENDER_VERSION"), getenv("BLENDER_TEMP"));
fclose(fp);
}
@@ -295,7 +349,7 @@ void BLI_bfile_init_vars() {
Eliminate trailing EOL by writing a \0 over it.
Name taken from Perl.
*/
-void chomp(char* line) {
+static void chomp(char* line) {
int len = strlen(line);
#ifndef WIN32
if (line[len - 1] == '\n') {
@@ -319,7 +373,7 @@ void chomp(char* line) {
#define MAX_LINE 4096
#define ENV_VAR 256
#define VAR_LEN 8192
-void init_vars_from_file(const char* path) {
+static void init_vars_from_file(const char* path) {
char line[MAX_LINE];
char name[ENV_VAR];
FILE *fp;
@@ -336,7 +390,7 @@ void init_vars_from_file(const char* path) {
/* Split into envvar name and contents */
separator = strchr(line, '=');
- if(separator && ((separator - line) < ENV_VAR)) {
+ if (separator && ((separator - line) < ENV_VAR)) {
/* First remove EOL */
chomp(line);
strncpy(name, line, separator - line);
@@ -366,7 +420,7 @@ void init_vars_from_file(const char* path) {
#define ENVVAR_SUFFIX "%"
#define ENVVAR_S_SIZE 1
#endif /* WIN32 */
-void expand_envvars(char* src, char* dst) {
+static void expand_envvars(char* src, char* dst) {
char* hit1;
char* hit2;
char name[ENV_VAR];
@@ -427,7 +481,7 @@ void expand_envvars(char* src, char* dst) {
#else
#define SEPARATOR ':'
#endif
-char* find_in_pathlist(char* filename, char* pathlist) {
+static char* find_in_pathlist(char* filename, char* pathlist) {
char first[FILE_MAX + 10];
char* rest = NULL;
@@ -445,12 +499,12 @@ char* find_in_pathlist(char* filename, char* pathlist) {
/* Check if combination exists */
BLI_add_slash(first);
strcat(first, filename);
- if(BLI_exist(first)) {
+ if (BLI_exist(first)) {
return strdup(first);
}
/* First path failed, try with rest of paths if possible */
- if(rest) {
+ if (rest) {
return find_in_pathlist(filename, rest);
} else {
return NULL;
@@ -461,35 +515,42 @@ char* find_in_pathlist(char* filename, char* pathlist) {
/**
Setup fpath and tpath based in the needs of the bfile.
*/
-void fill_paths(BFILE *bfile, const char *path) {
+static void fill_paths(BFILE *bfile, const char *path, const char *relpath) {
char* source_path = NULL;
char* temp_path = NULL;
int bflags = bfile->uflags;
- if(bflags & BFILE_NORMAL || bflags & BFILE_RAW) {
+ if (bflags & BFILE_NORMAL || bflags & BFILE_RAW) {
// bfile->fpath is path with // replaced
}
- if(bflags & BFILE_TEMP) {
+ if (bflags & BFILE_TEMP) {
temp_path = MEM_mallocN(MAXPATHLEN, "bfile-fpath-1");
snprintf(temp_path, MAXPATHLEN, "%s/%s", getenv("BLENDER_TEMP"), path);
bfile->fpath = temp_path;
}
- if(bflags & BFILE_CONFIG) {
+ if (bflags & (BFILE_CONFIG_BASE | BFILE_CONFIG_DATAFILES |
+ BFILE_CONFIG_PYTHON | BFILE_CONFIG_PLUGINS)) {
+// evars
// bfile->fpath is userdir+version+path
// source_path is first hit in (if using fallback to older versions)
// userdir+curversion+path (... userdir+limitversion+path) sysdir+path
// (limitversion is based in path, using some kind of regex or "tables")
}
- if(bfile->classf & BCF_WRITE && !(bflags & BFILE_RAW)) {
- /* Generate temp path */
+ if (bfile->classf & BCF_WRITE && !(bflags & BFILE_RAW)) {
+ /* Generate random named path */
temp_path = MEM_mallocN(MAXPATHLEN, "bfile-fpath-2");
snprintf(temp_path, MAXPATHLEN, "%s.XXXXXX", path);
- bfile->tpath = mkdtemp(temp_path);
- if(!(bfile->classf & BCF_DISCARD)) {
- /* Copy data to tpath */
- if(source_path) {
- // copy it from older version or sys version
+ bfile->fd = mkstemp(temp_path);
+ bfile->tpath = temp_path;
+ /* It will be reopened in upper levels, later */
+ close(bfile->fd);
+ if (!(bfile->classf & BCF_DISCARD)) {
+ /* Copy original data into temp location */
+ if (source_path) {
+ BLI_copy_fileops(source_path, bfile->tpath);
+ } else {
+ BLI_copy_fileops(bfile->fpath, bfile->tpath);
}
}
} else {
@@ -499,17 +560,32 @@ void fill_paths(BFILE *bfile, const char *path) {
/**
+ Free memory used for path strings.
+ */
+static void free_paths(BFILE* bfile) {
+ if (bfile->fpath) {
+ MEM_freeN(bfile->fpath);
+ }
+ if (bfile->tpath) {
+ MEM_freeN(bfile->tpath);
+ }
+}
+
+
+/**
Create a temp directory in safe and multiuser way.
*/
-void setup_temp() {
+static void setup_temp() {
char template[MAXPATHLEN];
char* tempdir;
- if(getenv("TMPDIR")) {
+ if (getenv("TMPDIR")) {
sprintf(template, "%s/blender-XXXXXX", getenv("TMPDIR"));
} else {
sprintf(template, "/tmp/blender-XXXXXX");
// MacOSX NSTemporaryDirectory and WIN32 ???
+// https://bugs.launchpad.net/cuneiform-linux/+bug/267136
+// https://svn.r-project.org/R/trunk/src/main/mkdtemp.c
}
tempdir = mkdtemp(template);
BLI_setenv("BLENDER_TEMP", tempdir);