/* kampath.h  -- per-thread logical current-directory + path resolution.
 *
 * #39 concurrency: the engine used the PROCESS-GLOBAL cwd (_chdir) to locate
 * table/index/catalog files, then opened them by RELATIVE name. That is a
 * single shared resource, so concurrent connections stomped each other and the
 * engine needed a coarse ExecMutex to stay correct.
 *
 * This layer replaces the process cwd with a PER-THREAD logical cwd. KAM_chdir
 * updates the calling thread's own cwd string (no _chdir); every relative file
 * open is resolved against that thread's cwd. Threads no longer share the cwd,
 * so concurrent queries are correct WITHOUT the lock.
 *
 * The file-primitive macros below redirect relative fopen/remove/rename/chmod
 * through the resolver. They are function-like (only fire on `name(`), contain
 * no `stat`/`open` (which collide with struct/member names), and must be
 * included AFTER all system headers -- hence they live at the very bottom of
 * isqllib.h. The implementation TU (kampath.c) defines KAMPATH_IMPL first so it
 * calls the real CRT functions.
 */
#ifndef KAMPATH_H
#define KAMPATH_H

#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

/* Resolve `in` to an absolute path in `out` (size outsz). Absolute inputs are
 * copied through unchanged; relative inputs are prefixed with this thread's
 * logical cwd. Returns `out`. */
char *KamResolvePath(const char *in, char *out, int outsz);

/* Set / get this thread's logical cwd. KamSetThreadCwd returns 0 on success,
 * -1 if the resolved directory does not exist (matches _chdir's convention so
 * existing `if(KAM_chdir(...)!=0)` callers behave the same). */
int   KamSetThreadCwd(const char *path);
char *KamGetThreadCwd(char *buf, int n);

/* Resolving wrappers over the CRT path functions. */
FILE *KamFopenResolved (const char *path, const char *mode);
int   KamRemoveResolved(const char *path);
int   KamRenameResolved(const char *a, const char *b);
int   KamChmodResolved (const char *path, int mode);

#ifdef __cplusplus
}
#endif

/* In every TU EXCEPT the implementation, redirect the relative-path CRT calls
 * through the resolver. Guarded so kampath.c itself keeps the real functions. */
#if !defined(KAMPATH_IMPL) && !defined(KAMPATH_NO_MACROS)
#define fopen(p,m)    KamFopenResolved((p),(m))
#define remove(p)     KamRemoveResolved((p))
#define rename(a,b)   KamRenameResolved((a),(b))
#define chmod(p,m)    KamChmodResolved((p),(m))
#endif

#endif /* KAMPATH_H */
