Technische Universität Braunschweig
  • Study & Teaching
    • Beginning your Studies
      • Prospective Students
      • Degree Programmes
      • Application
      • Fit4TU
      • Why Braunschweig?
    • During your Studies
      • Fresher's Hub
      • Term Dates
      • Courses
      • Practical Information
      • Beratungsnavi
      • Additional Qualifications
      • Financing and Costs
      • Special Circumstances
      • Health and Well-being
      • Campus life
    • At the End of your Studies
      • Discontinuation and Credentials Certification
      • After graduation
      • Alumni*ae
    • For Teaching Staff
      • Strategy, Offers and Information
      • Learning Management System Stud.IP
    • Contact
      • Study Service Centre
      • Academic Advice Service
      • Student Office
      • Career Service
  • Research
    • Research Profile
      • Core Research Areas
      • Clusters of Excellence at TU Braunschweig
      • Research Projects
      • Research Centres
      • Professors‘ Research Profiles
    • Early Career Researchers
      • Support in the early stages of an academic career
      • PhD-Students
      • Postdocs
      • Junior research group leaders
      • Junior Professorship and Tenure-Track
      • Habilitation
      • Service Offers for Scientists
    • Research Data & Transparency
      • Transparency in Research
      • Research Data
      • Open Access Strategy
      • Digital Research Announcement
    • Research Funding
      • Research Funding Network
      • Research funding
    • Contact
      • Research Services
      • Academy for Graduates
  • International
    • International Students
      • Why Braunschweig?
      • Degree seeking students
      • Exchange Studies
      • TU Braunschweig Summer School
      • Refugees
      • International Student Support
    • Going Abroad
      • Studying abroad
      • Internships abroad
      • Teaching and research abroad
      • Working abroad
    • International Researchers
      • Welcome Support
      • PhD Studies
      • Service for host institutes
    • Language and intercultural competence training
      • Learning German
      • Learning Foreign Languages
      • Intercultural Communication
    • International Profile
      • Internationalisation
      • International Cooperations
      • Strategic Partnerships
      • International networks
    • International House
      • About us
      • Contact & Office Hours
      • News and Events
      • International Days
      • 5th Student Conference: Internationalisation of Higher Education
      • Newsletter, Podcast & Videos
      • Job Advertisements
  • TU Braunschweig
    • Our Profile
      • Aims & Values
      • Regulations and Guidelines
      • Alliances & Partners
      • The University Development Initiative 2030
      • Foundation University
      • Facts & Figures
      • Our History
    • Career
      • Working at TU Braunschweig
      • Vacancies
    • Economy & Business
      • Entrepreneurship
      • Friends & Supporters
    • General Public
      • Check-in for Students
      • The Student House
      • Access to the University Library
    • Media Services
      • Communications and Press Service
      • Services for media
      • Film and photo permits
      • Advices for scientists
      • Topics and stories
    • Contact
      • General Contact
      • Getting here
  • Organisation
    • Presidency & Administration
      • Executive Board
      • Designated Offices
      • Administration
      • Committees
    • Faculties
      • Carl-Friedrich-Gauß-Fakultät
      • Faculty of Life Sciences
      • Faculty of Architecture, Civil Engineering and Environmental Sciences
      • Faculty of Mechanical Engineering
      • Faculty of Electrical Engineering, Information Technology, Physics
      • Faculty of Humanities and Education
    • Institutes
      • Institutes from A to Z
    • Facilities
      • University Library
      • Gauß-IT-Zentrum
      • Professional and Personnel Development
      • International House
      • The Project House of the TU Braunschweig
      • Transfer Service
      • University Sports Center
      • Facilities from A to Z
    • Equal Opportunity Office
      • Equal Opportunity Office
      • Family
      • Diversity for Students
  • Search
  • Quicklinks
    • People Search
    • Webmail
    • cloud.TU Braunschweig
    • Messenger
    • Cafeteria
    • Courses
    • Stud.IP
    • Library Catalogue
    • IT Services
    • Information Portal (employees)
    • Link Collection
    • DE
    • EN
    • IBR YouTube
    • Facebook
    • Instagram
    • YouTube
    • LinkedIn
    • Mastodon
