Skip to contentSkip to conversation

chmod.2, lchmod.3: Document lchmod()

PATCH In review Bruno Haible 3 participants 6 messages Jan 10, 2021 – Jan 18, 2021 Man-pages: manual pages for Linux -- Sections 2, 3, 4, 5, and 7

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 chmod.2, lchmod.3: Document lchmod()

Hi,

lchmod (= the effect of fchmod with flag AT_SYMLINK_NOFOLLOW) is implemented since glibc 2.32, see
https://sourceware.org/bugzilla/show_bug.cgi?id=14578
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=752dd17443e55a4535cb9e6baa4e550ede383540

Here is a patch to update the man pages accordingly.

From 22cbd89a89bc26a518537739d677a5736727738f Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 10 Jan 2021 05:20:30 +0100
Subject: [PATCH] chmod.2, lchmod.3: Document lchmod().

---
 man2/chmod.2  | 25 +++++++++++++++++++++----
 man3/lchmod.3 |  1 +
 2 files changed, 22 insertions(+), 4 deletions(-)
 create mode 100644 man3/lchmod.3
man2/chmod.2 +21 -4
index a54aec7..897dd87 100644
@@ -29,15 +29,16 @@
 .\"   <[email protected]>: NFS details
 .\" Modified 2004-06-23 by Michael Kerrisk <[email protected]>
 .\"
-.TH CHMOD 2 2017-09-15 "Linux" "Linux Programmer's Manual"
+.TH CHMOD 2 2021-01-10 "Linux" "Linux Programmer's Manual"
 .SH NAME
-chmod, fchmod, fchmodat \- change permissions of a file
+chmod, fchmod, lchmod, fchmodat \- change permissions of a file
 .SH SYNOPSIS
 .nf
 .B #include <sys/stat.h>
 .PP
 .BI "int chmod(const char *" pathname ", mode_t " mode );
 .BI "int fchmod(int " fd ", mode_t " mode );
+.BI "int lchmod(const char *" pathname ", mode_t " mode );
 .PP
 .BR "#include <fcntl.h>" "           /* Definition of AT_* constants */"
 .B #include <sys/stat.h>
@@ -68,6 +69,12 @@ Feature Test Macro Requirements for glibc (see
 .\"        || (_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED)
 .fi
 .PP
+.BR lchmod ():
+.nf
+    Since glibc 2.32:
+        _DEFAULT_SOURCE
+.fi
+.PP
 .BR fchmodat ():
 .nf
     Since glibc 2.10:
@@ -93,6 +100,11 @@ which is dereferenced if it is a symbolic link.
 .BR fchmod ()
 changes the mode of the file referred to by the open file descriptor
 .IR fd .
+.IP *
+.BR lchmod ()
+is like
+.BR chmod (),
+but does not dereference symbolic links.
 .PP
 The new file mode is specified in
 .IR mode ,
@@ -220,8 +232,13 @@ can either be 0, or include the following flag:
 If
 .I pathname
 is a symbolic link, do not dereference it:
-instead operate on the link itself.
-This flag is not currently implemented.
+instead operate on the link itself, like
+.BR lchmod ().
+(By default,
+.BR fchmodat ()
+dereferences symbolic links, like
+.BR chmod ().)
+This flag is implemented since glibc 2.32.
 .PP
 See
 .BR openat (2)
man3/lchmod.3 new file +1 -0
new file mode 100644
index 0000000..92647d2
@@ -0,0 +1 @@
+.so man2/chmod.2
Signature · 1 line
2.7.4
#1 lore raw

Hi,

Quoted 8 lines · Bruno Haible

Hi,

lchmod (= the effect of fchmod with flag AT_SYMLINK_NOFOLLOW) is implemented since glibc 2.32, see
https://sourceware.org/bugzilla/show_bug.cgi?id=14578
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=752dd17443e55a4535cb9e6baa4e550ede383540

Here is a patch to update the man pages accordingly.

Please note the important limitation of that implementation:
it doesn't work when /proc is not mounted, see
https://sourceware.org/bugzilla/show_bug.cgi?id=26401

Signature · 1 line
ldv
#2 lore raw
Quoted 5 lines · Dmitry V. Levin
Quoted 1 line

Here is a patch to update the man pages accordingly.

Please note the important limitation of that implementation:
it doesn't work when /proc is not mounted, see
https://sourceware.org/bugzilla/show_bug.cgi?id=26401

Thanks for the pointer. Revised patch attached.

From 56ce64325fa9a9184b820eac908ecc5d53a5154b Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 10 Jan 2021 05:20:30 +0100
Subject: [PATCH] chmod.2, lchmod.3: Document lchmod().

---
 man2/chmod.2  | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 man3/lchmod.3 |  1 +
 2 files changed, 65 insertions(+), 6 deletions(-)
 create mode 100644 man3/lchmod.3
man2/chmod.2 +64 -6
index a54aec7..f1709ef 100644
@@ -29,15 +29,16 @@
 .\"   <[email protected]>: NFS details
 .\" Modified 2004-06-23 by Michael Kerrisk <[email protected]>
 .\"
-.TH CHMOD 2 2017-09-15 "Linux" "Linux Programmer's Manual"
+.TH CHMOD 2 2021-01-10 "Linux" "Linux Programmer's Manual"
 .SH NAME
-chmod, fchmod, fchmodat \- change permissions of a file
+chmod, fchmod, lchmod, fchmodat \- change permissions of a file
 .SH SYNOPSIS
 .nf
 .B #include <sys/stat.h>
 .PP
 .BI "int chmod(const char *" pathname ", mode_t " mode );
 .BI "int fchmod(int " fd ", mode_t " mode );
