OSDN Git Service

Update README
[linuxjm/LDP_man-pages.git] / draft / man2 / open_by_handle_at.2
1 .\" Copyright (c) 2014 by Michael Kerrisk <mtk.manpages@gmail.com>
2 .\"
3 .\" %%%LICENSE_START(VERBATIM)
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
7 .\"
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
12 .\"
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date.  The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein.  The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
19 .\" professionally.
20 .\"
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
23 .\" %%%LICENSE_END
24 .\"
25 .\"*******************************************************************
26 .\"
27 .\" This file was generated with po4a. Translate the source file.
28 .\"
29 .\"*******************************************************************
30 .TH OPEN_BY_HANDLE_AT 2 2014\-06\-13 Linux "Linux Programmer's Manual"
31 .SH 名前
32 name_to_handle_at, open_by_handle_at \- パス名に対するハンドルの取得とハンドルによるファイルのオープン
33 .SH 書式
34 .nf
35 \fB#define _GNU_SOURCE\fP         /* feature_test_macros(7) 参照 */
36 \fB#include <sys/types.h>\fP
37 \fB#include <sys/stat.h>\fP
38 \fB#include <fcntl.h>\fP
39
40 \fBint name_to_handle_at(int \fP\fIdirfd\fP\fB, const char *\fP\fIpathname\fP\fB,\fP
41 \fB                      struct file_handle *\fP\fIhandle\fP\fB,\fP
42 \fB                      int *\fP\fImount_id\fP\fB, int \fP\fIflags\fP\fB);\fP
43
44 \fBint open_by_handle_at(int \fP\fImount_fd\fP\fB, struct file_handle *\fP\fIhandle\fP\fB,\fP
45 \fB                      int \fP\fIflags\fP\fB);\fP
46 .fi
47 .SH 説明
48 .\"
49 .\"
50 システムコール \fBname_to_handle_at\fP() と \fBopen_by_handle_at\fP() は \fBopenat\fP(2) の機能を
51 2 つに分割したものである。 \fBname_to_handle_at\fP() は指定されたファイルに対応するハンドルを返す。
52 \fBopen_by_handle_at\fP() は \fBname_to_handle_at\fP() が返したハンドルに対応するファイルをオープンし、
53 オープンされたファイルディスクリプターを返す。
54 .SS name_to_handle_at()
55 \fBname_to_handle_at\fP() システムコールは、 引き数 \fIdirfd\fP と \fIpathname\fP
56 で指定されるファイルに対応するファイルハンドルとマウント ID を返す。 ファイルハンドルは引き数 \fIhandle\fP で返される。 \fIhandle\fP
57 は以下の形式の構造体へのポインターである。
58
59 .in +4n
60 .nf
61 struct file_handle {
62     unsigned int  handle_bytes;   /* Size of f_handle [in, out] */
63     int           handle_type;    /* Handle type [out] */
64     unsigned char f_handle[0];    /* File identifier (sized by
65                                      caller) [out] */
66 };
67 .fi
68 .in
69 .PP
70 \fIf_handle\fP で返されるハンドルを保持するのに十分な大きさの構造体を確保するのは、 呼び出し元が責任をもって行う必要がある。 呼び出し前に、
71 \fIhandle_bytes\fP フィールドは \fIf_handle\fP 用に格納されたサイズで初期化すべきである
72 (\fI<fcntl.h>\fP で定義されている定数 \fBMAX_HANDLE_SZ\fP でファイルハンドルの最大サイズが規定されている)。
73 呼び出しが成功でリターンする際、 \fIhandle_bytes\fP フィールドは \fIf_handle\fP に実際に書き込まれたバイト数に更新される。
74
75 呼び出し元では、 \fIhandle\->handle_bytes\fP を 0 に設定して呼び出しを行うことで、 \fIfile_handle\fP
76 構造体に必要なサイズを知ることができる。 この場合、 この呼び出しはエラー \fBEOVERFLOW\fP で失敗し、
77 \fIhandle\->handle_bytes\fP に必要なサイズが設定される。
78 呼び出し元はこの情報を使って、正しいサイズの構造体を割り当てることができる (下記の「例」を参照)。
79
80 \fIhandle_bytes\fP フィールドを使用する以外は、 呼び出し元は \fIfile_handle\fP 構造体の内容を意識せずに扱うべきである。
81 フィールド \fIhandle_type\fP と \fIf_handle\fP は後で \fBopen_by_handle_at\fP()
82 を呼び出す場合にだけ必要である。
83
84 \fIflags\fP 引き数は、 下記の \fBAT_EMPTY_PATH\fP と \fBAT_SYMLINK_FOLLOW\fP のうち 0
85 個以上の論理和を取って構成されるビットマスクである。
86
87 引き数 \fIpathname\fP と \fIdirfd\fP はその組み合わせでハンドルを取得するファイルを指定する。 以下の 4 つのパターンがある。
88 .IP * 3
89 \fIpathname\fP が空でない文字列で絶対パス名を含む場合、 このパス名が参照するファイルに対するハンドルが返される。
90 .IP *
91 \fIpathname\fP が相対パスが入った空でない文字列で、 \fIdirfd\fP が特別な値 \fBAT_FDCWD\fP の場合、 \fIpathname\fP
92 は呼び出し元のカレントワーキングディレクトリに対する相対パスと解釈され、 そのファイルに対するハンドルが返される。
93 .IP *
94 \fIpathname\fP が相対パスが入った空でない文字列で、 \fIdirfd\fP がディレクトリを参照するファイルディスクリプターの場合、
95 \fIpathname\fP は \fIdirfd\fP が参照するディレクトリに対する相対パスと解釈され、
96 そのファイルを参照するハンドルが返される。(なぜ「ディレクトリファイルディスクリプター」が役に立つのかについては \fBopenat\fP(2) を参照。)
97 .IP *
98 \fIpathname\fP が空の文字列で \fIflags\fP に \fBAT_EMPTY_PATH\fP が指定されている場合、 \fIdirfd\fP
99 には任意の種別のファイルを参照するオープンされたファイルディスクリプターか \fBAT_FDCWD\fP (カレントワーキングディレクトリを意味する)
100 を指定でき、 \fIdirfd\fP が参照するファイルに対するハンドルが返される。
101 .PP
102 \fImount_id\fP 引き数は、 \fIpathname\fP に対応するファイルシステムのマウントの識別子を返す。 この識別子は
103 \fI/proc/self/mountinfo\fP のいずれかのレコードの最初のフィールドに対応する。 対応するレコードの 5
104 番目のフィールドのパス名をオープンすると、 このマウントポイントのファイルディスクリプターが得られる。 このファイルディスクリプターはこの後の
105 \fBopen_by_handle_at\fP() の呼び出しで使用できる。
106
107 デフォルトでは、 \fBname_to_handle_at\fP() は \fIpathname\fP がシンボリックリンクの場合にその展開
108 (dereference) を行わず、 リンク自身に対するハンドルを返す。 \fBAT_SYMLINK_FOLLOW\fP が \fIflags\fP
109 に指定されると、 \fIpathname\fP がシンボリックリンクの場合にリンクの展開が行われる (リンクが参照するファイルに対するハンドルが返される)。
110 .SS open_by_handle_at()
111 \fBopen_by_handle_at\fP() システムコールは \fIhandle\fP が参照するファイルをオープンする。 \fIhandle\fP は
112 前に呼び出した \fBname_to_handle_at\fP() が返したファイルハンドルである。
113
114 \fImount_fd\fP 引き数は、 \fIhandle\fP がそのファイルシステムに関連すると解釈されるマウントされたファイルシステム内の任意のオブジェクト
115 (ファイル、 ディレクトリなど) のファイルディスクリプターである。 特別な値 \fBAT_FDCWD\fP も指定できる。
116 この値は呼び出し元のカレントワーキングディレクトリを意味する。
117
118 引き数 \fIflags\fP は \fBopen\fP(2) と同じである。 \fIhandle\fP がシンボリックリンクを参照している場合、 呼び出し元は
119 \fBO_PATH\fP フラグを指定しなければならず、 そのシンボリックリンクは展開されない。 \fBO_NOFOLLOW\fP が指定された場合は、
120 \fBO_NOFOLLOW\fP は無視される。
121
122
123 \fBopen_by_handle_at\fP() を呼び出すには、 呼び出し元が \fBCAP_DAC_READ_SEARCH\fP
124 ケーパビリティーを持っていなければならない。
125 .SH 返り値
126 成功すると、 \fBname_to_handle_at\fP() は 0 を返し、 \fBopen_by_handle_at\fP()
127 は負でないファイルディスクリプターを返す。
128
129 エラーの場合、 どちらのシステムコールも \-1 を返し、 \fIerrno\fP にエラーの原因を示す値を設定する。
130 .SH エラー
131 \fBname_to_handle_at\fP() と \fBopen_by_handle_at\fP() は \fBopenat\fP(2) と同じエラーで失敗する。
132 また、 これらのシステムコールは以下のエラーで失敗することもある。
133
134 \fBname_to_handle_at\fP() は以下のエラーで失敗することがある。
135 .TP 
136 \fBEFAULT\fP
137 \fIpathname\fP, \fImount_id\fP, \fIhandle\fP のどれかがアクセス可能なアドレス空間の外を指している。
138 .TP 
139 \fBEINVAL\fP
140 \fIflags\fP に無効なビット値が含まれている。
141 .TP 
142 \fBEINVAL\fP
143 \fIhandle\->handle_bytes\fP が \fBMAX_HANDLE_SZ\fP よりも大きい。
144 .TP 
145 \fBENOENT\fP
146 \fIpathname\fP が空文字列だが、 \fIflags\fP に \fBAT_EMPTY_PATH\fP がされていなかった。
147 .TP 
148 \fBENOTDIR\fP
149 \fIdirfd\fP で指定されたファイルディスクリプターがディレクトリを参照しておらず、 両方の \fIflags\fP に \fBAT_EMPTY_PATH\fP
150 が指定され、 かつ \fIpathname\fP が空文字列である場合でもない。
151 .TP 
152 \fBEOPNOTSUPP\fP
153 ファイルシステムがパス名をファイルハンドルへの変換をサポートしていない。
154 .TP 
155 \fBEOVERFLOW\fP
156 .\"
157 .\"
158 呼び出しに渡された \fIhandle\->handle_bytes\fP の値が小さすぎた。 このエラーが発生した際、
159 \fIhandle\->handle_bytes\fP はハンドルに必要なサイズに更新される。
160 .PP
161 \fBopen_by_handle_at\fP() は以下のエラーで失敗することがある。
162 .TP 
163 \fBEBADF\fP
164 \fImount_fd\fP がオープンされたファイルディスクリプターでない。
165 .TP 
166 \fBEFAULT\fP
167 \fIhandle\fP がアクセス可能なアドレス空間の外を指している。
168 .TP 
169 \fBEINVAL\fP
170 \fIhandle\->handle_bytes\fP が \fBMAX_HANDLE_SZ\fP より大きいか 0 に等しい。
171 .TP 
172 \fBELOOP\fP
173 \fIhandle\fP がシンボリックリンクを参照しているが、 \fIflags\fP に \fBO_PATH\fP がされていなかった。
174 .TP 
175 \fBEPERM\fP
176 呼び出し元が \fBCAP_DAC_READ_SEARCH\fP ケーパビリティを持っていない。
177 .TP 
178 \fBESTALE\fP
179 指定された \fIhandle\fP が有効ではない。 このエラーは、 例えばファイルが削除された場合などに発生する。
180 .SH バージョン
181 これらのシステムコールは Linux 2.6.39 で初めて登場した。ライブラリによるサポートはバージョン 2.14 以降の glibc
182 で提供されている。
183 .SH 準拠
184 これらのシステムコールは非標準の Linux の拡張である。
185
186 FreeBSD には \fBgetfh\fP() と \fBopenfh\fP() というほとんど同じ機能のシステムコールのペアが存在する。
187 .SH 注意
188 あるプロセスで \fBname_to_handle_at\fP() を使ってファイルハンドルを生成して、 そのハンドルを別のプロセスの
189 \fBopen_by_handle_at\fP() で使用することができる。
190
191 いくつかのファイルシステムでは、 パス名からファイルハンドルへの変換がサポートされていない。 例えば、 \fI/proc\fP, \fI/sys\fP
192 や種々のネットワークファイルシステムなどである。
193
194 ファイルハンドルは、 ファイルが削除されたり、 その他のファイルシステム固有の理由で、 無効 ("stale") になる場合がある。
195 無効なハンドルであることは、 \fBopen_by_handle_at\fP() からエラー \fBESTALE\fP が返ることで通知される。
196
197 .\" https://lwn.net/Articles/375888/
198 .\"     "Open by handle" - Jonathan Corbet, 2010-02-23
199 これらのシステムコールは、 ユーザー空間のファイルサーバーでの使用を意図して設計されている。 例えば、 ユーザー空間 NFS
200 サーバーがファイルハンドルを生成して、 そのハンドルを NFS クライアントに渡すことができる。 その後、
201 クライアントがファイルをオープンしようとした際に、 このハンドルをサーバーに送り返すことができる。 このような機能により、
202 ユーザー空間ファイルサーバーは、 そのサーバーが提供するファイルに関してステートレスで (状態を保持せずに) 動作することができる。
203
204 .\" commit bcda76524cd1fa32af748536f27f674a13e56700
205 \fIpathname\fP がシンボリックリンクを参照していて、 \fIflags\fP に \fBAT_SYMLINK_FOLLOW\fP が指定されていない場合、
206 \fBname_to_handle_at\fP() は (シンボリックが参照するファイルではなく) リンクに対するハンドルを返す。
207 ハンドルを受け取ったプロセスは、 \fBopen_by_handle_at\fP() の \fBO_PATH\fP
208 フラグを使ってハンドルをファイルディスクリプターに変換し、 そのファイルディスクリプターを \fBreadlinkat\fP(2) や
209 \fBfchownat\fP(2) などのシステムコールの \fIdirfd\fP 引き数として渡すことで、 そのシンボリックリンクに対して操作を行うことができる。
210 .SS "永続的なファイルシステム ID の取得"
211 \fI/proc/self/mountinfo\fP のマウント ID は、
212 ファイルシステムのアンマウント、マウントが行われるに連れて再利用されることがある。 したがって、 \fBname_to_handle_at\fP() (の
213 \fI*mount_id\fP) で返されたマウント ID は対応するマウントされたファイルシステムを表す永続的な ID と考えるべきではない。 ただし、
214 アプリケーションは、 マウント ID に対応する  \fImountinfo\fP レコードの情報を使うことで、 永続的な ID を得ることができる。
215
216 .\" e.g., http://stackoverflow.com/questions/6748429/using-libblkid-to-find-uuid-of-a-partition
217 例えば、 \fImountinfo\fP レコードの 5 番目のフィールドのデバイス名を使って、 \fI/dev/disks/by\-uuid\fP
218 のシンボリックリンク経由で対応するデバイス UUID を検索できる。 (UUID を取得するもっと便利な方法は \fBlibblkid\fP(3)
219 ライブラリを使用することである。) そのプロセスは、逆に、 この UUID を使ってデバイス名を検索し、 対応するマウントポイントを取得することで、
220 \fBopen_by_handle_at\fP() で使用する \fImount_fd\fP 引き数を生成することができる。
221 .SH 例
222 以下の 2 つのプログラムは \fBname_to_handle_at\fP() と \fBopen_by_handle_at\fP()
223 の使用例を示したものである。 最初のプログラム (\fIt_name_to_handle_at.c\fP) は \fBname_to_handle_at\fP()
224 を使用して、 コマンドライン引き数で指定されたファイルに対応するファイルハンドルとマウント ID を取得する。 ハンドルとマウント ID
225 は標準出力に出力される。
226
227 2 つ目のプログラム (\fIt_open_by_handle_at.c\fP) は、 標準入力からマウント ID とファイルハンドルを読み込む。 それから、
228 \fBopen_by_handle_at\fP() を利用して、 そのハンドルを使ってファイルをオープンする。 追加のコマンドライン引き数が指定された場合は、
229 \fBopen_by_handle_at\fP() の \fImount_fd\fP 引き数は、 この引き数で渡された名前のディレクトリをオープンして取得する。
230 それ以外の場合、 \fI/proc/self/mountinfo\fP からスキャンして標準入力から読み込んだマウント ID に一致するマウント ID
231 を検索し、 そのレコードで指定されているマウントディレクトリをオープンして、 \fImount_fd\fP を入手する。 (これらのプログラムではマウント
232 ID が永続的ではない点についての対処は行わない。)
233
234 以下のシェルセッションは、これら 2 つのプログラムの使用例である。
235
236 .in +4n
237 .nf
238 $ \fBecho 'Can you please think about it?' > cecilia.txt\fP
239 $ \fB./t_name_to_handle_at cecilia.txt > fh\fP
240 $ \fB./t_open_by_handle_at < fh\fP
241 open_by_handle_at: Operation not permitted
242 $ \fBsudo ./t_open_by_handle_at < fh\fP      # Need CAP_SYS_ADMIN
243 Read 31 bytes
244 $ \fBrm cecilia.txt\fP
245 .fi
246 .in
247
248 .\" Christoph Hellwig: That's why the file handles contain a generation
249 .\" counter that gets incremented in this case.
250 ここで、 ファイルを削除し (すぐに) 再作成する。 同じ内容で (運がよければ) 同じ inode になる。 この場合でも、
251 \fBopen_by_handle_at\fP() はこのファイルハンドルが参照する元のファイルがすでに存在しないことを認識する。
252
253 .in +4n
254 .nf
255 $ \fBstat \-\-printf="%i\en" cecilia.txt\fP     # Display inode number
256 4072121
257 $ \fBrm cecilia.txt\fP
258 $ \fBecho 'Can you please think about it?' > cecilia.txt\fP
259 $ \fBstat \-\-printf="%i\en" cecilia.txt\fP     # Check inode number
260 4072121
261 $ \fBsudo ./t_open_by_handle_at < fh\fP
262 open_by_handle_at: Stale NFS file handle
263 .fi
264 .in
265 .SS "プログラムのソース: t_name_to_handle_at.c"
266 \&
267 .nf
268 #define _GNU_SOURCE
269 #include <sys/types.h>
270 #include <sys/stat.h>
271 #include <fcntl.h>
272 #include <stdio.h>
273 #include <stdlib.h>
274 #include <unistd.h>
275 #include <errno.h>
276 #include <string.h>
277
278 #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \e
279                         } while (0)
280
281 int
282 main(int argc, char *argv[])
283 {
284     struct file_handle *fhp;
285     int mount_id, fhsize, flags, dirfd, j;
286     char *pathname;
287
288     if (argc != 2) {
289         fprintf(stderr, "Usage: %s pathname\en", argv[0]);
290         exit(EXIT_FAILURE);
291     }
292
293     pathname = argv[1];
294
295     /* file_handle 構造体を確保する */
296
297     fhsize = sizeof(*fhp);
298     fhp = malloc(fhsize);
299     if (fhp == NULL)
300         errExit("malloc");
301
302     /* name_to_handle_at() を最初に呼び出して
303        ファイルハンドルに必要なサイズを入手する */
304
305     dirfd = AT_FDCWD;           /* For name_to_handle_at() calls */
306     flags = 0;                  /* For name_to_handle_at() calls */
307     fhp\->handle_bytes = 0;
308     if (name_to_handle_at(dirfd, pathname, fhp,
309                 &mount_id, flags) != \-1 || errno != EOVERFLOW) {
310         fprintf(stderr, "Unexpected result from name_to_handle_at()\en");
311         exit(EXIT_FAILURE);
312     }
313
314     /* file_handle 構造体を正しいサイズに確保し直す */
315
316     fhsize = sizeof(struct file_handle) + fhp\->handle_bytes;
317     fhp = realloc(fhp, fhsize);         /* Copies fhp\->handle_bytes */
318     if (fhp == NULL)
319         errExit("realloc");
320
321     /* コマンドラインで指定されたパス名からファイルハンドルを取得 */
322
323     if (name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags) == \-1)
324         errExit("name_to_handle_at");
325
326     /* t_open_by_handle_at.c で後で再利用できるように、マウント ID、
327        ファイルハンドルのサイズ、ファイルハンドルを標準出力に書き出す */
328
329     printf("%d\en", mount_id);
330     printf("%d %d   ", fhp\->handle_bytes, fhp\->handle_type);
331     for (j = 0; j < fhp\->handle_bytes; j++)
332         printf(" %02x", fhp\->f_handle[j]);
333     printf("\en");
334
335     exit(EXIT_SUCCESS);
336 }
337 .fi
338 .SS "プログラムのソース: t_open_by_handle_at.c"
339 \&
340 .nf
341 #define _GNU_SOURCE
342 #include <sys/types.h>
343 #include <sys/stat.h>
344 #include <fcntl.h>
345 #include <limits.h>
346 #include <stdio.h>
347 #include <stdlib.h>
348 #include <unistd.h>
349 #include <string.h>
350
351 #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \e
352                         } while (0)
353
354 /* /proc/self/mountinfo をスキャンして、マウント ID が \(aqmount_id\(aq に
355    一致する行を探す。 (もっと簡単な方法は \(aqutil\-linux\(aq プロジェクト
356    が提供する \(aqlibmount\(aq ライブラリをインストールして使うことである)
357    対応するマウントパスをオープンし、得られたファイルディスクリプターを返す。 */
358
359 static int
360 open_mount_path_by_id(int mount_id)
361 {
362     char *linep;
363     size_t lsize;
364     char mount_path[PATH_MAX];
365     int mi_mount_id, found;
366     ssize_t nread;
367     FILE *fp;
368
369     fp = fopen("/proc/self/mountinfo", "r");
370     if (fp == NULL)
371         errExit("fopen");
372
373     found = 0;
374     linep = NULL;
375     while (!found) {
376         nread = getline(&linep, &lsize, fp);
377         if (nread == \-1)
378             break;
379
380         nread = sscanf(linep, "%d %*d %*s %*s %s",
381                        &mi_mount_id, mount_path);
382         if (nread != 2) {
383             fprintf(stderr, "Bad sscanf()\en");
384             exit(EXIT_FAILURE);
385         }
386
387         if (mi_mount_id == mount_id)
388             found = 1;
389     }
390     free(linep);
391
392     fclose(fp);
393
394     if (!found) {
395         fprintf(stderr, "Could not find mount point\en");
396         exit(EXIT_FAILURE);
397     }
398
399     return open(mount_path, O_RDONLY);
400 }
401
402 int
403 main(int argc, char *argv[])
404 {
405     struct file_handle *fhp;
406     int mount_id, fd, mount_fd, handle_bytes, j;
407     ssize_t nread;
408     char buf[1000];
409 #define LINE_SIZE 100
410     char line1[LINE_SIZE], line2[LINE_SIZE];
411     char *nextp;
412
413     if ((argc > 1 && strcmp(argv[1], "\-\-help") == 0) || argc > 2) {
414         fprintf(stderr, "Usage: %s [mount\-path]\en", argv[0]);
415         exit(EXIT_FAILURE);
416     }
417
418     /* マウント ID とファイルハンドル情報が入った標準入力:
419
420          Line 1: <mount_id>
421          Line 2: <handle_bytes> <handle_type>   <bytes of handle in hex>
422     */
423
424     if ((fgets(line1, sizeof(line1), stdin) == NULL) ||
425            (fgets(line2, sizeof(line2), stdin) == NULL)) {
426         fprintf(stderr, "Missing mount_id / file handle\en");
427         exit(EXIT_FAILURE);
428     }
429
430     mount_id = atoi(line1);
431
432     handle_bytes = strtoul(line2, &nextp, 0);
433
434     /* handle_bytes があれば、
435        file_handle 構造体をここで割り当てできる */
436
437     fhp = malloc(sizeof(struct file_handle) + handle_bytes);
438     if (fhp == NULL)
439         errExit("malloc");
440
441     fhp\->handle_bytes = handle_bytes;
442
443     fhp\->handle_type = strtoul(nextp, &nextp, 0);
444
445     for (j = 0; j < fhp\->handle_bytes; j++)
446         fhp\->f_handle[j] = strtoul(nextp, &nextp, 16);
447
448     /* マウントポイントのファイルディスクリプターを取得する。
449        取得は、コマンドラインで指定されたパス名をオープンするか、
450        /proc/self/mounts をスキャンして標準入力から受け取った
451        \(aqmount_id\(aq に一致するマウントを探すことで行う。 */
452
453     if (argc > 1)
454         mount_fd = open(argv[1], O_RDONLY);
455     else
456         mount_fd = open_mount_path_by_id(mount_id);
457
458     if (mount_fd == \-1)
459         errExit("opening mount fd");
460
461     /* ハンドルとマウントポイントを使ってファイルをオープンする */
462
463     fd = open_by_handle_at(mount_fd, fhp, O_RDONLY);
464     if (fd == \-1)
465         errExit("open_by_handle_at");
466
467     /* そのファイルからバイトを読み出す */
468
469     nread = read(fd, buf, sizeof(buf));
470     if (nread == \-1)
471         errExit("read");
472
473     printf("Read %zd bytes\en", nread);
474
475     exit(EXIT_SUCCESS);
476 }
477 .fi
478 .SH 関連項目
479 \fBopen\fP(2), \fBlibblkid\fP(3), \fBblkid\fP(8), \fBfindfs\fP(8), \fBmount\fP(8)
480
481 .UR https://www.kernel.org/pub/linux/utils/util\-linux/
482 .UE
483 で入手できる最新の
484 \fIutil\-linux\fP リリースの \fIlibblkid\fP と \fIlibmount\fP のドキュメント。
485 .SH この文書について
486 この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.79 の一部
487 である。プロジェクトの説明とバグ報告に関する情報は
488 http://www.kernel.org/doc/man\-pages/ に書かれている。