Closed
Bug 107641
Opened 25 years ago
Closed 24 years ago
on Linux CopyTo won't copy read-only files or broken symlinks[FIX]
Categories
(Core Graveyard :: File Handling, defect)
Tracking
(Not tracked)
RESOLVED
FIXED
mozilla0.9.9
People
(Reporter: gsmedley, Assigned: pete)
Details
Attachments
(1 file, 7 obsolete files)
|
4.63 KB,
patch
|
Details | Diff | Splinter Review |
In nsLocalFileUnix.cpp the function nsLocalFile::CopyTo creates the new file
with the same permissions as the old file. If the old file is read-only it means
the new file will be read-only and you won't be able to copy to it.
Suggest making files created by CopyTo have write permission for the owner,
something like:
rv = newFile->Create(NORMAL_FILE_TYPE, myPerms | S_IWRITE);
Comment 2•25 years ago
|
||
good suggestion. -> 0.9.8.
Status: NEW → ASSIGNED
Target Milestone: --- → mozilla0.9.8
Comment 3•24 years ago
|
||
pete, any interest in taking this bug?
| Assignee | ||
Updated•24 years ago
|
Status: NEW → ASSIGNED
| Reporter | ||
Comment 5•24 years ago
|
||
This is a patch for copying read-only files and directories on linux. It also
fixes a problem with recursive copy of directories, each sub-dir was being
copied twice, the first containing only the second.
| Assignee | ||
Comment 6•24 years ago
|
||
| Assignee | ||
Comment 7•24 years ago
|
||
Ok, my patch is incomplete
I forgot the dir creates.
However, there is still a problem even with your patch Garth.
If you have a readonly dir with a bunch of readonly sub dirs, the sub dirs are
not copied.
I am working in this now
The only difference in patches here is i am setting the new files/dirs perm bits
to the originals
which is the way copy should work. You shouldn't change permissions bits on a copy.
--pete
| Reporter | ||
Comment 8•24 years ago
|
||
oops submitted an old patch. Here is one that does copy read-only subfolders,
but does not restore the permissions after the copy. ( I agree it really ought
to. )
Attachment #65235 -
Attachment is obsolete: true
Updated•24 years ago
|
QA Contact: sairuh → tpreston
| Assignee | ||
Comment 9•24 years ago
|
||
| Assignee | ||
Updated•24 years ago
|
Attachment #65270 -
Attachment is obsolete: true
| Assignee | ||
Comment 10•24 years ago
|
||
Well, if you are not root, you can't stat a dir that is read only.
You need execute to open it up.
So if you want' to do a copy of a dir that is dr--------
You will only copy the dir and *not* it's contents.
This is the same behavior of cp -r as well.
Garth see if this updated patch works for you.
--pete
| Assignee | ||
Comment 11•24 years ago
|
||
Attachment #65314 -
Attachment is obsolete: true
| Assignee | ||
Comment 12•24 years ago
|
||
Attachment #65440 -
Attachment is obsolete: true
| Assignee | ||
Comment 13•24 years ago
|
||
Ok, some of these fixes for copyTo i did over the summer as part of the nsIFIle
reorg
work but i never checked it in.
attacchment 65441 fixes the currently broken copyTo.
I'll see if i can get some review love for when the tree opens.
cc'ing Brendan and Doug
--pete
| Assignee | ||
Updated•24 years ago
|
Comment 14•24 years ago
|
||
blizzard, can you review this patch?
Comment 15•24 years ago
|
||
Comment on attachment 65441 [details] [diff] [review]
removing comment and tabs in nsLocalFileUnix.h
r/sr=blizzard
Attachment #65441 -
Flags: review+
| Assignee | ||
Updated•24 years ago
|
Target Milestone: mozilla0.9.8 → mozilla0.9.9
| Assignee | ||
Comment 16•24 years ago
|
||
Brendan can you sr this?
Thanks
--pete
Comment 17•24 years ago
|
||
Comment on attachment 65441 [details] [diff] [review]
removing comment and tabs in nsLocalFileUnix.h
>Index: nsLocalFileUnix.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/xpcom/io/nsLocalFileUnix.cpp,v
>retrieving revision 1.80
>diff -u -r1.80 nsLocalFileUnix.cpp
>--- nsLocalFileUnix.cpp 2002/01/12 01:21:40 1.80
>+++ nsLocalFileUnix.cpp 2002/01/17 18:02:47
>@@ -633,8 +633,11 @@
> // get the dirs old permissions
> if (NS_FAILED(rv = GetPermissions(&oldPerms)))
> return rv;
>- if (NS_FAILED(rv = newParent->Create(DIRECTORY_TYPE, oldPerms)))
>+ if (NS_FAILED(rv = newParent->Create(DIRECTORY_TYPE, S_IRWXU)))
> return rv;
>+ // set permissions back to original
>+ if (NS_FAILED(rv = newParent->SetPermissions(oldPerms)))
>+ return rv;
> } else { // dir exists lets try to use leaf
> nsXPIDLCString leafName;
> if (NS_FAILED(rv = GetLeafName(getter_Copies(leafName))))
>@@ -645,7 +648,10 @@
> return rv;
> if (dirCheck)
> return NS_ERROR_FILE_ALREADY_EXISTS; // dest exists
>- if (NS_FAILED(rv = newParent->Create(DIRECTORY_TYPE, oldPerms)))
>+ if (NS_FAILED(rv = newParent->Create(DIRECTORY_TYPE, S_IRWXU)))
>+ return rv;
>+ // set permissions back to original
>+ if (NS_FAILED(rv = newParent->SetPermissions(oldPerms)))
> return rv;
> }
>
I don't see why either of these changes is needed -- Create makes no links in
the newly created directory, so why do you need to create with 0700, then chmod
back to oldPerms?
>@@ -659,20 +665,15 @@
> rv = dirIterator->GetNext((nsISupports**)getter_AddRefs(entry));
> if (NS_FAILED(rv))
> continue;
>- if (NS_FAILED(rv = entry->IsDirectory(&dirCheck)))
>- return rv;
> if (NS_FAILED(rv = entry->IsSymlink(&isSymlink)))
> return rv;
>+ if (NS_FAILED(rv = entry->IsDirectory(&dirCheck)))
>+ return rv;
> if (dirCheck && !isSymlink) {
Old nit, sorry for not asking earlier, or fixing myself: would not isDir match
isSymlink and be a better name all around than dirCheck?
> PRUint32 myPerms;
> GetPermissions(&myPerms);
>
>- // create the new file with the same permissions
>- rv = newFile->Create(NORMAL_FILE_TYPE, myPerms);
>+ // create the new file with user rwx permissions
>+ rv = newFile->Create(NORMAL_FILE_TYPE, S_IRWXU);
Ok, *here* I see the need to create a regular file with 0700, write it, and
finally fix the perms to be what were requested.
> if (NS_FAILED(rv)) {
> NS_RELEASE(newFile);
> return rv;
>@@ -772,16 +772,33 @@
> PRInt32 modeFlags = myPerms;
> PRFileDesc *newFD;
>
>- rv = newFile->OpenNSPRFileDesc(openFlags, modeFlags, &newFD);
>+ rv = newFile->OpenNSPRFileDesc(openFlags, S_IRWXU, &newFD);
> if (NS_FAILED(rv)) {
> NS_RELEASE(newFile);
> return rv;
> }
>
>+ // set the permissions of newFile to original files
>+ if (NS_FAILED(rv = newFile->SetPermissions(myPerms)))
>+ return rv;
You sure you want to do this before the read/write loop? I don't know whether
nsLocalFileUnix.cpp is supposed to work on NFS "local files", but as NFS is
stateless, I suspect you might have trouble writing after revoking write
permission.
>+ PRBool specialFile;
>+ if (NS_FAILED(rv = IsSpecial(&specialFile)))
>+ return rv;
>+ if (specialFile) {
>+#ifdef DEBUG
>+ printf("1: Operation not supported: %s\n", mPath.get());
>+#endif
1. Use PR_LOG, not printf, or don't print anything here (is this really
necessary for others? Could it be DEBUG_petejc or even removed once you've
tested?).
2. Use a better message: what does the "1: " mean above?
>+ if (stat(mPath.get(), &mCachedStat) == -1) {
>+ // try lstat it may be a symlink
>+ if (lstat(mPath.get(), &mCachedStat) == -1) {
>+#ifdef DEBUG
>+ printf("stat failed %s\n", mPath.get());
>+#endif
Same 2 comments here.
>+ return NS_ERROR_FAILURE;
And should this not be return NSRESULT_FOR_ERRNO()?
>+ }
>+ }
>+ mHaveCachedStat = PR_TRUE;
>+ return NS_OK;
> }
>-
> };
>
> #endif /* _nsLocalFileUNIX_H_ */
/be
Attachment #65441 -
Flags: needs-work+
| Assignee | ||
Comment 18•24 years ago
|
||
> I don't see why either of these changes is needed -- Create makes no links in
> the newly created directory, so why do you need to create with 0700, then chmod
> back to oldPerms?
Yes, i was being paranoid there. Removed
> Old nit, sorry for not asking earlier, or fixing myself: would not isDir match
> isSymlink and be a better name all around than dirCheck?
dirCheck is a generic name for a PRBool that is being used in various contexts.
IsDirectory, Equals, Exists etc. I did this to be efficient and i don't see any
need to change it.
> You sure you want to do this before the read/write loop?
I am very sure i want to do this before the read/write loop. This prevents
copyTo from breaking on socket files like '.X11-unix/X0'.
> I don't know whether
> nsLocalFileUnix.cpp is supposed to work on NFS "local files", but as NFS is
> stateless, I suspect you might have trouble writing after revoking write
> permission.
Nope, NFS mounted file writes work quite wonderfully.
> 1. Use PR_LOG, not printf, or don't print anything here (is this really
> necessary for others? Could it be DEBUG_petejc or even removed once you've
> tested?).
No, i am being consistant w/ code higher above that encounters uncopyable files.
> 2. Use a better message: what does the "1: " mean above?
Sorry, the 1: was a typo. I removed it.
The message is keeping with the convention of cp || cp -r
So if an uncopyable file is encountered, we print out the same message as good
o'l cp in DEBUG builds. This is to keep w/ common convention.
I removed the stat printf, that was for my own debugging and am returning
NSRESULT_FOR_ERRNO() instead of NS_ERROR_FAILURE.
Revised patch forthcoming.
--pete
| Assignee | ||
Comment 19•24 years ago
|
||
Attachment #65292 -
Attachment is obsolete: true
Attachment #65441 -
Attachment is obsolete: true
Comment 20•24 years ago
|
||
Comment on attachment 66638 [details] [diff] [review]
Fixes for Brendans review
>@@ -633,7 +633,10 @@
> // get the dirs old permissions
> if (NS_FAILED(rv = GetPermissions(&oldPerms)))
> return rv;
>- if (NS_FAILED(rv = newParent->Create(DIRECTORY_TYPE, oldPerms)))
>+ if (NS_FAILED(rv = newParent->Create(DIRECTORY_TYPE, S_IRWXU)))
>+ return rv;
>+ // set permissions back to original
>+ if (NS_FAILED(rv = newParent->SetPermissions(oldPerms)))
> return rv;
You missed this one -- there were two cases of a mkdir;chmod where just mkdir
with the ultimate perms will do.
>+ if (NS_FAILED(rv = entry->IsDirectory(&dirCheck)))
>+ return rv;
I hear you on dirCheck, I do that too -- I just wanted to reassure you that if
you use separate PRBool locals with precise names, any modern optimizing
compiler will unify them if their lifetimes are disjoint. So suit yourself,
but don't fear inefficiency -- the only downside of multiple, disjoint,
precisely named vars is the code clutter of declaring 'em.
dougt: are we still on an anti-printf embedding/embedability kick?
pete, thanks -- sr=brendan@mozilla.org with the above mkdir;chmod => mkdir fix.
/be
Attachment #66638 -
Flags: superreview+
Attachment #66638 -
Flags: review+
| Assignee | ||
Comment 21•24 years ago
|
||
Attachment #66638 -
Attachment is obsolete: true
| Assignee | ||
Comment 22•24 years ago
|
||
Checked in. Thanks everyone.
--pete
Status: ASSIGNED → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
Comment 23•24 years ago
|
||
FYI, I'm now getting this (linux, glibc2.1):
In file included from ../../dist/include/xpcom/nsLocalFile.h:46,
from nsComponentManager.cpp:56:
../../dist/include/xpcom/nsLocalFileUnix.h: In method `nsresult
nsLocalFile::FillStatCache()':
../../dist/include/xpcom/nsLocalFileUnix.h:102: `lstat' undeclared (first use
this function)
../../dist/include/xpcom/nsLocalFileUnix.h:102: (Each undeclared identifier is
reported only once
../../dist/include/xpcom/nsLocalFileUnix.h:102: for each function it appears in.)
| Assignee | ||
Comment 24•24 years ago
|
||
NAME
stat, fstat, lstat - get file status
SYNOPSIS
#include <sys/stat.h>
#include <unistd.h>
I just added <unistd.h> which was missing.
Seeing now if this fixes the problem.
--pete
| Assignee | ||
Comment 25•24 years ago
|
||
Hrmm, this is weird i can compile a sample using lstat on linux glib 1.2.6 no
problems.
--pete
Comment 26•24 years ago
|
||
glibc 2.2.4 only defines lstat if:
__USE_BSD , __USE_XOPEN_EXTENDED or
__USE_LARGEFILE64 are defined
| Assignee | ||
Comment 27•24 years ago
|
||
Well, lstat *has* been used for some time now in nsLocalFileUnix.cpp
implementation file.
seawood said that you need -D_BSD_SOURCE defeined for it to work.
But that is already defined. I will add _USE_BSD if we still fail on the next spin.
--pete
Comment 28•24 years ago
|
||
moving the lstat call out of the header file should have fixed the bustage
Comment 29•24 years ago
|
||
Builds good on my system. Ta.
Updated•10 years ago
|
Product: Core → Core Graveyard
You need to log in
before you can comment on or make changes to this bug.
Description
•