+.BI "int lchmod(const char *" pathname ", mode_t " mode );
 .PP
 .BR "#include <fcntl.h>" "           /* Definition of AT_* constants */"
 .B #include <sys/stat.h>
@@ -68,6 +69,12 @@ Feature Test Macro Requirements for glibc (see
 .\"        || (_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED)
 .fi
 .PP
+.BR lchmod ():
+.nf
+    Since glibc 2.32:
+        _DEFAULT_SOURCE
+.fi
+.PP
 .BR fchmodat ():
 .nf
     Since glibc 2.10:
@@ -80,10 +87,12 @@ The
 .BR chmod ()
 and
 .BR fchmod ()
-system calls change a files mode bits.
+system calls and the
+.BR lchmod ()
+function change a file's mode bits.
 (The file mode consists of the file permission bits plus the set-user-ID,
 set-group-ID, and sticky bits.)
-These system calls differ only in how the file is specified:
+These functions differ only in how the file is specified:
 .IP * 2
 .BR chmod ()
 changes the mode of the file specified whose pathname is given in
@@ -93,6 +102,11 @@ which is dereferenced if it is a symbolic link.
 .BR fchmod ()
 changes the mode of the file referred to by the open file descriptor
 .IR fd .
+.IP *
+.BR lchmod ()
+is like
+.BR chmod (),
+but does not dereference symbolic links.
 .PP
 The new file mode is specified in
 .IR mode ,
@@ -220,8 +234,13 @@ can either be 0, or include the following flag:
 If
 .I pathname
 is a symbolic link, do not dereference it:
-instead operate on the link itself.
-This flag is not currently implemented.
+instead operate on the link itself, like
+.BR lchmod ().
+(By default,
+.BR fchmodat ()
+dereferences symbolic links, like
+.BR chmod ().)
+This flag is implemented since glibc 2.32.
 .PP
 See
 .BR openat (2)
@@ -304,6 +323,17 @@ See above.
 The same errors that occur for
 .BR chmod ()
 can also occur for
+.BR lchmod ().
+The following additional errors can occur for
+.BR lchmod ():
+.TP
+.B EOPNOTSUPP
+.B /proc
+is not mounted.
+.PP
+The same errors that occur for
+.BR chmod ()
+can also occur for
 .BR fchmodat ().
 The following additional errors can occur for
 .BR fchmodat ():
@@ -323,14 +353,31 @@ is relative and
 is a file descriptor referring to a file other than a directory.
 .TP
 .B ENOTSUP
+(Before glibc 2.32.)
 .I flags
 specified
 .BR AT_SYMLINK_NOFOLLOW ,
 which is not supported.
+.TP
+.B EOPNOTSUPP
+(Since glibc 2.32.)
+.I flags
+specified
+.BR AT_SYMLINK_NOFOLLOW ,
+and
+.B /proc
+is not mounted.
 .SH VERSIONS
 .BR fchmodat ()
 was added to Linux in kernel 2.6.16;
 library support was added to glibc in version 2.4.
+.PP
+.BR lchmod ()
+and the handling of
+.B AT_SYMLINK_NOFOLLOW
+in
+.BR fchmodat ()
+were added in glibc version 2.32.
 .SH CONFORMING TO
 .BR chmod (),
 .BR fchmod ():
@@ -362,6 +409,17 @@ glibc constructs a pathname based on the symbolic link in
 that corresponds to the
 .IR dirfd
 argument.
+.SH BUGS
+.BR lchmod ()
+and
+.BR fchmodat ()
+with
+.B AT_SYMLINK_NOFOLLOW
+flag fail with error
+.B EOPNOTSUPP
+when the
+.B /proc
+file system is not mounted.
 .SH SEE ALSO
 .BR chmod (1),
 .BR chown (2),
man3/lchmod.3 new file +1 -0
new file mode 100644
index 0000000..92647d2
@@ -0,0 +1 @@
+.so man2/chmod.2
Signature · 1 line
2.7.4
#3 lore raw
Quoted 8 lines · Bruno Haible
Quoted 5 lines · Dmitry V. Levin
Quoted 1 line

Here is a patch to update the man pages accordingly.

Please note the important limitation of that implementation:
it doesn't work when /proc is not mounted, see
https://sourceware.org/bugzilla/show_bug.cgi?id=26401

Thanks for the pointer. Revised patch attached.

LGTM, thanks.

Signature · 1 line
ldv
#4 lore raw
In reply to Bruno Haible
Quoted 8 lines · Bruno Haible
Quoted 5 lines · Dmitry V. Levin
Quoted 1 line

Here is a patch to update the man pages accordingly.

Please note the important limitation of that implementation:
it doesn't work when /proc is not mounted, see
https://sourceware.org/bugzilla/show_bug.cgi?id=26401

Thanks for the pointer. Revised patch attached.

Hi Bruno,

Thank you for the patch.

But, I have a question: is lchown() actually usable? That is, are there any kinds of links whose mode can be changed? I can't seem to use it with normal symlinks, or for that matter, magic links:

[[

$ cat t_lchmod.c 
/*#* t_lchmod.c

Copyright Michael Kerrisk, Jan 2021
*/
#define _DEFAULT_SOURCE
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

typedef enum { FALSE, TRUE } Boolean;
int
main(int argc, char *argv[])

{
    if (argc < 2) {
	fprintf(stderr, "Usage: %s <file> <mode>\n", argv[0]);
	exit(EXIT_FAILURE);
    }

    int mode = strtoul(argv[2], NULL, 0);
    if (lchmod(argv[1], mode) == -1) {
        perror("lchmod");
	exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
}
$ touch a 
$ ln -s a b
$ ./t_lchmod b 700
lchmod: Operation not supported
$ ./t_lchmod /proc/self/fd/0 700
lchmod: Operation not supported
]]

Thanks,

Michael

=====

Quoted 1 line

From 56ce64325fa9a9184b820eac908ecc5d53a5154b Mon Sep 17 00:00:00 2001

From: Bruno Haible <[email protected]>
Date: Sun, 10 Jan 2021 05:20:30 +0100
Subject: [PATCH] chmod.2, lchmod.3: Document lchmod().

---
 man2/chmod.2  | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 man3/lchmod.3 |  1 +
 2 files changed, 65 insertions(+), 6 deletions(-)
 create mode 100644 man3/lchmod.3
man2/chmod.2 +64 -6
index a54aec7..f1709ef 100644
@@ -29,15 +29,16 @@
 .\"   <[email protected]>: NFS details
 .\" Modified 2004-06-23 by Michael Kerrisk <[email protected]>
 .\"
-.TH CHMOD 2 2017-09-15 "Linux" "Linux Programmer's Manual"
+.TH CHMOD 2 2021-01-10 "Linux" "Linux Programmer's Manual"
 .SH NAME
-chmod, fchmod, fchmodat \- change permissions of a file
+chmod, fchmod, lchmod, fchmodat \- change permissions of a file
 .SH SYNOPSIS
 .nf
 .B #include <sys/stat.h>
 .PP
 .BI "int chmod(const char *" pathname ", mode_t " mode );
 .BI "int fchmod(int " fd ", mode_t " mode );
