Why do I 'love' FreeBSD?

Tagged:  

Not only because of its the ugliest mbuf structure and the design of the network packet processing. I did not work with *bsd kernels more than 4 years already and very happy this horror was finished not even seriously started.

But even its userspace part is ugly. Let's see how Solaris and Linux implemented <code>sendfile()</code> call (although Solaris put it into special <code>libsendfile.so</code> library) compared to FreeBSD one:#ifdef HAVE_SENDFILE4_SUPPORT&#10;#include &lt;sys/sendfile.h&gt;&#10;int dnet_sendfile(struct dnet_net_state *st, int fd, off_t *offset, size_t size)&#10;{&#10;       int err;&#10;   &#10;   err = sendfile(st-&gt;s, fd, offset, size);&#10;        if (err &lt; 0)&#10;            return -errno;&#10;&#10;        return err;&#10;}&#10;#elif HAVE_SENDFILE7_SUPPORT&#10;#include &lt;sys/uio.h&gt;&#10;int dnet_sendfile(struct dnet_net_state *st, int fd, off_t *offset, size_t size)&#10;{&#10;       int err;&#10;   err = sendfile(fd, st-&gt;s, *offset, size, NULL, &amp;size, 0);&#10;   if (err &amp;&amp; errno != EAGAIN)&#10;                return -errno;&#10;&#10;        if (size) {&#10;                *offset += size;&#10;           return size;&#10;       }&#10;&#10;     return -EAGAIN;&#10;}&#10;#else&#10;#error &quot;Your platform does not support sendfile. Sorry.&quot;&#10;#endif

As you might expect the latter part of the compat layer is for FreeBSD - 7 arguments for the syscall (forget about registers), and weird return values: it may be zero, positive number of bytes and negative error. And <code>EAGAIN</code> mess. What prevented it from following Solaris way of having simple and vectorized sendfiles remains a riddle.

And that's my 'simple' m4 autoconf script to detect the proper sendfile usage.&#10;AC_DEFUN([AC_CHECK_SENDFILE],[&#10;AC_MSG_CHECKING([whether sendfile() is supported and what prototype it has])&#10;&#10;AC_CACHE_VAL([ac_sendfile4_supported],[&#10;      AC_TRY_LINK([#include &lt;sys/sendfile.h&gt;&#10;                       #include &lt;stdio.h&gt;],&#10;         [sendfile(1, 1, NULL, 0);],&#10;                [&#10;                  ac_sendfile4_supported=yes&#10;                 ac_sendfile_supported=yes&#10;                  AC_MSG_RESULT([usual Linux/Solaris sendfile()])&#10;            ],&#10;         [&#10;                  dnl Checking wether we need libsendfile&#10;                    dnl Presumably on Solaris&#10;                  AC_CHECK_LIB(sendfile, sendfile,&#10;                           [&#10;                                  ac_sendfile4_supported=yes&#10;                                 ac_sendfile_supported=yes&#10;                                  SENDFILE_LIBS=&quot;-lsendfile&quot;&#10;                                       AC_SUBST(SENDFILE_LIBS)&#10;                            ],&#10;                         [ac_sendfile_supported=no])&#10;                ])&#10;])&#10;if test x$ac_sendfile_supported = xno; then&#10;  AC_CACHE_VAL([ac_sendfile7_supported],[&#10;            AC_TRY_LINK([#include &lt;sys/socket.h&gt;&#10;                         #include &lt;stdio.h&gt;],&#10;                 [sendfile(1, 1, 0, 0, NULL, NULL, 0);],&#10;                    [&#10;                          ac_sendfile7_supported=yes&#10;                         ac_sendfile_supported=yes&#10;                          AC_MSG_RESULT([ugly FreeBSD sendfile()])&#10;                   ],&#10;                 [ac_sendfile_supported=no])&#10;        ])&#10;fi&#10;if test x$ac_sendfile_supported = xno; then&#10;  AC_MSG_ERROR([no sendfile support])&#10;fi&#10;if test x$ac_sendfile4_supported = xyes; then&#10;       AC_DEFINE(HAVE_SENDFILE4_SUPPORT, 1, [Define this if Linux/Solaris sendfile() is supported])&#10;fi&#10;if test x$ac_sendfile7_supported = xyes; then&#10;      AC_DEFINE(HAVE_SENDFILE7_SUPPORT, 1, [Define this if FreeBSD sendfile() is supported])&#10;fi&#10;])

I'm slowly starting to like autotools - although my project is about 5 thousands of lines and only generated <code>configure</code> script is about 5 times bigger, it is still simple and somewhat clear (although limited sometimes).

<a href="/projects/elliptics">Elliptics</a> network got full FreeBSD support and I even used it slightly to catch some bugs (mostly because of its <code>sendfile()</code> support). Project also got log events mask, compile-time ID size changes (<code>--with-id-size=$bytes</code> switch) and lots of other smaller bits (especially in the automatic configuration).

Tomorrow (if things will be completed before running out climbing) I will implement the testing tool described and start the process. Do you expect a failure? :)

looks like you never wrote a reasonable large portion of code that's supposed to be portable between say linux 2.4 and 2.6. freebsd 7 is years ahead of 4. not that i love freebsd tho.

Никак не могу заставить себя разобраться с autotools. Это настолько неприятная система, что к ней не хочется даже притрагиваться.

With newer autoconf versions (I think 2.62 and later), the autoconf code there is going to throw a warning (and fail to work as expected): the cache value variables should have "_cv_" in them; also ac_* (and AC_* for macros) should be reserved for autoconf-proper macros so I'd suggest using dnet_cv_sendfile_foo for the variables.