return fname[0] == '/';
}
-/* Return pointer to static buffer */
-char *absolutize_filepath(char buffer[PATH_MAX], const char *fname)
+char *absolutize_filepath(const char *fname, char *buffer, size_t bufsiz)
{
char cwd[PATH_MAX];
assert(fname && "Filename, passed to stdc function is NULL.");
if (absolute_filepath_p(fname) || getcwd(cwd, sizeof(cwd)) == NULL)
- snprintf(buffer, PATH_MAX, "%s", fname);
+ snprintf(buffer, bufsiz, "%s", fname);
else
- snprintf(buffer, PATH_MAX, "%s/%s", cwd, fname);
+ snprintf(buffer, bufsiz, "%s/%s", cwd, fname);
+ return buffer;
+}
+
+char *real_abs_path(int fd, char *buffer, size_t bufsiz)
+{
+ static const char *PROC_FD = "/proc/self/fd/%d";
+ char proc_path[sizeof(PROC_FD) + 16]; /* PATH_MAX not needed here */
+ ssize_t ret = 0;
+
+ if (fd < 0)
+ return NULL;
+
+ sprintf(proc_path, PROC_FD, fd);
+
+ ret = readlink(proc_path, buffer, bufsiz);
+ if (ret < 0) /* some error occured */
+ return NULL;
+ buffer[ret] = '\0';
+
return buffer;
}
//wchar_t* -> char*
void WcharToChar(char* pstrDest, const wchar_t* pwstrSrc);
-char *absolutize_filepath(char buf[PATH_MAX], const char *fname);
+char *absolutize_filepath(const char *fname, char *buf, size_t bufsiz);
+
+/* returns the real absolute file path (resolves symlinks) */
+char *real_abs_path(int fd, char *buffer, size_t bufsiz);
// screen capture functions
int initialize_screencapture();
static enum DaOptions _sopt = OPT_FILE;
+static inline char *get_abs_path(int fd, const char *fname,
+ char *buf, size_t bufsiz)
+{
+ char *path = real_abs_path(fd, buf, bufsiz);
+
+ if (!path)
+ path = absolutize_filepath(fname, buf, bufsiz);
+
+ return path;
+}
+
int open(const char* path, int oflag, ...)
{
static int (*openp)(const char* path, int oflag, ...);
int mode = 0;
BEFORE_ORIGINAL_FILE_NOFILTER(open, LIBC);
- _filepath = (char*)path;
if(oflag & O_CREAT)
{
ret = openp(path, oflag, mode);
+ _filepath = get_abs_path(ret, path, buffer, PATH_MAX);
+
AFTER_PACK_ORIGINAL_FD(API_ID_open, 'd', ret, 0, ret, FD_API_OPEN,
- "s4dd", absolutize_filepath(buffer, path), oflag,
- mode);
+ "s4dd", path, oflag, mode);
return ret;
}
int mode = 0;
BEFORE_ORIGINAL_FILE_NOFILTER(openat, LIBC);
- _filepath = (char*)path;
if(oflag & O_CREAT)
{
ret = openatp(fd, path, oflag, mode);
+ _filepath = get_abs_path(ret, path, buffer, PATH_MAX);
+
AFTER_PACK_ORIGINAL_FD(API_ID_openat, 'd', ret, 0, ret, FD_API_OPEN,
- "ds4dd", fd, absolutize_filepath(buffer, path),
- oflag, mode);
+ "ds4dd", fd, path, oflag, mode);
return ret;
}
char buffer[PATH_MAX];
BEFORE_ORIGINAL_FILE_NOFILTER(creat, LIBC);
- _filepath = (char*)path;
ret = creatp(path, mode);
+ _filepath = get_abs_path(ret, path, buffer, PATH_MAX);
+
AFTER_PACK_ORIGINAL_FD(API_ID_creat, 'd', ret, 0, ret, FD_API_OPEN,
- "s4d", absolutize_filepath(buffer, path), mode);
+ "s4d", path, mode);
return ret;
}
static enum DaOptions _sopt = OPT_FILE;
+static inline char *get_abs_path(FILE *file, const char *fname,
+ char *buf, size_t bufsiz)
+{
+ char *path = file ? real_abs_path(fileno(file), buf, bufsiz): NULL;
+
+ if (!path)
+ path = absolutize_filepath(fname, buf, bufsiz);
+
+ return path;
+}
+
FILE* fopen(const char* filename, const char* mode)
{
static FILE* (*fopenp)(const char* filename, const char* mode);
FILE* fret;
BEFORE_ORIGINAL_FILE_NOFILTER(fopen, LIBC);
- _filepath = (char*)filename;
fret = fopenp(filename, mode);
+ _filepath = get_abs_path(fret, filename, buffer, PATH_MAX);
+
AFTER_PACK_ORIGINAL_FILEP(API_ID_fopen,
'p', fret, 0, fret, FD_API_OPEN, "s4s",
- absolutize_filepath(buffer, filename), mode);
+ filename, mode);
return fret;
}
FILE* fret;
BEFORE_ORIGINAL_FILE_NOFILTER(freopen, LIBC);
- _filepath = (char*)filename;
fret = freopenp(filename, mode, stream);
+ _filepath = get_abs_path(fret, filename, buffer, PATH_MAX);
+
AFTER_PACK_ORIGINAL_FILEP(API_ID_freopen, 'p', fret, 0, fret, FD_API_OPEN,
- "s4sp", absolutize_filepath(buffer, filename),
- mode, voidp_to_uint64(stream));
+ "s4sp", filename, mode,
+ voidp_to_uint64(stream));
return fret;
}