bofc manual pages




fo_fail - configures new point of failure to occur.  


#include "fo.h"

#define FO_NULL ((intptr_t)NULL)
void fo_fail(int function, int countdown, intptr_t ret, int errn);  


A little note, each time I say function will fail I mean that libfo will not call original function, but instead will return previously configured value. When libfo calls original function it still may fail - but on its own accord without help from libfo.

fo_fail(3) installs new point of failure causing function to fail in countdown calls with ret return value and errno set to errn.

functions is integer value representing function that should fail. List of functions is defined in generated fo.h file, and is in form fo_function. So if you want write() to fail, you'd pass fo_write as first argument.

countdown describes when function should fail. Each call to overridden function decrements countdown value, and if that value hits 0, then configured error is returned, otherwise original function is called. So if you pass 1, next call to function will fail, if you set 3, then third call will fail, and first and second call will call original function. If you set countdown to 0, then function will never fail. When countdown reaches 0 and function fails, then next calls will no longer fail until next fo_fail(3) is called.

ret is value that will be returned when function fails. You can pass here integer value (like "-1") or pointer (like &foo or NULL). If you pass pointer you need to cast it to intptr_t or else compiler might emit warnings. There is FO_NULL macro provided for convenience, which can be used to configure setpoint to return NULL pointer on errors. Note that fo_fail(3) does not have to necessarily be used to return error cases, it could be used for example to force fileno() to return specific file descriptor that is configured to trigger specific reaction. For that you would just set ret to positive value like "5".

When function fails errno variable will be set to errn value.  


Function will return 0 on success. -1 with errno will be returned upon error.  


countdown is less than 0.
function number does not exist. This won't happen if you use fo_function enum values (which you really should anyway).


OK and FAIL are imaginary macros. OK means we expect function to finish with success, and with FAIL we expect function to return error.

    #include "fo.h"

    int main(void)

        /* first write() fails and no more */
        fo_fail(fo_write, 1, -1, EINVAL);
        FAIL(write(fd, buf, 2), EINVAL);
        OK(write(fd, buf, 2));
        OK(write(fd, buf, 2));

        /* third write() called shall fails */
        fo_fail(fo_write, 3, -1, ENOSYS);
        OK(write(fd, buf, 2));
        OK(write(fd, buf, 2));
        FAIL(write(fd, buf, 2), ENOSYS);
        OK(write(fd, buf, 2));

        /* emulate no memory error from strdup */
        fo_fail(fo_strdup, 1, FO_NULL, ENOMEM);
        FAIL((s1 = strdup(s2)), ENOMEM);

        /* make fileno() to return preconfigured fd */
        fo_fail(fo_fileno, 1, 3, 0);
        /* fileno() will succed and return 3 */
        OK(fd = fileno(f));

        /* fail custom function from custom lib */
        mt_fail(fo_libcustom_foo, 1, -1, ENOENT);
        FAIL(libcustom_foo(), ENOENT);

        return 0;


fogen(1), fo_init(3), libfo(7).

7 November 2019 (v0.2.1)