struct logger_entry header;
struct timespec now;
ssize_t ret = 0;
+ size_t count;
bool from_stdio = false;
if (writer->tag && writer->prio >= 2)
/* Prepend messages from STDOUT and STDERR with a tag and prio */
if (from_stdio) {
- return 0;
+ char *p;
+ size_t chunk_len = 0, c = 0;
+ /* -2 : priority byte and tag terminating '\0' */
+ size_t max_payload = LOGGER_ENTRY_MAX_PAYLOAD - writer->tag_len - 2;
+
+ if (writer->owner != current->group_leader) {
+ struct file *nfile;
+
+ nfile = make_new_file(file);
+ if (IS_ERR(nfile)) {
+ mutex_unlock(&log->mutex);
+ return PTR_ERR(nfile);
+ }
+
+ file = nfile;
+ writer = file->private_data;
+ }
+
+ /* Allocate STDIO line buffer */
+ if (!writer->buffer) {
+ writer->buffer = kzalloc(LOGGER_ENTRY_MAX_PAYLOAD, GFP_KERNEL);
+ writer->b_off = 0;
+
+ if (!writer->buffer) {
+ mutex_unlock(&log->mutex);
+ return -ENOMEM;
+ }
+ }
+
+ /* flush message from a different thread */
+ if (writer->b_owner != current && writer->b_off)
+ flush_thread_data(file);
+
+ count = 0;
+ /* -1 : leave space for message terminating '\0' */
+ c = min_t(size_t, iov_iter_count(from),
+ max_payload - writer->b_off - 1);
+
+ do {
+ size_t i;
+
+ if (copy_from_iter(writer->buffer + writer->b_off, c, from) != c) {
+ mutex_unlock(&log->mutex);
+ return -EFAULT;
+ }
+ count += c;
+ p = NULL;
+ for (i = 0; i < c; ++i) {
+ char *t = &writer->buffer[writer->b_off + i];
+ if (*t == '\0')
+ *t = '\n';
+ if (*t == '\n')
+ p = t;
+ }
+ if (p) {
+ *p++ = '\0';
+ chunk_len = p - writer->buffer;
+ } else {
+ writer->buffer[writer->b_off + c++] = '\0';
+ p = &writer->buffer[writer->b_off + c];
+ chunk_len = p - writer->buffer;
+
+ BUG_ON(chunk_len > max_payload);
+ if (chunk_len < max_payload ) {
+ writer->b_off = writer->b_off + c - 1;
+ continue;
+ }
+
+ }
+
+ header.len = chunk_len + writer->tag_len + 2;
+ fix_up_readers(log, sizeof(struct logger_entry) + header.len);
+
+ write_log_data(log, &header, writer, chunk_len);
+
+ /* move the remaining part of the message */
+ memmove(writer->buffer, p, writer->b_off + c - chunk_len);
+
+ /* new b_off points where the rimainder of the string ends */
+ writer->b_off = writer->b_off + c - chunk_len;
+ writer->buffer[writer->b_off] = '\0';
+
+ } while ((c = min_t(size_t, iov_iter_count(from), max_payload - 1)));
+
+ /* save for remaining unfinished line */
+ writer->b_header = header;
+ writer->b_owner = current;
} else {
orig = log->w_off;