Skip to content

Commit

Permalink
Fixed variadic arguments for open and added unit tests; Added fcntl;
Browse files Browse the repository at this point in the history
  • Loading branch information
drowaudio committed Jun 3, 2024
1 parent a46580a commit 983f575
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 22 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,14 @@ void set_error_mode (error_mode);
- [x] pthread_rwlock_wrlock ✔
- [x] pthread_spin_lock (linux)
- Files
- [x] open
- [x] open
- [x] openat
- [ ] close
- [x] fopen
- [ ] fread
- [ ] fwrite
- [ ] fclose
- [ ] fcntl
- [x] fcntl
- [ ] creat
- [ ] puts
- [ ] fputs
Expand Down
33 changes: 26 additions & 7 deletions src/rtcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,9 @@ struct check_flags_tests
assert(! are_all_bits_enabled (to_underlying (check_flags::malloc) + to_underlying (check_flags::realloc), 0b101));
assert(are_all_bits_enabled (to_underlying (check_flags::malloc) + to_underlying (check_flags::calloc), 0b100));
assert(are_all_bits_enabled (to_underlying (check_flags::syscall) + to_underlying (check_flags::openat), 0b0));
assert(! are_all_bits_enabled (to_underlying (check_flags::syscall) + to_underlying (check_flags::openat), 0b10010000000000000000000000000000000));
auto a1 = to_underlying (check_flags::syscall);
auto a2 = to_underlying (check_flags::openat);
assert(! are_all_bits_enabled (to_underlying (check_flags::syscall) + to_underlying (check_flags::openat), 0b10001000000000000000000000000000000000));
}
};

Expand All @@ -246,6 +248,7 @@ bool is_check_enabled_for_thread (check_flags check)
return are_all_bits_enabled (static_cast<uint64_t> (check), get_disabled_flags_for_thread());
}


//==============================================================================
// details
//==============================================================================
Expand Down Expand Up @@ -536,10 +539,10 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...)

va_list args;
va_start(args, oflag);
auto result = REAL(open)(path, oflag, args);
const mode_t mode = va_arg(args, int);
va_end(args);

return result;
return REAL(open)(path, oflag, mode);
}

INTERCEPTOR(FILE*, fopen, const char *path, const char *mode)
Expand All @@ -556,15 +559,27 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...)
{
log_function_if_realtime_context_and_enabled (rtc::check_flags::openat, __func__);

INTERCEPT_FUNCTION(int, openat, int, const char*, int, ...);

va_list args;
va_start(args, oflag);
INTERCEPT_FUNCTION(int, openat, int, const char*, int, ...);
auto result = REAL(openat)(fd, path, oflag, args);
mode_t mode = va_arg(args, int);
va_end(args);

return result;
return REAL(openat)(fd, path, oflag, args);
}

INTERCEPTOR(int, fcntl, int filedes, int cmd, ...)
{
log_function_if_realtime_context_and_enabled (rtc::check_flags::fcntl, __func__);

va_list args;
va_start(args, cmd);
void *arg = va_arg(args, void*);
va_end(args);

return fcntl(filedes, cmd, arg);
}

