The netlink service is used, among other things, to notify userspace about hotplug events (e.g. "a device has been connected"). These events come in the form of packets, which follow the following format, explained here:

The netlink packet contains a set of null terminated text lines. The
first line of the netlink packet combines the $ACTION and $DEVPATH
values, separated by an @ (at sign). Each line after the first
contains a KEYWORD=VALUE pair defining a hotplug event variable.

I have made an "SSCCE" of the code I use to parse these kinds of packets, and posted it on Ideone.com. I'd like a review on potential risks and bad practices.

I've rolled this back as it invalidated my answer. The original embedded code should be retained after receiving answers.
–
Jamal♦Aug 18 '14 at 19:10

@Jamal I'm sorry. For the record, the changes were reflecting your suggestion about the vector initialization (i.e. removing the '=' sign) and renaming the iterators in the loop - there was no need for it3, and the others were renamed for consistency.
–
KalrishAug 18 '14 at 19:14

3

That's alright, but be sure to read the Help Center since you're new here. The applicable section is at the very bottom.
–
Jamal♦Aug 18 '14 at 19:15

I probably would also use a vector. But I am not sure I follow your logic of not using a std::string. It is quite reasonable to put '\0' into a std::string.
–
Loki AstariAug 18 '14 at 21:59

@LokiAstari I haven't used a std::string because the constructor would stop scanning the string literal when it found the first '\0' character. Edit: Oh, sorry, I have just noticed what you meant (list initialization). In real code, I used std::vector because, after all, I was reading "raw" bytes from the netlink socket. But yes, it would have worked as well.
–
KalrishAug 20 '14 at 12:37

Thank you! About the inclusion directives, I purposedly put C++ standard headers first, then STL headers, and lastly other headers. I didn't know about your second nor your third point. Finally, as for the loop, I'll give it a look.
–
KalrishAug 18 '14 at 19:11

@Kalrish: Ah, I hadn't noticed the inclusion thing here. It's mostly up to you, but in many cases, library directives (C and C++) are kept together.
–
Jamal♦Aug 18 '14 at 19:13

/* Even if a std::string was used, a string literal would not work, because
the fake packet contains '\0'. */

It's true that a string literal would not work, but you can still use a std::string instead of a std::vector and your wode will work without any other change.

When possible, try to use std::begin and std::end instead of the member methods begin and end. When writing generic code, it helps to handle containers that do not have these methods work with the global functions (for example C arrays or std::valarray).

You return from your program with return EXIT_SUCCESS;. It should return 0 with most of the known implementations. If you don't plan to return any error codes from your program, you may as well forget about returning anything from main and let your compiler automagically return 0; at the end of main (it does so if there are no return statements in main). That may even allow you not to include <cstdlib> at all.

Generally speaking, you're doing with loops operations that could be abstracted into functions. For example, I would have created a split function so split a string on some characters. I would have split the string of \0 characters then on = characters when needed. That would probably produce code more readable than a bunch of loops on iterators. Think about it :)

I agree with you and Loki Astari (see the comment above) with regards to the std::string, although I still believe that std::vector is semantically more correct in this context. As for std::begin and std::end, I will use them - thanks! The return matter is not very important here, because this was just an "SSCCE", but I agree that it would have simplified the code snippet. Lastly, about functions, I avoided them to avoid copies, but I will look at it again, because it is indeed ugly :).
–
KalrishAug 20 '14 at 13:38