+.BI "int lchmod(const char *" pathname ", mode_t " mode );
 .PP
 .BR "#include <fcntl.h>" "           /* Definition of AT_* constants */"
 .B #include <sys/stat.h>
@@ -68,6 +69,12 @@ Feature Test Macro Requirements for glibc (see
 .\"        || (_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED)
 .fi
 .PP
+.BR lchmod ():
+.nf
+    Since glibc 2.32:
+        _DEFAULT_SOURCE
+.fi
+.PP
 .BR fchmodat ():
 .nf
     Since glibc 2.10:
@@ -80,10 +87,12 @@ The
 .BR chmod ()
 and
 .BR fchmod ()
-system calls change a files mode bits.
+system calls and the
+.BR lchmod ()
+function change a file's mode bits.
 (The file mode consists of the file permission bits plus the set-user-ID,
 set-group-ID, and sticky bits.)
-These system calls differ only in how the file is specified:
+These functions differ only in how the file is specified:
 .IP * 2
 .BR chmod ()
 changes the mode of the file specified whose pathname is given in
@@ -93,6 +102,11 @@ which is dereferenced if it is a symbolic link.
 .BR fchmod ()
 changes the mode of the file referred to by the open file descriptor
 .IR fd .
+.IP *
+.BR lchmod ()
+is like
+.BR chmod (),
+but does not dereference symbolic links.
 .PP
 The new file mode is specified in
 .IR mode ,
@@ -220,8 +234,13 @@ can either be 0, or include the following flag:
 If
 .I pathname
 is a symbolic link, do not dereference it:
-instead operate on the link itself.
-This flag is not currently implemented.
+instead operate on the link itself, like
+.BR lchmod ().
+(By default,
+.BR fchmodat ()
+dereferences symbolic links, like
+.BR chmod ().)
+This flag is implemented since glibc 2.32.
 .PP
 See
 .BR openat (2)
@@ -304,6 +323,17 @@ See above.
 The same errors that occur for
 .BR chmod ()
 can also occur for
+.BR lchmod ().
+The following additional errors can occur for
+.BR lchmod ():
+.TP
+.B EOPNOTSUPP
+.B /proc
+is not mounted.
+.PP
+The same errors that occur for
+.BR chmod ()
+can also occur for
 .BR fchmodat ().
 The following additional errors can occur for
 .BR fchmodat ():
@@ -323,14 +353,31 @@ is relative and
 is a file descriptor referring to a file other than a directory.
 .TP
 .B ENOTSUP
+(Before glibc 2.32.)
 .I flags
 specified
 .BR AT_SYMLINK_NOFOLLOW ,
 which is not supported.
+.TP
+.B EOPNOTSUPP
+(Since glibc 2.32.)
+.I flags
+specified
+.BR AT_SYMLINK_NOFOLLOW ,
+and
+.B /proc
+is not mounted.
 .SH VERSIONS
 .BR fchmodat ()
 was added to Linux in kernel 2.6.16;
 library support was added to glibc in version 2.4.
+.PP
+.BR lchmod ()
+and the handling of
+.B AT_SYMLINK_NOFOLLOW
+in
+.BR fchmodat ()
+were added in glibc version 2.32.
 .SH CONFORMING TO
 .BR chmod (),
 .BR fchmod ():
@@ -362,6 +409,17 @@ glibc constructs a pathname based on the symbolic link in
 that corresponds to the
 .IR dirfd
 argument.
+.SH BUGS
+.BR lchmod ()
+and
+.BR fchmodat ()
+with
+.B AT_SYMLINK_NOFOLLOW
+flag fail with error
+.B EOPNOTSUPP
+when the
+.B /proc
+file system is not mounted.
 .SH SEE ALSO
 .BR chmod (1),
 .BR chown (2),
man3/lchmod.3 new file +1 -0
new file mode 100644
index 0000000..92647d2
@@ -0,0 +1 @@
+.so man2/chmod.2
Signature · 7 lines
2.7.4

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
yo
#5 lore raw

Hi Bruno,

Ping!

Thanks,

Michael

Quoted 232 lines · Michael Kerrisk (man-pages)
Quoted 8 lines · Bruno Haible
Quoted 5 lines · Dmitry V. Levin
Quoted 1 line

Here is a patch to update the man pages accordingly.

Please note the important limitation of that implementation:
it doesn't work when /proc is not mounted, see
https://sourceware.org/bugzilla/show_bug.cgi?id=26401

Thanks for the pointer. Revised patch attached.

Hi Bruno,

Thank you for the patch.

But, I have a question: is lchown() actually usable? That is, are there any kinds of links whose mode can be changed? I can't seem to use it with normal symlinks, or for that matter, magic links:

[[

$ cat t_lchmod.c 
/*#* t_lchmod.c

Copyright Michael Kerrisk, Jan 2021
*/
#define _DEFAULT_SOURCE
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

typedef enum { FALSE, TRUE } Boolean;
int
main(int argc, char *argv[])

{
    if (argc < 2) {
	fprintf(stderr, "Usage: %s <file> <mode>\n", argv[0]);
	exit(EXIT_FAILURE);
    }

    int mode = strtoul(argv[2], NULL, 0);
    if (lchmod(argv[1], mode) == -1) {
        perror("lchmod");
	exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
}
$ touch a 
$ ln -s a b
$ ./t_lchmod b 700
lchmod: Operation not supported
$ ./t_lchmod /proc/self/fd/0 700
lchmod: Operation not supported
]]

Thanks,

Michael

=====

Quoted 1 line

From 56ce64325fa9a9184b820eac908ecc5d53a5154b Mon Sep 17 00:00:00 2001

From: Bruno Haible <[email protected]>
Date: Sun, 10 Jan 2021 05:20:30 +0100
Subject: [PATCH] chmod.2, lchmod.3: Document lchmod().

---
 man2/chmod.2  | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 man3/lchmod.3 |  1 +
 2 files changed, 65 insertions(+), 6 deletions(-)
 create mode 100644 man3/lchmod.3
man2/chmod.2 +64 -6
index a54aec7..f1709ef 100644
@@ -29,15 +29,16 @@
 .\"   <[email protected]>: NFS details
 .\" Modified 2004-06-23 by Michael Kerrisk <[email protected]>
 .\"
-.TH CHMOD 2 2017-09-15 "Linux" "Linux Programmer's Manual"
+.TH CHMOD 2 2021-01-10 "Linux" "Linux Programmer's Manual"
 .SH NAME
-chmod, fchmod, fchmodat \- change permissions of a file
+chmod, fchmod, lchmod, fchmodat \- change permissions of a file
 .SH SYNOPSIS
 .nf
 .B #include <sys/stat.h>
 .PP
 .BI "int chmod(const char *" pathname ", mode_t " mode );
 .BI "int fchmod(int " fd ", mode_t " mode );
