int index,
int braces)
{
- printf(_("%c%03d%c %-14s (%s,%s,%s,%s%s%s%s%s)\n"),
+ printf(_("%c%03d%c %-14s (%s,%s,%s,%s%s%s%s%s%s%s)\n"),
braces? '[' : ' ', index, braces? ']' : ' ', file->name,
file->flags & IO_FOREIGN ? _("foreign") : _("xfs"),
file->flags & IO_OSYNC ? _("sync") : _("non-sync"),
file->flags & IO_REALTIME ? _(",real-time") : "",
file->flags & IO_APPEND ? _(",append-only") : "",
file->flags & IO_NONBLOCK ? _(",non-block") : "",
- file->flags & IO_TMPFILE ? _(",tmpfile") : "");
+ file->flags & IO_TMPFILE ? _(",tmpfile") : "",
+ file->flags & IO_PATH ? _(",path") : "",
+ file->flags & IO_NOFOLLOW ? _(",nofollow") : "");
}
int
#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
#endif
+#ifndef O_PATH
+#if defined __alpha__
+#define O_PATH 040000000
+#elif defined(__hppa__)
+#define O_PATH 020000000
+#elif defined(__sparc__)
+#define O_PATH 0x1000000
+#else
+#define O_PATH 010000000
+#endif
+#endif /* O_PATH */
+
static cmdinfo_t open_cmd;
static cmdinfo_t close_cmd;
static cmdinfo_t chproj_cmd;
oflags |= O_NONBLOCK;
if (flags & IO_TMPFILE)
oflags |= O_TMPFILE;
+ if (flags & IO_PATH)
+ oflags |= O_PATH;
+ if (flags & IO_NOFOLLOW)
+ oflags |= O_NOFOLLOW;
fd = open(path, oflags, mode);
if (fd < 0) {
if (!geom || !platform_test_xfs_fd(fd))
return fd;
- if (xfsctl(path, fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
+ if (flags & IO_PATH) {
+ /* Can't call ioctl() on O_PATH fds */
+ memset(geom, 0, sizeof(*geom));
+ } else if (xfsctl(path, fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
perror("XFS_IOC_FSGEOMETRY");
close(fd);
return -1;
}
- if (!(flags & IO_READONLY) && (flags & IO_REALTIME)) {
+ if (!(flags & (IO_READONLY | IO_PATH)) && (flags & IO_REALTIME)) {
struct fsxattr attr;
if (xfsctl(path, fd, FS_IOC_FSGETXATTR, &attr) < 0) {
" -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n"
" -R -- mark the file as a realtime XFS file immediately after opening it\n"
" -T -- open with O_TMPFILE (create a file not visible in the namespace)\n"
+" -P -- open with O_PATH (create an fd that is merely a location reference)\n"
+" -L -- open with O_NOFOLLOW (don't follow symlink)\n"
" Note1: usually read/write direct IO requests must be blocksize aligned;\n"
" some kernels, however, allow sectorsize alignment for direct IO.\n"
" Note2: the bmap for non-regular files can be obtained provided the file\n"
return 0;
}
- while ((c = getopt(argc, argv, "FRTacdfm:nrstx")) != EOF) {
+ while ((c = getopt(argc, argv, "FLPRTacdfm:nrstx")) != EOF) {
switch (c) {
case 'F':
/* Ignored / deprecated now, handled automatically */
case 'T':
flags |= IO_TMPFILE;
break;
+ case 'P':
+ flags |= IO_PATH;
+ break;
+ case 'L':
+ flags |= IO_NOFOLLOW;
+ break;
default:
return command_usage(&open_cmd);
}
return -1;
}
+ if ((flags & (IO_PATH|IO_NOFOLLOW)) &&
+ (flags & ~(IO_PATH|IO_NOFOLLOW))) {
+ fprintf(stderr, _("-P and -L are incompatible with the other options\n"));
+ return -1;
+ }
+
fd = openfile(argv[optind], &geometry, flags, mode, &fsp);
if (fd < 0)
return 0;
open_cmd.argmax = -1;
open_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK |
CMD_FOREIGN_OK | CMD_FLAG_ONESHOT;
- open_cmd.args = _("[-acdrstxT] [-m mode] [path]");
+ open_cmd.args = _("[-acdrstxRTPL] [-m mode] [path]");
open_cmd.oneline = _("open the file specified by path");
open_cmd.help = open_help;
Display a list of all open files and (optionally) switch to an alternate
current open file.
.TP
-.BI "open [[ \-acdfrstRT ] " path " ]"
+.BI "open [[ \-acdfrstRTPL ] " path " ]"
Closes the current file, and opens the file specified by
.I path
instead. Without any arguments, displays statistics about the current
.B \-R
marks the file as a realtime XFS file after
opening it, if it is not already marked as such.
+.TP
+.B \-P
+opens the path as a referent only (O_PATH). This is incompatible with other
+flags specifying other O_xxx flags apart from
+.BR \-L .
+.TP
+.B \-L
+doesn't follow symlinks (O_NOFOLLOW). This is incompatible with other
+flags specifying other O_xxx flags apart from
+.BR \-P .
.PD
.RE
.TP