Skip to content

Commit 5785fd3

Browse files
extend sanity kit
1 parent 317e23d commit 5785fd3

File tree

2 files changed

+372
-0
lines changed

2 files changed

+372
-0
lines changed

code/logic/fossil/pizza/sanity.h

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,81 @@ int fossil_sanity_sys_create_dir(const char* dirname);
116116
*/
117117
int fossil_sanity_sys_dir_exists(const char* dirname);
118118

119+
/**
120+
* @brief Reads the entire contents of a file into memory.
121+
*
122+
* The returned buffer is null-terminated and allocated dynamically.
123+
* The caller is responsible for freeing the returned memory using free().
124+
*
125+
* @param filename Path to the file to read.
126+
* @return char* Pointer to allocated null-terminated buffer on success,
127+
* or NULL on failure.
128+
*/
129+
char* fossil_sanity_sys_read_file(const char* filename);
130+
131+
/**
132+
* @brief Writes data to a file, replacing any existing contents.
133+
*
134+
* @param filename Path to the file.
135+
* @param data Null-terminated string to write.
136+
* @return int Returns 0 on success, negative on failure.
137+
*/
138+
int fossil_sanity_sys_write_file(const char* filename, const char* data);
139+
140+
/**
141+
* @brief Deletes a file from the filesystem.
142+
*
143+
* @param filename Path to the file to delete.
144+
* @return int Returns 0 on success, negative on failure.
145+
*/
146+
int fossil_sanity_sys_delete_file(const char* filename);
147+
148+
/**
149+
* @brief Retrieves the value of an environment variable.
150+
*
151+
* @param name Name of the environment variable.
152+
* @return const char* Value of the variable, or NULL if not found.
153+
*/
154+
const char* fossil_sanity_sys_getenv(const char* name);
155+
156+
/**
157+
* @brief Sets or overrides an environment variable.
158+
*
159+
* @param name Name of the environment variable.
160+
* @param value Value to set.
161+
* @return int Returns 0 on success, negative on failure.
162+
*/
163+
int fossil_sanity_sys_setenv(const char* name, const char* value);
164+
165+
/**
166+
* @brief Retrieves the current system timestamp as a formatted string.
167+
*
168+
* @return char* Newly allocated string with timestamp (caller must free).
169+
*/
170+
char* fossil_sanity_sys_timestamp(void);
171+
172+
/**
173+
* @brief Returns uptime in milliseconds since process start.
174+
*
175+
* @return long long Milliseconds since process launch.
176+
*/
177+
long long fossil_sanity_sys_uptime_ms(void);
178+
179+
/**
180+
* @brief Checks if a process is still running.
181+
*
182+
* @param pid Process ID.
183+
* @return int Returns 1 if running, 0 if not, negative on error.
184+
*/
185+
int fossil_sanity_sys_is_running(int pid);
186+
187+
/**
188+
* @brief Attempts to terminate a process by PID.
189+
*
190+
* @param pid Process ID.
191+
* @return int Returns 0 on success, negative on failure.
192+
*/
193+
int fossil_sanity_sys_kill(int pid);
119194

120195
#ifdef __cplusplus
121196
}
@@ -225,6 +300,91 @@ int fossil_sanity_sys_dir_exists(const char* dirname);
225300
#define _FOSSIL_SANITY_SYS_DIR_EXISTS(dirname) \
226301
fossil_sanity_sys_dir_exists(dirname)
227302

