Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       rename, renameat, renameat2 - ファイルの名前や位置を変更する

書式

       #include <stdio.h>

       int rename(const char *oldpath, const char *newpath);

       #include <fcntl.h>           /* AT_* 定数の定義 */
       #include <stdio.h>

       int renameat(int olddirfd, const char *oldpath,
                    int newdirfd, const char *newpath);

       int renameat2(int olddirfd, const char *oldpath,
                     int newdirfd, const char *newpath, unsigned int flags);

   glibc 向けの機能検査マクロの要件 (feature_test_macros(7)  参照):

       renameat():
           glibc 2.10 以降:
               _POSIX_C_SOURCE >= 200809L
           glibc 2.10 より前:
               _ATFILE_SOURCE
       renameat2():
           _GNU_SOURCE

説明

       rename()      はファイルの名前を変更し、必要ならばディレクトリ間の移動を行なう。     そのファイルに対する
       (link(2) を使用して作られた) 他のハードリンク (hard link) には影響はない。 オープン済の oldpath  に対する
       ファイルディスクリプターにも影響はない。

       Various restrictions determine whether or not the rename operation succeeds: see ERRORS below.

       If  newpath  already  exists,  it will be atomically replaced, so that there is no point at which another
       process attempting to access newpath will find it missing.  However, there will probably be a  window  in
       which both oldpath and newpath refer to the file being renamed.

       oldpathnewpath がどちらも既存のハードリンクで、同じファイルを参照している場合、 rename() は何も行わ
       ず、ステータスとして成功を返す。

       newpath が存在し、何らかの理由で操作が失敗した場合、 rename()  は newpath  の実体を元のまま残すことを保証
       する。

       oldpath  にはディレクトリを指定することもできる。 この場合、 newpath は存在しないか、空のディレクトリでな
       ければならない。

       oldpath がシンボリックリンク (symbolic  link)  を参照している場合は、  リンクの名前が変更される。  また、
       newpath がシンボリックリンクを参照している場合は、リンクが上書きされる。

   renameat()
       renameat() システムコールは rename() と全く同様に動作するが、以下で説明する点が異なる。

       oldpath  で指定されたパス名が相対パスの場合、このパス名はファイルディスクリプター olddirfd が参照するディ
       レクトリに対する相対パスと解釈される (rename(2)  に相対パス名を渡した場合のように、呼び出したプロセスのカ
       レントワーキングディレクトリに対する相対パスではない)。

       oldpath  で指定されたパス名が相対パスで、  olddirfd  が特別な値  AT_FDCWD  の場合、  (rename(2) と同様に)
       oldpath は呼び出したプロセスのカレントワーキングディレクトリに対する相対パスと解釈される。

       oldpath で指定されたパス名が絶対パスの場合、 olddirfd は無視される。

       newpath の解釈は oldpath と同じである。  相対パスのパス名がファイルディスクリプター  newdirfd  が参照する
       ディレクトリと解釈される点だけが異なる。

       renameat() の必要性についての説明については openat(2) を参照。

   renameat2()
       renameat2()  には追加の flags 引数がある。 flags 引数が 0 の renameat2() の呼び出しは renameat() と等価で
       ある。

       flags 引数は、以下のフラグの 0 個以上のビットマスクである。

       RENAME_EXCHANGE
              oldpathnewpath をアトミックに入れ換える。 両方のパス名が存在しなければならないが、  ファイル種
              別は異なっていてもよい (例えば、一方は空でないディレクトリで、もう一方はシンボリックリンクであるな
              ど)。

       RENAME_NOREPLACE
              rename の newpath を上書きしない。 newpath がすでに存在する場合エラーを返す。

              RENAME_NOREPLACE can't be employed together with RENAME_EXCHANGE.

              RENAME_NOREPLACE requires support from the underlying filesystem.  Support for various filesystems
              was added as follows:

              *
                  ext4 (Linux 3.15);

              *
                  btrfs, shmem, cifs (Linux 3.17);

              *
                  xfs (Linux 4.0);

              *  Support  for  many  other  filesystems was added in Linux 4.9, including ext2, minix, reiserfs,
                 jfs, vfat, and bpf.

       RENAME_WHITEOUT (Linux 3.18 以降)
              This operation makes sense only for overlay/union filesystem implementations.

              Specifying RENAME_WHITEOUT creates a "whiteout" object at the source of the  rename  at  the  same
              time as performing the rename.  The whole operation is atomic, so that if the rename succeeds then
              the whiteout will also have been created.

              A "whiteout" is an object that has special meaning in  union/overlay  filesystem  constructs.   In
              these  constructs,  multiple layers exist and only the top one is ever modified.  A whiteout on an
              upper layer will effectively hide a matching file in the lower layer, making it appear as  if  the
              file didn't exist.

              When a file that exists on the lower layer is renamed, the file is first copied up (if not already
              on the upper layer)  and then renamed on the upper, read-write  layer.   At  the  same  time,  the
              source file needs to be "whiteouted" (so that the version of the source file in the lower layer is
              rendered invisible).  The whole operation needs to be done atomically.

              When not part of a union/overlay, the whiteout appears as a character device with a  {0,0}  device
              number.   (Note  that other union/overlay implementations may employ different methods for storing
              whiteout entries; specifically, BSD union mount employs a  separate  inode  type,  DT_WHT,  which,
              while  supported  by  some filesystems available in Linux, such as CODA and XFS, is ignored by the
              kernel's whiteout support code, as of Linux 4.19, at least.)

              RENAME_WHITEOUT requires the same privileges as  creating  a  device  node  (i.e.,  the  CAP_MKNOD
              capability).

              RENAME_WHITEOUT can't be employed together with RENAME_EXCHANGE.

              RENAME_WHITEOUT  requires  support  from  the  underlying  filesystem.  Among the filesystems that
              provide that support are tmpfs (since Linux 3.18), ext4 (since Linux 3.18), XFS (since Linux 4.1),
              f2fs (since Linux 4.2), btrfs (since Linux 4.7), and ubifs (since Linux 4.9).

返り値

       成功した場合は 0 が返される。エラーの場合は -1 が返され、 errno が適切に設定される。

エラー

       EACCES oldpath  または  newpath  を含んでいるディレクトリの書き込み許可がない。  または、  oldpath または
              newpath のディレクトリ部分のどれかに検索許可がない。 または、 oldpath がディレクトリで (..  エント
              リーを更新するのに必要な) 書き込み許可がない (path_resolution(7)  も参照)。

       EBUSY  oldpath  または newpath がディレクトリで、何らかのプロセスが使用中 (多分、カレントワーキングディレ
              クトリか、ルートディレクトリか、 読み込みのためにオープンされているかでろう)  もしくは、システムが
              使用中 (例えばマウントポイントである)  であり、システムがこれをエラーであると判断したために rename
              が失敗した。 (このような場合に EBUSY を返すことは規格では要求されていない点に注意すること。 このよ
              うな場合に、rename をとにかく実行してみるのは何の問題もない。 ただし、そのような状況で、システムが
              他に返すエラーがない場合には EBUSY を返すことが許されている。)

       EDQUOT ディスクブロックか inode がそのファイルシステムのユーザークォータに達していた。

       EFAULT oldpathnewpath がアクセス可能なアドレス空間の外を指している。

       EINVAL newpatholdpath のパス部分を含んでいる。ディレクトリを自分自身のサブディレクトリに 変更しようと
              した場合がほとんどである。

       EISDIR newpath は存在しているディレクトリであるが、 oldpath はディレクトリでない。

       ELOOP  oldpath または newpath を解決する際に遭遇したシンボリックリンクが多過ぎる。

       EMLINK oldpath  は既に最大数までのリンクを持っているか、それがディレクトリで newpath を含んでいるディレク
              トリが最大数までのリンクを持っている。

       ENAMETOOLONG
              oldpath または newpath が長過ぎる。

       ENOENT oldpath という名前のリンクが存在しない。 または、  newpath  というディレクトリが存在しない。  また
              は、 oldpathnewpath が空の文字列である。

       ENOMEM 十分なカーネルメモリーがない。

       ENOSPC そのファイルを含んでいるデバイスに新しいディレクトリエントリーを 作成するための空きがない。

       ENOTDIR
              oldpathnewpath に含まれているディレクトリ部分が 実際にはディレクトリでない。 または oldpath が
              ディレクトリで、 newpath が存在してディレクトリでない。

       ENOTEMPTY  または  EEXIST
              newpath が空でないディレクトリである。すなわち "." と ".." 以外を含んでいる。

       EPERM または EACCES
              oldpath のあるディレクトリにスティッキービット (sticky bit)  (S_ISVTX)  が設定されており、  プロセ
              スの実効ユーザー  ID  が 削除しようとするファイルのユーザー ID と そのファイルを含むディレクトリの
              ユーザー ID のいずれとも一致せず、かつ プロセスに特権がない (Linux では CAP_FOWNER  ケーパビリティ
              (capability)  がない)。  または、 newpath がすでに存在するファイルで、親ディレクトリにスティッキー
              ビットが設定されており、 プロセスの実効ユーザー ID が 置き換えようとするファイルのユーザー  ID  と
              そのファイルを含むディレクトリのユーザー ID のいずれとも一致せず、かつ プロセスに特権がない (Linux
              では CAP_FOWNER ケーパビリティがない)。 または oldpathnewpath が存在するファイルシステムが、要
              求された種類の名前の変更を サポートしていない。

       EROFS  ファイルが読み込み専用のファイルシステムに存在する。

       EXDEV  oldpathnewpath が同じマウントされたファイルシステムに存在しない。 (Linux は 1 つのファイルシス
              テムを複数のマウント位置に マウントすることを許可している。 しかし rename() は、たとえ同じファイル
              システムであっても、 別々のマウント位置を跨いでは動作しない。)

       renameat() と renameat2() では以下のエラーも発生する。

       EBADF  olddirfdnewdirfd が有効なファイルディスクリプターでない。

       ENOTDIR
              oldpath  が相対パスで、  olddirfd  がディレクトリ以外のファイルを参照している。または  newpathnewdirfd に関して同じ状況である。

       renameat2() では以下のエラーも発生する。

       EEXIST flagsRENAME_NOREPLACE が指定されているが、 newpath がすでに存在する。

       EINVAL 無効なフラグ値が flags に指定された。

       EINVAL RENAME_NOREPLACERENAME_EXCHANGE の両方が flags に指定された。

       EINVAL Both RENAME_WHITEOUT and RENAME_EXCHANGE were specified in flags.

       EINVAL flags にファイルシステムでサポートされていないフラグが指定された。

       ENOENT flagsRENAME_EXCHANGE が指定されたが、 newpath が存在しない。

       EPERM  RENAME_WHITEOUTflags に指定されたが、呼び出し元が CAP_MKNOD ケーパビリティを持っていない。

バージョン

       renameat()  はカーネル 2.6.16 で Linux に追加された。 ライブラリによるサポートはバージョン 2.4  で  glibc
       に追加された。

       renameat2()  はカーネル 3.15 で Linux に追加された。 ライブラリによるサポートは glibc 2.28 で追加された。

準拠

       rename(): 4.3BSD, C89, C99, POSIX.1-2001, POSIX.1-2008.

       renameat(): POSIX.1-2008.

       renameat2()  は Linux 固有である。

注意

   glibc での注意
       renameat()  が利用できない古いカーネルでは、 glibc ラッパー関数は rename() を使用するモードにフォールバッ
       クする。 oldpathnewpath が相対パスの場合、 glibc は olddirfdnewdirfd 引数に対応する /proc/self/fd
       のシンボリックリンクに基づいてそれぞれパス名を構成する。

バグ

       NFS ファイルシステムでは、操作が失敗したからといって、 ファイルの名前が変更できなかったと決めてかかること
       はできない。 サーバが rename 操作を終えてからクラッシュした場合、 サーバが再び立ち上がったときに、 再送信
       された  RPC が処理されるが、これは失敗となる。 アプリケーションはこの問題を正しく取り扱うことが期待されて
       いる。 同様の問題について link(2)  にも書かれている。

関連項目

        mv(1), rename(1), chmod(2), link(2), symlink(2), unlink(2), path_resolution(7), symlink(7)

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 5.10  の一部である。プロジェクトの説明とバグ報告
       に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。