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:
meep-eep
2003-08-31 18:40:01 +00:00
parent 96abf389ab
commit afb34fa474
10 changed files with 190 additions and 9 deletions
+20
View File
@@ -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);
+8
View File
@@ -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
+4 -2
View File
@@ -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);
+78 -3
View File
@@ -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
+4
View File
@@ -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);
+18 -3
View File
@@ -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);
+2 -1
View File
@@ -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);
+53
View File
@@ -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;
+2
View File
@@ -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);
+1
View File
@@ -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,