[Libsysio-commit] HEAD: libsysio/src rename.c
Brought to you by:
lward
From: Lee W. <lw...@us...> - 2004-08-26 09:03:11
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20651 Modified Files: rename.c Log Message: Fixed many bugs in rename. This is a complex function. Should be right now. I was carefuly this time. Really, I promise :-) Index: rename.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/rename.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -w -b -B -p -r1.8 -r1.9 --- rename.c 9 Aug 2004 14:30:00 -0000 1.8 +++ rename.c 26 Aug 2004 09:03:03 -0000 1.9 @@ -65,18 +65,30 @@ SYSIO_INTERFACE_NAME(rename)(const char SYSIO_INTERFACE_DISPLAY_BLOCK; SYSIO_INTERFACE_ENTER; + + /* + * Neither old nor new may be the empty string. + */ + if (*oldpath == '\0' || *newpath == '\0') + SYSIO_INTERFACE_RETURN(-1, -ENOENT); + /* * Resolve oldpath to a path node. */ INTENT_INIT(&intent, INT_UPDPARENT, NULL, NULL); - err = _sysio_namei(_sysio_cwd, oldpath, 0, &intent, &old); + err = _sysio_namei(_sysio_cwd, oldpath, ND_NOFOLLOW, &intent, &old); if (err) goto error3; /* * Resolve newpath to a path node. */ INTENT_INIT(&intent, INT_UPDPARENT, NULL, NULL); - err = _sysio_namei(_sysio_cwd, newpath, ND_NEGOK, &intent, &new); + err = + _sysio_namei(_sysio_cwd, + newpath, + ND_NOFOLLOW | ND_NEGOK, + &intent, + &new); if (err) goto error2; @@ -109,6 +121,12 @@ SYSIO_INTERFACE_NAME(rename)(const char } } while (nxtpb); + /* + * If old == new, we're done. + */ + if (old->p_base->pb_ino == new->p_base->pb_ino) + goto out; + while (new->p_base->pb_ino) { /* * Existing entry. We're replacing the new. Make sure that's @@ -129,17 +147,17 @@ SYSIO_INTERFACE_NAME(rename)(const char (void )_sysio_p_validate(new, NULL, NULL); continue; } - if (S_ISDIR(ostbuf.st_mode)) { - if (!S_ISDIR(nstbuf.st_mode)) { - err = -ENOTDIR; + if (S_ISDIR(nstbuf.st_mode)) { + if (!S_ISDIR(ostbuf.st_mode)) { + err = -EISDIR; goto error1; } if (nstbuf.st_nlink > 2) { err = -ENOTEMPTY; goto error1; } - } else if (S_ISDIR(nstbuf.st_mode)) { - err = -EEXIST; + } else if (S_ISDIR(ostbuf.st_mode)) { + err = -ENOTDIR; goto error1; } break; @@ -151,7 +169,7 @@ SYSIO_INTERFACE_NAME(rename)(const char * now. If it becomes an issue, we can do it later. For now, I've * elected to use the semantic that says, basically, the entire * sub-tree must be unreferenced. That's per POSIX, but it's a nasty - * this to do to the caller. + * thing to do to the caller. */ if (_sysio_p_prune(new) != 1) { err = -EBUSY; |