2

Today I ran into some code that's writing a newline character explicitly into a sysctl file. See moby/docker source code. My first thought is that the author has diligently copied the shell's behaviour into go despite the newline being redundant.

But then I started to look for documentation on the subject and found it a really hard one to find information on either way. I haven't managed to come up with anything so far.


When writing sysctl files in /proc/sys/ many of the values are integers written in ASCII. For example, to toggle something on or off you have to write 1 or 0 as text into a file.

Often the advice here on U&L and on blogs etc. is to do this in the shell using echo. For example turning on IPv4 forwarding:

echo 1 > /proc/sys/net/ipv4/ip_forward

But this advice does something subtly different to its stated goal. It doesn't write a single byte 0x31 to the file. It writes two: 0x31 0x0A also known as 1\n. I had always assumed the newline (0x0A) was simply ignored by the kernel.


Does writing a newline character into a sysctl file (eg /proc/sys/net/ipv4/ip_forward) have any effect? References welcome even if they are links to source code.

1
  • Some files do complain when you try to write a newline, but some don't. Let me see if I can find an example of the complainers
    – muru
    Apr 7 at 9:59

1 Answer 1

1

In most cases it shouldn’t make any difference either way, at least at the end of an input string. In all cases, only written data is processed — the kernel knows how long the supplied buffer is (1 byte for 1 with no newline, 2 for 1 with a newline) and will only process that many bytes.

sysctl entries using the standard sysctl-handling functions handle newlines explicitly: in strings, they terminate input, in vectors, they separate entries (most numeric values end up being handled as vectors, e.g. /proc/sys/net/ipv4/ip_forward). This is in addition to reaching the end of user input, which always ends processing.

So the following all produce the same result:

$ echo 1 > /proc/sys/net/ipv4/ip_forward
$ printf 1 > /proc/sys/net/ipv4/ip_forward
$ printf '1\n0\n' > /proc/sys/net/ipv4/ip_forward

Thus the answer to

Does writing a newline character into a sysctl (/proc/sys) file have any effect?

is yes: it indicates the end of a value. That indication may or may not add information compared to the end of the input as a whole; that depends on the context (specifically, whether the value being written is a vector or not).

Code handling output for sysctl, i.e. producing the text that’s read when something reads from a sysctl entry, always adds a terminating newline, as might be expected.

The sysctl utility always writes a newline, so it’s safe to assume that in most cases this will continue to be valid.

(I haven’t checked all the sysctl handlers so there may be some specific handlers which object to newlines.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.