1

When I'm in a mounted directory (9p) on my gentoo-guest and do the following:

TMPDIR='./foo' # The directory './foo' exists and the name 'TMPDIR' is important
cat <<EOF
hello world
EOF

I get the following output:

cat: -: No such file or directory

As soon I unset $TMPDIR and/or remove ./foo everything just works as expected.

It seems like cat depends on $TMPDIR. Is this a bug?

Edit

the strace looks like this:

execve("/bin/cat", ["cat"], 0x7fffdbbfeb20 /* 23 vars */) = 0
brk(NULL)                               = 0x55eca4cce000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=22796, ...}) = 0
mmap(NULL, 22796, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7166997000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1857312, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7166995000
mmap(NULL, 3963464, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f71663af000
mprotect(0x7f716656d000, 2097152, PROT_NONE) = 0
mmap(0x7f716676d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1be000) = 0x7f716676d000
mmap(0x7f7166773000, 14920, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7166773000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7f7166996540) = 0
mprotect(0x7f716676d000, 16384, PROT_READ) = 0
mprotect(0x55eca40ce000, 4096, PROT_READ) = 0
mprotect(0x7f716699d000, 4096, PROT_READ) = 0
munmap(0x7f7166997000, 22796)           = 0
brk(NULL)                               = 0x55eca4cce000
brk(0x55eca4cef000)                     = 0x55eca4cef000
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(229, 0), ...}) = 0
fstat(0, 0x7ffe16cc1ec0)                = -1 ENOENT (No such file or directory)
write(2, "cat: ", 5)                    = 5
write(2, "-", 1)                        = 1
write(2, ": No such file or directory", 27) = 27
write(2, "\n", 1)                       = 1
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(1)                           = ?
+++ exited with 1 +++
  • I suspect your specific problem may be related to the fact that you are using a relative path for $TMPDIR. Did you try an ls -ld $TMPDIR before cat? – U. Windl Apr 25 at 9:51
  • I've tried it with an absolute path which results the same behavior. – Cosinus Apr 25 at 9:58
  • 2
    Did you try strace cat <<... to find out what's going on? – U. Windl Apr 25 at 10:04
  • @U.Windl I did a strace, but I do not understand what goes wrong, it seems like somewhere the stdin (fd=0) goes missing – Cosinus Apr 25 at 11:08
  • 1
1

Actually cat does not depend on $TMPDIR, but the shell redirection << does.

In this case it seems cat tries do do an fstat() on stdin (fd 0), and it fails for some reason (from strace):

fstat(0, 0x7ffe16cc1ec0)                = -1 ENOENT (No such file or directory)

In a normal environment this is not a problem:

strace -f cat <<FOO
> bar
> FOO
execve("/usr/bin/cat", ["cat"], [/* 91 vars */]) = 0

...

fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
fstat(0, {st_mode=S_IFREG|0600, st_size=4, ...}) = 0
fadvise64(0, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
mmap(NULL, 139264, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4844156000
read(0, "bar\n", 131072)                = 4
write(1, "bar\n", 4bar
)                    = 4
read(0, "", 131072)                     = 0
munmap(0x7f4844156000, 139264)          = 0
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

So again: It's not a bug in cat, but some bug in the virtual environment.

  • but if I replace cat with less it works – Cosinus Apr 25 at 9:53
  • Exactly, bash implements here-docs with temporary files. That makes them seekable. – mosvy Apr 25 at 11:44
  • Yes I saw that in the traces too, but why does it work on any mounted block device, but does not on a 9p-device? – Cosinus Apr 25 at 12:24
  • the difference between cat and less is that cat does a fstat() on stdin and less doesn't. It's some strange hiccup or bug with virtio/9p (unfortunately, I'm not able to debug it now). But anyways, nothing to do with cat, less, bash, etc ;-) – mosvy Apr 25 at 12:42
  • that's most certainly caused by this bug, already mentioned in the comment. I'm using nfs and cifs/samba with qemu virtual machines -- I don't know how easy is to switch to that within the constraints of the libvirt straight-jacket, though. – mosvy Apr 30 at 9:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.