From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-3.5 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, RP_MATCHES_RCVD,URIBL_BLOCKED shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: misc@80x24.org Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 96687633843; Fri, 30 Oct 2015 22:26:04 +0000 (UTC) Date: Fri, 30 Oct 2015 22:26:06 +0000 From: Eric Wong To: ruby-talk@ruby-lang.org Cc: misc@80x24.org Subject: how-to: inherit FDs w/o sd_listen_fds(3) in pure Ruby Message-ID: <20151030-inherit-fds-w-o-sd_listen_fds-in-pure@ruby> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline List-Id: Inevitably systemd is taking over; and socket activation is a great idea[1]. People writing daemons might want to take advantage of socket activation, regardless of whether they target systemd or not. Since maintaining C or FFI extensions can lead to portability and installation issues, I'd much rather use only standard features in Ruby. Anyways, I consider this snippet[2] too short to release as a gem: # see the sd_listen_fds(3) manpage for details sd_pid, sd_fds = ENV.values_at('LISTEN_PID', 'LISTEN_FDS') if sd_pid.to_i == $$ # n.b. $$ can never be zero # 3 = SD_LISTEN_FDS_START inherited = (3...(3 + sd_fds.to_i)).map { |fd| Socket.for_fd(fd) } end For non-systemd users, it is completely innocuous other than taking around 2K of RAM for the bytecode. It won't do anything if the environment variables are unset. This can conceivably work on any POSIX/Unix-like system; including ones not supported by systemd itself. You can see that even on non-systemd hosts, you can take advantage of using LISTEN_PID and LISTEN_FDS in the environment to share FDs for socket activation. You may choose to delete the LISTEN_PID/LISTEN_FDS variables from ENV after using them, but I prefer to leave them for debugging. Keep in mind old versions of the sd_listen_fds(3) manpage stated this: > This function is provided by the reference > implementation of APIs for new-style daemons and > distributed with the systemd package. The algorithm it > implements is simple, and can easily be reimplemented > in daemons if it is important to support this > interface without using the reference > implementation. But the systemd developers nowadays prefer people link to the shared library; which may not be easy or practical for scripting languages. CC0 / Public domain declaration: To the extent possible under law, Eric Wong has waived all copyright and related or neighboring rights to the contents of this message. If anybody actually wants this released as a gem, they can do it themselves; preferably without mentioning or crediting me at all. [1] Disclaimer: Do not consider this an endorsement of systemd. [2] Disclaimer #2: Any code snippet you use may eat your hard drive (or children). There is no warranty. P.S. You can probably link to this post via: http://mid.gmane.org/20151030-inherit-fds-w-o-sd_listen_fds-in-pure@ruby (or link via the Message-ID via any other mail archival service) P.P.S: Ruby 2.3 fixes a bug which prevented Ruby itself from testing this feature independently of systemd: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/70390