Linux host fst resource support.

This commit is contained in:
chris 2020-08-20 11:28:45 -04:00
parent 4805720545
commit b05713f017
2 changed files with 56 additions and 10 deletions

View File

@ -406,6 +406,14 @@ static char *get_path2(void) {
return NULL;
}
#if defined (__linux__)
static void get_resource_pathname(const char *path, char *rpath) {
char *pos=strrchr(path,'/');
strncpy(rpath, path, (pos-path)+1);
strcat(rpath, "._");
strcat(rpath, pos+1);
}
#endif
/*
* shutdown is called when switching to p8.
@ -546,6 +554,17 @@ static word32 fst_destroy(int class, const char *path) {
int ok = S_ISDIR(st.st_mode) ? rmdir(path) : unlink(path);
#if defined(__linux__)
if (! S_ISDIR(st.st_mode)) {
// on linux remove the resource fork file as well.
char rpath[1024];
get_resource_pathname(path, rpath);
if (stat(rpath, &st) == 0) {
int ok2 = unlink(rpath);
if (ok2 < 0) return host_map_errno_path(errno, path);
}
}
#endif
if (ok < 0) return host_map_errno_path(errno, path);
return 0;
}
@ -768,12 +787,18 @@ static int open_data_fork(const char *path, word16 *access, word16 *error) {
return fd;
}
#if defined(__APPLE__) || defined(__linux__)
static int open_resource_fork(const char *path, word16 *access, word16 *error) {
#if defined(__APPLE__)
static int open_resource_fork(const char *path, word16 *access, word16 *error) {
// os x / hfs/apfs don't need to specifically create a resource fork.
// or do they?
char *rpath = host_gc_append_path(path, _PATH_RSRCFORKSPEC);
#else
char rpath[1024];
get_resource_pathname(path, rpath);
#endif
int fd = -1;
for (;;) {
@ -852,11 +877,6 @@ static int open_resource_fork(const char *path, word16 *access, word16 *error) {
return fd;
}
#elif defined __linux__
static int open_resource_fork(const char *path, word16 *access, word16 *error) {
*error = resForkNotFound;
return -1;
}
#else
static int open_resource_fork(const char *path, word16 *access, word16 *error) {
*error = resForkNotFound;
@ -1534,9 +1554,20 @@ static word32 fst_change_path(int class, const char *path1, const char *path2) {
return invalidAccess;
// rename will delete any previous file. ChangePath should return an error.
#if ! defined(__linux__)
if (stat(path2, &st) == 0) return dupPathname;
if (rename(path1, path2) < 0) return host_map_errno_path(errno, path2);
#else
//on linux rename both the file and the resource file.
char rpath1[1024], rpath2[1024];
get_resource_pathname(path1, rpath1);
get_resource_pathname(path2, rpath2);
if (stat(path2, &st) == 0 || stat(rpath2, &st) == 0) return dupPathname;
if (rename(path1, path2) < 0) return host_map_errno_path(errno, path2);
if (rename(rpath1, rpath2) < 0) return host_map_errno_path(errno, rpath2);
#endif
return 0;
}

View File

@ -256,10 +256,25 @@ void host_get_file_xinfo(const char *path, struct file_info *fi) {
void host_get_file_xinfo(const char *path, struct file_info *fi) {
ssize_t tmp;
tmp = getxattr(path, "user.com.apple.ResourceFork", NULL, 0);
if (tmp < 0) tmp = 0;
fi->resource_eof = tmp;
fi->resource_blocks = (tmp + 511) / 512;
struct stat st;
char rpath[1024] = {0};
char *pos=strrchr(path,'/');
if (pos) {
strncpy(rpath, path, (pos-path)+1);
} else {
pos = (char *)path - 1;
}
strcat(rpath, "._");
strcat(rpath, pos+1);
int ok = stat(rpath, &st);
if (ok < 0) {
fi->resource_eof = 0;
fi->resource_blocks = 0;
} else {
fi->resource_eof = st.st_size;
fi->resource_blocks = st.st_blocks;
}
tmp = getxattr(path, "user.com.apple.FinderInfo", fi->finder_info, 32);
if (tmp == 16 || tmp == 32) {
@ -398,7 +413,7 @@ word32 host_set_file_info(const char *path, struct file_info *fi) {
word32 host_set_file_info(const char *path, struct file_info *fi) {
if (fi->has_fi && fi->storage_type != 0x0d) {
int ok = setxattr(path, "user.apple.FinderInfo", fi->finder_info, 32, 0);
int ok = setxattr(path, "user.com.apple.FinderInfo", fi->finder_info, 32, 0);
if (ok < 0) return host_map_errno(errno);
}