2009-11-18 02:42:52 +03:00
- 8ch indent, no tabs
2014-08-21 18:10:37 +04:00
- Don't break code lines too eagerly. We do *not* force line breaks at
80ch, all of today's screens should be much larger than that. But
then again, don't overdo it, ~140ch should be enough really.
2013-03-08 21:58:08 +04:00
- Variables and functions *must* be static, unless they have a
2013-12-04 01:27:45 +04:00
prototype, and are supposed to be exported.
2009-11-18 02:42:52 +03:00
2013-12-10 01:51:35 +04:00
- structs in MixedCase (with exceptions, such as public API structs),
variables + functions in lower_case.
2013-03-08 21:58:08 +04:00
- The destructors always unregister the object from the next bigger
2009-11-18 02:42:52 +03:00
object, not the other way around
2014-06-28 02:48:28 +04:00
- To minimize strict aliasing violations, we prefer unions over casting
2009-11-18 02:42:52 +03:00
2014-06-28 02:48:28 +04:00
- For robustness reasons, destructors should be able to destruct
2009-11-18 02:42:52 +03:00
half-initialized objects, too
2014-10-22 13:09:00 +04:00
- Error codes are returned as negative Exxx. e.g. return -EINVAL. There
2014-06-28 02:48:28 +04:00
are some exceptions: for constructors, it is OK to return NULL on
OOM. For lookup functions, NULL is fine too for "not found".
2013-03-08 21:58:08 +04:00
Be strict with this. When you write a function that can fail due to
more than one cause, it *really* should have "int" as return value
for the error code.
2014-06-28 02:50:28 +04:00
- Do not bother with error checking whether writing to stdout/stderr
2013-12-10 01:51:35 +04:00
worked.
2013-03-08 21:58:08 +04:00
- Do not log errors from "library" code, only do so from "main
2014-06-28 02:50:28 +04:00
program" code. (With one exception: it is OK to log with DEBUG level
2013-12-10 01:51:35 +04:00
from any code, with the exception of maybe inner loops).
2013-03-08 21:58:08 +04:00
2014-06-28 02:50:28 +04:00
- Always check OOM. There is no excuse. In program code, you can use
2013-12-10 01:51:35 +04:00
"log_oom()" for then printing a short message, but not in "library" code.
2010-02-15 00:44:51 +03:00
- Do not issue NSS requests (that includes user name and host name
2013-12-10 01:51:35 +04:00
lookups) from PID 1 as this might trigger deadlocks when those
lookups involve synchronously talking to services that we would need
to start up
2010-02-15 00:44:51 +03:00
2014-06-28 02:50:28 +04:00
- Do not synchronously talk to any other service from PID 1, due to
2013-12-10 01:51:35 +04:00
risk of deadlocks
2013-03-08 21:58:08 +04:00
2014-06-28 02:49:12 +04:00
- Avoid fixed-size string buffers, unless you really know the maximum
2013-03-08 21:58:08 +04:00
size and that maximum size is small. They are a source of errors,
2014-06-28 02:49:12 +04:00
since they possibly result in truncated strings. It is often nicer
to use dynamic memory, alloca() or VLAs. If you do allocate fixed-size
2014-06-28 02:50:28 +04:00
strings on the stack, then it is probably only OK if you either
2013-12-10 01:51:35 +04:00
use a maximum size such as LINE_MAX, or count in detail the maximum
size a string can have. (DECIMAL_STR_MAX and DECIMAL_STR_WIDTH
macros are your friends for this!)
Or in other words, if you use "char buf[256]" then you are likely
doing something wrong!
2013-03-08 21:58:08 +04:00
- Stay uniform. For example, always use "usec_t" for time
2014-10-22 13:09:00 +04:00
values. Do not mix usec and msec, and usec and whatnot.
2013-03-08 21:58:08 +04:00
- Make use of _cleanup_free_ and friends. It makes your code much
nicer to read!
- Be exceptionally careful when formatting and parsing floating point
numbers. Their syntax is locale dependent (i.e. "5.000" in en_US is
generally understood as 5, while on de_DE as 5000.).
- Try to use this:
void foo() {
}
instead of this:
void foo()
{
}
2014-06-28 02:50:28 +04:00
But it is OK if you do not.
2013-03-08 21:58:08 +04:00
2014-10-22 13:09:00 +04:00
- Single-line "if" blocks should not be enclosed in {}. Use this:
if (foobar)
waldo();
instead of this:
if (foobar) {
waldo();
}
2014-06-28 02:50:28 +04:00
- Do not write "foo ()", write "foo()".
2013-03-08 21:58:08 +04:00
- Please use streq() and strneq() instead of strcmp(), strncmp() where applicable.
- Please do not allocate variables on the stack in the middle of code,
even if C99 allows it. Wrong:
{
a = 5;
int b;
b = a;
}
Right:
{
int b;
a = 5;
b = a;
}
- Unless you allocate an array, "double" is always the better choice
than "float". Processors speak "double" natively anyway, so this is
2014-06-28 02:49:12 +04:00
no speed benefit, and on calls like printf() "float"s get promoted
2013-03-08 21:58:08 +04:00
to "double"s anyway, so there is no point.
2014-06-28 02:50:28 +04:00
- Do not invoke functions when you allocate variables on the stack. Wrong:
2013-03-08 21:58:08 +04:00
{
int a = foobar();
uint64_t x = 7;
}
Right:
{
int a;
uint64_t x = 7;
a = foobar();
}
- Use "goto" for cleaning up, and only use it for that. i.e. you may
2013-12-10 01:51:35 +04:00
only jump to the end of a function, and little else. Never jump
backwards!
2013-03-08 21:58:08 +04:00
- Think about the types you use. If a value cannot sensibly be
2014-06-28 02:50:28 +04:00
negative, do not use "int", but use "unsigned".
2013-03-08 21:58:08 +04:00
2014-06-28 02:50:28 +04:00
- Do not use types like "short". They *never* make sense. Use ints,
2013-03-08 21:58:08 +04:00
longs, long longs, all in unsigned+signed fashion, and the fixed
2014-06-28 02:48:28 +04:00
size types uint32_t and so on, as well as size_t, but nothing else.
2013-12-10 01:51:35 +04:00
- Public API calls (i.e. functions exported by our shared libraries)
must be marked "_public_" and need to be prefixed with "sd_". No
other functions should be prefixed like that.
2014-06-28 02:48:28 +04:00
- In public API calls, you *must* validate all your input arguments for
2013-12-10 01:51:35 +04:00
programming error with assert_return() and return a sensible return
2014-06-28 02:48:28 +04:00
code. In all other calls, it is recommended to check for programming
2013-12-10 01:51:35 +04:00
errors with a more brutal assert(). We are more forgiving to public
users then for ourselves! Note that assert() and assert_return()
really only should be used for detecting programming errors, not for
runtime errors. assert() and assert_return() by usage of _likely_()
2014-06-28 02:50:28 +04:00
inform the compiler that he should not expect these checks to fail,
2013-12-10 01:51:35 +04:00
and they inform fellow programmers about the expected validity and
range of parameters.
- Never use strtol(), atoi() and similar calls. Use safe_atoli(),
safe_atou32() and suchlike instead. They are much nicer to use in
most cases and correctly check for parsing errors.
- For every function you add, think about whether it is a "logging"
function or a "non-logging" function. "Logging" functions do logging
on their own, "non-logging" function never log on their own and
expect their callers to log. All functions in "library" code,
2014-08-30 19:13:16 +04:00
i.e. in src/shared/ and suchlike must be "non-logging". Every time a
2014-06-28 02:48:28 +04:00
"logging" function calls a "non-logging" function, it should log
2013-12-10 01:51:35 +04:00
about the resulting errors. If a "logging" function calls another
"logging" function, then it should not generate log messages, so
that log messages are not generated twice for the same errors.
- Avoid static variables, except for caches and very few other
cases. Think about thread-safety! While most of our code is never
2014-06-28 02:48:28 +04:00
used in threaded environments, at least the library code should make
2013-12-10 01:51:35 +04:00
sure it works correctly in them. Instead of doing a lot of locking
2014-06-28 02:48:28 +04:00
for that, we tend to prefer using TLS to do per-thread caching (which
2013-12-10 01:51:35 +04:00
only works for small, fixed-size cache objects), or we disable
caching for any thread that is not the main thread. Use
is_main_thread() to detect whether the calling thread is the main
thread.
2014-08-02 19:12:21 +04:00
2014-10-27 20:09:07 +03:00
- Command line option parsing:
2014-08-02 19:12:21 +04:00
- Do not print full help() on error, be specific about the error.
- Do not print messages to stdout on error.
- Do not POSIX_ME_HARDER unless necessary, i.e. avoid "+" in option string.
2014-10-27 20:09:07 +03:00
- Do not write functions that clobber call-by-reference variables on
failure. Use temporary variables for these cases and change the
passed in variables only on success.
2014-10-30 19:05:25 +03:00
- When you allocate a file descriptor, it should be made O_CLOEXEC
right from the beginning, as none of our files should leak to forked
binaries by default. Hence, whenever you open a file, O_CLOEXEC must
be specified, right from the beginning.