+static int trace_calls = 0;
+
+#define TRACE_CALL(fs,...) \
+ if (trace_calls) { \
+ fprintf (stderr, "%s: %s (" fs ")\n", \
+ program_name, __func__, __VA_ARGS__); \
+ }
fg_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
{
fg_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
{
+ TRACE_CALL ("%s, [{ %ld, %ld }, { %ld, %ld }]",
+ path, ts[0].tv_sec, ts[0].tv_nsec, ts[1].tv_sec, ts[1].tv_nsec);
+
-/* This call is quite hard to emulate through the guestfs(3) API. In
- * one sense it's a little like access (see above) because it tests
- * whether opening a file would succeed given the flags. But it also
- * has side effects such as truncating the file if O_TRUNC is given.
- * Therefore we need to emulate it ... painfully.
+/* All this function needs to do is to check that the requested open
+ * flags are valid. See the notes in <fuse/fuse.h>.
- int r, exists;
-
- if (fi->flags & O_WRONLY) {
- if (read_only)
- return -EROFS;
- }
-
- exists = guestfs_exists (g, path);
- if (exists == -1)
- return error ();
-
- if (fi->flags & O_CREAT) {
- if (read_only)
- return -EROFS;
-
- dir_cache_invalidate (path);
-
- /* Exclusive? File must not exist already. */
- if (fi->flags & O_EXCL) {
- if (exists)
- return -EEXIST;
- }
+ TRACE_CALL ("%s, 0%o", path, fi->flags);
+
+ int flags = fi->flags & 3;
- /* Create? Touch it and optionally truncate it. */
- r = guestfs_touch (g, path);
- if (r == -1)
- return error ();
-
- if (fi->flags & O_TRUNC) {
- r = guestfs_truncate (g, path);
- if (r == -1)
- return error ();
- }
- } else {
- /* Not create, just check it exists. */
- if (!exists)
- return -ENOENT;
- }
+ if (read_only && flags != O_RDONLY)
+ return -EROFS;
fg_read (const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
fg_read (const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
fg_write (const char *path, const char *buf, size_t size,
off_t offset, struct fuse_file_info *fi)
{
fg_write (const char *path, const char *buf, size_t size,
off_t offset, struct fuse_file_info *fi)
{
struct guestfs_statvfs *r;
r = guestfs_statvfs (g, path);
struct guestfs_statvfs *r;
r = guestfs_statvfs (g, path);
static int fg_fsync(const char *path, int isdatasync,
struct fuse_file_info *fi)
{
static int fg_fsync(const char *path, int isdatasync,
struct fuse_file_info *fi)
{
fg_setxattr (const char *path, const char *name, const char *value,
size_t size, int flags)
{
fg_setxattr (const char *path, const char *name, const char *value,
size_t size, int flags)
{
fg_getxattr (const char *path, const char *name, char *value,
size_t size)
{
fg_getxattr (const char *path, const char *name, char *value,
size_t size)
{
" -i|--inspector Automatically mount filesystems\n"
" --help Display help message and exit\n"
" --keys-from-stdin Read passphrases from stdin\n"
" -i|--inspector Automatically mount filesystems\n"
" --help Display help message and exit\n"
" --keys-from-stdin Read passphrases from stdin\n"
" -m|--mount dev[:mnt] Mount dev on mnt (if omitted, /)\n"
" -n|--no-sync Don't autosync\n"
" -o|--option opt Pass extra option to FUSE\n"
" -m|--mount dev[:mnt] Mount dev on mnt (if omitted, /)\n"
" -n|--no-sync Don't autosync\n"
" -o|--option opt Pass extra option to FUSE\n"
/* The command line arguments are broadly compatible with (a subset
* of) guestfish. Thus we have to deal mainly with -a, -m and --ro.
*/
/* The command line arguments are broadly compatible with (a subset
* of) guestfish. Thus we have to deal mainly with -a, -m and --ro.
*/
static const struct option long_options[] = {
{ "add", 1, 0, 'a' },
{ "connect", 1, 0, 'c' },
static const struct option long_options[] = {
{ "add", 1, 0, 'a' },
{ "connect", 1, 0, 'c' },
{ "help", 0, 0, HELP_OPTION },
{ "inspector", 0, 0, 'i' },
{ "keys-from-stdin", 0, 0, 0 },
{ "help", 0, 0, HELP_OPTION },
{ "inspector", 0, 0, 'i' },
{ "keys-from-stdin", 0, 0, 0 },
{ "mount", 1, 0, 'm' },
{ "no-sync", 0, 0, 'n' },
{ "option", 1, 0, 'o' },
{ "ro", 0, 0, 'r' },
{ "mount", 1, 0, 'm' },
{ "no-sync", 0, 0, 'n' },
{ "option", 1, 0, 'o' },
{ "ro", 0, 0, 'r' },
{ "selinux", 0, 0, 0 },
{ "trace", 0, 0, 'x' },
{ "verbose", 0, 0, 'v' },
{ "selinux", 0, 0, 0 },
{ "trace", 0, 0, 'x' },
{ "verbose", 0, 0, 'v' },
} else {
fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
program_name, long_options[option_index].name, option_index);
} else {
fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
program_name, long_options[option_index].name, option_index);