tst: passthrough-fuse: windows-posix layer

This commit is contained in:
Bill Zissimopoulos 2017-01-29 10:29:37 -08:00
parent 473914d45f
commit a91e5b01ab
3 changed files with 310 additions and 14 deletions

View File

@ -16,6 +16,7 @@
*/
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@ -195,7 +196,7 @@ static int ptfs_create(const char *path, fuse_mode_t mode, struct fuse_file_info
ptfs_impl_fullpath(path);
int fd;
return -1 != (fd = creat(path, mode)) ? (fi->fh = fd, 0) : -errno;
return -1 != (fd = open(path, O_CREAT | O_EXCL, mode)) ? (fi->fh = fd, 0) : -errno;
}
static int ptfs_ftruncate(const char *path, fuse_off_t off, struct fuse_file_info *fi)

View File

@ -15,5 +15,292 @@
* software.
*/
#include <windows.h>
#include <fcntl.h>
#include <fuse.h>
#include "winposix.h"
static int maperror(int winerrno);
char *realpath(const char *path, char *resolved)
{
char *result;
HANDLE h = CreateFileA(path,
FILE_READ_ATTRIBUTES, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if (INVALID_HANDLE_VALUE == h)
{
errno = maperror(GetLastError());
return 0;
}
if (0 == resolved)
{
result = malloc(PATH_MAX); /* sets errno */
if (0 == result)
return 0;
}
else
result = resolved;
if (PATH_MAX < GetFinalPathNameByHandleA(h, resolved, PATH_MAX, 0))
{
if (result != resolved)
free(result);
errno = EINVAL;
result = 0;
}
CloseHandle(h);
return result;
}
int statvfs(const char *path, struct fuse_statvfs *stbuf)
{
char root[PATH_MAX];
DWORD
VolumeSerialNumber,
MaxComponentLength,
SectorsPerCluster,
BytesPerSector,
NumberOfFreeClusters,
TotalNumberOfClusters;
if (!GetVolumePathNameA(path, root, PATH_MAX) ||
!GetVolumeInformationA(root, 0, 0, &VolumeSerialNumber, &MaxComponentLength, 0, 0, 0) ||
!GetDiskFreeSpaceA(root, &SectorsPerCluster, &BytesPerSector,
&NumberOfFreeClusters, &TotalNumberOfClusters))
{
errno = maperror(GetLastError());
return -1;
}
memset(stbuf, 0, sizeof *stbuf);
stbuf->f_bsize = SectorsPerCluster * BytesPerSector;
stbuf->f_frsize = BytesPerSector;
stbuf->f_blocks = TotalNumberOfClusters;
stbuf->f_bfree = NumberOfFreeClusters;
stbuf->f_bavail = TotalNumberOfClusters;
stbuf->f_fsid = VolumeSerialNumber;
stbuf->f_namemax = MaxComponentLength;
return -1;
}
int open(const char *path, int oflag, ...)
{
static DWORD da[] = { GENERIC_READ, GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE, 0 };
static DWORD cd[] = { OPEN_EXISTING, OPEN_ALWAYS, TRUNCATE_EXISTING, CREATE_ALWAYS };
DWORD DesiredAccess = 0 == (oflag & _O_APPEND) ?
da[oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)] :
(da[oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)] & ~FILE_WRITE_DATA) | FILE_APPEND_DATA;
DWORD CreationDisposition = (_O_CREAT | _O_EXCL) == (oflag & (_O_CREAT | _O_EXCL)) ?
CREATE_NEW :
cd[(oflag & (_O_CREAT | _O_TRUNC)) >> 8];
HANDLE h = CreateFileA(path,
DesiredAccess, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0,
CreationDisposition, FILE_ATTRIBUTE_NORMAL, 0);
if (INVALID_HANDLE_VALUE == h)
{
errno = maperror(GetLastError());
return -1;
}
return (int)(intptr_t)h;
}
int fstat(int fd, struct fuse_stat *stbuf)
{
return -1;
}
int ftruncate(int fd, fuse_off_t size)
{
return -1;
}
int pread(int fd, void *buf, size_t nbyte, fuse_off_t offset)
{
return -1;
}
int pwrite(int fd, const void *buf, size_t nbyte, fuse_off_t offset)
{
return -1;
}
int fsync(int fd)
{
return -1;
}
int close(int fd)
{
return -1;
}
int lstat(const char *path, struct fuse_stat *stbuf)
{
return -1;
}
int chmod(const char *path, fuse_mode_t mode)
{
return -1;
}
int lchown(const char *path, fuse_uid_t uid, fuse_gid_t gid)
{
return -1;
}
int truncate(const char *path, fuse_off_t size)
{
return -1;
}
int utime(const char *path, const struct fuse_utimbuf *timbuf)
{
return -1;
}
int unlink(const char *path)
{
return -1;
}
int rename(const char *oldpath, const char *newpath)
{
return -1;
}
int mkdir(const char *path, fuse_mode_t mode)
{
return -1;
}
int rmdir(const char *path)
{
return -1;
}
DIR *opendir(const char *path)
{
return 0;
}
struct dirent *readdir(DIR *dirp)
{
return 0;
}
int closedir(DIR *dp)
{
return -1;
}
static int maperror(int winerrno)
{
switch (winerrno)
{
case ERROR_INVALID_FUNCTION:
return EINVAL;
case ERROR_FILE_NOT_FOUND:
return ENOENT;
case ERROR_PATH_NOT_FOUND:
return ENOENT;
case ERROR_TOO_MANY_OPEN_FILES:
return EMFILE;
case ERROR_ACCESS_DENIED:
return EACCES;
case ERROR_INVALID_HANDLE:
return EBADF;
case ERROR_ARENA_TRASHED:
return ENOMEM;
case ERROR_NOT_ENOUGH_MEMORY:
return ENOMEM;
case ERROR_INVALID_BLOCK:
return ENOMEM;
case ERROR_BAD_ENVIRONMENT:
return E2BIG;
case ERROR_BAD_FORMAT:
return ENOEXEC;
case ERROR_INVALID_ACCESS:
return EINVAL;
case ERROR_INVALID_DATA:
return EINVAL;
case ERROR_INVALID_DRIVE:
return ENOENT;
case ERROR_CURRENT_DIRECTORY:
return EACCES;
case ERROR_NOT_SAME_DEVICE:
return EXDEV;
case ERROR_NO_MORE_FILES:
return ENOENT;
case ERROR_LOCK_VIOLATION:
return EACCES;
case ERROR_BAD_NETPATH:
return ENOENT;
case ERROR_NETWORK_ACCESS_DENIED:
return EACCES;
case ERROR_BAD_NET_NAME:
return ENOENT;
case ERROR_FILE_EXISTS:
return EEXIST;
case ERROR_CANNOT_MAKE:
return EACCES;
case ERROR_FAIL_I24:
return EACCES;
case ERROR_INVALID_PARAMETER:
return EINVAL;
case ERROR_NO_PROC_SLOTS:
return EAGAIN;
case ERROR_DRIVE_LOCKED:
return EACCES;
case ERROR_BROKEN_PIPE:
return EPIPE;
case ERROR_DISK_FULL:
return ENOSPC;
case ERROR_INVALID_TARGET_HANDLE:
return EBADF;
case ERROR_WAIT_NO_CHILDREN:
return ECHILD;
case ERROR_CHILD_NOT_COMPLETE:
return ECHILD;
case ERROR_DIRECT_ACCESS_HANDLE:
return EBADF;
case ERROR_NEGATIVE_SEEK:
return EINVAL;
case ERROR_SEEK_ON_DEVICE:
return EACCES;
case ERROR_DIR_NOT_EMPTY:
return ENOTEMPTY;
case ERROR_NOT_LOCKED:
return EACCES;
case ERROR_BAD_PATHNAME:
return ENOENT;
case ERROR_MAX_THRDS_REACHED:
return EAGAIN;
case ERROR_LOCK_FAILED:
return EACCES;
case ERROR_ALREADY_EXISTS:
return EEXIST;
case ERROR_FILENAME_EXCED_RANGE:
return ENOENT;
case ERROR_NESTING_NOT_ALLOWED:
return EAGAIN;
case ERROR_NOT_ENOUGH_QUOTA:
return ENOMEM;
default:
if (ERROR_WRITE_PROTECT <= winerrno && winerrno <= ERROR_SHARING_BUFFER_EXCEEDED)
return EACCES;
else if (ERROR_INVALID_STARTING_CODESEG <= winerrno && winerrno <= ERROR_INFLOOP_IN_RELOC_CHAIN)
return ENOEXEC;
else
return EINVAL;
}
}

