#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <assert.h>
#include "daprobe.h"
DECLARE_VARIABLE_STANDARD; \
char* _filepath = ""; \
int __attribute((unused)) _fd; \
+ ssize_t __attribute((unused)) _filesize; \
int __attribute((unused)) _fstatret = -1; \
struct stat __attribute((unused)) _statbuf
GET_REAL_FUNC(FUNCNAME, LIBNAME); \
bfiltering = false; \
PRE_PROBEBLOCK()
-
// ==================================================================
// Additional macro for READ_START and WRITE_START
// ==================================================================
-#define FILE_API_START_BLOCK(API_ID, APITYPE) \
- PRE_PROBEBLOCK(); \
- POST_PACK_PROBEBLOCK_BEGIN(); \
- PREPARE_LOCAL_BUF(); \
- PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, "", 0); \
- PACK_COMMON_END(0, 0, 0); \
- PACK_RESOURCE(0, 0, APITYPE, 0, _filepath); \
- FLUSH_LOCAL_BUF(); \
- POST_PACK_PROBEBLOCK_END()
+#define DEFINE_FILESIZE_FD(fd) _fd = (fd); _filesize = get_fd_filesize(_fd);
+#define DEFINE_FILESIZE_FP(fp) _fd = checked_fileno(fp); _filesize = get_fd_filesize(_fd);
+#define DEFINE_FILESIZE_0() _fd = _filesize = 0;
+
+#define AFTER_PACK_ORIGINAL(API_ID, RVAL, SIZE, ERRNO, FD, FILESIZE, APITYPE, INPUTFORMAT, ...) \
+ POST_PACK_PROBEBLOCK_BEGIN(); \
+ PREPARE_LOCAL_BUF(); \
+ PACK_COMMON_BEGIN(MSG_PROBE_RESOURCE, API_ID, INPUTFORMAT, __VA_ARGS__); \
+ PACK_COMMON_END(RVAL,ERRNO, blockresult); \
+ PACK_RESOURCE(SIZE, FD, APITYPE, FILESIZE, _filepath); \
+ FLUSH_LOCAL_BUF(); \
+ POST_PACK_PROBEBLOCK_END();
+
+#define FILE_API_START_BLOCK(API_ID, APITYPE, INPUTFORMAT, ...) \
+ AFTER_PACK_ORIGINAL(API_ID, 0, 0, 0, _fd, _filesize, APITYPE, INPUTFORMAT, __VA_ARGS__)
+
+#define FILE_API_END_BLOCK(API_ID, RVAL, SIZE, APITYPE, INPUTFORMAT,...) \
+ blockresult = 0; bfiltering = 1; \
+ PRE_PROBEBLOCK(); \
+ AFTER_PACK_ORIGINAL(API_ID,RVAL, SIZE, newerrno, _fd, _filesize, APITYPE, INPUTFORMAT, __VA_ARGS__)
// ==================================================================
// AFTER_ORIGINAL macro for file
POST_PACK_PROBEBLOCK_MIDDLE_FD(SIZE, _fd, APITYPE); \
POST_PACK_PROBEBLOCK_END()
+
+
+static inline ssize_t get_fd_filesize(int fd)
+{
+ /**
+ * Calling library function on invalid file descriptiors is okay,
+ * for such cases we assume size == 0
+ * FIXME: Separate empty files and invalid descriptors.
+ **/
+ struct stat buf;
+ int err = fstat(fd, &buf);
+ if (err)
+ return 0;
+ return buf.st_size ?: 0;
+}
+
+static inline int checked_fileno(FILE *fp)
+{
+ assert((fp != NULL) &&
+ "This function (checked_fileno) is only called from probes\n"
+ "on library functions. Passing NULL instead of file pointer\n"
+ "to standart C functions is undefined behavior\n"
+ "and as such fatal error.\n");
+ return fileno(fp);
+}
+
+
#endif // __DA_IO_H__
ssize_t sret;
BEFORE_ORIGINAL_FILE(pread, LIBC);
-
- FILE_API_START_BLOCK(API_ID_pread, FD_API_READ_START);
-
+ DEFINE_FILESIZE_FD(fd);
+ FILE_API_START_BLOCK(API_ID_pread,FD_API_READ_START,
+ "dpxx", fd, buf, nbyte, offset);
sret = preadp(fd, buf, nbyte, offset);
-
- AFTER_PACK_ORIGINAL_FD(API_ID_pread,
- sret, (unsigned int)sret, fd, FD_API_READ_END,
- "dpxx", fd, buf, nbyte, offset);
+ FILE_API_END_BLOCK(API_ID_pread, sret, (unsigned int)sret,
+ FD_API_READ_END, "dpxx", fd, buf, nbyte, offset);
return sret;
}
ssize_t sret;
BEFORE_ORIGINAL_FILE(read, LIBC);
-
- FILE_API_START_BLOCK(API_ID_read, FD_API_READ_START);
+ DEFINE_FILESIZE_FD(fd);
+ FILE_API_START_BLOCK(API_ID_read, FD_API_READ_START,
+ "dpx", fd, buf, nbyte);
sret = readp(fd, buf, nbyte);
- AFTER_PACK_ORIGINAL_FD(API_ID_read,
- sret, (unsigned int)sret, fd, FD_API_READ_END,
- "dpx", fd, buf, nbyte);
+ FILE_API_END_BLOCK(API_ID_read, sret, (unsigned int)sret,
+ FD_API_READ_END, "dpx", fd, buf, nbyte);
return sret;
}
ssize_t sret;
BEFORE_ORIGINAL_FILE(pwrite, LIBC);
-
- FILE_API_START_BLOCK(API_ID_pwrite, FD_API_WRITE_START);
+ DEFINE_FILESIZE_FD(fd);
+ FILE_API_START_BLOCK(API_ID_pwrite, FD_API_WRITE_START,
+ "dpxx", fd, buf, nbyte, offset);
sret = pwritep(fd, buf, nbyte, offset);
- AFTER_PACK_ORIGINAL_FD(API_ID_pwrite,
- sret, (unsigned int)sret, fd, FD_API_WRITE_END,
- "dpxx", fd, buf, nbyte, offset);
+ FILE_API_END_BLOCK(API_ID_pwrite, sret, (unsigned int)sret,
+ FD_API_WRITE_END, "dpxx", fd, buf, nbyte, offset);
return sret;
}
ssize_t sret;
BEFORE_ORIGINAL_FILE(write, LIBC);
-
- FILE_API_START_BLOCK(API_ID_write, FD_API_WRITE_START);
-
+ DEFINE_FILESIZE_FD(fd);
+ FILE_API_START_BLOCK(API_ID_write, FD_API_WRITE_START,
+ "dpx", fd, buf, nbyte);
sret = writep(fd, buf, nbyte);
- AFTER_PACK_ORIGINAL_FD(API_ID_write,
- sret, (unsigned int)sret, fd, FD_API_WRITE_END,
- "dpx", fd, buf, nbyte);
+ FILE_API_END_BLOCK(API_ID_write, sret, (unsigned int)sret,
+ FD_API_WRITE_END, "dpx", fd, buf, nbyte);
return sret;
}
ssize_t sret;
BEFORE_ORIGINAL_FILE(readv, LIBC);
-
- FILE_API_START_BLOCK(API_ID_readv, FD_API_READ_START);
-
+ DEFINE_FILESIZE_FD(fd);
+ FILE_API_START_BLOCK(API_ID_readv, FD_API_READ_START,
+ "dpd", fd, iov, iovcnt);
sret = readvp(fd,iov,iovcnt);
- AFTER_PACK_ORIGINAL_FD(API_ID_readv,
- sret, (unsigned int)sret, fd, FD_API_READ_END,
- "dpd", fd, iov, iovcnt);
+ FILE_API_END_BLOCK(API_ID_readv, sret, (unsigned int)sret,
+ FD_API_READ_END, "dpd", fd, iov, iovcnt);
return sret;
}
static int (*vfprintfp)(FILE* stream, const char* format, va_list arg);
BEFORE_ORIGINAL_FILE(vfprintf, LIBC);
- FILE_API_START_BLOCK(API_ID_vfprintf, FD_API_WRITE_START);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_vfprintf, FD_API_WRITE_START,
+ "ps", stream, format);
ret = vfprintfp(stream, format, arg);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_vfprintf,
- ret, ret, stream, FD_API_WRITE_END, "ps", stream, format);
+ FILE_API_END_BLOCK(API_ID_vfprintf, ret, ret,
+ FD_API_WRITE_END, "ps", stream, format);
return ret;
}
static int (*vfscanfp)(FILE* stream, const char* format, va_list arg);
BEFORE_ORIGINAL_FILE(vfscanf, LIBC);
- FILE_API_START_BLOCK(API_ID_vfscanf, FD_API_READ_START);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_vfscanf, FD_API_READ_START,
+ "ps", stream, format);
ret = vfscanfp(stream, format, arg);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_vfscanf,
- ret, ret, stream, FD_API_READ_END, "ps", stream, format);
+ FILE_API_END_BLOCK(API_ID_vfscanf, ret, ret,
+ FD_API_READ_END, "ps", stream, format);
return ret;
}
static int (*fgetcp)(FILE* stream);
BEFORE_ORIGINAL_FILE(fgetc, LIBC);
- FILE_API_START_BLOCK(API_ID_fgetc, FD_API_READ_START);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_fgetc, FD_API_READ_START,
+ "p", stream);
ret = fgetcp(stream);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_fgetc,
- ret, (ret == EOF ? 0 : 1), stream, FD_API_READ_END, "p", stream);
+ FILE_API_END_BLOCK(API_ID_fgetc, ret, (ret != EOF),
+ FD_API_READ_END, "p", stream);
return ret;
}
BEFORE_ORIGINAL_FILE(fgets, LIBC);
- FILE_API_START_BLOCK(API_ID_fgets, FD_API_READ_START);
+ FILE_API_START_BLOCK(API_ID_fgets, FD_API_READ_START, "sdp", str, size, stream);
cret = fgetsp(str, size, stream);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_fgets, cret, (ret == NULL ? 0 : strlen(cret)),
- stream, FD_API_READ_END, "sdp", str, size, stream);
+ FILE_API_END_BLOCK(API_ID_fgets, cret, (ret == NULL ? 0 : strlen(cret)),
+ FD_API_READ_END, "sdp", str, size, stream);
return cret;
}
static int (*fputcp)(int character, FILE* stream);
BEFORE_ORIGINAL_FILE(fputc, LIBC);
- FILE_API_START_BLOCK(API_ID_fputc, FD_API_WRITE_START);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_fputc, FD_API_WRITE_START,
+ "dp", character, stream);
ret = fputcp(character, stream);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_fputc,
- ret, (ret == EOF ? 0 : 1), stream, FD_API_WRITE_END,
- "dp", character, stream);
+ FILE_API_END_BLOCK(API_ID_fputc, ret, (ret != EOF),
+ FD_API_WRITE_END, "dp", character, stream);
return ret;
}
static int (*fputsp)(const char* str, FILE* stream);
BEFORE_ORIGINAL_FILE(fputs, LIBC);
- FILE_API_START_BLOCK(API_ID_fputs, FD_API_WRITE_START);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_fputs, FD_API_WRITE_START,
+ "sp", str, stream);
ret = fputsp(str, stream);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_fputs,
- ret, ret, stream, FD_API_WRITE_END, "sp", str, stream);
+ FILE_API_END_BLOCK(API_ID_fputs, ret, ret, FD_API_WRITE_END,
+ "sp", str, stream);
return ret;
}
static int (*getcp)(FILE* stream);
BEFORE_ORIGINAL_FILE(getc, LIBC);
- FILE_API_START_BLOCK(API_ID_getc, FD_API_READ_START);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_getc, FD_API_READ_START,
+ "p", stream);
ret = getcp(stream);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_getc,
- ret, (ret == EOF ? 0 : 1), stream, FD_API_READ_END, "p", stream);
+ FILE_API_END_BLOCK(API_ID_getc, ret, (ret != EOF),
+ FD_API_READ_END, "p", stream);
return ret;
}
static int (*putcp)(int character, FILE* stream);
BEFORE_ORIGINAL_FILE(putc, LIBC);
- FILE_API_START_BLOCK(API_ID_putc, FD_API_WRITE_START);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_putc, FD_API_WRITE_START,
+ "dp", character, stream);
ret = putcp(character, stream);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_putc,
- ret, (ret == EOF ? 0 : 1), stream, FD_API_WRITE_END,
- "dp", character, stream);
+ FILE_API_END_BLOCK(API_ID_putc, ret, (ret != EOF),
+ FD_API_WRITE_END, "dp", character, stream);
return ret;
}
static int (*ungetcp)(int character, FILE* stream);
BEFORE_ORIGINAL_FILE(ungetc, LIBC);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_putc, FD_API_WRITE_START,
+ "dp", character, stream);
ret = ungetcp(character, stream);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_ungetc,
- ret, 0, stream, FD_API_OTHER, "dp", character, stream);
+ FILE_API_END_BLOCK(API_ID_ungetc, ret, 0,
+ FD_API_OTHER, "dp", character, stream);
return ret;
}
size_t tret;
BEFORE_ORIGINAL_FILE(fread, LIBC);
-
- FILE_API_START_BLOCK(API_ID_fread, FD_API_READ_START);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_fread, FD_API_READ_START,
+ "pxxp", ptr, size, count, stream);
tret = freadp(ptr, size, count, stream);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_fread,
- tret, 0, stream, FD_API_READ_END,
- "pxxp", ptr, size, count, stream);
+ FILE_API_END_BLOCK(API_ID_fread, tret, tret*size, FD_API_READ_END,
+ "pxxp", ptr, size, count, stream);
return tret;
}
size_t tret;
BEFORE_ORIGINAL_FILE(fwrite, LIBC);
-
- FILE_API_START_BLOCK(API_ID_fwrite, FD_API_WRITE_START);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_fwrite, FD_API_WRITE_START,
+ "pxxp", ptr, size, count, stream);
tret = fwritep(ptr, size, count, stream);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_fwrite,
- tret, 0, stream, FD_API_WRITE_END,
+ FILE_API_END_BLOCK(API_ID_fwrite, tret, tret*size, FD_API_WRITE_END,
"pxxp", ptr, size, count, stream);
return tret;
static int (*vfprintfp)(FILE* stream, const char* format, ...);
BEFORE_ORIGINAL_FILE(vfprintf, LIBC);
-
- FILE_API_START_BLOCK(API_ID_fprintf, FD_API_WRITE_START);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_fprintf, FD_API_WRITE_START,
+ "ps", stream, format);
va_list arg;
va_start(arg, format);
ret = vfprintfp(stream, format, arg);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_fprintf,
- ret, ret, stream, FD_API_WRITE_END, "ps", stream, format);
+ FILE_API_END_BLOCK(API_ID_fprintf, ret, ret, FD_API_WRITE_END,
+ "ps", stream, format);
va_end(arg);
return ret;
int fscanf(FILE* stream, const char* format, ...)
{
static int (*vfscanfp)(FILE* stream, const char* format, ...);
-
- BEFORE_ORIGINAL_FILE(vfscanf, LIBC);
- FILE_API_START_BLOCK(API_ID_fscanf, FD_API_READ_START);
+ BEFORE_ORIGINAL_FILE(vfscanf, LIBC);
+ DEFINE_FILESIZE_FP(stream);
+ FILE_API_START_BLOCK(API_ID_fscanf, FD_API_READ_START,
+ "ps", stream, format);
va_list arg;
va_start(arg, format);
ret = vfscanfp(stream, format, arg);
- AFTER_PACK_ORIGINAL_FILEP(API_ID_fscanf,
- ret, ret, stream, FD_API_READ_END, "ps", stream, format);
+ FILE_API_END_BLOCK(API_ID_fscanf, ret, ret,
+ FD_API_READ_END, "ps", stream, format);
va_end(arg);
return ret;
int printf(const char* format, ...)
{
static int (*vprintfp)(const char* format, ...);
-
- BEFORE_ORIGINAL_FILE(vprintf, LIBC);
- FILE_API_START_BLOCK(API_ID_printf, FD_API_WRITE_START);
+ BEFORE_ORIGINAL_FILE(vprintf, LIBC);
+ DEFINE_FILESIZE_0();
+ FILE_API_START_BLOCK(API_ID_printf, FD_API_WRITE_START,
+ "s", format);
va_list arg;
va_start(arg, format);
ret = vprintfp(format, arg);
- AFTER_PACK_ORIGINAL_NOFD(API_ID_printf,
- ret, ret, FD_API_WRITE_END, "s", format);
+ FILE_API_END_BLOCK(API_ID_printf, ret, ret,
+ FD_API_WRITE_END, "s", format);
va_end(arg);
return ret;
static int (*vscanfp)(const char* format, ...);
BEFORE_ORIGINAL_FILE(vscanf, LIBC);
-
- FILE_API_START_BLOCK(API_ID_scanf, FD_API_READ_START);
+ DEFINE_FILESIZE_0();
+ FILE_API_START_BLOCK(API_ID_scanf, FD_API_READ_START,
+ "s", format);
va_list arg;
va_start(arg, format);
ret = vscanfp(format, arg);
- AFTER_PACK_ORIGINAL_NOFD(API_ID_scanf,
- ret, ret, FD_API_READ_END, "s", format);
+ FILE_API_END_BLOCK(API_ID_scanf, ret, ret,
+ FD_API_READ_END, "s", format);
va_end(arg);
return ret;
static int (*getcharp)();
BEFORE_ORIGINAL_FILE(getchar, LIBC);
- FILE_API_START_BLOCK(API_ID_getchar, FD_API_READ_START);
+ DEFINE_FILESIZE_0();
+ FILE_API_START_BLOCK(API_ID_getchar, FD_API_READ_START,
+ "s", "");
ret = getcharp();
- AFTER_PACK_ORIGINAL_NOFD(API_ID_getchar,
- ret, (ret == EOF ? 0 : 1), FD_API_READ_END, "s", "");
+ FILE_API_END_BLOCK(API_ID_getchar, ret, (ret != EOF ),
+ FD_API_READ_END, "", 0);
return ret;
}
static int (*putcharp)(int c);
BEFORE_ORIGINAL_FILE(putchar, LIBC);
- FILE_API_START_BLOCK(API_ID_putchar, FD_API_WRITE_START);
+ DEFINE_FILESIZE_0();
+ FILE_API_START_BLOCK(API_ID_putchar, FD_API_WRITE_START,
+ "d", c);
ret = putcharp(c);
- AFTER_PACK_ORIGINAL_NOFD(API_ID_putchar,
- ret, (ret == EOF ? 0 : 1), FD_API_WRITE_END, "d", c);
+ FILE_API_END_BLOCK(API_ID_putchar, ret, (ret != EOF),
+ FD_API_WRITE_END, "d", c);
return ret;
}
char* cret;
BEFORE_ORIGINAL_FILE(gets, LIBC);
-
- FILE_API_START_BLOCK(API_ID_gets, FD_API_READ_START);
+ DEFINE_FILESIZE_0();
+ FILE_API_START_BLOCK(API_ID_gets, FD_API_READ_START,
+ "s", str);
cret = getsp(str);
- AFTER_PACK_ORIGINAL_NOFD(API_ID_gets,
- cret, strlen(cret), FD_API_READ_END, "s", str);
+ FILE_API_END_BLOCK(API_ID_gets, cret, strlen(cret),
+ FD_API_READ_END, "s", str);
return cret;
}
static int (*putsp)(const char* str);
BEFORE_ORIGINAL_FILE(puts, LIBC);
- FILE_API_START_BLOCK(API_ID_puts, FD_API_WRITE_START);
+ DEFINE_FILESIZE_0();
+ FILE_API_START_BLOCK(API_ID_puts, FD_API_WRITE_START,
+ "s", str);
ret = putsp(str);
- AFTER_PACK_ORIGINAL_NOFD(API_ID_puts,
- ret, ret, FD_API_WRITE_END, "s", str);
+ FILE_API_END_BLOCK(API_ID_puts, ret, ret,
+ FD_API_WRITE_END, "s", str);
return ret;
}
#endif