This is a bug report for perl from Paul....@nsc.com,
generated with the help of perlbug 1.34 running under perl v5.8.0.
-----------------------------------------------------------------
[Please enter your report here]
The chown perl built in function has no way of changing the
ownership of a symlink. It always follows the link and changes
the ownership of the destination. Perhaps it needs an option
to not follow symbolic links.
[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
category=core
severity=low
---
Site configuration information for perl v5.8.0:
Configured by tooladm at Mon Mar 3 09:36:12 MST 2003.
Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration:
Platform:
osname=linux, osvers=2.4.7-10, archname=i686-linux
uname='linux si14 2.4.7-10 #1 thu sep 6 17:27:27 edt 2001 i686 unknown '
config_args=''
hint=previous, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef
usemultiplicity=undef
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='gcc', ccflags ='-fno-strict-aliasing -I/tools/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O3',
cppflags='-fno-strict-aliasing -I/tools/include -fno-strict-aliasing
-I/tools/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-fno-strict-aliasing -I/tools/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -fno-strict-aliasing -I/tools/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fno-strict-aliasing
-I/tools/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-fno-strict-aliasing -I/tools/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64'
ccversion='', gccversion='3.2.2', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
alignbytes=4, prototype=define
Linker and Libraries:
ld='gcc', ldflags ='-L/tools/lib'
libpth=/lib /usr/lib /tools/lib
libs=-lnsl -ldb -ldl -lm -lc -lcrypt -lutil
perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil
libc=/lib/libc-2.2.4.so, so=so, useshrplib=false, libperl=libperl.a
gnulibc_version='2.2.4'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
cccdlflags='-fpic', lddlflags='-shared -L/tools/lib'
Locally applied patches:
---
@INC for perl v5.8.0:
/tools/install/perl/5.8.0/lib/distrib/i686-linux
/tools/install/perl/5.8.0/lib/distrib
/tools/install/perl/5.8.0/lib/add-ons/lib/i686-linux
/tools/install/perl/5.8.0/lib/add-ons/lib
/tools/install/perl/5.8.0/lib/add-ons/lib
/tools/install/perl/5.8.0/lib/site_perl/lib/i686-linux
/tools/install/perl/5.8.0/lib/site_perl/lib
/tools/install/perl/5.8.0/lib/site_perl/lib
.
---
Environment for perl v5.8.0:
HOME=/home/pkramer
LANG=C
LANGUAGE (unset)
LD_LIBRARY_PATH=/lib:/usr/lib:/usr/kerberos/lib:/usr/X11R6/lib:/usr/lib/qt-2.3.1/lib:/usr/lib/sane:/usr/lib/wine:/tools/lib
LOGDIR (unset)
PATH=/tools/install/perl/5.8.0/bin:/tools/install/perl/5.8.0/lib/add-ons/bin:/tools/install/fileutils/release/bin:/tools/install/xemacs/21.4.12/bin:/home/pkramer/bin/linux:/tools/overloadbin:/tools/bin:/bin:/usr/bin:/usr/X11R6/bin:./:/usr/sbin:/sbin:/usr/local/bin:/cad/bin
PERL_BADLANG (unset)
SHELL=/usr/local/bin/tcsh
Hmm, now there's an interesting topic. Whether the chown() system call
applies to the link or its referent is highly OS-dependent, and whether
there's a separate system call to do the link is similarly dependent, eg
from the linux chown(2) manpage:
NOTES
In versions of Linux prior to 2.1.81 (and distinct from
2.1.46), chown did not follow symbolic links. Since Linux
2.1.81, chown does follow symbolic links, and there is a
new system call lchown that does not follow symbolic
links. Since Linux 2.1.86, this new call (that has the
same semantics as the old chown) has got the same syscall
number, and chown got the newly introduced number.
Perll's configure currently probes for lchown(2), but doesn't do anything
with it, apart from a comment in doio.c:
/*
XXX Should we make lchown() directly available from perl?
For now, we'll let Configure test for HAS_LCHOWN, but do
nothing in the core.
--AD 5/1998
*/
--
"I do not resent critisism, even when, for the sake of emphasis,
it parts for the time with reality".
-- Winston Churchill, House of Commons, 22nd Jan 1941.
woohoo, sounds like a new built-in to me.
(OTOH on some platforms chown() will do what lchown() does and some
other, and lchown() will croak as unimplemented. That's against the
rule of perl of being mostly portable.)
Is lchown POSIX ? (is chown POSIX by the way) ? because we could
stick it in the POSIX module, or, if not appropriate, in a simple
seperate module.
("yes")x2
It occurred to me that in some cases we could provide fallback behaviour
to achieve the same effect by removing the link and creating it with the
right ownership, but I think it would be a bad idea to do so - firstly
because it could be difficult to determine that this really is one of
the cases we can handle, and secondly because of the race conditions
(such as temporary non-existence of the link) that it would introduce.
:Is lchown POSIX ? (is chown POSIX by the way) ? because we could
:stick it in the POSIX module [...]
That sounds like the best approach to me.
Hugo
Here's a patch.
While we're at it. The POSIX chown/lchown call is supposed to return 0
on success, -1 on error. That's what does my POSIX::lchown(). But that's
not what does POSIX::chown() which only calls CORE::chown() (that
returns, of course, 0 on failure...) This is, of course, fixable, but I
don't know whether it's worth the backward compatibilty breakage.
(Anyway the return value of POSIX::chown() and POSIX::lchown() need to
be consistent.)
Index: ext/POSIX/POSIX.xs
===================================================================
--- ext/POSIX/POSIX.xs (revision 3306)
+++ ext/POSIX/POSIX.xs (working copy)
@@ -1875,3 +1875,18 @@
XSprePUSH; PUSHTARG;
}
+int
+lchown(uid, gid, path)
+ Uid_t uid
+ Gid_t gid
+ char * path
+ CODE:
+#ifdef HAS_LCHOWN
+ /* yes, the order of arguments is different,
+ * but consistent with CORE::chown() */
+ RETVAL = lchown(path, uid, gid);
+#else
+ RETVAL = not_here("lchown");
+#endif
+ OUTPUT:
+ RETVAL
Index: ext/POSIX/POSIX.pm
===================================================================
--- ext/POSIX/POSIX.pm (revision 3306)
+++ ext/POSIX/POSIX.pm (working copy)
@@ -921,6 +921,7 @@
gmtime
isatty
kill
+ lchown
link
localtime
log
> h...@crypt.org wrote:
> > :Is lchown POSIX ? (is chown POSIX by the way) ? because we could
> > :stick it in the POSIX module [...]
> >
> > That sounds like the best approach to me.
>
> Here's a patch.
>
> While we're at it. The POSIX chown/lchown call is supposed to return 0
> on success, -1 on error. That's what does my POSIX::lchown(). But that's
> not what does POSIX::chown() which only calls CORE::chown() (that
> returns, of course, 0 on failure...) This is, of course, fixable, but I
> don't know whether it's worth the backward compatibilty breakage.
> (Anyway the return value of POSIX::chown() and POSIX::lchown() need to
> be consistent.)
Isn't this what T_SYSRET typemap entry is meant to be for?
--
Tim Jenness
JAC software
http://www.jach.hawaii.edu/~timj
Of course it is!
So with SysRet lchown() would return 0 (fail) or "0 but true".
> +#ifdef HAS_LCHOWN
Where does that come from?
Well, Configure probed it already. (and it probes fchown too)
This solution applied as #22513.