From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) by sourceware.org (Postfix) with ESMTP id ACE813851C07 for ; Tue, 12 May 2020 03:05:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org ACE813851C07 Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-353-Hi0IL8VqOPKzsXN9SFlcSg-1; Mon, 11 May 2020 23:05:20 -0400 X-MC-Unique: Hi0IL8VqOPKzsXN9SFlcSg-1 Received: by mail-qv1-f72.google.com with SMTP id l17so6105849qvm.12 for ; Mon, 11 May 2020 20:05:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:organization :message-id:date:user-agent:mime-version:in-reply-to :content-language:content-transfer-encoding; bh=9IkNrCQM6RCJI/441rkJeFTAwMLpXCRHhRVyOaoppLc=; b=uXO1Pp3XJOrPSFd0WwRm2VpbKdM2Jry9zyqOothMqNNaZ+DFqbwrb+P5EihqwmY1PL vRgWDkqMjLaR0zxq+JY2M8qZ6mdYtUIRf0ECbDvJ5YOJk7hLmeYJfAoEu2LYuyhYXKEn bPYd3O/vsboGxZEbqNG6b2Rn0fLdZYEF32JDzDeLPzD4KJaKWgByfkWwX3NhWAhcwZpX Qkeol+SlrqX1YeR/Q+uCZUuxTFPQhNdtPS8dWOXOT6KnYIuS1mNgUzf+zD0N6QHVBjBx QmvQ73C6mEXhhHKxY0lMUuSPvkkr+QLbqTUY6PV2oRyqar2jkmEwfSuCi3Ynk+QCxr/G NVAg== X-Gm-Message-State: AGi0PubXkl13YAtBi3aMxvo2KH3gOrKpdzkGipHOENlaN/x50hi/Oddv 9BHugZXpWT3cdyVERSrpap19uAYdWapvZK0qdt0z6I2F+EL6WeUXsFPi9oiX59bY0oJDAnvID0N Xf+HycR9aYhOaNRihObzi X-Received: by 2002:a05:620a:6d5:: with SMTP id 21mr17847529qky.417.1589252719751; Mon, 11 May 2020 20:05:19 -0700 (PDT) X-Google-Smtp-Source: APiQypLiBAKuAfRrbANgwiiNUIAucU1Pco0OT4BqCnJu+J0AQgo6mMR9yRiZJEBGQi/naUgc3lru5A== X-Received: by 2002:a05:620a:6d5:: with SMTP id 21mr17847492qky.417.1589252719158; Mon, 11 May 2020 20:05:19 -0700 (PDT) Received: from [192.168.1.4] (198-84-170-103.cpe.teksavvy.com. [198.84.170.103]) by smtp.gmail.com with ESMTPSA id c68sm10034798qke.129.2020.05.11.20.05.18 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 11 May 2020 20:05:18 -0700 (PDT) Subject: Re: [PATCH] manual: Add Descriptor-Relative Access section To: Florian Weimer Cc: libc-alpha References: <87d07p9v73.fsf@mid.deneb.enyo.de> <87zhaoxnt4.fsf@mid.deneb.enyo.de> <65c7dd0a-bfc8-7a23-6503-1f813947e5fa@gmail.com> <87wo5suku5.fsf@mid.deneb.enyo.de> <87lfm8uf0u.fsf@mid.deneb.enyo.de> From: Carlos O'Donell Organization: Red Hat Message-ID: <85084320-8c01-2303-1f72-299627086560@redhat.com> Date: Mon, 11 May 2020 23:05:17 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <87lfm8uf0u.fsf@mid.deneb.enyo.de> Content-Language: en-US X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-13.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 May 2020 03:05:24 -0000 On 5/4/20 7:16 AM, Florian Weimer wrote: > * Michael Kerrisk: > >>> +@item >>> +If a progrem wishes to access a directory tree which is being modified >>> +concurrently, perhaps even by a different user on the system, the >>> +program typically must avoid following symbolic links. With POSIX >>> +interfaces, this can be done using the @code{O_NOFOLLOW} flag >>> +(@pxref{Open-time Flags}) or the @code{AT_SYMLINK_FOLLOW} flag >>> +(described below), but these flags affect only the final component of a >>> +file name (the basename). Symbolic links in the parent directory part >>> +are still followed. Therefore, without directory-relative access, it is >>> +necessary to use the @code{fchdir} function to change the working >>> +directory (@pxref{Working Directory}) and use the basename for file >>> +system access. As explained before, this is not thread-safe. Keeping a >>> +file descriptor of the directory is also required to be able to return >> Maybe better: s/of/that refers to/ >> >>> +to it later, so descriptor-based access is a natural fit. >> s/descriptor-relativebased/descriptor-relative/ ? > Thanks, we have now: > ... > directory (@pxref{Working Directory}) and use the basename for file > system access. As explained before, this is not thread-safe. Keeping a > file descriptor that refers to the directory is also required to be able > to return to it later, so descriptor-relative access is a natural fit. > > 8<------------------------------------------------------------------8< For the record `git am -c` will cut at this point. To test this I'm going to post your last patch again until I can see it coming through patchwork. Test 1 - Encoding is UTF-8. 8<------------------------------------------------------------------8< And document the functions openat, openat64, fstatat, fstatat64. (The safety assessment for fstatat was already obsolete because current glibc assumes kernel support for the underlying system call.) ----- manual/filesys.texi | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++-- manual/llio.texi | 28 ++++++++++ manual/startup.texi | 7 +-- 3 files changed, 174 insertions(+), 7 deletions(-) diff --git a/manual/filesys.texi b/manual/filesys.texi index 73e630842e..c690ddf716 100644 --- a/manual/filesys.texi +++ b/manual/filesys.texi @@ -15,6 +15,7 @@ access permissions and modification times. @menu * Working Directory:: This is used to resolve relative file names. +* Descriptor-Relative Access:: Ways to control pathname lookup. * Accessing Directories:: Finding out what files a directory contains. * Working with Directory Trees:: Apply actions to all files or a selectable @@ -206,6 +207,110 @@ An I/O error occurred. @end table @end deftypefun +@node Descriptor-Relative Access +@section Descriptor-Relative Access +@cindex pathname resolution based on descriptors +@cindex descriptor-based pathname resolution +@cindex @code{@dots{}at} functions + +Many functions that accept pathnames have variants have @code{@dots{}at} +variants which accept a file descriptor and pathname argument instead of +just a pathname argument. For example, @code{fstatat} is the +descriptor-based variant of the @code{fstat} function. Most of such +functions also accept an additional flags argument which changes the +behavior of the pathname lookup based on the @code{AT_@dots{}} flags +specified. + +The file descriptor used by these @code{@dots{}at} functions has the +following uses: + +@itemize @bullet +@item +It can be a file descriptor referring to a directory. Such a descriptor +can be created explicitly using the @code{open} function, with or +without the @code{O_DIRECTORY} flag. @xref{Opening and Closing Files}. +Or it can be created implicity by @code{opendir} and retrieved using the +@code{dirfd} function. @xref{Opening a Directory}. + +If a directory descriptor is used with one of the @code{@dots{}at} +functions, a relative pathname argument is resolved relatively to that +directory, just as if the directory were the current working directory. +Absolute pathname arguments (starting with @samp{/}) are resolved +against the file system root, and the descriptor argument is effectively +ignored for the purposes of pathname lookup. + +This means that pathname lookup is not constrained to the directory of +the descriptor. For example, it is possible to access a file +@file{example} in the parent directory using a pathname argument +@code{"../example"}, or in the root directory using @code{"/example"}. + +@item +@vindex @code{AT_FDCWD} +The special value @code{AT_FDCWD}. This means that the current working +directory is used for the lookup if the pathname is a relative. For +@code{@dots{}at} functions with an @code{AT_@dots{}} flags argument, +this provides a shortcut to use those flags with regular (not +descriptor-based) pathname lookups. + +@item +An arbitrary file descriptor, along with an empty string @code{""} as +the pathname argument, and the @code{AT_EMPTY_PATH} flag. In this case, +the operation uses the file descriptor directly, without further +pathname resolution. On Linux, this allows operations on descriptors +opened with the @code{O_PATH} flag. For regular descriptors (without +@code{O_PATH}), the same functionality is also available through the +plain descriptor-based functions (for example, @code{fstat} instead of +@code{fstatat}). + +This is a GNU extension. +@end itemize + +@cindex pathname resolution flags +@cindex @code{AT_*} pathname resolution flags +The flags argument in @code{@dots{}at} functions can be a combination of +the following flags, defined in @file{fcntl.h}. Not all such functions +support all flags, and some (such as @code{openat}) do not accept a +flags argument at all. + +In the flag descriptions below, the @dfn{effective final pathname +component} refers to the final component (basename) of the full path +constructed from the descriptor and pathname arguments, using pathname +lookup, as described above. + +@vtable @code +@item AT_EMPTY_PATH +This flag is used with an empty pathname @code{""} and a descriptor +which does not necessarily refer to a directory. It is most useful with +@code{O_PATH} descriptors, as described above. This flag is a GNU +extension. + +@item AT_NO_AUTOMOUNT +If the effective final pathname component refers to a potential file +system mount point controlled by an auto-mounting service, the operation +does not trigger auto-mounting and refers to the unmounted mount point +instead. @xref{Mount-Unmount-Remount}. If a file system has already +been mounted at the effective final pathname component, the operation +applies to the mounted file system, not the underlying file system that +was mounted over. This flag is a GNU extension. + +@item AT_SYMLINK_FOLLOW +If the effective final pathname component is a symbolic link, the +operation follows the symbolic link and operates on its target. (For +most functions, this is the default behavior.) + +@item AT_SYMLINK_NOFOLLOW +If the effective final pathname component is a symbolic link, the +operation operates on the symbolic link, without following it. The +difference in behavior enabled by this flag is similar to the difference +between the @code{lstat} and @code{stat} functions, or the behavior +activated by the @code{O_NOFOLLOW} argument to the @code{open} function. +Even with the @code{AT_SYMLINK_NOFOLLOW} flag present, symbolic links in +a non-final position of the pathname are still followed. +@end vtable + +There is no relationship between these flags and the type argument to +the @code{getauxval} function (with @code{AT_@dots{}} constants defined +in @file{elf.h}). @node Accessing Directories @section Accessing Directories @@ -1250,10 +1355,11 @@ A hardware error occurred while trying to read or write the to filesystem. The @code{linkat} function is analogous to the @code{link} function, except that it identifies its source and target using a combination of a -file descriptor (referring to a directory) and a pathname. If a -pathnames is not absolute, it is resolved relative to the corresponding -file descriptor. The special file descriptor @code{AT_FDCWD} denotes -the current directory. +file descriptor (referring to a directory) and a pathname. +@xref{Descriptor-Relative Access}. For @code{linkat}, if a pathname is +not absolute, it is resolved relative to the corresponding file +descriptor. As usual, the special file descriptor @code{AT_FDCWD} +denotes the current directory. The @var{flags} argument is a combination of the following flags: @@ -2095,6 +2201,38 @@ replaces the interface for small files on 32-bit machines. @c available. @c @safety{@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + +@deftypefun int fstatat (int @var{filedes}, const char *@var{filename}, struct stat *@var{buf}, int @var{flags}) +@standards{POSIX.1, sys/stat.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +This function is a descriptor-relative version of the @code{fstat} +function above. @xref{Descriptor-Relative Access}. The @var{flags} +argument can contain a combination of the flags @code{AT_EMPTY_PATH}, +@code{AT_NO_AUTOMOUNT}, @code{AT_SYMLINK_NOFOLLOW}. + +Compared to @code{fstat}, the following additional error conditions can +occur: + +@table @code +@item EBADF +The @var{filedes} argument is not a valid file descriptor. + +@item EINVAL +The @var{flags} argument is not valid for this function. + +@item ENOTDIR +The descriptor @var{filedes} is not associated with a directory, and +@var{filename} is a relative pathname. +@end table +@end deftypefun + +@deftypefun int fstatat64 (int @var{filedes}, const char *@var{filename}, struct stat64 *@var{buf}, int @var{flags}) +@standards{GNU, sys/stat.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +This function is the large-file variant of @code{fstatat}, similar to +how @code{fstat64} is the variant of @code{fstat}. +@end deftypefun + @deftypefun int lstat (const char *@var{filename}, struct stat *@var{buf}) @standards{BSD, sys/stat.h} @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} diff --git a/manual/llio.texi b/manual/llio.texi index fe59002915..48fe2dc862 100644 --- a/manual/llio.texi +++ b/manual/llio.texi @@ -180,6 +180,34 @@ new, extended API using 64 bit file sizes and offsets transparently replaces the old API. @end deftypefun +@deftypefun int openat (int @var{filedes}, const char *@var{filename}, int @var{flags}[, mode_t @var{mode}]) +@standards{POSIX.1, fcntl.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} +This function is the descriptor-relative variant of the @code{open} +function. @xref{Descriptor-Relative Access}. + +Note that the @var{flags} argument of @code{openat} does not accept +@code{AT_@dots{}} flags, only the flags described for the @code{open} +function above. + +The @code{openat} function can fail for additional reasons: + +@table @code +@item EBADF +The @var{filedes} argument is not a valid file descriptor. + +@item ENOTDIR +The descriptor @var{filedes} is not associated with a directory, and +@var{filename} is a relative pathname. +@end table +@end deftypefun + +@deftypefun int openat (int @var{filedes}, const char *@var{filename}, int @var{flags}[, mode_t @var{mode}]) +@standards{GNU, fcntl.h} +The large-file variant of the @code{openat}, similar to how +@code{open64} is the large-file variant of @code{open}. +@end deftypefun + @deftypefn {Obsolete function} int creat (const char *@var{filename}, mode_t @var{mode}) @standards{POSIX.1, fcntl.h} @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} diff --git a/manual/startup.texi b/manual/startup.texi index 21c48cd037..b2577cc0c4 100644 --- a/manual/startup.texi +++ b/manual/startup.texi @@ -664,9 +664,10 @@ basis there may be information that is not available any other way. @c Reads from hwcap or iterates over constant auxv. This function is used to inquire about the entries in the auxiliary vector. The @var{type} argument should be one of the @samp{AT_} symbols -defined in @file{elf.h}. If a matching entry is found, the value is -returned; if the entry is not found, zero is returned and @code{errno} is -set to @code{ENOENT}. +defined in @file{elf.h}. (There is no relationship between these types +and the pathname lookup flags in @file{fcntl.h}.) If a matching entry +is found, the value is returned; if the entry is not found, zero is +returned and @code{errno} is set to @code{ENOENT}. @end deftypefun For some platforms, the key @code{AT_HWCAP} is the easiest way to inquire