View File

@ -18,6 +18,14 @@
#ifndef WINPOSIX_H_INCLUDED
#define WINPOSIX_H_INCLUDED
#define O_RDONLY _O_RDONLY
#define O_WRONLY _O_WRONLY
#define O_RDWR _O_RDWR
#define O_APPEND _O_APPEND
#define O_CREAT _O_CREAT
#define O_EXCL _O_EXCL
#define O_TRUNC _O_TRUNC
#define PATH_MAX 1024
typedef struct _DIR DIR;
@ -26,28 +34,28 @@ struct dirent
char d_name[255];
};
char *realpath(const char *path, char *resolved_path);
char *realpath(const char *path, char *resolved);
int statvfs(const char *path, struct fuse_statvfs *buf);
int statvfs(const char *path, struct fuse_statvfs *stbuf);
int mkdir(const char *path, fuse_mode_t mode);
int rmdir(const char *path);
int open(const char *path, int oflag, ...);
int fstat(int fd, struct fuse_stat *stbuf);
int ftruncate(int fd, fuse_off_t size);
int pread(int fd, void *buf, size_t nbyte, fuse_off_t offset);
int pwrite(int fd, const void *buf, size_t nbyte, fuse_off_t offset);
int fsync(int fd);
int close(int fd);
int unlink(const char *path);
int lstat(const char *path, struct fuse_stat *stbuf);
int chmod(const char *path, fuse_mode_t mode);
int lchown(const char *path, fuse_uid_t uid, fuse_gid_t gid);
int truncate(const char *path, fuse_off_t size);
int utime(const char *path, const struct fuse_utimbuf *timbuf);
int unlink(const char *path);
int rename(const char *oldpath, const char *newpath);
int creat(const char *path, fuse_mode_t mode);
int open(const char *path, int oflag);
int fstat(int fd, struct fuse_stat *stbuf);
int ftruncate(int fd, fuse_off_t size);;
int pread(int fd, void *buf, size_t nbyte, fuse_off_t offset);
int pwrite(int fd, const void *buf, size_t nbyte, fuse_off_t offset);
int fsync(int fd);
int close(int fd);
int mkdir(const char *path, fuse_mode_t mode);
int rmdir(const char *path);
DIR *opendir(const char *path);
struct dirent *readdir(DIR *dirp);