Messages in this thread Patch in this message | | | Date | Wed, 03 Aug 2005 11:35:34 +0200 | From | Guillaume Chazarain <> | Subject | [PATCH] Wrong printk return value |
| |
What's the true meaning of the printk return value? Should it include the prioty prefix length of 3? and what about the timing information? In both cases it was broken:
strace -e write echo 1 > /dev/kmsg => write(1, "1\n", 2) = 5
strace -e write echo "<1>1" > /dev/kmsg => write(1, "<1>1\n", 5) = 8
The returned length was "length of input string + 3", I made it "length of printed string including any prefix".
Successful printk calls can have a return value different than the input length (priority prefix, timing), so /bin/echo will still think there is an error. So, to avoid breaking programs that assume write(buff, len) != len is an error, /dev/kmsg should return the buffer length when the call succeeds.
The only drawback is that now it's no more possible to use /dev/kmsg to check the printk return value :-(
-- Guillaume
--- linux-2.6.13-rc5/kernel/printk.c +++ linux-2.6.13-rc5/kernel/printk.c @@ -553,7 +553,7 @@ p[1] <= '7' && p[2] == '>') { loglev_char = p[1]; p += 3; - printed_len += 3; + printed_len -= 3; } else { loglev_char = default_message_loglevel + '0'; @@ -568,7 +568,7 @@ for (tp = tbuf; tp < tbuf + tlen; tp++) emit_log_char(*tp); - printed_len += tlen - 3; + printed_len += tlen; } else { if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') { @@ -576,8 +576,8 @@ emit_log_char(default_message_loglevel + '0'); emit_log_char('>'); + printed_len += 3; } - printed_len += 3; } log_level_unknown = 0; if (!*p) --- linux-2.6.13-rc5/drivers/char/mem.c +++ linux-2.6.13-rc5/drivers/char/mem.c @@ -819,7 +819,7 @@ static ssize_t kmsg_write(struct file * size_t count, loff_t *ppos) { char *tmp; - int ret; + ssize_t ret; tmp = kmalloc(count + 1, GFP_KERNEL); if (tmp == NULL) @@ -828,6 +828,9 @@ static ssize_t kmsg_write(struct file * if (!copy_from_user(tmp, buf, count)) { tmp[count] = 0; ret = printk("%s", tmp); + if (ret > count) + /* printk can add a prefix */ + ret = count; } kfree(tmp); return ret; | |