no68
no68

Reputation: 143

The influence of file mode when file is read and written by a same user in different processes

This is my code

fd=open("a",O_RDWR | O_CREAT);
printf("%d\n", fd);
if(fd < 0)
{
    perror("error");
    exit(1);
}
lseek(fd, 0, SEEK_SET);
read(fd, buf, 10);
write(STDOUT_FILENO, buf, 10);
getchar();//1

lseek(fd, 0, SEEK_SET);
write(fd, "xxxxxxxxxx", 10);
getchar();//2

lseek(fd, 0, SEEK_SET);
read(fd, buf, 10);
write(STDOUT_FILENO, buf, 10);
getchar();//3

next is something about file a

//file a, mode 600
//aaaaaaaaaaa

when at step 2, the text of file a will be changed into "xxxxx...".

then I use vim to change the text into "bbbbbbb..." in another terminal.

the output at step 3 is "xxxxx..."

however, when file a is

//file a, mode 606 or 660
//aaaaaaaaaaaa

do same thing as above

the output is "bbbbbbb...."

my system is os x 10.9

Upvotes: 1

Views: 47

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754700

I can reproduce the problem, to my considerable surprise (Mac OS X 10.9.4).

However, as I hinted might be a possibility in my comment, the problem seems to be that vim is changing the inode number of the file when the file has 600 permission:

$ for mode in 600 606 660 666
> do
>     echo "Mode: $mode"
>     echo "abcdefghijklmnopqrst" > a
>     chmod $mode a
>     ls -li a
>     vim a
>     cat a
>     ls -li a
> done
Mode: 600
25542402 -rw-------  1 jleffler  staff  21 Sep  2 07:58 a
xxxxxxxxxxklmnopqrst
25542484 -rw-------  1 jleffler  staff  21 Sep  2 07:58 a
Mode: 606
25542484 -rw----rw-  1 jleffler  staff  21 Sep  2 07:58 a
xxxxxxxxxxklmnopqrst
25542484 -rw----rw-  1 jleffler  staff  21 Sep  2 07:58 a
Mode: 660
25542484 -rw-rw----  1 jleffler  staff  21 Sep  2 07:58 a
xxxxxxxxxxklmnopqrst
25542484 -rw-rw----  1 jleffler  staff  21 Sep  2 07:58 a
Mode: 666
25542484 -rw-rw-rw-  1 jleffler  staff  21 Sep  2 07:58 a
xxxxxxxxxxklmnopqrst
25542484 -rw-rw-rw-  1 jleffler  staff  21 Sep  2 07:58 a
$

In each case, I ran the command 10rx and :x in vim.

I'm not clear why vim needs to change the inode when the file is 600 permission, but it smacks of a bug from where I'm sitting. It is behaviour I would not have expected at all (except that it explained what you saw).

Because the 'file descriptor' program (the outline code in the question) keeps the same file open, the inode number of the file it is working with does not change, but because vim rewrites the file with a new inode number (meaning: it creates a new file with a new name and inode number containing the modified contents, then removes the old version of a and replaces it with the new file), the edit made by vim (when the file has 600 permission) is not seen in the file that the program has open. At the end of the 'file descriptor' program when the permissions are 600, the file that it had open has no name and its contents are deleted by the system; the file that vim created has taken the place of the original file.

Upvotes: 1

Related Questions