303+
/**
304+
* @brief Reads the entire contents of a file into memory.
305+
*
306+
* The returned buffer is null-terminated and allocated dynamically.
307+
* The caller is responsible for freeing the returned memory using free().
308+
*
309+
* @param filename Path to the file to read.
310+
* @return char* Pointer to allocated null-terminated buffer on success,
311+
* or NULL on failure.
312+
*/
313+
#define _FOSSIL_SANITY_SYS_READ_FILE(filename) \
314+
fossil_sanity_sys_read_file(filename)
315+
316+
/**
317+
* @brief Writes data to a file, replacing any existing contents.
318+
*
319+
* @param filename Path to the file.
320+
* @param data Null-terminated string to write.
321+
* @return int Returns 0 on success, negative on failure.
322+
*/
323+
#define _FOSSIL_SANITY_SYS_WRITE_FILE(filename, data) \
324+
fossil_sanity_sys_write_file(filename, data)
325+
326+
/**
327+
* @brief Deletes a file from the filesystem.
328+
*
329+
* @param filename Path to the file to delete.
330+
* @return int Returns 0 on success, negative on failure.
331+
*/
332+
#define _FOSSIL_SANITY_SYS_DELETE_FILE(filename) \
333+
fossil_sanity_sys_delete_file(filename)
334+
335+
/**
336+
* @brief Retrieves the value of an environment variable.
337+
*
338+
* @param name Name of the environment variable.
339+
* @return const char* Value of the variable, or NULL if not found.
340+
*/
341+
#define _FOSSIL_SANITY_SYS_GETENV(name) \
342+
fossil_sanity_sys_getenv(name)
343+
344+
/**
345+
* @brief Sets or overrides an environment variable.
346+
*
347+
* @param name Name of the environment variable.
348+
* @param value Value to set.
349+
* @return int Returns 0 on success, negative on failure.
350+
*/
351+
#define _FOSSIL_SANITY_SYS_SETENV(name, value) \
352+
fossil_sanity_sys_setenv(name, value)
353+
354+
/**
355+
* @brief Retrieves the current system timestamp as a formatted string.
356+
*
357+
* @return char* Newly allocated string with timestamp (caller must free).
358+
*/
359+
#define _FOSSIL_SANITY_SYS_TIMESTAMP() \
360+
fossil_sanity_sys_timestamp()
361+
362+
/**
363+
* @brief Returns uptime in milliseconds since process start.
364+
*
365+
* @return long long Milliseconds since process launch.
366+
*/
367+
#define _FOSSIL_SANITY_SYS_UPTIME_MS() \
368+
fossil_sanity_sys_uptime_ms()
369+
370+
/**
371+
* @brief Checks if a process is still running.
372+
*
373+
* @param pid Process ID.
374+
* @return int Returns 1 if running, 0 if not, negative on error.
375+
*/
376+
#define _FOSSIL_SANITY_SYS_IS_RUNNING(pid) \
377+
fossil_sanity_sys_is_running(pid)
378+
379+
/**
380+
* @brief Attempts to terminate a process by PID.
381+
*
382+
* @param pid Process ID.
383+
* @return int Returns 0 on success, negative on failure.
384+
*/
385+
#define _FOSSIL_SANITY_SYS_KILL(pid) \
386+
fossil_sanity_sys_kill(pid)
387+
228388
// *****************************************************************************
229389
// Public API Macros
230390
// *****************************************************************************
@@ -323,4 +483,89 @@ int fossil_sanity_sys_dir_exists(const char* dirname);
323483
#define FOSSIL_SANITY_SYS_DIR_EXISTS(dirname) \
324484
_FOSSIL_SANITY_SYS_DIR_EXISTS(dirname)
325485

486+
/**
487+
* @brief Reads the entire contents of a file into memory.
488+
*
489+
* The returned buffer is null-terminated and allocated dynamically.
490+
* The caller is responsible for freeing the returned memory using free().
491+
*
492+
* @param filename Path to the file to read.
493+
* @return char* Pointer to allocated null-terminated buffer on success,
494+
* or NULL on failure.
495+
*/
496+
#define FOSSIL_SANITY_SYS_READ_FILE(filename) \
497+
_FOSSIL_SANITY_SYS_READ_FILE(filename)
498+
499+
/**
500+
* @brief Writes data to a file, replacing any existing contents.
501+
*
502+
* @param filename Path to the file.
503+
* @param data Null-terminated string to write.
504+
* @return int Returns 0 on success, negative on failure.
505+
*/
506+
#define FOSSIL_SANITY_SYS_WRITE_FILE(filename, data) \
507+
_FOSSIL_SANITY_SYS_WRITE_FILE(filename, data)
508+
509+
/**
510+
* @brief Deletes a file from the filesystem.
511+
*
512+
* @param filename Path to the file to delete.
513+
* @return int Returns 0 on success, negative on failure.
514+
*/
515+
#define FOSSIL_SANITY_SYS_DELETE_FILE(filename) \
516+
_FOSSIL_SANITY_SYS_DELETE_FILE(filename)
517+
518+
/**
519+
* @brief Retrieves the value of an environment variable.
520+
*
521+
* @param name Name of the environment variable.
522+
* @return const char* Value of the variable, or NULL if not found.
523+
*/
524+
#define FOSSIL_SANITY_SYS_GETENV(name) \
525+
_FOSSIL_SANITY_SYS_GETENV(name)
526+
527+
/**
528+
* @brief Sets or overrides an environment variable.
529+
*
530+
* @param name Name of the environment variable.
531+
* @param value Value to set.
532+
* @return int Returns 0 on success, negative on failure.
533+
*/
534+
#define FOSSIL_SANITY_SYS_SETENV(name, value) \
535+
_FOSSIL_SANITY_SYS_SETENV(name, value)
536+
537+
/**
538+
* @brief Retrieves the current system timestamp as a formatted string.
539+
*
540+
* @return char* Newly allocated string with timestamp (caller must free).
541+
*/
542+
#define FOSSIL_SANITY_SYS_TIMESTAMP() \
543+
_FOSSIL_SANITY_SYS_TIMESTAMP()
544+
545+
/**
546+
* @brief Returns uptime in milliseconds since process start.
547+
*
548+
* @return long long Milliseconds since process launch.
549+
*/
550+
#define FOSSIL_SANITY_SYS_UPTIME_MS() \
551+
_FOSSIL_SANITY_SYS_UPTIME_MS()
552+
553+
/**
554+
* @brief Checks if a process is still running.
555+
*
556+
* @param pid Process ID.
557+
* @return int Returns 1 if running, 0 if not, negative on error.
558+
*/
559+
#define FOSSIL_SANITY_SYS_IS_RUNNING(pid) \
560+
_FOSSIL_SANITY_SYS_IS_RUNNING(pid)
561+
562+
/**
563+
* @brief Kills a running process.
564+
*
565+
* @param pid Process ID.
566+
* @return int Returns 0 on success, negative on failure.
567+
*/
568+
#define FOSSIL_SANITY_SYS_KILL(pid) \
569+
_FOSSIL_SANITY_SYS_KILL(pid)
570+
326571
#endif // FOSSIL_SANITY_H

