]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - CODING_STYLE
final v236 update (#7649)
[thirdparty/systemd.git] / CODING_STYLE
index 46e366898e7ee5ddeac6882ef9fa51c081de7cd0..4119cfec234ffc86aed285002f2d9930851848cb 100644 (file)
   programming error with assert_return() and return a sensible return
   code. In all other calls, it is recommended to check for programming
   errors with a more brutal assert(). We are more forgiving to public
-  users then for ourselves! Note that assert() and assert_return()
+  users than 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_()
   inform the compiler that he should not expect these checks to fail,
   b) socket() and socketpair() must get SOCK_CLOEXEC passed
   c) recvmsg() must get MSG_CMSG_CLOEXEC set
   d) F_DUPFD_CLOEXEC should be used instead of F_DUPFD, and so on
+  f) invocations of fopen() should take "e"
 
 - We never use the POSIX version of basename() (which glibc defines it in
   libgen.h), only the GNU version (which glibc defines in string.h).
   The only reason to include libgen.h is because dirname()
-  is needed. Everytime you need that please immediately undefine
+  is needed. Every time you need that please immediately undefine
   basename(), and add a comment about it, so that no code ever ends up
   using the POSIX version!
 
 
       unlink("/foo/bar/baz");
 
+  Don't cast function calls to (void) that return no error
+  conditions. Specifically, the various xyz_unref() calls that return a NULL
+  object shouldn't be cast to (void), since not using the return value does not
+  hide any errors.
+
 - Don't invoke exit(), ever. It is not replacement for proper error
   handling. Please escalate errors up your call chain, and use normal
   "return" to exit from the main function of a process. If you
   proper event, instead of doing time-based poll loops.
 
 - To determine the length of a constant string "foo", don't bother
-  with sizeof("foo")-1, please use strlen("foo") directly. gcc knows
-  strlen() anyway and turns it into a constant expression if possible.
+  with sizeof("foo")-1, please use STRLEN() instead.
 
 - If you want to concatenate two or more strings, consider using
   strjoin() rather than asprintf(), as the latter is a lot
   global variables. Why are global variables bad? They usually hinder
   generic reusability of code (since they break in threaded programs,
   and usually would require locking there), and as the code using them
-  has side-effects make programs intransparent. That said, there are
+  has side-effects make programs non-transparent. That said, there are
   many cases where they explicitly make a lot of sense, and are OK to
   use. For example, the log level and target in log.c is stored in a
   global variable, and that's OK and probably expected by most. Also
   tools, and we should continue to do so, as it makes it easy to
   identify command line parameter variables, and makes it clear why it
   is OK that they are global variables.
+
+- When exposing public C APIs, be careful what function parameters you make
+  "const". For example, a parameter taking a context object should probably not
+  be "const", even if you are writing an otherwise read-only accessor function
+  for it. The reason is that making it "const" fixates the contract that your
+  call won't alter the object ever, as part of the API. However, that's often
+  quite a promise, given that this even prohibits object-internal caching or
+  lazy initialization of object variables. Moreover it's usually not too useful
+  for client applications. Hence: please be careful and avoid "const" on object
+  parameters, unless you are very sure "const" is appropriate.
+
+- Make sure to enforce limits on every user controllable resource. If the user
+  can allocate resources in your code, your code must enforce some form of
+  limits after which it will refuse operation. It's fine if it is hard-coded (at
+  least initially), but it needs to be there. This is particularly important
+  for objects that unprivileged users may allocate, but also matters for
+  everything else any user may allocated.
+
+- htonl()/ntohl() and htons()/ntohs() are weird. Please use htobe32() and
+  htobe16() instead, it's much more descriptive, and actually says what really
+  is happening, after all htonl() and htons() don't operate on longs and
+  shorts as their name would suggest, but on uint32_t and uint16_t. Also,
+  "network byte order" is just a weird name for "big endian", hence we might
+  want to call it "big endian" right-away.
+
+- You might wonder what kind of common code belongs in src/shared/ and what
+  belongs in src/basic/. The split is like this: anything that uses public APIs
+  we expose (i.e. any of the sd-bus, sd-login, sd-id128, ... APIs) must be
+  located in src/shared/. All stuff that only uses external libraries from
+  other projects (such as glibc's APIs), or APIs from src/basic/ itself should
+  be placed in src/basic/. Conversely, src/libsystemd/ may only use symbols
+  from src/basic, but not from src/shared/. To summarize:
+
+  src/basic/      → may be used by all code in the tree
+                  → may not use any code outside of src/basic/
+
+  src/libsystemd/ → may be used by all code in the tree, except for code in src/basic/
+                  → may not use any code outside of src/basic/, src/libsystemd/
+
+  src/shared/     → may be used by all code in the tree, except for code in src/basic/, src/libsystemd/
+                  → may not use any code outside of src/basic/, src/libsystemd/, src/shared/
+
+- Our focus is on the GNU libc (glibc), not any other libcs. If other libcs are
+  incompatible with glibc it's on them. However, if there are equivalent POSIX
+  and Linux/GNU-specific APIs, we generally prefer the POSIX APIs. If there
+  aren't, we are happy to use GNU or Linux APIs, and expect non-GNU
+  implementations of libc to catch up with glibc.
+
+- Whenever installing a signal handler, make sure to set SA_RESTART for it, so
+  that interrupted system calls are automatically restarted, and we minimize
+  hassles with handling EINTR (in particular as EINTR handling is pretty broken
+  on Linux).
+
+- When applying C-style unescaping as well as specifier expansion on the same
+  string, always apply the C-style unescaping fist, followed by the specifier
+  expansion. When doing the reverse, make sure to escape '%' in specifier-style
+  first (i.e. '%' → '%%'), and then do C-style escaping where necessary.