Write-only mapping a O_WRONLY opened file supposed to work?
The IEEE Std 1003.1, 2004 Edition (POSIX.1 2004) appears to forbid it.
An implementation may permit accesses other than those specified by
prot
; however, if the Memory Protection option is supported, the implementation shall not permit a write to succeed wherePROT_WRITE
has not been set or shall not permit any access wherePROT_NONE
alone has been set. The implementation shall support at least the following values ofprot
:PROT_NONE
,PROT_READ
,PROT_WRITE
, and the bitwise-inclusive OR ofPROT_READ
andPROT_WRITE
. If the Memory Protection option is not supported, the result of any access that conflicts with the specified protection is undefined. The file descriptorfildes
shall have been opened with read permission, regardless of the protection options specified. IfPROT_WRITE
is specified, the application shall ensure that it has opened the file descriptorfildes
with write permission unlessMAP_PRIVATE
is specified in theflags
parameter as described below.
(emphasis added)
Also, on x86, it is not possible to have write-only memory, and this is a limitation of the page table entries. Pages may be marked read-only or read-write and independently may be executable or non-executable, but cannot be write-only. Moreover the man-page for mprotect()
says:
Whether
PROT_EXEC
has any effect different fromPROT_READ
is architecture- and kernel version-dependent. On some hardware architectures (e.g., i386),PROT_WRITE
impliesPROT_READ
.
This being the case, you've opened a file descriptor without read access, but mmap()
would be bypassing the O_WRONLY
by giving you PROT_READ
rights. Instead, it will refuse outright with EACCESS
.
How to open (read-write) or create a file with truncation allowed?
According to OpenGroup:
O_TRUNC
If the file exists and is a regular file, and the file is successfully
opened O_RDWR or O_WRONLY, its length is truncated to 0 and the mode
and owner are unchanged. It will have no effect on FIFO special files
or terminal device files. Its effect on other file types is
implementation-dependent. The result of using O_TRUNC with O_RDONLY is
undefined.
So, O_TRUNC is probably passed when opening a file with "w" or "w+". This gives "truncation" a different meaning, not what I want.
With python the solution seems to open file at low-level I/O with os.open()
function.
The following python function:
def touchopen(filename, *args, **kwargs):
# Open the file in R/W and create if it doesn't exist. *Don't* pass O_TRUNC
fd = os.open(filename, os.O_RDWR | os.O_CREAT)
# Encapsulate the low-level file descriptor in a python file object
return os.fdopen(fd, *args, **kwargs)
has the behavior I wanted. You can use it like this (it's in fact my use case):
# Open an existing file or create if it doesn't exist
with touchopen("./tool.run", "r+") as doing_fd:
# Acquire a non-blocking exclusive lock
fcntl.lockf(doing_fd, fcntl.LOCK_EX)
# Read a previous value if present
previous_value = doing_fd.read()
print previous_value
# Write the new value and truncate
doing_fd.seek(0)
doing_fd.write("new value")
doing_fd.truncate()
Android Studio file mapping problem, not recognize files
It happens because of wrong File Encoding and you can see my answer about it in here.
Solution: The solution will be reinstalling Android Studio or, go to:
File -> Other Settings -> Default Settings
, find File Encodings, change Project Encoding
to System-Default
or UTF-8
format.
mmap: will the mapped file be loaded into memory immediately?
No, yes, maybe. It depends.
Calling mmap
generally only means that to your application, the mapped file's contents are mapped to its address space as if the file was loaded there. Or, as if the file really existed in memory, as if they were one and the same (which includes changes being written back to disk, assuming you have write access).
No more, no less. It has no notion of loading something, nor does the application know what this means.
An application does not truly have knowledge of any such thing as memory, although the virtual memory system makes it appear like that. The memory that an application can "see" (and access) may or may not correspond to actual physical memory, and this can in principle change at any time, without prior warning, and without an obvious reason (obvious to your application).
Other than possibly experiencing a small delay due to a page fault, an application is (in principle) entirely unaware of any such thing happening and has little or no control over it1.
Applications will, generally, load pages from mapped files (including the main executable!) on demand, as a consequence of encountering a fault. However, an operating system will usually try to speculatively prefetch data to optimize performance.
In practice, calling mmap
will immediately begin to (asynchronously) prefetch pages from the beginning of the mapping, up to a certain implementation-specified size. Which means, in principle, for small files the answer would be "yes", and for larger files it would be "no".
However, mmap
does not block to wait for completion of the readahead, which means that you have no guarantee that any of the file is in RAM immediately after mmap
returns (not that you have that guarantee at any time anyway!). Insofar, the answer is "maybe".
Under Linux, last time I looked, the default prefetch size was 31 blocks (~127k) -- but this may have changed, plus it's a tuneable parameter. As pages near or at the end of the prefetched area are touched, more pages are being prefetched asynchronously.
If you have hinted MADV_RANDOM
to madvise
, prefetching is "less likely to happen", under Linux this completely disables prefetch.
On the other hand, giving the MADV_SEQUENTIAL
hint will asynchronously prefetch "more aggressively" beginning from the beginning of the mapping (and may discard accessed pages quicker). Under Linux, "more aggressively" means twice the normal amount.
Giving the MADV_WILLNEED
hint suggests (but does not guarantee) that all pages in the given range are loaded as soon as possible (since you're saying you're going to access them). The OS may ignore this, but under Linux, it is treated rather as an order than a hint, up to the process' maximum RSS limit, and an implementation-specified limit (if I remember correctly, 1/2 the amount of physical RAM).
Note that MADV_DONTNEED
is arguably implemented wrongly under Linux. The hint is not interpreted in the way specified by POSIX, i.e. you're OK with pages being paged out for the moment, but rather that you mean to discard them. Which makes no big difference for readonly mapped pages (other than a small delay, which you said would be OK), but it sure does matter for everything else.
In particular, using MADV_DONTNEED
thinking Linux will release unneeded pages after the OS has written them lazily to disk is not how things work! You must explicitly sync, or prepare for a surprise.
Having called readahead
on the file descriptor prior to calling mmap
(or alternatively, having had read/written the file previously), the file's contents will in practice indeed be in RAM immediately.
This is, however, only an implementation detail (unified virtual memory system), and subject to memory pressure on the system.
Calling mlock
will -- assuming it succeeds2 -- immediately load the requested pages into RAM. It blocks until all pages are physically present, and you have the guarantee that the pages will stay in RAM until you unlock them.
1 There exist functionality to query (
mincore
) whether any or all of the pages in a particular range are actually present at the very moment, and functionality to hint the OS about what you would like to see happening without any hard guarantees (madvise
), and finally functionality to force a limited subset of pages to be present in memory (mlock
) for privilegued processes.2 It might not, both for lack of privilegues and for exceeding quotas or the amount of physical RAM present.
Sorting file using system and library functions
I put fseek(file, 0, SEEK_CUR);
after every fread()
and fwrite()
functions and that worked for me. I don't know why.
Related Topics
Why Using Pipe for Sort (Linux Command) Is Slow
Save and Restore Terminal Content
Find the Ip Address of the Client in an Ssh Session
Readelf VS. Objdump: Why Are Both Needed
How to Remove the Win10's Path from Wsl
What Is the *Nix Command to View a User's Default Login Shell
Is There an Acceptable Linux Targeted Gui Client for Git-Svn
Linux - Save Only Recent 10 Folders and Delete The Rest
Difference Between Retq and Ret
How to Pass Command Line Parameters from a File
Oracle:Io Exception: the Network Adapter Could Not Establish the Connection
How to Get the List of Dependent Child Images in Docker
Remove Odd or Even Lines from a Text File
Iterate Over Lines Instead of Words in a for Loop of Shell Script
Rm: Cannot Remove: Permission Denied