code/logic/sanity.c

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,130 @@ int fossil_sanity_sys_dir_exists(const char* dirname) {
103103
return (stat(dirname, &buffer) == 0 && S_ISDIR(buffer.st_mode)); // On Unix-like systems, use the stat function to check if the directory exists.
104104
#endif
105105
}
106+
107+
// *****************************************************************************
108+
// File I/O
109+
// *****************************************************************************
110+
111+
char* fossil_sanity_sys_read_file(const char* filename) {
112+
if (!filename) return NULL;
113+
114+
FILE* f = fopen(filename, "rb");
115+
if (!f) return NULL;
116+
117+
fseek(f, 0, SEEK_END);
118+
long size = ftell(f);
119+
rewind(f);
120+
121+
if (size < 0) { fclose(f); return NULL; }
122+
123+
char* buffer = (char*)malloc(size + 1);
124+
if (!buffer) { fclose(f); return NULL; }
125+
126+
size_t read = fread(buffer, 1, size, f);
127+
buffer[read] = '\0';
128+
fclose(f);
129+
130+
return buffer;
131+
}
132+
133+
int fossil_sanity_sys_write_file(const char* filename, const char* data) {
134+
if (!filename || !data) return -1;
135+
136+
FILE* f = fopen(filename, "wb");
137+
if (!f) return -1;
138+
139+
size_t len = strlen(data);
140+
size_t written = fwrite(data, 1, len, f);
141+
fclose(f);
142+
143+
return (written == len) ? 0 : -1;
144+
}
145+
146+
int fossil_sanity_sys_delete_file(const char* filename) {
147+
if (!filename) return -1;
148+
return remove(filename) == 0 ? 0 : -1;
149+
}
150+
151+
// *****************************************************************************
152+
// Environment Variables
153+
// *****************************************************************************
154+
155+
const char* fossil_sanity_sys_getenv(const char* name) {
156+
if (!name) return NULL;
157+
return getenv(name);
158+
}
159+
160+
int fossil_sanity_sys_setenv(const char* name, const char* value) {
161+
if (!name || !value) return -1;
162+
163+
#ifdef _WIN32
164+
return _putenv_s(name, value) == 0 ? 0 : -1;
165+
#else
166+
return setenv(name, value, 1) == 0 ? 0 : -1;
167+
#endif
168+
}
169+
170+
// *****************************************************************************
171+
// Time Utilities
172+
// *****************************************************************************
173+
174+
char* fossil_sanity_sys_timestamp(void) {
175+
time_t now = time(NULL);
176+
if (now == (time_t)-1) return NULL;
177+
178+
struct tm tstruct;
179+
#ifdef _WIN32
180+
localtime_s(&tstruct, &now);
181+
#else
182+
localtime_r(&now, &tstruct);
183+
#endif
184+
185+
char buf[64];
186+
if (strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tstruct) == 0)
187+
return NULL;
188+
189+
char* out = strdup(buf);
190+
return out;
191+
}
192+
193+
long long fossil_sanity_sys_uptime_ms(void) {
194+
#ifdef _WIN32
195+
return GetTickCount64();
196+
#else
197+
struct timeval tv;
198+
if (gettimeofday(&tv, NULL) != 0) return -1;
199+
return (long long)tv.tv_sec * 1000LL + (tv.tv_usec / 1000);
200+
#endif
201+
}
202+
203+
// *****************************************************************************
204+
// Process Utilities
205+
// *****************************************************************************
206+
207+
int fossil_sanity_sys_is_running(int pid) {
208+
if (pid <= 0) return -1;
209+
#ifdef _WIN32
210+
HANDLE h = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)pid);
211+
if (!h) return 0;
212+
DWORD code;
213+
int running = (GetExitCodeProcess(h, &code) && code == STILL_ACTIVE);
214+
CloseHandle(h);
215+
return running ? 1 : 0;
216+
#else
217+
return (kill(pid, 0) == 0) ? 1 : 0;
218+
#endif
219+
}
220+
221+
int fossil_sanity_sys_kill(int pid) {
222+
if (pid <= 0) return -1;
223+
#ifdef _WIN32
224+
HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, (DWORD)pid);
225+
if (!h) return -1;
226+
int result = TerminateProcess(h, 1) ? 0 : -1;
227+
CloseHandle(h);
228+
return result;
229+
#else
230+
return (kill(pid, SIGTERM) == 0) ? 0 : -1;
231+
#endif
232+
}

0 commit comments

Comments
 (0)