VFS: line buffer LOG file-system

Buffer data written to log file handles until newline or overflow.

Ref #2467
Ref #2919
This commit is contained in:
Emery Hemingway 2018-07-16 16:41:55 +02:00 committed by Christian Helmuth
parent d1e7ca23e2
commit 64a63885d1
3 changed files with 70 additions and 7 deletions

View File

@ -22,7 +22,7 @@ install_config {
<resource name="RAM" quantum="400M"/>
<config>
<vfs> <dir name="dev"> <log/> </dir> </vfs>
<libc stdout="/dev/log"/>
<libc stdout="/dev/log" stderr="/dev/log"/>
</config>
</start>
</config>

View File

@ -36,6 +36,15 @@ int main(int argc, char **argv)
printf("Does printf work?\n");
printf("We can find out by printing a floating-point number: %f. How does that work?\n", 1.2345);
fprintf(stdout, "stdout: ");
for (int x = 0; x < 10; ++x)
fprintf(stdout, "%d ", x);
fprintf(stdout, "\n");
fprintf(stderr, "stderr: ");
for (int x = 0; x < 10; ++x)
fprintf(stderr, "%d ", x);
fprintf(stderr, "\n\n");
enum { ROUNDS = 64, SIZE_LARGE = 2048 };
@ -137,5 +146,7 @@ int main(int argc, char **argv)
}
}
perror("perror");
exit(error_count);
}

View File

@ -50,8 +50,32 @@ class Vfs::Log_file_system : public Single_file_system
{
private:
char _line_buf[Genode::Log_session::MAX_STRING_LEN];
int _line_pos = 0;
Genode::Log_session &_log;
void _flush()
{
int strip = 0;
for (int i = _line_pos - 1; i > 0; --i) {
switch(_line_buf[i]) {
case '\n':
case '\t':
case ' ':
++strip;
--_line_pos;
continue;
}
break;
}
_line_buf[_line_pos > 0 ? _line_pos : 0] = '\0';
_log.write(_line_buf);
_line_pos = 0;
}
public:
Log_vfs_handle(Directory_service &ds,
@ -61,6 +85,11 @@ class Vfs::Log_file_system : public Single_file_system
: Single_vfs_handle(ds, fs, alloc, 0),
_log(log) { }
~Log_vfs_handle()
{
if (_line_pos > 0) _flush();
}
Read_result read(char *, file_size, file_size &out_count) override
{
out_count = 0;
@ -74,11 +103,22 @@ class Vfs::Log_file_system : public Single_file_system
/* count does not include the trailing '\0' */
while (count > 0) {
char tmp[Genode::Log_session::MAX_STRING_LEN];
int const curr_count = min(count, sizeof(tmp) - 1);
memcpy(tmp, src, curr_count);
tmp[curr_count > 0 ? curr_count : 0] = 0;
_log.write(tmp);
int curr_count = min(count, ((sizeof(_line_buf) - 1) - _line_pos));
for (int i = 0; i < curr_count; ++i) {
if (src[i] == '\n') {
curr_count = i + 1;
break;
}
}
memcpy(_line_buf + _line_pos, src, curr_count);
_line_pos += curr_count;
if ((_line_pos == sizeof(_line_buf) - 1) ||
(_line_buf[_line_pos - 1] == '\n'))
_flush();
count -= curr_count;
src += curr_count;
}
@ -86,7 +126,13 @@ class Vfs::Log_file_system : public Single_file_system
return WRITE_OK;
}
bool read_ready() { return false; }
bool read_ready() override { return false; }
void sync()
{
if (_line_pos > 0)
_flush();
}
};
public:
@ -121,6 +167,12 @@ class Vfs::Log_file_system : public Single_file_system
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
}
Sync_result complete_sync(Vfs_handle *vfs_handle)
{
static_cast<Log_vfs_handle *>(vfs_handle)->sync();
return SYNC_OK;
}
};
#endif /* _INCLUDE__VFS__LOG_FILE_SYSTEM_H_ */