Hello, I'm not sure wheter this is a bug or a feature... However, I just noticed that cp(1) fails to copy /proc/cpuinfo to the file system (tested on i686 and x86_64 lenny systems):
$ wc -l /proc/cpuinfo 200 /proc/cpuinfo $ cp /proc/cpuinfo /tmp $ echo $? 0 $ wc -l /tmp/cpuinfo 125 /tmp/cpuinfo The first part of the file is copied correctly, but the rest is missing. Running strace(1) on cp reveals that cp requests to read 4 kB, receives less (but still >0), writes the received data to the destination file and exits: $ strace cp /proc/cpuinfo /tmp [...] open("/proc/cpuinfo", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 open("/tmp/cpuinfo", O_WRONLY|O_CREAT|O_EXCL, 0444) = 4 fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 read(3, "processor\t: 0\nvendor_id\t: Genuine"..., 4096) = 3535 write(4, "processor\t: 0\nvendor_id\t: Genuine"..., 3535) = 3535 close(4) = 0 close(3) = 0 close(0) = 0 close(1) = 0 close(2) = 0 exit_group(0) = ? Subsequent read(2)s would have returned more data (and thus allowed cp to successfully copy the file), as running strace on the the attached test program shows: $ strace ./a.out /proc/cpuinfo /tmp [...] open("/proc/cpuinfo", O_RDONLY) = 3 open("/tmp/cpuinfo", O_WRONLY|O_CREAT|O_EXCL, 0777) = 4 read(3, "processor\t: 0\nvendor_id\t: Genuine"..., 8192) = 3535 write(4, "processor\t: 0\nvendor_id\t: Genuine"..., 3535) = 3535 read(3, "processor\t: 5\nvendor_id\t: Genuine"..., 8192) = 2121 write(4, "processor\t: 5\nvendor_id\t: Genuine"..., 2121) = 2121 read(3, ""..., 8192) = 0 exit_group(0) = ? What's the problem here? Is this a bug in cp, in the proc file system, or is cp simply not supposed to work on such file systems? TIA, Jukka -- This email fills a much-needed gap in the archives.
#include <err.h> #include <fcntl.h> #include <unistd.h> int main(int argc, char *argv[]) { char buf[8*1024], *bufp; int in, out; int nread, nwritten, nleft; if ((in = open(argv[1], O_RDONLY, 0)) == -1) { err(1, "open(src)"); } if ((out = open(argv[2], O_WRONLY|O_CREAT|O_EXCL, 0777)) == -1) { err(1, "open(dst)"); } while ((nread = read(in, buf, sizeof buf)) > 0) { nleft = nread; bufp = buf; while (nleft > 0) { if ((nwritten = write(out, bufp, nleft)) == -1) { err(1, "write"); } nleft -= nwritten; bufp += nwritten; } } if (nread == -1) { err(1, "read"); } return 0; }