I just wanted some quick debugging messages in a daemon written by someone else in a cross complied kernel. I ran into a compile error trying to use printk, as <linux/module.h> could not be included. Rather then battle with that excessively (to do this the right way) I cheated and used the following lazy, but functional 5 minute workaround:
void dmesg( const char *tag, const char *msg, const int len ) { size_t taglen = strlen(tag); char buffer[taglen + len]; memcpy(&buffer[0], tag, taglen); memcpy(&buffer[taglen], msg, len); int fd_kmsg = open("/dev/kmsg", O_WRONLY); write(fd_kmsg, &buffer, TAG_LEN + len); close(fd_kmsg); } void dmesgWarn(const char *msg, const int len) { dmesg("<4>", msg, len); } void dmesgInfo(const char *msg, const int len) { dmesg("<6>", msg, len); } void dmesgDebug(const char *msg, const int len) { dmesg("<7>", msg, len); }
UPDATE (Thanks @glglgl!)
A much simpler version could be like this:
void dmesg( const unsigned int tag, const char *msg) { size_t msglen = sprintf(NULL, "<%u>%s", tag, msg); char buffer[msglen + 1]; sprintf(buffer, "<%u>%s", tag, msg); // snprintf(buffer, sizeof(buffer), "<%u>%s", tag, msg); // would be safer, but here we make sure that everything works as it should. int fd_kmsg = open("/dev/kmsg", O_WRONLY); write(fd_kmsg, &buffer, msglen); close(fd_kmsg); } void dmesgWarn(const char *msg) { dmesg(4, msg); } void dmesgInfo(const char *msg) { dmesg(6, msg); } void dmesgDebug(const char *msg) { dmesg(7, msg); }
It now just takes strings, integrates them in a message to be written to that file and writes it.
Now that we talk about it, it can be even much easier:
void dmesg( const unsigned int tag, const char *msg) { int fd_kmsg = open("/dev/kmsg", O_WRONLY); FILE * f_kmsg = fdopen(fd_kmsg, "w"); fprintf(f_kmsg, "<%u>%s", tag, msg); fclose(f_kmsg); // closes the underlying fd_kmsg as well } void dmesgWarn(const char *msg) { dmesg(4, msg); } void dmesgInfo(const char *msg) { dmesg(6, msg); } void dmesgDebug(const char *msg) { dmesg(7, msg); }