Menu
  • Organisation
  • Faculties
  • Carl-Friedrich-Gauß-Fakultät
  • Institutes
  • Institute of Operating Systems and Computer Networks
  • Prof. Dr.-Ing. Christian Dietrich
  • Advent(2)
  • Santa's Postbox
Logo IBR
IBR Login
  • Institute of Operating Systems and Computer Networks
    • News
    • About us
      • Whole Team
      • Directions
      • Floor Plan
      • Projects
      • Publications
      • Software
      • News Archive
    • Connected and Mobile Systems
      • Team
      • Courses
      • Theses
      • Projects
      • Publications
      • Software
      • Datasets
    • Reliable System Software
      • Overview
      • Team
      • Teaching
      • Theses & Jobs
      • Research
      • Publications
    • Algorithms
      • Team
      • Courses
      • Theses
      • Projects
      • Publications
    • Microprocessor Lab
    • Education
      • Winter 2025/2026
      • Summer 2025
      • Theses
    • Services
      • Library
      • Mailinglists
      • Webmail
      • Knowledge Base
      • Wiki
      • Account Management
      • Services Status
    • Spin-Offs
      • Docoloc
      • bliq (formerly AIPARK)
      • Confidential Technologies
    • Research Cooperations
      • IST.hub
  • Task Overview
  • Git repository
  • Mailing list
  • Matrix-Channel

Santa's Postbox

☃️
Git-Repository: Template Solution Solution-Diff (Solution is posted at 18:00 CET)
Workload: 74 lines of code
Important System-Calls: fifo(7), unix(7), mknod(2)
Recommended Reads:
  • Dec. 7: Select a Gift file 110 lines [select(2)]
  • Dec. 10: Pipes Full of Gravy ipc 131 lines [epoll_create(2), epoll_ctl(2), epoll_wait(2), pipe(7), splice(2)]
Illustration for this exercsie

In the last days, the ELFs were quite busy optimizing the gift pipeline and did not have the time to do their yearly maintenance run on Santa's permanent infrastructure. Now, halfway through the Advent, the issue became quite pressing and an ELF started to walk around the site, inspecting the installations, whereby the catastrophe became clear: Santa's postbox, made from quite durable northern pine, has rotten away to an unidentifiable pile of wood dust. Therefore, it was decided to build a new postbox for Santa that also provides all kind of digital interfaces for all those children who would rather like to provide their wishlist with write() instead of drawing some pictures. As the postbox should be rather versatile, it was decided to work two days on the postbox.

Today and tomorrow, we will talk about inter-process communication (IPC): How can we pass data between processes and/or we signal new messages to the other process. In our scenario, our postbox is a single-threaded server (with epoll) that accepts data on different communication channels. While we provide you with the epoll-based framework (postbox.c), it is your task to implement the specific channels. Today, we will start with (named) FIFOs and Unix domain sockets.

FIFO

In the epoll exercise we already talked a little bit about pipe(7)s as we used them there to communicate data between processes. There, we created pipe pairs with pipe(2) and gave one end to our filter processes and kept the other end for reading or writing with splice(2). Of course for our postbox scenario, we miss this control instance that creates a pipe pair and gives the write end to our client (the child) and the read end to us (the postbox). Somehow, we have to use a different rendezvous mechanism where child and postbox meet, and that is where named pipes or fifo(7) come in handy.

Named pipes are a special kind of files that have a name but no content. Virtually, each FIFO is backed by an pipe pair and we get the read end if we open the FIFO with O_RDONLY and the write end if we ask for O_WRONLY. As named pipes are files after all, they also have permissions, which are checked when calling open(). So, in the end, we use the file system and its capability to provide a hierarchical, privilege-checked namespace as an rendezvous place for processes that want to connect to each other via pipes. Isn't that cool? We have pipes as unidirectional connection between processes and just by hooking them into the file system, we created a powerful IPC pattern. And even better, as pipes are also used to stream between processes and files (think: cat .. | grep ... > foo), we can send messages by simply echoing into the FIFO:

