7

Does Linux provide a system call which can create a "view" of a limited byte range of a backing file? I'm envisioning something that for example would act on an open file descriptor and either modify it or generate a new file descriptor where file offsets are relative to the beginning of the range and end at the end of the range.

The use-case would be to limit a non-cooperating subprocess to accessing only a particular portion of an input file.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
llasram
  • 173
  • 4
  • See also [Create a virtual file that is actually a command](https://unix.stackexchange.com/questions/66990/create-a-virtual-file-that-is-actually-a-command) – Gilles 'SO- stop being evil' Feb 27 '19 at 18:24
  • @Gilles I was avoiding a pipe (named or otherwise) because I wanted to avoid the extra copy of data through userspace, and thought I'd need the subprocess to seek arbitrarily in its constrained input. But now that you've mentioned it, a pipe plus the `splice()` system call seems like it would be nearly right for the stream case. – llasram Feb 27 '19 at 20:26
  • 1
    While the accepted answer works, it's not really a "system call" as the question asked. For system calls, the `mmap()` call comes to mind, as long as the subprocess is spawned from the process that does the mapping... – twalberg Feb 27 '19 at 21:20
  • See also mandatory file locking where you could lock a region of the file so that process could not read or write it. – Stéphane Chazelas Feb 27 '19 at 23:27

1 Answers1

12

One way of doing this is to use a loop device. This approach does have two requirements which may make it less useful: you need to be root to set it up, and the non-cooperating subprocess must be able to write to a block device. Oh, and it doesn’t deal with conflicting changes.

To set the loop device up, run

losetup -o 1024 --sizelimit 2048 --show -f yourfile

replacing 1024, 2048 and yourfile with appropriate values — -o specifies the start offset, --sizelimit the size (counting from the offset). Note that sizelimit has to be a multiple of 512.

This will output the name of the loop device which has been set up; adjust the permissions as necessary, and give it to your non-cooperating sub-process. When you no longer need the device, delete it with

losetup -d /dev/loopN

replacing N as appropriate.

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
  • Hmm, what do you mean with conflicting changes? Do you mean writes that come through the loop device not being in sync with direct writes to the backing file? – ilkkachu Feb 27 '19 at 18:43
  • Not 100% what I wanted, but in the absence of anything closer I'll take it. Thanks! – llasram Feb 27 '19 at 19:32
  • @ilkkachu yes, I mean that there needs to be some “agreement” between the processes about who is allowed to write. (It can be simple enough — if the “parent” process doesn’t write while the loop device is set up for the non-cooperating subprocess, everything will be fine.) – Stephen Kitt Feb 27 '19 at 19:33
  • @llasram right, I know this isn’t perfect; the FIFO approach in Gilles’ link is interesting to look at too. – Stephen Kitt Feb 27 '19 at 19:34