Added uio_rename(). It only works on files at the moment.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1160 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -63,6 +63,7 @@ static int debugCmdLs(DebugContext *debugContext, int argc, char *argv[]);
|
||||
static int debugCmdMem(DebugContext *debugContext, int argc, char *argv[]);
|
||||
static int debugCmdMkDir(DebugContext *debugContext, int argc, char *argv[]);
|
||||
static int debugCmdMount(DebugContext *debugContext, int argc, char *argv[]);
|
||||
static int debugCmdMv(DebugContext *debugContext, int argc, char *argv[]);
|
||||
static int debugCmdPwd(DebugContext *debugContext, int argc, char *argv[]);
|
||||
static int debugCmdRm(DebugContext *debugContext, int argc, char *argv[]);
|
||||
static int debugCmdRmDir(DebugContext *debugContext, int argc, char *argv[]);
|
||||
@@ -92,6 +93,7 @@ DebugCommand debugCommands[] = {
|
||||
{ "mem", debugCmdMem },
|
||||
{ "mkdir", debugCmdMkDir },
|
||||
{ "mount", debugCmdMount },
|
||||
{ "mv", debugCmdMv },
|
||||
{ "pwd", debugCmdPwd },
|
||||
{ "rm", debugCmdRm },
|
||||
{ "rmdir", debugCmdRmDir },
|
||||
@@ -634,6 +636,24 @@ debugCmdMount(DebugContext *debugContext, int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
debugCmdMv(DebugContext *debugContext, int argc, char *argv[]) {
|
||||
int retVal;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(debugContext->err, "Invalid number of arguments.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
retVal = uio_rename(debugContext->cwd, argv[1],
|
||||
debugContext->cwd, argv[2]);
|
||||
if (retVal == -1) {
|
||||
fprintf(debugContext->err, "Could not rename: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
debugCmdPwd(DebugContext *debugContext, int argc, char *argv[]) {
|
||||
uio_DirHandle_print(debugContext->cwd, debugContext->out);
|
||||
|
||||
@@ -35,6 +35,9 @@ Bugs:
|
||||
- uio_Stream file might get unaligned (not sure).
|
||||
- 'openDir(repository, "dir/")' will have the trailing '/'
|
||||
in the dirHandle, which will cause problems.
|
||||
- uio_rename() doesn't work on directories
|
||||
uio_GetPhysicalAccess() needs to be changed so that it works the same on
|
||||
dirs as on files. stat() can be cleaned up too then.
|
||||
|
||||
Extra features (not necessary for UQM):
|
||||
- Make functions to use for uio_malloc, uio_free and uio_realloc
|
||||
@@ -56,6 +59,11 @@ Extra features (not necessary for UQM):
|
||||
is accessed with the long vs the short ("PROGRA~1") name, or when
|
||||
capitalisation is involved.
|
||||
- accept non-dir, non-regular-file dir entries in stdio.
|
||||
- Add non-merging mounts. Make 'merging' an option for the mount.
|
||||
- make uio_rename() work cross-fs, or provide a wrapper which does that.
|
||||
(the system rename() doesn't work cross-fs either, so keeping uio_rename()
|
||||
as it is makes sense, as I'm trying to stay close to the system functions,
|
||||
even though hiding file systems from the user would be nicer)
|
||||
|
||||
Optimisations (not necessary for UQM):
|
||||
- use mmap for fileBlocks
|
||||
|
||||
@@ -65,10 +65,12 @@ struct uio_FileSystemHandler {
|
||||
int (*fstat) (uio_Handle *, struct stat *);
|
||||
int (*stat) (uio_PDirHandle *, const char *,
|
||||
struct stat *);
|
||||
uio_PDirHandle * (*mkdir) (uio_PDirHandle *, const char *, mode_t);
|
||||
uio_Handle * (*open) (uio_PDirHandle *, const char *, int,
|
||||
uio_PDirHandle * (*mkdir) (uio_PDirHandle *, const char *, mode_t);
|
||||
uio_Handle * (*open) (uio_PDirHandle *, const char *, int,
|
||||
mode_t);
|
||||
ssize_t (*read) (uio_Handle *, void *, size_t);
|
||||
int (*rename) (uio_PDirHandle *, const char *,
|
||||
uio_PDirHandle *, const char *);
|
||||
int (*rmdir) (uio_PDirHandle *, const char *);
|
||||
off_t (*seek) (uio_Handle *, off_t, int);
|
||||
ssize_t (*write) (uio_Handle *, const void *, size_t);
|
||||
|
||||
@@ -329,6 +329,81 @@ uio_close(uio_Handle *handle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
uio_rename(uio_DirHandle *oldDir, const char *oldPath,
|
||||
uio_DirHandle *newDir, const char *newPath) {
|
||||
uio_PDirHandle *oldPReadDir, *newPReadDir, *newPWriteDir;
|
||||
uio_MountInfo *oldReadMountInfo, *newReadMountInfo, *newWriteMountInfo;
|
||||
char *oldName, *newName;
|
||||
int retVal;
|
||||
|
||||
if (uio_getPhysicalAccess(oldDir, oldPath, O_RDONLY, 0,
|
||||
&oldReadMountInfo, &oldPReadDir,
|
||||
NULL, NULL, &oldName) == -1) {
|
||||
// errno is set
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uio_getPhysicalAccess(newDir, newPath, O_WRONLY | O_CREAT | O_EXCL,
|
||||
uio_GPA_NOWRITE, &newReadMountInfo, &newPReadDir,
|
||||
&newWriteMountInfo, &newPWriteDir, &newName) == -1) {
|
||||
int saveErrno = errno;
|
||||
uio_PDirHandle_unref(oldPReadDir);
|
||||
uio_free(oldName);
|
||||
errno = saveErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (oldReadMountInfo != newWriteMountInfo) {
|
||||
uio_PDirHandle_unref(oldPReadDir);
|
||||
uio_PDirHandle_unref(newPReadDir);
|
||||
uio_PDirHandle_unref(newPWriteDir);
|
||||
uio_free(oldName);
|
||||
uio_free(newName);
|
||||
errno = EXDEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uio_mountInfoIsReadOnly(oldReadMountInfo)) {
|
||||
uio_PDirHandle_unref(oldPReadDir);
|
||||
uio_PDirHandle_unref(newPReadDir);
|
||||
uio_PDirHandle_unref(newPWriteDir);
|
||||
uio_free(oldName);
|
||||
uio_free(newName);
|
||||
errno = EROFS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (oldReadMountInfo->pDirHandle->pRoot->handler->rename == NULL) {
|
||||
uio_PDirHandle_unref(oldPReadDir);
|
||||
uio_PDirHandle_unref(newPReadDir);
|
||||
uio_PDirHandle_unref(newPWriteDir);
|
||||
uio_free(oldName);
|
||||
uio_free(newName);
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
retVal = oldReadMountInfo->pDirHandle->pRoot->handler->rename(
|
||||
oldPReadDir, oldName, newPReadDir, newName);
|
||||
if (retVal == -1) {
|
||||
int saveErrno = errno;
|
||||
uio_PDirHandle_unref(oldPReadDir);
|
||||
uio_PDirHandle_unref(newPReadDir);
|
||||
uio_PDirHandle_unref(newPWriteDir);
|
||||
uio_free(oldName);
|
||||
uio_free(newName);
|
||||
errno = saveErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uio_PDirHandle_unref(oldPReadDir);
|
||||
uio_PDirHandle_unref(newPReadDir);
|
||||
uio_PDirHandle_unref(newPWriteDir);
|
||||
uio_free(oldName);
|
||||
uio_free(newName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
uio_fstat(uio_Handle *handle, struct stat *statBuf) {
|
||||
if (handle->root->handler->fstat == NULL) {
|
||||
@@ -345,7 +420,7 @@ uio_stat(uio_DirHandle *dir, const char *path, struct stat *statBuf) {
|
||||
char *name;
|
||||
int result;
|
||||
|
||||
if (uio_getPhysicalAccess(dir, path, O_RDONLY,
|
||||
if (uio_getPhysicalAccess(dir, path, O_RDONLY, 0,
|
||||
&readMountInfo, &pReadDir,
|
||||
NULL, NULL, &name) == -1) {
|
||||
if (uio_statDir(dir, path, statBuf) == -1) {
|
||||
@@ -435,7 +510,7 @@ uio_mkdir(uio_DirHandle *dir, const char *path, mode_t mode) {
|
||||
char *name;
|
||||
uio_PDirHandle *newDirHandle;
|
||||
|
||||
if (uio_getPhysicalAccess(dir, path, O_WRONLY | O_CREAT | O_EXCL,
|
||||
if (uio_getPhysicalAccess(dir, path, O_WRONLY | O_CREAT | O_EXCL, 0,
|
||||
&readMountInfo, &pReadDir,
|
||||
&writeMountInfo, &pWriteDir, &name) == -1) {
|
||||
// errno is set
|
||||
@@ -474,7 +549,7 @@ uio_open(uio_DirHandle *dir, const char *path, int flags, mode_t mode) {
|
||||
char *name;
|
||||
uio_Handle *handle;
|
||||
|
||||
if (uio_getPhysicalAccess(dir, path, flags,
|
||||
if (uio_getPhysicalAccess(dir, path, flags, 0,
|
||||
&readMountInfo, &readPDirHandle,
|
||||
&writeMountInfo, &writePDirHandle, &name) == -1) {
|
||||
// errno is set
|
||||
|
||||
@@ -94,6 +94,10 @@ uio_Handle *uio_open(uio_DirHandle *dir, const char *file, int flags,
|
||||
// Close a file descriptor for a file opened by uio_open
|
||||
int uio_close(uio_Handle *handle);
|
||||
|
||||
// Rename or move a file or directory.
|
||||
int uio_rename(uio_DirHandle *oldDir, const char *oldPath,
|
||||
uio_DirHandle *newDir, const char *newPath);
|
||||
|
||||
// Fstat a file descriptor
|
||||
int uio_fstat(uio_Handle *handle, struct stat *statBuf);
|
||||
|
||||
|
||||
@@ -257,6 +257,12 @@ copyError(int error,
|
||||
* Either O_RDONLY, O_RDWR, O_WRONLY. They may be
|
||||
* OR'd with other values accepted by open(). These
|
||||
* are ignored.
|
||||
* extraFlags - either 0 or uio_GPA_NOWRITE
|
||||
* When 0, the path will be created if it doesn't
|
||||
* exist in the writing location, but does exist
|
||||
* in the reading location. With uio_GPA_NOWRITE, it
|
||||
* won't be created, and -1 will be returned and errno
|
||||
* will be set to ENOENT.
|
||||
* mountInfoReadPtr - pointer to location where the pointer
|
||||
* to the MountInfo structure for the reading location
|
||||
* should be stored.
|
||||
@@ -272,8 +278,8 @@ copyError(int error,
|
||||
* to by readPDirHandlePtr, the handles will be the
|
||||
* same too.
|
||||
* restPtr - pointer to a newly created string with as contents
|
||||
* the last component of 'path'.
|
||||
* The caller is responsible for freeing this.
|
||||
* the last component of 'path'.
|
||||
* The caller is responsible for freeing this.
|
||||
* Returns: 0 - success
|
||||
* -1 - failure (errno set)
|
||||
* NB: This is the function that would most benefit from
|
||||
@@ -283,7 +289,7 @@ copyError(int error,
|
||||
*/
|
||||
int
|
||||
uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
|
||||
int flags,
|
||||
int flags, int extraFlags,
|
||||
uio_MountInfo **mountInfoReadPtr, uio_PDirHandle **readPDirHandlePtr,
|
||||
uio_MountInfo **mountInfoWritePtr, uio_PDirHandle **writePDirHandlePtr,
|
||||
char **restPtr) {
|
||||
@@ -433,6 +439,15 @@ uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
|
||||
|
||||
// There exists no path for a write dir, so it will have to be created.
|
||||
// writeMountInfo indicates the physical tree where it should end up.
|
||||
|
||||
if (extraFlags & uio_GPA_NOWRITE) {
|
||||
// The caller has specified that the path should not be created.
|
||||
uio_PDirHandle_unref(readPDirHandle);
|
||||
uio_free(fullPath);
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pRootPath = uio_mountTreeItemRestPath(writeItem, tree->lastComp,
|
||||
fullPath);
|
||||
|
||||
|
||||
@@ -33,9 +33,10 @@ uio_PDirHandle *uio_makePath(uio_PDirHandle *pDirHandle, const char *path,
|
||||
int uio_copyFilePhysical(uio_PDirHandle *fromDir, const char *fromName,
|
||||
uio_PDirHandle *toDir, const char *toName);
|
||||
int uio_getPhysicalAccess(uio_DirHandle *dirHandle, const char *path,
|
||||
int flags, uio_MountInfo **mountInfoReadPtr,
|
||||
int flags, int extraFlags, uio_MountInfo **mountInfoReadPtr,
|
||||
uio_PDirHandle **readPDirHandlePtr, uio_MountInfo **mountInfoWritePtr,
|
||||
uio_PDirHandle **writePDirHandlePtr, char **restPtr);
|
||||
#define uio_GPA_NOWRITE 1
|
||||
int uio_getPathPhysicalDirs(uio_DirHandle *dirHandle, const char *path,
|
||||
size_t pathLen, uio_PDirHandle ***resPDirHandles,
|
||||
int *resNumPDirHandles, uio_MountTreeItem ***resItems);
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// The GPDir structures and functions are used for caching only.
|
||||
|
||||
|
||||
#include "./stdio.h"
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -71,6 +74,7 @@ uio_FileSystemHandler stdio_fileSystemHandler = {
|
||||
/* .mkdir = */ stdio_mkdir,
|
||||
/* .open = */ stdio_open,
|
||||
/* .read = */ stdio_read,
|
||||
/* .rename = */ stdio_rename,
|
||||
/* .rmdir = */ stdio_rmdir,
|
||||
/* .seek = */ stdio_seek,
|
||||
/* .write = */ stdio_write,
|
||||
@@ -201,10 +205,12 @@ stdio_open(uio_PDirHandle *pDirHandle, const char *file, int flags,
|
||||
}
|
||||
uio_free(path);
|
||||
|
||||
#if 0
|
||||
if (flags & O_CREAT) {
|
||||
if (uio_GPDir_getGPDirEntry(pDirHandle->extra, file) == NULL)
|
||||
stdio_addFile(pDirHandle->extra, file);
|
||||
}
|
||||
#endif
|
||||
|
||||
handle = uio_malloc(sizeof (stdio_Handle));
|
||||
handle->fd = fd;
|
||||
@@ -217,6 +223,53 @@ stdio_read(uio_Handle *handle, void *buf, size_t count) {
|
||||
return read(handle->native->fd, buf, count);
|
||||
}
|
||||
|
||||
int
|
||||
stdio_rename(uio_PDirHandle *oldPDirHandle, const char *oldName,
|
||||
uio_PDirHandle *newPDirHandle, const char *newName) {
|
||||
char *newPath, *oldPath;
|
||||
int result;
|
||||
|
||||
oldPath = joinPaths(stdio_getPath(oldPDirHandle->extra), oldName);
|
||||
if (oldPath == NULL) {
|
||||
// errno is set
|
||||
return -1;
|
||||
}
|
||||
|
||||
newPath = joinPaths(stdio_getPath(newPDirHandle->extra), newName);
|
||||
if (newPath == NULL) {
|
||||
// errno is set
|
||||
uio_free(oldPath);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = rename(oldPath, newPath);
|
||||
if (result == -1) {
|
||||
int saveErrno = errno;
|
||||
uio_free(oldPath);
|
||||
uio_free(newPath);
|
||||
errno = saveErrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uio_free(oldPath);
|
||||
uio_free(newPath);
|
||||
|
||||
{
|
||||
// update the GPDir structure
|
||||
uio_GPDirEntry *entry;
|
||||
|
||||
// TODO: add locking
|
||||
entry = uio_GPDir_getGPDirEntry(oldPDirHandle->extra, oldName);
|
||||
if (entry != NULL) {
|
||||
uio_GPDirEntries_remove(oldPDirHandle->extra->entries, oldName);
|
||||
uio_GPDirEntries_add(newPDirHandle->extra->entries, newName,
|
||||
entry);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
stdio_rmdir(uio_PDirHandle *pDirHandle, const char *name) {
|
||||
char *path;
|
||||
|
||||
@@ -87,6 +87,8 @@ int stdio_fstat(uio_Handle *handle, struct stat *statBuf);
|
||||
int stdio_stat(uio_PDirHandle *pDirHandle, const char *name,
|
||||
struct stat *statBuf);
|
||||
ssize_t stdio_read(uio_Handle *handle, void *buf, size_t count);
|
||||
int stdio_rename(uio_PDirHandle *oldPDirHandle, const char *oldName,
|
||||
uio_PDirHandle *newPDirHandle, const char *newName);
|
||||
int stdio_rmdir(uio_PDirHandle *pDirHandle, const char *name);
|
||||
off_t stdio_seek(uio_Handle *handle, off_t offset, int whence);
|
||||
ssize_t stdio_write(uio_Handle *handle, const void *buf, size_t count);
|
||||
|
||||
@@ -102,6 +102,7 @@ uio_FileSystemHandler zip_fileSystemHandler = {
|
||||
/* .mkdir = */ NULL,
|
||||
/* .open = */ zip_open,
|
||||
/* .read = */ zip_read,
|
||||
/* .rename = */ NULL,
|
||||
/* .rmdir = */ NULL,
|
||||
/* .seek = */ zip_seek,
|
||||
/* .write = */ NULL,
|
||||
|
||||
Reference in New Issue
Block a user