1+ /**
2+ * @file helper.h
3+ * @author Pradosh (pradoshgame@gmail.com)
4+ * @brief Contains helper code for syscalls.
5+ * @version 0.1
6+ * @date 2026-04-03
7+ *
8+ * @copyright Copyright (c) Pradosh 2026
9+ *
10+ */
11+ #ifndef SYS_HELPER_H
12+ #define SYS_HELPER_H
13+
14+ #include <heap.h>
15+ #include <syscalls.h>
16+ #include <memory.h>
17+
18+ /**
19+ * @brief Frees a dynamically allocated array of strings.
20+ *
21+ * Releases memory for each string in the array and then frees
22+ * the array itself. Assumes each element and the array were
23+ * allocated using the kernel allocator (kfree-compatible).
24+ *
25+ * @param arr Pointer to the array of string pointers.
26+ * @param count Number of elements in the array.
27+ *
28+ * @note If @p arr is NULL, the function does nothing.
29+ * @warning Each element in @p arr must be individually allocated.
30+ */
31+ static void free_copied_string_array (char * * arr , int count ) {
32+ if (!arr )
33+ return ;
34+
35+ for (int i = 0 ; i < count ; ++ i ) {
36+ if (arr [i ]) // safety check
37+ kfree (arr [i ]);
38+ }
39+
40+ kfree (arr );
41+ }
42+
43+ /**
44+ * @brief Copies a NULL-terminated array of user strings into kernel space.
45+ *
46+ * Allocates a new array of strings and copies each string from the user-provided
47+ * array into kernel-managed memory. The resulting array is always NULL-terminated.
48+ *
49+ * A maximum of 32 strings are copied to prevent unbounded memory usage.
50+ *
51+ * @param user_arr Pointer to a NULL-terminated array of user-space strings.
52+ * @param out_arr Output pointer that receives the newly allocated array.
53+ *
54+ * @return Number of strings successfully copied on success.
55+ * @retval 0 If @p user_arr is NULL (no strings to copy).
56+ * @retval -LINUX_ENOMEM If memory allocation fails at any point.
57+ *
58+ * @note The caller is responsible for freeing the returned array using
59+ * free_copied_string_array().
60+ *
61+ * @warning Each string in @p user_arr must be valid and accessible.
62+ * No validation of user-space pointers is performed.
63+ *
64+ * @warning The function copies at most 32 strings; additional entries
65+ * in @p user_arr are ignored.
66+ */
67+ static int copy_user_string_array (char * const * user_arr , char * * * out_arr ) {
68+ if (!user_arr ) {
69+ * out_arr = NULL ;
70+ return 0 ;
71+ }
72+
73+ char * * copied = kmalloc (sizeof (char * ) * 33 );
74+ if (!copied )
75+ return - LINUX_ENOMEM ;
76+
77+ int count = 0 ;
78+ for (; count < 32 ; ++ count ) {
79+ const char * src = user_arr [count ];
80+ if (!src ) {
81+ copied [count ] = NULL ;
82+ * out_arr = copied ;
83+ return count ;
84+ }
85+
86+ size_t len = strlen (src );
87+ copied [count ] = kmalloc (len + 1 );
88+ if (!copied [count ]) {
89+ free_copied_string_array (copied , count );
90+ return - LINUX_ENOMEM ;
91+ }
92+
93+ memcpy (copied [count ], src , len + 1 );
94+ }
95+
96+ copied [32 ] = NULL ;
97+ * out_arr = copied ;
98+ return 32 ;
99+ }
100+
101+ /**
102+ * @brief Computes a hash value for a filesystem path.
103+ *
104+ * Uses a 32-bit FNV-1a hash algorithm to generate a deterministic
105+ * hash from a null-terminated path string. This can be used for
106+ * fast lookup or mapping paths to inode identifiers.
107+ *
108+ * @param path Null-terminated string representing the file path.
109+ *
110+ * @return 32-bit hash value for the given path.
111+ *
112+ * @note Returns a non-zero hash value. If the computed hash is zero,
113+ * it is replaced with 1 to avoid special-case handling.
114+ *
115+ * @warning The input @p path must be a valid null-terminated string.
116+ * Passing NULL results in undefined behavior.
117+ */
118+ static uint32_t path_inode_hash (const char * path ) {
119+ if (!path )
120+ return 1 ;
121+
122+ uint32_t hash = 2166136261u ;
123+ for (const unsigned char * p = (const unsigned char * )path ; p && * p ; ++ p ) {
124+ hash ^= * p ;
125+ hash *= 16777619u ;
126+ }
127+ return hash ? hash : 1 ;
128+ }
129+
130+ #endif
0 commit comments