+.BI "int lchmod(const char *" pathname ", mode_t " mode );
 .PP
 .BR "#include <fcntl.h>" "           /* Definition of AT_* constants */"
 .B #include <sys/stat.h>
@@ -68,6 +69,12 @@ Feature Test Macro Requirements for glibc (see
 .\"        || (_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED)
 .fi
 .PP
+.BR lchmod ():
+.nf
+    Since glibc 2.32:
+        _DEFAULT_SOURCE
+.fi
+.PP
 .BR fchmodat ():
 .nf
     Since glibc 2.10:
@@ -80,10 +87,12 @@ The
 .BR chmod ()
 and
 .BR fchmod ()
-system calls change a files mode bits.
+system calls and the
+.BR lchmod ()
+function change a file's mode bits.
 (The file mode consists of the file permission bits plus the set-user-ID,
 set-group-ID, and sticky bits.)
-These system calls differ only in how the file is specified:
+These functions differ only in how the file is specified:
 .IP * 2
 .BR chmod ()
 changes the mode of the file specified whose pathname is given in
@@ -93,6 +102,11 @@ which is dereferenced if it is a symbolic link.
 .BR fchmod ()
 changes the mode of the file referred to by the open file descriptor
 .IR fd .
+.IP *
+.BR lchmod ()
+is like
+.BR chmod (),
+but does not dereference symbolic links.
 .PP
 The new file mode is specified in
 .IR mode ,
@@ -220,8 +234,13 @@ can either be 0, or include the following flag:
 If
 .I pathname
 is a symbolic link, do not dereference it:
-instead operate on the link itself.
-This flag is not currently implemented.
+instead operate on the link itself, like
+.BR lchmod ().
+(By default,
+.BR fchmodat ()
+dereferences symbolic links, like
+.BR chmod ().)
+This flag is implemented since glibc 2.32.
 .PP
 See
 .BR openat (2)
@@ -304,6 +323,17 @@ See above.
 The same errors that occur for
 .BR chmod ()
 can also occur for
+.BR lchmod ().
+The following additional errors can occur for
+.BR lchmod ():
+.TP
+.B EOPNOTSUPP
+.B /proc
+is not mounted.
+.PP
+The same errors that occur for
+.BR chmod ()
+can also occur for
 .BR fchmodat ().
 The following additional errors can occur for
 .BR fchmodat ():
@@ -323,14 +353,31 @@ is relative and
 is a file descriptor referring to a file other than a directory.
 .TP
 .B ENOTSUP
+(Before glibc 2.32.)
 .I flags
 specified
 .BR AT_SYMLINK_NOFOLLOW ,
 which is not supported.
+.TP
+.B EOPNOTSUPP
+(Since glibc 2.32.)
+.I flags
+specified
+.BR AT_SYMLINK_NOFOLLOW ,
+and
+.B /proc
+is not mounted.
 .SH VERSIONS
 .BR fchmodat ()
 was added to Linux in kernel 2.6.16;
 library support was added to glibc in version 2.4.
+.PP
+.BR lchmod ()
+and the handling of
+.B AT_SYMLINK_NOFOLLOW
+in
+.BR fchmodat ()
+were added in glibc version 2.32.
 .SH CONFORMING TO
 .BR chmod (),
 .BR fchmod ():
@@ -362,6 +409,17 @@ glibc constructs a pathname based on the symbolic link in
 that corresponds to the
 .IR dirfd
 argument.
+.SH BUGS
+.BR lchmod ()
+and
+.BR fchmodat ()
+with
+.B AT_SYMLINK_NOFOLLOW
+flag fail with error
+.B EOPNOTSUPP
+when the
+.B /proc
+file system is not mounted.
 .SH SEE ALSO
 .BR chmod (1),
 .BR chown (2),
man3/lchmod.3 new file +1 -0
new file mode 100644
index 0000000..92647d2
@@ -0,0 +1 @@
+.so man2/chmod.2
Signature · 3 lines
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/