//==============================================================================
// system
Expand All @@ -591,13 +606,17 @@ INTERCEPTOR(long, context_switch, struct task_struct *prev, struct task_struct *
// syscall is deprecated, but still in use in libc++
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

#define FORWARD_ARGS(func, ...) func(__VA_ARGS__)
#define EXPAND_ARGS(...) (__VA_ARGS__)

INTERCEPTOR(long int, syscall, long int sid, ...)
{
log_function_if_realtime_context_and_enabled (rtc::check_flags::syscall, __func__);

INTERCEPT_FUNCTION(long, syscall, long, ...);

va_list args;
va_start(args, sid);
INTERCEPT_FUNCTION(long, syscall, long, ...);
va_end(args);

return REAL(syscall)(sid);
Expand Down
27 changes: 14 additions & 13 deletions src/rtcheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ namespace rtc
pthread_rwlock_wrlock = 1 << 21,
pthread_spin_lock = 1 << 22, // linux only
futex = 1 << 23, // linux only
OSSpinLockLock = 1ull << 35, // apple only
os_unfair_lock_lock = 1ull << 36, // apple only
OSSpinLockLock = 1 << 24, // apple only
os_unfair_lock_lock = 1 << 25, // apple only

threads = pthread_create | pthread_mutex_lock | pthread_mutex_unlock | pthread_join
| pthread_cond_signal | pthread_cond_broadcast | pthread_cond_wait
Expand All @@ -118,29 +118,30 @@ namespace rtc
//==============================================================================
// sleeping
//==============================================================================
sleep = 1 << 24,
usleep = 1 << 25,
nanosleep = 1 << 26,
sleep = 1 << 26,
usleep = 1 << 27,
nanosleep = 1 << 28,

sleeping = sleep | usleep | nanosleep,

//==============================================================================
// files
//==============================================================================
stat = 1 << 27,
fstat = 1 << 28,
open = 1 << 29,
fopen = 1 << 30,
openat = 1ull << 31,
stat = 1 << 29,
fstat = 1 << 30,
open = 1ull << 31,
fopen = 1ull << 32,
openat = 1ull << 33,
fcntl = 1ull << 34,

files = stat | fstat | open | fopen | openat,

//==============================================================================
// system
//==============================================================================
schedule = 1ull << 32, // linux only
context_switch = 1ull << 33, // linux only
syscall = 1ull << 34,
schedule = 1ull << 35, // linux only
context_switch = 1ull << 36, // linux only
syscall = 1ull << 37,

sys = schedule | context_switch | syscall
};
Expand Down
42 changes: 42 additions & 0 deletions tests/fail_fcntl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <rtcheck.h>
#include <memory>
#include <cassert>
#include <fcntl.h>
#include <filesystem>
#include <functional>
#include <rtcheck.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

int main()
{
rtc::realtime_context rc;

namespace fs = std::filesystem;
const fs::path temp_file = std::tmpnam (nullptr);
int fd = creat(temp_file.c_str(), S_IRUSR | S_IWUSR);
assert(fd != -1);

auto func = [fd] {
struct flock lock{};
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
lock.l_pid = ::getpid();

assert(fcntl(fd, F_GETLK, &lock) == 0);
assert(lock.l_type == F_UNLCK);
};

close(fd);
std::remove (temp_file.c_str());

return 0;
}

#pragma clang diagnostic pop
39 changes: 39 additions & 0 deletions tests/fail_open.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <rtcheck.h>
#include <memory>
#include <cassert>
#include <fcntl.h>
#include <filesystem>
#include <functional>
#include <rtcheck.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

int main()
{
rtc::realtime_context rc;

namespace fs = std::filesystem;
const fs::path temp_file = std::tmpnam (nullptr);

const int mode = S_IRGRP | S_IROTH | S_IRUSR | S_IWUSR;
const int fd = open (temp_file.c_str(), O_CREAT | O_WRONLY, mode);
assert(fd != -1);
close(fd);

struct stat st;
assert(stat(temp_file.c_str(), &st) == 0);

// Mask st_mode to get permission bits only
assert((st.st_mode & 0777) == mode);

auto res = fs::remove (temp_file);
assert (res);

return 0;
}

#pragma clang diagnostic pop
64 changes: 64 additions & 0 deletions tests/pass_unit_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <cassert>
#include <fcntl.h>
#include <filesystem>
#include <rtcheck.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

bool test_openCreatesFileWithProperMode()
{
namespace fs = std::filesystem;
const fs::path temp_file = std::tmpnam (nullptr);

const int mode = S_IRGRP | S_IROTH | S_IRUSR | S_IWUSR;
const int fd = open (temp_file.c_str(), O_CREAT | O_WRONLY, mode);
assert(fd != -1);
close(fd);

struct stat st;
assert(stat(temp_file.c_str(), &st) == 0);

// Mask st_mode to get permission bits only
assert((st.st_mode & 0777) == mode);

auto res = fs::remove (temp_file);
assert (res);
}

void test_fcntlFlockDiesWhenRealtime()
{
namespace fs = std::filesystem;
const fs::path temp_file = std::tmpnam (nullptr);
int fd = creat(temp_file.c_str(), S_IRUSR | S_IWUSR);
assert(fd != -1);

auto func = [fd] {
struct flock lock{};
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
lock.l_pid = ::getpid();

assert(fcntl(fd, F_GETLK, &lock) == 0);
assert(lock.l_type == F_UNLCK);
};

close(fd);
std::remove (temp_file.c_str());
}

#pragma clang diagnostic pop

int main()
{
test_openCreatesFileWithProperMode();
test_fcntlFlockDiesWhenRealtime();

return 0;
}

0 comments on commit 983f575

Please sign in to comment.