> Kaz Kylheku <
k...@kylheku.com> writes:
>> On 2014-06-05, Kenny McCormack <
gaz...@shell.xmission.com> wrote:
>>> % echo 'main() { printf("sizeof(int) = %d\\n",sizeof(int)); }' | gcc -xc - -o /dev/stdout | ./lgo
>>> fexecve: Permission denied
>
> [...]
>
>> A possible way would be to support mmap on a pipe. This is not inconceivable.
>> It would simply buffer the contents of the pipe from byte 0 as far as it
>> has been accessed, and map to virtual memory.
>
> Conceptually, a pipe is an unidirectional byte-stream and there is no
> way to execute a bytestream as there's always just 'the current byte',
This is true, but in addition to the current byte there is the historic
bytes that came before the current byte.
> all previous bytes are gone from the pipe and all future bytes are not
> yet accessible.
When you read a random access file using a 512 byte buffer, and lseek all over
the place between reads, all the 512 byte blocks you ever read before are also
gone.
Yet a memory mapping can integrate the pages that are touched and keep them
persistent.
> Granted, that's not how implementations usually work and
> pipes could be implemented on top of some kind of 'shared memory
> filesystem' providing regular files residing in kernel memory where a
All you need is to implement the mmap VFS method for pipes. As the data
is arriving, allocate pages for it and map them.
The restriction could be (or would have to be) imposed that the mapping must be
arranged prior to the first page being read.
Like say you've read 500 megs of data from a pipe and suddenly get the crazy
idea to mmap it. Of course, the 500 megs is gone. A pipe can't hoard all the
data just in case someone might mmap it. (Or, maybe it can: crazy idea #2: have
an O_MMAP_PIPE flag to request this, which can be passed into pipe2).
From the time a mmap is made, any data which lands into the mapped range
can be stashed away by the pipe, and incorporated to the mapping.
Alignment is an issue. Suppose you've read 41 bytes from a pipe. Do we say
that those bytes 0-40 are "water under the bridge", and the new mmap now
being requested aligns byte 41 on the start of a page?
It doesn't seem reasonable to enforce pager alignment based on absolute stream
position.
> writing application could copy 'all of the input data' into kernel
> memory atomically and the kernel could then do an execve once it sees an
> input EOF on the write descriptor but that would bascially mean that the
> kernel would provide an implicit 'temporary file' just to enable
> 'execution of pipes', a rather bizarre idea.
The exec does not have to block until an EOF is seen. Basically, the pipe
is mapped upfront. The exec format handler will touch some early part of the
mapping for the ELF header or whatever, and so it is blocked until those pages
are read from the pipe and integrated into the mapping. Then it will arrange
for users space to branch to some location in the executable, so again, that
has to block until enough of the executable is mapped to cover that page, and
so on. Something like that.
The pipe does not have to be read through to EOF, if some tail part of it is
never touched during execution.
I have a pretty clear idea on how this would work; except that it would
be the laughing stock of
kernel.org.