echo 1 > fifo-file

However, there is a downside: each named pipe has exactly one pipe pair, whereby only a single parallel connection is possible. Furthermore, when the client (the echo from above) closes its write end, the read end is also closed. While the first problem cannot be fixed, you have to reopen the FIFO again when your read() returns zero.

To create a FIFO, we could use the library function mkfifo(3), however, we have started Advent(2) to not use the C library but to use the naked syscall interface. So how is mkfifo() implemented? Let's take a look at the musl C library [musl: src/stat/mkfifo.c]:

int mkfifo(const char *path, mode_t mode) {
    return mknod(path, mode | S_IFIFO, 0);
}

On Linux, mkfifo is just a thin wrapper around the generic mknod(2) function, which can be used to create all kinds of nodes in the file system. With mknod(), we cannot only create FIFOs, but also regular files, character-device files, block-device files, and others. And why not? Creating a node, no matter how special it is, should be possible with the same system call.

Unix Domain Sockets

To overcome the one-connection limitation of named pipes, we also want to provide a second access path to our postbox with unix(7) domain sockets. As you might know socket(7)s are the way UNIX handles network connections; both, on the server and on the client. Most commonly, sockets are used for TCP (or UDP) connections, where server and client rendezvous via IP addresses and port numbers to establish a bidirectional connection. However, similar to named pipes, Unix provides a mean to rendezvous sockets via the file system with UNIX domain sockets. By the way, analogous to pipe(), the socketpair(2) system call allows us to create an anonymous socket pair on the local machine.

While we could use mknod() to create a Unix domain socket, we better use the usual socket(2)-bind(2)-listen(2)-accept(2) dance to accept connections to our postbox. Thereby, we create two sockets: one for listening and a derived one once we call accept (which also has to be added to epoll).

The really nice thing about Unix domain sockets is that we can apply the well-known file-based access control (chmod(2), acl(5)) on local connections. This is a vast benefit over "network" connection on localhost (127.0.0.1), where the server has not really an idea who its client is.

To talk directly from the console with an domain socket, you can use netcat(1):

Task

Complete the FIFO and the Unix domain socket connection module for our postbox. For FIFO, you have to implement fifo_prepare(), which is called once, and fifo_handle(), which is called if new data arrives on the FIFO. For domain sockets, domain_prepare() initializes the socket and the framework invokes domain_accept() on new connections, where you also have to register the client socket with epoll_add(). In epoll_recv(), you implement the data and connection handling for domain sockets. After today, the solution produces the following output, if messages are received on both channels:

Santas Postbox is open! Send your requests ...
... by fifo:   echo 1 > fifo
... by socket: echo 2 | nc -U socket
... by signal: /bin/kill -USR1 -q 3 781565 
... by mq_send: ./mq_send 4 (see also `cat /dev/mqueue/postbox`)
fifo: 1
socket[pid=781581,uid=10104,gid=10150]: 2

Hints

  • You can use unlink(2) to remove the fifo/socket file, before recreating it.
  • getsockopt(2) with SO_PEERCRED (see unix(7)) allows you identify your client process on an domain socket.
  • Learn about abstract socket addresses of UNIX domain sockets to explain, where a client connects to when it is using the address: sun_path = "\0foobar\0". Explore your system and the listening abstract sockets with ss -l 'src = unix:@*'.

Last modified: 2023-12-01 15:52:28.084420, Last author: , Permalink: /p/advent-12-postbox


last changed 2023-12-01, 15:52 by Prof. Dr.-Ing. Christian Dietrich

For All Visitors

Vacancies of TU Braunschweig
Career Service' Job Exchange 
Merchandising

For Students

Term Dates
Courses
Degree Programmes
Information for Freshman
TUCard

Internal Tools

Glossary (GER-EN)
Change your Personal Data

Contact

Technische Universität Braunschweig
Universitätsplatz 2
38106 Braunschweig

P. O. Box: 38092 Braunschweig
GERMANY

Phone: +49 (0) 531 391-0

Getting here

© Technische Universität Braunschweig
Imprint Privacy Accessibility