Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
226 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/* | ||
This file is part of Kismet | ||
Kismet is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation; either version 2 of the License, or | ||
(at your option) any later version. | ||
Kismet is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with Kismet; if not, write to the Free Software | ||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
*/ | ||
|
||
#include <stdio.h> | ||
|
||
#include "util.h" | ||
#include "filewritebuf.h" | ||
|
||
FileWritebuf::FileWritebuf(std::string in_filename, size_t in_chunk) { | ||
filename = in_filename; | ||
chunk_sz = in_chunk; | ||
|
||
reserve_chunk = NULL; | ||
free_commit = false; | ||
|
||
if ((backfile = fopen(in_filename.c_str(), "wb")) == NULL) { | ||
throw std::runtime_error("Unable to open file " + in_filename + ":" + | ||
kis_strerror_r(errno)); | ||
return; | ||
} | ||
|
||
reserve_chunk = new uint8_t[chunk_sz]; | ||
} | ||
|
||
FileWritebuf::~FileWritebuf() { | ||
local_eol_locker lock(&write_mutex); | ||
|
||
if (backfile != NULL) { | ||
fflush(backfile); | ||
fclose(backfile); | ||
backfile = NULL; | ||
} | ||
|
||
if (reserve_chunk != NULL) | ||
delete[] reserve_chunk; | ||
|
||
} | ||
|
||
void FileWritebuf::clear() { | ||
local_locker lock(&write_mutex); | ||
|
||
if (backfile != NULL) { | ||
if (ftruncate(fileno(backfile), 0) < 0) { | ||
fflush(backfile); | ||
fclose(backfile); | ||
backfile = NULL; | ||
} | ||
} | ||
} | ||
|
||
size_t FileWritebuf::used() { | ||
local_locker lock(&write_mutex); | ||
|
||
if (backfile != NULL) | ||
return (size_t) ftell(backfile); | ||
|
||
return 0; | ||
} | ||
|
||
size_t FileWritebuf::total() { | ||
local_locker lock(&write_mutex); | ||
|
||
if (backfile != NULL) | ||
return (size_t) ftell(backfile); | ||
|
||
return 0; | ||
} | ||
|
||
ssize_t FileWritebuf::write(uint8_t *in_data, size_t in_sz) { | ||
local_locker lock(&write_mutex); | ||
|
||
if (backfile == NULL) | ||
return -1; | ||
|
||
return (ssize_t) fwrite(in_data, in_sz, 1, backfile); | ||
} | ||
|
||
ssize_t FileWritebuf::reserve(unsigned char **data, size_t in_sz) { | ||
local_eol_locker lock(&write_mutex); | ||
|
||
if (write_reserved) { | ||
throw std::runtime_error("filebuf already reserved"); | ||
} | ||
|
||
if (in_sz < chunk_sz) { | ||
*data = reserve_chunk; | ||
free_commit = false; | ||
return in_sz; | ||
} | ||
|
||
*data = new unsigned char[in_sz]; | ||
free_commit = true; | ||
return in_sz; | ||
|
||
} | ||
|
||
ssize_t FileWritebuf::zero_copy_reserve(unsigned char **data, size_t in_sz) { | ||
return reserve(data, in_sz); | ||
} | ||
|
||
bool FileWritebuf::commit(unsigned char *data, size_t in_sz) { | ||
local_unlocker unwritelock(&write_mutex); | ||
|
||
if (!write_reserved) | ||
throw std::runtime_error("filebuf no pending commit"); | ||
|
||
if (backfile == NULL) | ||
throw std::runtime_error("filebuf could not open " + filename); | ||
|
||
write_reserved = false; | ||
|
||
size_t written = fwrite(data, in_sz, 1, backfile); | ||
|
||
if (free_commit) { | ||
free_commit = false; | ||
delete[] data; | ||
} | ||
|
||
return written == in_sz; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
This file is part of Kismet | ||
Kismet is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation; either version 2 of the License, or | ||
(at your option) any later version. | ||
Kismet is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with Kismet; if not, write to the Free Software | ||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
*/ | ||
|
||
#ifndef __FILEBUF_H__ | ||
#define __FILEBUF_H__ | ||
|
||
#include <stdint.h> | ||
#include <unistd.h> | ||
#include <pthread.h> | ||
#include <mutex> | ||
#include "buffer_handler.h" | ||
|
||
// Direct file IO buffer for writing logs via the buffer API | ||
// | ||
// MAY THROW EXCEPTIONS on construction if the file cannot be opened | ||
|
||
class FileWritebuf : public CommonBuffer { | ||
public: | ||
// Specify a file and a block size | ||
FileWritebuf(std::string in_path, size_t chunk_sz); | ||
virtual ~FileWritebuf(); | ||
|
||
virtual void clear(); | ||
|
||
virtual ssize_t size() { | ||
return chunk_sz; | ||
} | ||
|
||
virtual ssize_t available() { | ||
return chunk_sz; | ||
} | ||
|
||
virtual size_t used(); | ||
|
||
virtual size_t total(); | ||
|
||
// Write-only buffer, we don't allow peeking | ||
virtual ssize_t peek(unsigned char **ret_data, size_t in_sz) { | ||
return -1; | ||
} | ||
|
||
virtual ssize_t zero_copy_peek(unsigned char **ret_data, size_t in_sz) { | ||
return -1; | ||
} | ||
|
||
virtual void peek_free(unsigned char *in_data) { | ||
return; | ||
} | ||
|
||
// Write amount to buffer, arbitrarily allocating new chunks | ||
virtual ssize_t write(unsigned char *in_data, size_t in_sz); | ||
|
||
virtual ssize_t reserve(unsigned char **data, size_t in_sz); | ||
virtual ssize_t zero_copy_reserve(unsigned char **data, size_t in_sz); | ||
virtual bool commit(unsigned char *data, size_t in_sz); | ||
|
||
// Consume from buffer | ||
size_t consume(size_t in_sz) { | ||
return 0; | ||
} | ||
|
||
protected: | ||
size_t chunk_sz; | ||
uint8_t *reserve_chunk; | ||
|
||
bool free_commit; | ||
|
||
std::string filename; | ||
|
||
FILE *backfile; | ||
}; | ||
|
||
#endif | ||
|