My native language is not English. So I got problems when I read the document. In man page of close in FreeBSD: close - delete a file descriptor. And in Linux man page, close() closes a file descriptor, so that it no longer refers to any file. I'm wondering are they the same?
Related
In Linux, is it possible to open a file at given file descriptor?
man open says:
The open() function shall return a file descriptor for the named file that is the lowest file descriptor not currently open for that process.
Currently I'm calling open followed by dup2 and close. 3 syscalls. Is this the best we can do?
I can redirect the output of a process to a file
./prog > a.txt
But if I delete a.txt and do not restart prog, then no more output will get into a.txt. The same is the case if I use the append-redirect >>.
Is there a way to make my redirection recreate the file when it is deleted during the runtime of prog?
Redirection is part of the OS I think and not of prog. So maybe there are some tools or settings.
Thanks!
At the OS level, a file is made up of many components:
the content, stored somewhere on the storage device;
an i-node that keeps all file information except the name;
the name, listed in a directory (also stored on the storage device);
when the file is open, each application that opens it handle memory buffers that keep some of the file content.
All these are linked and the OS keeps their booking.
If you delete the file while it is open by another application (the redirect operator > keeps it open until ./prog completes), only the name is removed from the directory. The other pieces of the puzzle are still there and they keep working until the last application that keeps the file open closes it. This is when the file content is discarded on the storage medium.
If you delete the file, while ./prog keeps running and producing output the file grows and uses space on the storage medium but it cannot be open again because there is no way to access it. Only the programs that have it already open when it was deleted can still access the file until they close it.
Even if you re-create the file, it is a different file that happens to have the same name as the deleted one. ./prog is not affected, its output goes to the old, deleted file.
When its output is redirected, apart from restarting ./prog, there is no way to persuade it to store its output in a different file when a.txt is deleted.
There are several ways to make this happen if ./prog writes itself into a.txt (they all require changing the code of ./prog).
You can use gdb to redirect the output of program to file when original file is deleted.
Refer to this post.
For later references, I give the only excerpt from the post:
Find the files that are opened by the process using /proc/<pid>/fd.
Attach the PID of program to gdb.
Close the file descriptor of the deleted file through gdb session.
Redirect the program output to another file using gdb calls.
Examples
Suppose that PID of program is 19080 and file descriptor of deleted file is 2.
gdb attach 19080
ls -l /proc/19080/fd
gdb> p close(2)
$1 = 0
gdb> p fopen("/tmp/file", "w")
$2 = 20746416
(gdb) p fileno($2)
$3 = 7
gdb> quit
N.B.: If data of the deleted file is required, recover the deleted text file before closing the file handle:
cp -pv /proc/19080/fd/2 recovered_file.txt
Let's say I need to get the file descriptor of a file (or a directory) which has only execution (or search) permission.
The X/Open norm defines a O_SEARCH flag for the open() function. See http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
However, Linux doesn't. There are only 3 available flags (O_RDONLY, O_WRONLY and O_RDWR). See http://man7.org/linux/man-pages/man2/open.2.html
Why? And how can I get the fd of a directory with only search permission?
Thanks
It turns out Linux doesn't support, yet, this flag, as stated in W. Richard Stevens Stephen A. Rago's book "Advanced Programming in the UNIX Environment" which you can have a look at here Link to the book on google books
Actually, the flag is defined in POSIX, implemented in standard C library (which is in this case glibc, that's why you find it under man 3 open) but is not implemented in Linux kernel (thus not found under man 2 open).
EDIT 1 :
Since we use GNU under Linux, it includes specific headers for Linux to be able to make appropriate system calls that are feasable by Linux (in this case, it includes fcntl-linux.h in addition to fcntl.h).
EDIT 2 : Bug ticket
https://sourceware.org/bugzilla/show_bug.cgi?id=18228
Please, correct me if I'm wrong!
On Linux, you can obtain an fd for a directory that only has search permission using O_PATH. On other POSIX systems, you can fork a process and chdir to the directory; whenever you want to do openat relative to that directory, you can have the process perform open for you and send the fd to your main process (AF_UNIX and SCM_RIGHTS are a portable way of doing this).
Neither is strictly equivalent to O_SEARCH in the case where search permissions are revoked from the directory before access. POSIX guarantees that there will be no further permissions checks for an fd opened with O_SEARCH, but both O_PATH and chdir will check on every access.
If you look at open(3) (it looks like 3P in man pages, link) you should see that flag. I use ArchLinux updated at 2017-05-24.
EDIT 1: I edit the post to put a link to the screenshot so you can see the image, althoug I cannot use it in C.
If you want to look for into a directory, use opendir, readdir and the syscalls used for directory managing.
Why? And how can I get the fd of a directory with only search permission?
I don't know if that helps, but you can open read-only and look for the file you need, and then open that file with fopen in read-only mode.
I thought about a concurrency issue (in Solaris), what happen if while reading someone tries to delete the same file. I have a query regarding file existence in the Solaris/Linux. suppose I have a file test.txt, I have open it in vi editor, and then I have open a duplicate session and remove that file, but even after deleting that file I am able to read that file. so here are my questions:
Do I need to thinks about any locking mechanism while reading, so no one able to delete same file while reading.
What is the reason of showing different behavior from windows(like in windows if file is open in in some editor than we can not delete that file)
After removing that file, how I am still able to read that file, if I haven't closed file from vi editor.
I am asking files in general,but yes platform specific i.e. unix. what will happen if I am using a java program (buffer reader) for read file and file is deleted while reading, does buffer reader still able to read the file for next chunk or not?
You have basically 2 or 3 unrelated questions there. Text editors like to read the whole file into memory at the start of the editing session. Imagine every character you type being saved to disk immediately, with all characters after it in the file being rewritten one place further along to make room. That would be awful. Much better that the thing you're actually editing is a memory representation of the file (array of pointers to lines, probably with some metadata attached) which only gets converted back into a linear stream when you explicitly save.
Any relatively recent version of vim will notify you if the file you are editing is deleted from its original location with the message
E211: File "filename" no longer available
This warning is not just for unix. gvim on Windows will give it to you if you delete the file being edited. It serves as a reminder that you need to save the version you're working on before you exit, if you don't want the file to be gone.
(Note: the warning doesn't appear instantly - vim only checks for the original file's existence when you bring it back into the foreground after having switched away from it.)
So that's question 1, the behavior of text editors - there's no reason for them to keep the file open for the whole session because they aren't actually using it except at startup and during a save operation.
Question 2, why do some Windows editors keep the file open and locked - I don't know, Windows people are nuts.
Question 3, the one that's actually about unix, why do open files stay accessible after they're deleted - this is the most interesting one. The answer, guaranteed to shock you when presented directly:
There is no command, function, syscall, or any other method which actually requests deletion of a file.
Underlying rm and any other command that may appear to delete a file there is the system call unlink. And it's called unlink, not remove or deletefile or anything similar, because it doesn't remove a file. It removes a link (a.k.a. directory entry) which is an association between a file and a name in a directory. (Note: ANSI C added remove as a more generic function to appease non-unix people who had no intention of implementing unix filesystem semantics, but on unix, remove is just a rmdir if the target is a directory, and unlink for everything else.)
A file can have multiple links (see the ln command for how they are created), which means that the same file is known by multiple names. If you rm one of them, the others stick around and the file is not deleted. What happens when you remove the last link? Well, now you have a file with no name. But names are only one kind of reference to a file. There are at least 2 others: file descriptors and mmap regions. When the last reference to a file goes away, that's when the file is deleted.
Since references come in several forms, there are many kinds of events that can cause a file to be deleted. Here are some examples:
unlink (rm, etc.)
close file descriptor
dup2 (can implicitly closes a file descriptor before replacing it with a copy of a different file descriptor)
exec (can cause file descriptors to be closed via close-on-exec flag)
munmap (unmap memory region)
mmap (if you create a new memory map at an address that's already mapped, the old mapping is unmapped)
process death (which closes all file descriptors and unmaps all memory mappings of the process)
normal exit
fatal signal generated by the kernel (^C, segfault)
fatal signal sent from another process (kill)
I won't call that a complete list. And I don't encourage anyone to try to build a complete list. Just know that rm is "remove name", not "remove file", and files go away as soon as they're not in use.
If you want to destroy the contents of a file immediately, truncate it. All processes already using it will find that its size has suddenly become 0. (This is destruction as far as the normal file access methods are concerned. To destroy it more thoroughly so that even someone with raw disk access can't read what used to be there, you need to overwrite it. There's a tool called shred for that.)
I think your question has nothing to do with the difference between Windows/Linux. It's about how VI works.
when using VI to edit a file. VI will create a .swp file. And the .swp file is what you are actually editing. At the same time, if other users delete the original file will not effect your editing.
And when you type :w in VI, VI will use .swp file to overwrite the original file.
In OS level,how can it achieve knowing something's changed(like file changing)
e.g:
In node,we can monitor a file and perform some actions while it changes
fs.watch(file_path,function(){
//do something while the file's changed;
});
can someone give me a brief intuition/idea/keyword about how it really works
one I can come up is that while I hit :w in vim ,it somehow invoke some system *fake_save_file* function,and inside this *fake_save_file* function,it dispatch some events to somewhere else
You might know that the kernel indexes the files in file system as file descriptors. File watching is achieved by listening to changes to those file descriptors. In linux inotify does that.
Whenever you open, read, write/modify or move a file, the kernel issues operations upon the file descriptor. Inotify extends the filesystem by tracking these operations and showing them to you.
The example you gave is somewhat incorrect. The fake_save_file is created by your text editor vim to store the temporary changes made unless you the user actually saves it. When you save it with :w the editor replaces your actual_save_file with a copy of fake_save_file.
As a user you would be watching your actual_save_file. This gets changed when you enter :w in vim. You will be notified as vim modified its contents.
pyinotify is might be you want.please check it.