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); }