MINHERIT(2)

πŸ’– MINHERIT(2) πŸ’–

ok bestie so you know how the manual calls this thing MINHERIT(2) and files it under the System Calls Manual? yeah. that's us. let's get into it πŸ¦‹


✨ NAME ✨

minherit β€” literally just controlling the inheritance of pages πŸ’…


πŸŽ€ LIBRARY πŸŽ€

Standard C Library (libc, -lc)


🌸 SYNOPSIS 🌸

#include <sys/mman.h>

int
minherit(void *addr, size_t len, int inherit);

✨ DESCRIPTION ✨

ok so the minherit() system call changes the specified pages so they have the inheritance characteristic inherit. no cap. 🫢

here's the thing though β€” not all implementations will guarantee that the inheritance characteristic can be set on a page basis; the granularity of changes may be as large as an entire region 😭. FreeBSD is built different tho, it can adjust inheritance characteristics on a page basis. slay.

inheritance only effects children created by fork(). it has no effect on exec() β€” exec'd processes replace their address space entirely, so like, nothing to inherit, gone, bye πŸ’€. this system call also has no effect on the parent's address space (other than to potentially share the address space with its children).

ngl inheritance is a rather esoteric feature that's largely been superseded by the MAP_SHARED feature of mmap(). but bestie, it's still iconic for one thing: it is possible to use minherit() to share a block of memory between parent and child that has been mapped MAP_PRIVATE. that is, modifications made by parent or child are shared but the original underlying file is left untouched ✨. obsessed.

  • INHERIT_SHARE β€” this option causes the address space in question to be shared between parent and child πŸ’ž. it has no effect on how the original underlying backing store was mapped.
  • INHERIT_NONE β€” this option prevents the address space in question from being inherited at all 🚫. the address space will be unmapped in the child.
  • INHERIT_COPY β€” this option causes the child to inherit the address space as copy-on-write. and this option also has an unfortunate side effect of causing the parent address space to become copy-on-write when the parent forks 😭. if the original mapping was MAP_SHARED, it will no longer be shared in the parent after the parent forks and there is no way to get the previous shared-backing-store mapping without unmapping and remapping the address space in the parent. it's giving irreversible, fr fr.
  • INHERIT_ZERO β€” this option causes the address space in question to be mapped as new anonymous pages, which would be initialized to all zero bytes, in the child process 🌸.

πŸ’– RETURN VALUES πŸ’–

the minherit() function returns the value 0 if successful πŸŽ‰; otherwise the value -1 is returned and the global variable errno is set to indicate the error πŸ˜”.


🌈 ERRORS 🌈

the minherit() system call will fail if:

  • [EINVAL] β€” the virtual address range specified by the addr and len arguments is not valid πŸ™ˆ.
  • [EACCES] β€” the flags specified by the inherit argument were not valid for the pages specified by the addr and len arguments.

πŸ¦‹ SEE ALSO πŸ¦‹

fork(2), madvise(2), mincore(2), mprotect(2), msync(2), munmap(2), rfork(2)


πŸ‘‘ HISTORY πŸ‘‘

the minherit() system call first appeared in OpenBSD and then in FreeBSD 2.2 ⭐.

the INHERIT_ZERO support first appeared in OpenBSD 5.6 and then in FreeBSD 12.0 🌟.


πŸ’€ BUGS πŸ’€

once you set inheritance to MAP_PRIVATE or MAP_SHARED, there is no way to recover the original copy-on-write semantics short of unmapping and remapping the area 😭. periodt. no undo button bestie.


and that's the whole page β€” this cutie came out of Debian, dated March 15, 2017, and it lives in the System Calls Manual πŸŽ€βœ¨

πŸ“¦ where this page comes from