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:
Ehmry - 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"/> <resource name="RAM" quantum="400M"/>
<config> <config>
<vfs> <dir name="dev"> <log/> </dir> </vfs> <vfs> <dir name="dev"> <log/> </dir> </vfs>
<libc stdout="/dev/log"/> <libc stdout="/dev/log" stderr="/dev/log"/>
</config> </config>
</start> </start>
</config> </config>

View File

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

View File

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