aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Łyszczek <michal.lyszczek@bofc.pl>2019-11-06 09:16:57 +0100
committerMichał Łyszczek <michal.lyszczek@bofc.pl>2019-11-06 09:21:48 +0100
commitfba5504d6162ee242d196508d87204e4a4a419ef (patch)
treea8389a6b2db339e7639f0c28c922899920e4059d
parenta48a2ad779284ccdb83815cce174f89c3a0f084d (diff)
downloadlibfo-fba5504d6162ee242d196508d87204e4a4a419ef.tar.gz
libfo-fba5504d6162ee242d196508d87204e4a4a419ef.tar.bz2
libfo-fba5504d6162ee242d196508d87204e4a4a419ef.zip
fogen: protect init from self overriden functions
if LIBFO_INIT_FILE is set, user overrides fgets() and installs failing point in fgets(), once we initialize failing point for fgets() our call to fgets() might fail by triggering failing point. This is because when fgets() is overriden, when we call fgets() we go via our overriden routing and not original one. This applies to all functions used in fo_init(). Signed-off-by: Michał Łyszczek <michal.lyszczek@bofc.pl>
-rw-r--r--Makefile2
-rw-r--r--db.conf8
-rw-r--r--fo.c.in330
-rwxr-xr-xfogen183
4 files changed, 366 insertions, 157 deletions
diff --git a/Makefile b/Makefile
index 49ac063..986ed33 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ RM ?= rm -f
all: libfo.so
fo.c:
- ./fogen
+ ./fogen -r.
fo.o: fo.c
gcc -fPIC -c fo.c -o fo.o
diff --git a/db.conf b/db.conf
index 3131caa..46033f1 100644
--- a/db.conf
+++ b/db.conf
@@ -24,12 +24,20 @@
headers, rtype, fname, args
# next lines are info about supported funcitons, leading spaces are striped
# so it can be used to increase readability
+stdio.h, int, fclose, FILE *
+stdio.h, int, feof, FILE *
stdio.h, char *, fgets, char *;int;FILE *
stdio.h, size_t, fread, void *;size_t;size_t;FILE *
stdio.h, size_t, fwrite, const void *;size_t;size_t;FILE *
stdio.h, int, rename, const char *;const char *
+stdlib.h, int, atoi, const char *
+stdlib.h, long, atol, const char *
+stdlib.h, long long, atoll, const char *
string.h, int, memcmp, const void *; const void *; size_t
+string.h, void *, memset, void *;int;size_t
+string.h, int, strcmp, const char *;const char *
string.h, char *, strcpy, char *;const char *
+string.h, char *, strerror, int
sys/socket.h, int, bind, int;const struct sockaddr *;socklen_t
sys/socket.h, int, getsockopt, int;int;int;void *;socklen_t *
sys/socket.h, ssize_t, recv, int;void *;size_t;int
diff --git a/fo.c.in b/fo.c.in
index 8da5a5d..532264a 100644
--- a/fo.c.in
+++ b/fo.c.in
@@ -78,142 +78,143 @@ static struct fo_info fo_info[fo_f_max];
static int errno_str_to_int
(
- const char *s
+ const char *s,
+ int (*real_strcmp)(const char *, const char *)
)
{
- if (strcmp(s, "EPERM") == 0) return EPERM;
- else if (strcmp(s, "ENOENT") == 0) return ENOENT;
- else if (strcmp(s, "ESRCH") == 0) return ESRCH;
- else if (strcmp(s, "EINTR") == 0) return EINTR;
- else if (strcmp(s, "EIO") == 0) return EIO;
- else if (strcmp(s, "ENXIO") == 0) return ENXIO;
- else if (strcmp(s, "E2BIG") == 0) return E2BIG;
- else if (strcmp(s, "ENOEXEC") == 0) return ENOEXEC;
- else if (strcmp(s, "EBADF") == 0) return EBADF;
- else if (strcmp(s, "ECHILD") == 0) return ECHILD;
- else if (strcmp(s, "EAGAIN") == 0) return EAGAIN;
- else if (strcmp(s, "ENOMEM") == 0) return ENOMEM;
- else if (strcmp(s, "EACCES") == 0) return EACCES;
- else if (strcmp(s, "EFAULT") == 0) return EFAULT;
- else if (strcmp(s, "ENOTBLK") == 0) return ENOTBLK;
- else if (strcmp(s, "EBUSY") == 0) return EBUSY;
- else if (strcmp(s, "EEXIST") == 0) return EEXIST;
- else if (strcmp(s, "EXDEV") == 0) return EXDEV;
- else if (strcmp(s, "ENODEV") == 0) return ENODEV;
- else if (strcmp(s, "ENOTDIR") == 0) return ENOTDIR;
- else if (strcmp(s, "EISDIR") == 0) return EISDIR;
- else if (strcmp(s, "EINVAL") == 0) return EINVAL;
- else if (strcmp(s, "ENFILE") == 0) return ENFILE;
- else if (strcmp(s, "EMFILE") == 0) return EMFILE;
- else if (strcmp(s, "ENOTTY") == 0) return ENOTTY;
- else if (strcmp(s, "ETXTBSY") == 0) return ETXTBSY;
- else if (strcmp(s, "EFBIG") == 0) return EFBIG;
- else if (strcmp(s, "ENOSPC") == 0) return ENOSPC;
- else if (strcmp(s, "ESPIPE") == 0) return ESPIPE;
- else if (strcmp(s, "EROFS") == 0) return EROFS;
- else if (strcmp(s, "EMLINK") == 0) return EMLINK;
- else if (strcmp(s, "EPIPE") == 0) return EPIPE;
- else if (strcmp(s, "EDOM") == 0) return EDOM;
- else if (strcmp(s, "ERANGE") == 0) return ERANGE;
- else if (strcmp(s, "EDEADLK") == 0) return EDEADLK;
- else if (strcmp(s, "ENAMETOOLONG") == 0) return ENAMETOOLONG;
- else if (strcmp(s, "ENOLCK") == 0) return ENOLCK;
- else if (strcmp(s, "ENOSYS") == 0) return ENOSYS;
- else if (strcmp(s, "ENOTEMPTY") == 0) return ENOTEMPTY;
- else if (strcmp(s, "ELOOP") == 0) return ELOOP;
- else if (strcmp(s, "EWOULDBLOCK") == 0) return EWOULDBLOCK;
- else if (strcmp(s, "ENOMSG") == 0) return ENOMSG;
- else if (strcmp(s, "EIDRM") == 0) return EIDRM;
- else if (strcmp(s, "ECHRNG") == 0) return ECHRNG;
- else if (strcmp(s, "EL2NSYNC") == 0) return EL2NSYNC;
- else if (strcmp(s, "EL3HLT") == 0) return EL3HLT;
- else if (strcmp(s, "EL3RST") == 0) return EL3RST;
- else if (strcmp(s, "ELNRNG") == 0) return ELNRNG;
- else if (strcmp(s, "EUNATCH") == 0) return EUNATCH;
- else if (strcmp(s, "ENOCSI") == 0) return ENOCSI;
- else if (strcmp(s, "EL2HLT") == 0) return EL2HLT;
- else if (strcmp(s, "EBADE") == 0) return EBADE;
- else if (strcmp(s, "EBADR") == 0) return EBADR;
- else if (strcmp(s, "EXFULL") == 0) return EXFULL;
- else if (strcmp(s, "ENOANO") == 0) return ENOANO;
- else if (strcmp(s, "EBADRQC") == 0) return EBADRQC;
- else if (strcmp(s, "EBADSLT") == 0) return EBADSLT;
- else if (strcmp(s, "EDEADLOCK") == 0) return EDEADLOCK;
- else if (strcmp(s, "EBFONT") == 0) return EBFONT;
- else if (strcmp(s, "ENOSTR") == 0) return ENOSTR;
- else if (strcmp(s, "ENODATA") == 0) return ENODATA;
- else if (strcmp(s, "ETIME") == 0) return ETIME;
- else if (strcmp(s, "ENOSR") == 0) return ENOSR;
- else if (strcmp(s, "ENONET") == 0) return ENONET;
- else if (strcmp(s, "ENOPKG") == 0) return ENOPKG;
- else if (strcmp(s, "EREMOTE") == 0) return EREMOTE;
- else if (strcmp(s, "ENOLINK") == 0) return ENOLINK;
- else if (strcmp(s, "EADV") == 0) return EADV;
- else if (strcmp(s, "ESRMNT") == 0) return ESRMNT;
- else if (strcmp(s, "ECOMM") == 0) return ECOMM;
- else if (strcmp(s, "EPROTO") == 0) return EPROTO;
- else if (strcmp(s, "EMULTIHOP") == 0) return EMULTIHOP;
- else if (strcmp(s, "EDOTDOT") == 0) return EDOTDOT;
- else if (strcmp(s, "EBADMSG") == 0) return EBADMSG;
- else if (strcmp(s, "EOVERFLOW") == 0) return EOVERFLOW;
- else if (strcmp(s, "ENOTUNIQ") == 0) return ENOTUNIQ;
- else if (strcmp(s, "EBADFD") == 0) return EBADFD;
- else if (strcmp(s, "EREMCHG") == 0) return EREMCHG;
- else if (strcmp(s, "ELIBACC") == 0) return ELIBACC;
- else if (strcmp(s, "ELIBBAD") == 0) return ELIBBAD;
- else if (strcmp(s, "ELIBSCN") == 0) return ELIBSCN;
- else if (strcmp(s, "ELIBMAX") == 0) return ELIBMAX;
- else if (strcmp(s, "ELIBEXEC") == 0) return ELIBEXEC;
- else if (strcmp(s, "EILSEQ") == 0) return EILSEQ;
- else if (strcmp(s, "ERESTART") == 0) return ERESTART;
- else if (strcmp(s, "ESTRPIPE") == 0) return ESTRPIPE;
- else if (strcmp(s, "EUSERS") == 0) return EUSERS;
- else if (strcmp(s, "ENOTSOCK") == 0) return ENOTSOCK;
- else if (strcmp(s, "EDESTADDRREQ") == 0) return EDESTADDRREQ;
- else if (strcmp(s, "EMSGSIZE") == 0) return EMSGSIZE;
- else if (strcmp(s, "EPROTOTYPE") == 0) return EPROTOTYPE;
- else if (strcmp(s, "ENOPROTOOPT") == 0) return ENOPROTOOPT;
- else if (strcmp(s, "EPROTONOSUPPORT") == 0) return EPROTONOSUPPORT;
- else if (strcmp(s, "ESOCKTNOSUPPORT") == 0) return ESOCKTNOSUPPORT;
- else if (strcmp(s, "EOPNOTSUPP") == 0) return EOPNOTSUPP;
- else if (strcmp(s, "EPFNOSUPPORT") == 0) return EPFNOSUPPORT;
- else if (strcmp(s, "EAFNOSUPPORT") == 0) return EAFNOSUPPORT;
- else if (strcmp(s, "EADDRINUSE") == 0) return EADDRINUSE;
- else if (strcmp(s, "EADDRNOTAVAIL") == 0) return EADDRNOTAVAIL;
- else if (strcmp(s, "ENETDOWN") == 0) return ENETDOWN;
- else if (strcmp(s, "ENETUNREACH") == 0) return ENETUNREACH;
- else if (strcmp(s, "ENETRESET") == 0) return ENETRESET;
- else if (strcmp(s, "ECONNABORTED") == 0) return ECONNABORTED;
- else if (strcmp(s, "ECONNRESET") == 0) return ECONNRESET;
- else if (strcmp(s, "ENOBUFS") == 0) return ENOBUFS;
- else if (strcmp(s, "EISCONN") == 0) return EISCONN;
- else if (strcmp(s, "ENOTCONN") == 0) return ENOTCONN;
- else if (strcmp(s, "ESHUTDOWN") == 0) return ESHUTDOWN;
- else if (strcmp(s, "ETOOMANYREFS") == 0) return ETOOMANYREFS;
- else if (strcmp(s, "ETIMEDOUT") == 0) return ETIMEDOUT;
- else if (strcmp(s, "ECONNREFUSED") == 0) return ECONNREFUSED;
- else if (strcmp(s, "EHOSTDOWN") == 0) return EHOSTDOWN;
- else if (strcmp(s, "EHOSTUNREACH") == 0) return EHOSTUNREACH;
- else if (strcmp(s, "EALREADY") == 0) return EALREADY;
- else if (strcmp(s, "EINPROGRESS") == 0) return EINPROGRESS;
- else if (strcmp(s, "ESTALE") == 0) return ESTALE;
- else if (strcmp(s, "EUCLEAN") == 0) return EUCLEAN;
- else if (strcmp(s, "ENOTNAM") == 0) return ENOTNAM;
- else if (strcmp(s, "ENAVAIL") == 0) return ENAVAIL;
- else if (strcmp(s, "EISNAM") == 0) return EISNAM;
- else if (strcmp(s, "EREMOTEIO") == 0) return EREMOTEIO;
- else if (strcmp(s, "EDQUOT") == 0) return EDQUOT;
- else if (strcmp(s, "ENOMEDIUM") == 0) return ENOMEDIUM;
- else if (strcmp(s, "EMEDIUMTYPE") == 0) return EMEDIUMTYPE;
- else if (strcmp(s, "ECANCELED") == 0) return ECANCELED;
- else if (strcmp(s, "ENOKEY") == 0) return ENOKEY;
- else if (strcmp(s, "EKEYEXPIRED") == 0) return EKEYEXPIRED;
- else if (strcmp(s, "EKEYREVOKED") == 0) return EKEYREVOKED;
- else if (strcmp(s, "EKEYREJECTED") == 0) return EKEYREJECTED;
- else if (strcmp(s, "EOWNERDEAD") == 0) return EOWNERDEAD;
- else if (strcmp(s, "ENOTRECOVERABLE") == 0) return ENOTRECOVERABLE;
- else if (strcmp(s, "ERFKILL") == 0) return ERFKILL;
- else if (strcmp(s, "EHWPOISON") == 0) return EHWPOISON;
+ if (real_strcmp(s, "EPERM") == 0) return EPERM;
+ else if (real_strcmp(s, "ENOENT") == 0) return ENOENT;
+ else if (real_strcmp(s, "ESRCH") == 0) return ESRCH;
+ else if (real_strcmp(s, "EINTR") == 0) return EINTR;
+ else if (real_strcmp(s, "EIO") == 0) return EIO;
+ else if (real_strcmp(s, "ENXIO") == 0) return ENXIO;
+ else if (real_strcmp(s, "E2BIG") == 0) return E2BIG;
+ else if (real_strcmp(s, "ENOEXEC") == 0) return ENOEXEC;
+ else if (real_strcmp(s, "EBADF") == 0) return EBADF;
+ else if (real_strcmp(s, "ECHILD") == 0) return ECHILD;
+ else if (real_strcmp(s, "EAGAIN") == 0) return EAGAIN;
+ else if (real_strcmp(s, "ENOMEM") == 0) return ENOMEM;
+ else if (real_strcmp(s, "EACCES") == 0) return EACCES;
+ else if (real_strcmp(s, "EFAULT") == 0) return EFAULT;
+ else if (real_strcmp(s, "ENOTBLK") == 0) return ENOTBLK;
+ else if (real_strcmp(s, "EBUSY") == 0) return EBUSY;
+ else if (real_strcmp(s, "EEXIST") == 0) return EEXIST;
+ else if (real_strcmp(s, "EXDEV") == 0) return EXDEV;
+ else if (real_strcmp(s, "ENODEV") == 0) return ENODEV;
+ else if (real_strcmp(s, "ENOTDIR") == 0) return ENOTDIR;
+ else if (real_strcmp(s, "EISDIR") == 0) return EISDIR;
+ else if (real_strcmp(s, "EINVAL") == 0) return EINVAL;
+ else if (real_strcmp(s, "ENFILE") == 0) return ENFILE;
+ else if (real_strcmp(s, "EMFILE") == 0) return EMFILE;
+ else if (real_strcmp(s, "ENOTTY") == 0) return ENOTTY;
+ else if (real_strcmp(s, "ETXTBSY") == 0) return ETXTBSY;
+ else if (real_strcmp(s, "EFBIG") == 0) return EFBIG;
+ else if (real_strcmp(s, "ENOSPC") == 0) return ENOSPC;
+ else if (real_strcmp(s, "ESPIPE") == 0) return ESPIPE;
+ else if (real_strcmp(s, "EROFS") == 0) return EROFS;
+ else if (real_strcmp(s, "EMLINK") == 0) return EMLINK;
+ else if (real_strcmp(s, "EPIPE") == 0) return EPIPE;
+ else if (real_strcmp(s, "EDOM") == 0) return EDOM;
+ else if (real_strcmp(s, "ERANGE") == 0) return ERANGE;
+ else if (real_strcmp(s, "EDEADLK") == 0) return EDEADLK;
+ else if (real_strcmp(s, "ENAMETOOLONG") == 0) return ENAMETOOLONG;
+ else if (real_strcmp(s, "ENOLCK") == 0) return ENOLCK;
+ else if (real_strcmp(s, "ENOSYS") == 0) return ENOSYS;
+ else if (real_strcmp(s, "ENOTEMPTY") == 0) return ENOTEMPTY;
+ else if (real_strcmp(s, "ELOOP") == 0) return ELOOP;
+ else if (real_strcmp(s, "EWOULDBLOCK") == 0) return EWOULDBLOCK;
+ else if (real_strcmp(s, "ENOMSG") == 0) return ENOMSG;
+ else if (real_strcmp(s, "EIDRM") == 0) return EIDRM;
+ else if (real_strcmp(s, "ECHRNG") == 0) return ECHRNG;
+ else if (real_strcmp(s, "EL2NSYNC") == 0) return EL2NSYNC;
+ else if (real_strcmp(s, "EL3HLT") == 0) return EL3HLT;
+ else if (real_strcmp(s, "EL3RST") == 0) return EL3RST;
+ else if (real_strcmp(s, "ELNRNG") == 0) return ELNRNG;
+ else if (real_strcmp(s, "EUNATCH") == 0) return EUNATCH;
+ else if (real_strcmp(s, "ENOCSI") == 0) return ENOCSI;
+ else if (real_strcmp(s, "EL2HLT") == 0) return EL2HLT;
+ else if (real_strcmp(s, "EBADE") == 0) return EBADE;
+ else if (real_strcmp(s, "EBADR") == 0) return EBADR;
+ else if (real_strcmp(s, "EXFULL") == 0) return EXFULL;
+ else if (real_strcmp(s, "ENOANO") == 0) return ENOANO;
+ else if (real_strcmp(s, "EBADRQC") == 0) return EBADRQC;
+ else if (real_strcmp(s, "EBADSLT") == 0) return EBADSLT;
+ else if (real_strcmp(s, "EDEADLOCK") == 0) return EDEADLOCK;
+ else if (real_strcmp(s, "EBFONT") == 0) return EBFONT;
+ else if (real_strcmp(s, "ENOSTR") == 0) return ENOSTR;
+ else if (real_strcmp(s, "ENODATA") == 0) return ENODATA;
+ else if (real_strcmp(s, "ETIME") == 0) return ETIME;
+ else if (real_strcmp(s, "ENOSR") == 0) return ENOSR;
+ else if (real_strcmp(s, "ENONET") == 0) return ENONET;
+ else if (real_strcmp(s, "ENOPKG") == 0) return ENOPKG;
+ else if (real_strcmp(s, "EREMOTE") == 0) return EREMOTE;
+ else if (real_strcmp(s, "ENOLINK") == 0) return ENOLINK;
+ else if (real_strcmp(s, "EADV") == 0) return EADV;
+ else if (real_strcmp(s, "ESRMNT") == 0) return ESRMNT;
+ else if (real_strcmp(s, "ECOMM") == 0) return ECOMM;
+ else if (real_strcmp(s, "EPROTO") == 0) return EPROTO;
+ else if (real_strcmp(s, "EMULTIHOP") == 0) return EMULTIHOP;
+ else if (real_strcmp(s, "EDOTDOT") == 0) return EDOTDOT;
+ else if (real_strcmp(s, "EBADMSG") == 0) return EBADMSG;
+ else if (real_strcmp(s, "EOVERFLOW") == 0) return EOVERFLOW;
+ else if (real_strcmp(s, "ENOTUNIQ") == 0) return ENOTUNIQ;
+ else if (real_strcmp(s, "EBADFD") == 0) return EBADFD;
+ else if (real_strcmp(s, "EREMCHG") == 0) return EREMCHG;
+ else if (real_strcmp(s, "ELIBACC") == 0) return ELIBACC;
+ else if (real_strcmp(s, "ELIBBAD") == 0) return ELIBBAD;
+ else if (real_strcmp(s, "ELIBSCN") == 0) return ELIBSCN;
+ else if (real_strcmp(s, "ELIBMAX") == 0) return ELIBMAX;
+ else if (real_strcmp(s, "ELIBEXEC") == 0) return ELIBEXEC;
+ else if (real_strcmp(s, "EILSEQ") == 0) return EILSEQ;
+ else if (real_strcmp(s, "ERESTART") == 0) return ERESTART;
+ else if (real_strcmp(s, "ESTRPIPE") == 0) return ESTRPIPE;
+ else if (real_strcmp(s, "EUSERS") == 0) return EUSERS;
+ else if (real_strcmp(s, "ENOTSOCK") == 0) return ENOTSOCK;
+ else if (real_strcmp(s, "EDESTADDRREQ") == 0) return EDESTADDRREQ;
+ else if (real_strcmp(s, "EMSGSIZE") == 0) return EMSGSIZE;
+ else if (real_strcmp(s, "EPROTOTYPE") == 0) return EPROTOTYPE;
+ else if (real_strcmp(s, "ENOPROTOOPT") == 0) return ENOPROTOOPT;
+ else if (real_strcmp(s, "EPROTONOSUPPORT") == 0) return EPROTONOSUPPORT;
+ else if (real_strcmp(s, "ESOCKTNOSUPPORT") == 0) return ESOCKTNOSUPPORT;
+ else if (real_strcmp(s, "EOPNOTSUPP") == 0) return EOPNOTSUPP;
+ else if (real_strcmp(s, "EPFNOSUPPORT") == 0) return EPFNOSUPPORT;
+ else if (real_strcmp(s, "EAFNOSUPPORT") == 0) return EAFNOSUPPORT;
+ else if (real_strcmp(s, "EADDRINUSE") == 0) return EADDRINUSE;
+ else if (real_strcmp(s, "EADDRNOTAVAIL") == 0) return EADDRNOTAVAIL;
+ else if (real_strcmp(s, "ENETDOWN") == 0) return ENETDOWN;
+ else if (real_strcmp(s, "ENETUNREACH") == 0) return ENETUNREACH;
+ else if (real_strcmp(s, "ENETRESET") == 0) return ENETRESET;
+ else if (real_strcmp(s, "ECONNABORTED") == 0) return ECONNABORTED;
+ else if (real_strcmp(s, "ECONNRESET") == 0) return ECONNRESET;
+ else if (real_strcmp(s, "ENOBUFS") == 0) return ENOBUFS;
+ else if (real_strcmp(s, "EISCONN") == 0) return EISCONN;
+ else if (real_strcmp(s, "ENOTCONN") == 0) return ENOTCONN;
+ else if (real_strcmp(s, "ESHUTDOWN") == 0) return ESHUTDOWN;
+ else if (real_strcmp(s, "ETOOMANYREFS") == 0) return ETOOMANYREFS;
+ else if (real_strcmp(s, "ETIMEDOUT") == 0) return ETIMEDOUT;
+ else if (real_strcmp(s, "ECONNREFUSED") == 0) return ECONNREFUSED;
+ else if (real_strcmp(s, "EHOSTDOWN") == 0) return EHOSTDOWN;
+ else if (real_strcmp(s, "EHOSTUNREACH") == 0) return EHOSTUNREACH;
+ else if (real_strcmp(s, "EALREADY") == 0) return EALREADY;
+ else if (real_strcmp(s, "EINPROGRESS") == 0) return EINPROGRESS;
+ else if (real_strcmp(s, "ESTALE") == 0) return ESTALE;
+ else if (real_strcmp(s, "EUCLEAN") == 0) return EUCLEAN;
+ else if (real_strcmp(s, "ENOTNAM") == 0) return ENOTNAM;
+ else if (real_strcmp(s, "ENAVAIL") == 0) return ENAVAIL;
+ else if (real_strcmp(s, "EISNAM") == 0) return EISNAM;
+ else if (real_strcmp(s, "EREMOTEIO") == 0) return EREMOTEIO;
+ else if (real_strcmp(s, "EDQUOT") == 0) return EDQUOT;
+ else if (real_strcmp(s, "ENOMEDIUM") == 0) return ENOMEDIUM;
+ else if (real_strcmp(s, "EMEDIUMTYPE") == 0) return EMEDIUMTYPE;
+ else if (real_strcmp(s, "ECANCELED") == 0) return ECANCELED;
+ else if (real_strcmp(s, "ENOKEY") == 0) return ENOKEY;
+ else if (real_strcmp(s, "EKEYEXPIRED") == 0) return EKEYEXPIRED;
+ else if (real_strcmp(s, "EKEYREVOKED") == 0) return EKEYREVOKED;
+ else if (real_strcmp(s, "EKEYREJECTED") == 0) return EKEYREJECTED;
+ else if (real_strcmp(s, "EOWNERDEAD") == 0) return EOWNERDEAD;
+ else if (real_strcmp(s, "ENOTRECOVERABLE") == 0) return ENOTRECOVERABLE;
+ else if (real_strcmp(s, "ERFKILL") == 0) return ERFKILL;
+ else if (real_strcmp(s, "EHWPOISON") == 0) return EHWPOISON;
return 0;
}
@@ -252,6 +253,15 @@ void fo_init
const char *init_file; /* optional file used to load failing points */
char line[256]; /* single line from init_file */
FILE *f; /* init_file stdio handle */
+
+ char * (*real_fgets)(char *, int, FILE *);
+ char * (*real_strerror)(int);
+ int (*real_atoi)(const char *);
+ int (*real_fclose)(FILE *);
+ int (*real_feof)(FILE *);
+ int (*real_strcmp)(const char *, const char *);
+ long (*real_atol)(const char *);
+ void * (*real_memset)(void *, int, size_t);
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
#define die(S, ...) do { fprintf(stderr, S, __VA_ARGS__); exit(1); } while (0)
@@ -274,6 +284,29 @@ ${fo_init_list}
if ((init_file = getenv("LIBFO_INIT_FILE")) == NULL)
return;
+ /* in case user overrides fgets() or any function we use, we
+ * could end up in a situation where his failing point hits us
+ * right in our face. To prevent crashing we store original
+ * functions in out pointer.
+ */
+ real_fgets = fgets;
+ real_strerror = strerror;
+ real_atoi = atoi;
+ real_fclose = fclose;
+ real_feof = feof;
+ real_strcmp = strcmp;
+ real_atol = atol;
+ real_memset = memset;
+
+%{if ${fo_fgets_used}} real_fgets = fo_info[fo_fgets].original;%{fi}
+%{if ${fo_strerror_used}} real_strerror = fo_info[fo_strerror].original;%{fi}
+%{if ${fo_atoi_used}} real_atoi = fo_info[fo_atoi].original;%{fi}
+%{if ${fo_fclose_used}} real_fclose = fo_info[fo_fclose].original;%{fi}
+%{if ${fo_feof_used}} real_feof = fo_info[fo_feof].original;%{fi}
+%{if ${fo_strcmp_used}} real_strcmp = fo_info[fo_strcmp].original;%{fi}
+%{if ${fo_atol_used}} real_atol = fo_info[fo_atol].original;%{fi}
+%{if ${fo_memset_used}} real_memset = fo_info[fo_memset].original;%{fi}
+
if ((f = fopen(init_file, "r")) == NULL)
die("error opening init-file %s: %s\n", init_file, strerror(errno));
@@ -291,19 +324,19 @@ ${fo_init_list}
l = line;
line[sizeof(line) - 1] = 0x7f;
- memset(ret, 0x00, sizeof(ret));
- memset(errn, 0x00, sizeof(errn));
- memset(function, 0x00, sizeof(function));
- memset(countdown, 0x00, sizeof(countdown));
+ real_memset(ret, 0x00, sizeof(ret));
+ real_memset(errn, 0x00, sizeof(errn));
+ real_memset(function, 0x00, sizeof(function));
+ real_memset(countdown, 0x00, sizeof(countdown));
- if (fgets(line, sizeof(line), f) == NULL)
+ if (real_fgets(line, sizeof(line), f) == NULL)
{
- int ret = feof(f);
- fclose(f);
+ int ret = real_feof(f);
+ real_fclose(f);
if (ret)
return;
- die("fgets() on %s failed: %s\n", init_file, strerror(errno));
+ die("fgets() on %s failed: %s\n", init_file, real_strerror(errno));
}
if (line[sizeof(line) - 1] == '\0' && line[sizeof(line) - 2] != '\n')
@@ -320,18 +353,21 @@ ${fo_init_list}
for (pos = 0; *l != ',' && *l != '\0'; errn[pos++] = *l++);
errn[pos - 1] = '\0'; /* remove last \n */
- for (pos = 0; pos != fo_f_max; ++pos)
+ for (fo_pos = fo_f_max, pos = 0; pos != fo_f_max; ++pos)
{
- if (strcmp(fo_info[pos].str, function))
+ if (real_strcmp(fo_info[pos].str, function))
continue;
fo_pos = pos;
break;
}
- fo_info[fo_pos].countdown = atoi(countdown);
- fo_info[fo_pos].errn = errno_str_to_int(errn);
- fo_info[fo_pos].ret = strcmp(ret, "NULL") ? atol(ret) : FO_NULL;
+ if (fo_pos == fo_f_max)
+ die("function %s not overriden in fo.c\n", function);
+
+ fo_info[fo_pos].countdown = real_atoi(countdown);
+ fo_info[fo_pos].errn = errno_str_to_int(errn, real_strcmp);
+ fo_info[fo_pos].ret = real_strcmp(ret, "NULL") ? real_atol(ret) : FO_NULL;
}
}
diff --git a/fogen b/fogen
index 82d8e2c..45003b4 100755
--- a/fogen
+++ b/fogen
@@ -53,6 +53,125 @@ def eprint(
):
print(*args, file=sys.stderr, **kwargs)
+## ==========================================================================
+# Function removes conditionals from specified file. Conditional must be
+# in format %{if <bool>} (...) %{fi}, and if <bool> is 0, all data between
+# %{if} and %{fi} will be removed. Here are some examples.
+#
+# example 1:
+# %{if 0}
+# some code
+# more code
+# %{fi}
+# different cnode
+#
+# will return
+# different code
+#
+# while example 2:
+# %{if 1}
+# some code
+# more code
+# %{fi}
+# different cnode
+#
+# will return:
+# some code
+# more code
+# different code
+#
+# This function is stupid and does not work with any variables, it is
+# designed to work with stirng.subsitute(), so if you want variables use
+# %{if ${some_variable}} and run the file through string.substitute()
+# to change ${some_variable> to 0 or 1, and then run this function.
+#
+# %{if} can be in the middle of string like
+#
+# example 3:
+# if (%{if 1}some_check ||%{fi} another_check)
+## ==========================================================================
+
+
+def process_conditionals(
+ content # string on which to perform conditional removal
+):
+ inside_cond = 0 # flag to know if we are inside %{if} or not
+ cond_true = 0 # value of %{if} conditional
+ out = "" # output file after processing
+ i = 0 # current file position
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+
+ while i < len(content):
+ if content[i] == '\n':
+ line_started = 1
+ out += content[i]
+ i += 1
+ continue
+
+ if inside_cond == 0:
+ # we are outside of conditional section, check if we are
+ # about to enter one
+ if not content[i: i + 5].startswith("%{if ") or \
+ content[i + 6] != "}":
+ # nope, current position is not "%{if " or there is no
+ # closing "}" character, so this is not conditional
+ line_started = 0
+ out += content[i]
+ i += 1
+ continue
+
+ # yes, content[i] is "%{if 1}" or "%{if 0}" we are dealing
+ # with conditional, read conditional value and set flag
+ # to know we are inside conditional now
+ cond_true = content[i + 5]
+ inside_cond = 1
+
+ # obviously we do not store conditional in out, so skip it
+ i += 7
+
+ if (i == 7 or content[i - 7 - 1] == "\n") and content[i] == "\n":
+ # unique situation, %{if N} is the only text in the
+ # line, so let's also remove a new line character
+ # that follows it
+ i += 1
+ else:
+ # we are inside conditional, let's look for closing %{fi}
+ # statement
+
+ if not content[i: i + 5].startswith("%{fi}"):
+ # does not look like and conditonal ending, but what
+ # should we do with data inside conditional?
+
+ if int(cond_true) != 0:
+ # true, we should store that content in out,
+ # otherwise we do nothing, data is not stored
+ # and we only increment i
+ out += content[i]
+
+ i += 1
+ continue
+
+ # we got ending "%{fi}", so simply skip it and mark
+ # we are out of conditional
+ i += 5
+ inside_cond = 0
+
+ if content[i - 5 - 1] == "\n" and content[i] == "\n":
+ # unique situation, %{fi} is the only text in the
+ # line, so let's also remove a new line character
+ # that follows it
+ i += 1
+ continue
+
+ if int(cond_true) == 0 and line_started and content[i] == "\n":
+ # remove whole line if the only thing we have there
+ # is conditional and that conditional is false, to
+ # avoid printing unnecessary blank lines.
+ i += 1
+
+ # parsing is done, return processed data
+ return out
+
## ==========================================================================
# __ __
@@ -134,16 +253,50 @@ db = []
dbt = dict()
dbt = [row for row in csv.DictReader(dbc.splitlines(), skipinitialspace=1)]
+fo_fgets_used = 0
+fo_strerror_used = 0
+fo_atoi_used = 0
+fo_fclose_used = 0
+fo_feof_used = 0
+fo_strcmp_used = 0
+fo_atol_used = 0
+fo_memset_used = 0
+used_funcs = []
+
+
if len(flist) == 0:
- db = dbt
+ db = dbt
+ for opt in dbt:
+ used_funcs.append(opt['fname'])
else:
- with open(flist) as fl:
- for opt in dbt:
- fl.seek(0)
- for f in fl.read().splitlines():
- if f == opt['fname']:
- db.append(opt)
- break
+ with open(flist) as fl:
+ used_funcs = fl.read().splitlines()
+ for opt in dbt:
+ fl.seek(0)
+ for f in fl.read().splitlines():
+ if f == opt['fname']:
+ db.append(opt)
+ break
+
+
+
+for f in used_funcs:
+ if f == "fgets":
+ fo_fgets_used = 1
+ elif f == "strerror":
+ fo_strerror_used = 1
+ elif f == "atoi":
+ fo_atoi_used = 1
+ elif f == "fclose":
+ fo_fclose_used = 1
+ elif f == "feof":
+ fo_feof_used = 1
+ elif f == "strcmp":
+ fo_strcmp_used = 1
+ elif f == "atol":
+ fo_atol_used = 1
+ elif f == "memset":
+ fo_memset_used = 1
## ==================================================================
@@ -262,8 +415,20 @@ with open(resdir + "/fo.c.in") as file_in, open(outc, "w") as file_out:
d['fo_init_list'] = fo_init_list
d['fo_overrides'] = fo_overrides
+ d['fo_fgets_used'] = fo_fgets_used
+ d['fo_strerror_used'] = fo_strerror_used
+ d['fo_atoi_used'] = fo_atoi_used
+ d['fo_fclose_used'] = fo_fclose_used
+ d['fo_feof_used'] = fo_feof_used
+ d['fo_strcmp_used'] = fo_strcmp_used
+ d['fo_atol_used'] = fo_atol_used
+ d['fo_memset_used'] = fo_memset_used
+
# and replace all
- file_out.write(Template(file_in.read()).substitute(d))
+ content = Template(file_in.read()).substitute(d)
+
+ # now replace all the conditionals
+ file_out.write(process_conditionals(content))
with open(resdir + "/fo.h.in") as file_in, open(outh, "w") as file_out: