P_LIB_API PShm * p_shm_new (const pchar *name, psize size, PShmAccessPerms perms, PError **error) { PShm *ret; pchar *new_name; if (P_UNLIKELY (name == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IPC_INVALID_ARGUMENT, 0, "Invalid input argument"); return NULL; } if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PShm))) == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IPC_NO_RESOURCES, 0, "Failed to allocate memory for shared segment"); return NULL; } if (P_UNLIKELY ((new_name = p_malloc0 (strlen (name) + strlen (P_SHM_SUFFIX) + 1)) == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IPC_NO_RESOURCES, 0, "Failed to allocate memory for segment name"); p_shm_free (ret); return NULL; } strcpy (new_name, name); strcat (new_name, P_SHM_SUFFIX); ret->platform_key = p_ipc_get_platform_key (new_name, FALSE); ret->perms = perms; ret->size = size; p_free (new_name); if (P_UNLIKELY (pp_shm_create_handle (ret, error) == FALSE)) { p_shm_free (ret); return NULL; } if (P_LIKELY (ret->size > size && size != 0)) ret->size = size; return ret; }
P_LIB_API void p_hash_table_insert (PHashTable *table, ppointer key, ppointer value) { PHashTableNode *node; puint hash; if (P_UNLIKELY (table == NULL)) return; if ((node = pp_hash_table_find_node (table, key)) == NULL) { if (P_UNLIKELY ((node = p_malloc0 (sizeof (PHashTableNode))) == NULL)) { P_ERROR ("PHashTable::p_hash_table_insert: failed to allocate memory"); return; } hash = pp_hash_table_calc_hash (key, table->size); /* Insert a new node in front of others */ node->key = key; node->value = value; node->next = table->table[hash]; table->table[hash] = node; } else node->value = value; }
P_LIB_API PDirEntry * p_dir_get_next_entry (PDir *dir, PError **error) { PDirEntry *ret; DWORD dwAttrs; if (P_UNLIKELY (dir == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IO_INVALID_ARGUMENT, 0, "Invalid input argument"); return NULL; } if (dir->cached == TRUE) dir->cached = FALSE; else { if (P_UNLIKELY (dir->search_handle == INVALID_HANDLE_VALUE)) { p_error_set_error_p (error, (pint) P_ERROR_IO_INVALID_ARGUMENT, 0, "Not a valid (or closed) directory stream"); return NULL; } if (P_UNLIKELY (!FindNextFileA (dir->search_handle, &dir->find_data))) { p_error_set_error_p (error, (pint) p_error_get_last_io (), p_error_get_last_system (), "Failed to call FindNextFileA() to read directory stream"); FindClose (dir->search_handle); dir->search_handle = INVALID_HANDLE_VALUE; return NULL; } } if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PDirEntry))) == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IO_NO_RESOURCES, 0, "Failed to allocate memory for directory entry"); return NULL; } ret->name = p_strdup (dir->find_data.cFileName); dwAttrs = dir->find_data.dwFileAttributes; if (dwAttrs & FILE_ATTRIBUTE_DIRECTORY) ret->type = P_DIR_ENTRY_TYPE_DIR; else if (dwAttrs & FILE_ATTRIBUTE_DEVICE) ret->type = P_DIR_ENTRY_TYPE_OTHER; else ret->type = P_DIR_ENTRY_TYPE_FILE; return ret; }
P_LIB_API PDir * p_dir_new (const pchar *path, PError **error) { PDir *ret; pchar *pathp; if (P_UNLIKELY (path == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IO_INVALID_ARGUMENT, 0, "Invalid input argument"); return NULL; } if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PDir))) == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IO_NO_RESOURCES, 0, "Failed to allocate memory for directory structure"); return NULL; } if (P_UNLIKELY (!GetFullPathNameA (path, MAX_PATH, ret->path, NULL))) { p_error_set_error_p (error, (pint) p_error_get_last_io (), p_error_get_last_system (), "Failed to call GetFullPathNameA() to get directory path"); p_free (ret); return NULL; } /* Append the search pattern "\\*\0" to the directory name */ pathp = strchr (ret->path, '\0'); if (ret->path < pathp && *(pathp - 1) != '\\' && *(pathp - 1) != ':') *pathp++ = '\\'; *pathp++ = '*'; *pathp = '\0'; /* Open directory stream and retrieve the first entry */ ret->search_handle = FindFirstFileA (ret->path, &ret->find_data); if (P_UNLIKELY (ret->search_handle == INVALID_HANDLE_VALUE)) { p_error_set_error_p (error, (pint) p_error_get_last_io (), p_error_get_last_system (), "Failed to call FindFirstFileA() to open directory stream"); p_free (ret); return NULL; } ret->cached = TRUE; ret->orig_path = p_strdup (path); return ret; }
P_LIB_API PError * p_error_new (void) { PError *ret; if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PError))) == NULL)) return NULL; return ret; }
P_LIB_API PHashTable * p_hash_table_new (void) { PHashTable *ret; if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PHashTable))) == NULL)) { P_ERROR ("PHashTable::p_hash_table_new: failed(1) to allocate memory"); return NULL; } if (P_UNLIKELY ((ret->table = p_malloc0 (P_HASH_TABLE_SIZE * sizeof (PHashTableNode *))) == NULL)) { P_ERROR ("PHashTable::p_hash_table_new: failed(2) to allocate memory"); p_free (ret); return NULL; } ret->size = P_HASH_TABLE_SIZE; return ret; }
P_LIB_API PTimeProfiler * p_time_profiler_new () { PTimeProfiler *ret; if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PTimeProfiler))) == NULL)) { P_ERROR ("PTimeProfiler: failed to allocate memory"); return NULL; } ret->counter = p_time_profiler_get_ticks_internal (); return ret; }
P_LIB_API PShmBuffer * p_shm_buffer_new (const pchar *name, psize size, PError **error) { PShmBuffer *ret; PShm *shm; if (P_UNLIKELY (name == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IPC_INVALID_ARGUMENT, 0, "Invalid input argument"); return NULL; } if (P_UNLIKELY ((shm = p_shm_new (name, (size != 0) ? size + P_SHM_BUFFER_DATA_OFFSET + 1 : 0, P_SHM_ACCESS_READWRITE, error)) == NULL)) return NULL; if (P_UNLIKELY (p_shm_get_size (shm) <= P_SHM_BUFFER_DATA_OFFSET + 1)) { p_error_set_error_p (error, (pint) P_ERROR_IPC_INVALID_ARGUMENT, 0, "Too small memory segment to hold required data"); p_shm_free (shm); return NULL; } if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PShmBuffer))) == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IPC_NO_RESOURCES, 0, "Failed to allocate memory for shared buffer"); p_shm_free (shm); return NULL; } ret->shm = shm; ret->size = p_shm_get_size (shm) - P_SHM_BUFFER_DATA_OFFSET; return ret; }
P_LIB_API PRWLock * p_rwlock_new (void) { PRWLock *ret; if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PRWLock))) == NULL)) { P_ERROR ("PRWLock::p_rwlock_new: failed to allocate memory"); return NULL; } if (P_UNLIKELY (rwlock_init (&ret->hdl, USYNC_THREAD, NULL) != 0)) { P_ERROR ("PRWLock::p_rwlock_new: rwlock_init() failed"); p_free (ret); return NULL; } return ret; }
P_LIB_API PCondVariable * p_cond_variable_new (void) { PCondVariable *ret; if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PCondVariable))) == NULL)) { P_ERROR ("PCondVariable::p_cond_variable_new: failed to allocate memory"); return NULL; } if (P_UNLIKELY (pp_cond_variable_init_func (ret) != TRUE)) { P_ERROR ("PCondVariable::p_cond_variable_new: failed to initialize"); p_free (ret); return NULL; } return ret; }
P_LIB_API PSpinLock * p_spinlock_new (void) { PSpinLock *ret; if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PSpinLock))) == NULL)) { P_ERROR ("PSpinLock::p_spinlock_new: failed to allocate memory"); return NULL; } if (P_UNLIKELY ((ret->mutex = p_mutex_new ()) == NULL)) { P_ERROR ("PSpinLock::p_spinlock_new: p_mutex_new() failed"); p_free (ret); return NULL; } return ret; }
P_LIB_API PMutex * p_mutex_new (void) { PMutex *ret; if ((P_UNLIKELY (ret = p_malloc0 (sizeof (PMutex))) == NULL)) { P_ERROR ("PMutex::p_mutex_new: failed to allocate memory"); return NULL; } if (P_UNLIKELY (mutex_init (&ret->hdl, USYNC_THREAD, NULL) != 0)) { P_ERROR ("PMutex::p_mutex_new: mutex_init() failed"); p_free (ret); return NULL; } return ret; }
P_LIB_API PDir * p_dir_new (const pchar *path, PError **error) { PDir *ret; DIR *dir; pchar *pathp; if (P_UNLIKELY (path == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IO_INVALID_ARGUMENT, 0, "Invalid input argument"); return NULL; } if (P_UNLIKELY ((dir = opendir (path)) == NULL)) { p_error_set_error_p (error, (pint) p_error_get_last_io (), p_error_get_last_system (), "Failed to call opendir() to open directory stream"); return NULL; } if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PDir))) == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IO_NO_RESOURCES, 0, "Failed to allocate memory for directory structure"); closedir (dir); return NULL; } ret->dir = dir; ret->path = p_strdup (path); ret->orig_path = p_strdup (path); pathp = ret->path + strlen (ret->path) - 1; if (*pathp == '/' || *pathp == '\\') *pathp = '\0'; return ret; }
P_LIB_API pchar * p_strchomp (const pchar *str) { pssize pos_start, pos_end; psize str_len; pchar *ret; const pchar *ptr; if (P_UNLIKELY (str == NULL)) return NULL; ptr = str; pos_start = 0; pos_end = ((pssize) strlen (str)) - 1; while (pos_start < pos_end && isspace (* ((const puchar *) ptr++))) ++pos_start; ptr = str + pos_end; while (pos_end > 0 && isspace (* ((const puchar *) ptr--))) --pos_end; if (pos_end < pos_start) return p_strdup ("\0"); if (pos_end == pos_start && isspace (* ((const puchar *) (str + pos_end)))) return p_strdup ("\0"); str_len = (psize) (pos_end - pos_start + 2); if (P_UNLIKELY ((ret = p_malloc0 (str_len)) == NULL)) return NULL; memcpy (ret, str + pos_start, str_len - 1); *(ret + str_len - 1) = '\0'; return ret; }
P_LIB_API PLibraryLoader * p_library_loader_new (const pchar *path) { PLibraryLoader *loader = NULL; plibrary_handle handle; #if defined (P_OS_FREEBSD) || defined (P_OS_DRAGONFLY) struct stat stat_buf; #endif if (!p_file_is_exists (path)) return NULL; #if defined (P_OS_FREEBSD) || defined (P_OS_DRAGONFLY) if (P_UNLIKELY (stat (path, &stat_buf) != 0)) { P_ERROR ("PLibraryLoader::p_library_loader_new: stat() failed"); return NULL; } if (P_UNLIKELY (stat_buf.st_size == 0)) { P_ERROR ("PLibraryLoader::p_library_loader_new: unable to handle zero-size file"); return NULL; } #endif if (P_UNLIKELY ((handle = dlopen (path, RTLD_NOW)) == NULL)) { P_ERROR ("PLibraryLoader::p_library_loader_new: dlopen() failed"); return NULL; } if (P_UNLIKELY ((loader = p_malloc0 (sizeof (PLibraryLoader))) == NULL)) { P_ERROR ("PLibraryLoader::p_library_loader_new: failed to allocate memory"); pp_library_loader_clean_handle (handle); return NULL; } loader->handle = handle; return loader; }
static pboolean pp_cond_variable_init_xp (PCondVariable *cond) { PCondVariableXP *cv_xp; if ((cond->cv = p_malloc0 (sizeof (PCondVariableXP))) == NULL) { P_ERROR ("PCondVariable::pp_cond_variable_init_xp: failed to allocate memory (internal)"); return FALSE; } cv_xp = ((PCondVariableXP *) cond->cv); cv_xp->waiters_count = 0; cv_xp->waiters_sema = CreateSemaphoreA (NULL, 0, MAXLONG, NULL); if (P_UNLIKELY (cv_xp->waiters_sema == NULL)) { P_ERROR ("PCondVariable::pp_cond_variable_init_xp: failed to initialize semaphore"); p_free (cond->cv); cond->cv = NULL; return FALSE; } return TRUE; }
P_LIB_API PDirEntry * p_dir_get_next_entry (PDir *dir, PError **error) { PDirEntry *ret; #ifdef P_DIR_NEED_BUF_ALLOC struct dirent *dirent_st; #else struct dirent dirent_st; #endif struct stat sb; pchar *entry_path; psize path_len; #ifdef P_DIR_NEED_BUF_ALLOC pint name_max; #endif if (P_UNLIKELY (dir == NULL || dir->dir == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IO_INVALID_ARGUMENT, 0, "Invalid input argument"); return NULL; } #if defined(P_OS_SOLARIS) name_max = (pint) (FILENAME_MAX); #elif defined(P_OS_SCO) || defined(P_OS_IRIX) name_max = (pint) pathconf (dir->orig_path, _PC_NAME_MAX); if (name_max == -1) { if (p_error_get_last_system () == 0) name_max = _POSIX_PATH_MAX; else { p_error_set_error_p (error, (pint) P_ERROR_IO_FAILED, 0, "Failed to get NAME_MAX using pathconf()"); return NULL; } } #elif defined(P_OS_QNX6) || defined(P_OS_UNIXWARE) || defined(P_OS_HAIKU) name_max = (pint) (NAME_MAX); #endif #ifdef P_DIR_NEED_BUF_ALLOC if (P_UNLIKELY ((dirent_st = p_malloc0 (sizeof (struct dirent) + name_max + 1)) == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IO_NO_RESOURCES, 0, "Failed to allocate memory for internal directory entry"); return NULL; } # ifdef P_DIR_NEED_SIMPLE_R if ((dir->dir_result = readdir_r (dir->dir, dirent_st)) == NULL) { if (P_UNLIKELY (p_error_get_last_system () != 0)) { p_error_set_error_p (error, (pint) p_error_get_last_io (), p_error_get_last_system (), "Failed to call readdir_r() to read directory stream"); p_free (dirent_st); return NULL; } } # else if (P_UNLIKELY (readdir_r (dir->dir, dirent_st, &dir->dir_result) != 0)) { p_error_set_error_p (error, (pint) p_error_get_last_io (), p_error_get_last_system (), "Failed to call readdir_r() to read directory stream"); p_free (dirent_st); return NULL; } # endif #else if (P_UNLIKELY (readdir_r (dir->dir, &dirent_st, &dir->dir_result) != 0)) { p_error_set_error_p (error, (pint) p_error_get_last_io (), p_error_get_last_system (), "Failed to call readdir_r() to read directory stream"); return NULL; } #endif if (dir->dir_result == NULL) { #ifdef P_DIR_NEED_BUF_ALLOC p_free (dirent_st); #endif return NULL; } if (P_UNLIKELY ((ret = p_malloc0 (sizeof (PDirEntry))) == NULL)) { p_error_set_error_p (error, (pint) P_ERROR_IO_NO_RESOURCES, 0, "Failed to allocate memory for directory entry"); #ifdef P_DIR_NEED_BUF_ALLOC p_free (dirent_st); #endif return NULL; } #ifdef P_DIR_NEED_BUF_ALLOC ret->name = p_strdup (dirent_st->d_name); p_free (dirent_st); #else ret->name = p_strdup (dirent_st.d_name); #endif path_len = strlen (dir->path); if (P_UNLIKELY ((entry_path = p_malloc0 (path_len + strlen (ret->name) + 2)) == NULL)) { P_WARNING ("PDir::p_dir_get_next_entry: failed to allocate memory for stat()"); ret->type = P_DIR_ENTRY_TYPE_OTHER; return ret; } strcat (entry_path, dir->path); *(entry_path + path_len) = '/'; strcat (entry_path + path_len + 1, ret->name); if (P_UNLIKELY (stat (entry_path, &sb) != 0)) { P_WARNING ("PDir::p_dir_get_next_entry: stat() failed"); ret->type = P_DIR_ENTRY_TYPE_OTHER; p_free (entry_path); return ret; } p_free (entry_path); if (S_ISDIR (sb.st_mode)) ret->type = P_DIR_ENTRY_TYPE_DIR; else if (S_ISREG (sb.st_mode)) ret->type = P_DIR_ENTRY_TYPE_FILE; else ret->type = P_DIR_ENTRY_TYPE_OTHER; return ret; }
static void general_hash_test (PCryptoHashType type, psize hash_len, const pchar *msg1, const pchar *msg2, const puchar *etalon1, const puchar *etalon2, const puchar *etalon3, const pchar *hash1, const pchar *hash2, const pchar *hash3, const pchar *hash_stress) { PCryptoHash *crypto_hash; psize dig_len; pchar *hash_str; pchar *long_str; puchar *hash_dig; crypto_hash = p_crypto_hash_new (type); BOOST_REQUIRE ((psize) p_crypto_hash_get_length (crypto_hash) == hash_len); BOOST_REQUIRE (p_crypto_hash_get_type (crypto_hash) == type); hash_str = p_crypto_hash_get_string (crypto_hash); BOOST_REQUIRE (hash_str != NULL); p_crypto_hash_reset (crypto_hash); p_free (hash_str); hash_dig = (puchar *) p_malloc0 (hash_len); BOOST_REQUIRE (hash_dig != NULL); long_str = (pchar *) p_malloc0 (PCRYPTO_STRESS_LENGTH); BOOST_REQUIRE (long_str != NULL); for (int i = 0; i < PCRYPTO_STRESS_LENGTH; ++i) long_str[i] = (pchar) (97 + i % 20); /* Case 1 */ /* Check string */ p_crypto_hash_update (crypto_hash, (const puchar *) msg1, strlen (msg1)); hash_str = p_crypto_hash_get_string (crypto_hash); BOOST_CHECK (strcmp (hash_str, hash1) == 0); p_free (hash_str); p_crypto_hash_reset (crypto_hash); /* Check digest */ dig_len = hash_len; p_crypto_hash_update (crypto_hash, (const puchar *) msg1, strlen (msg1)); p_crypto_hash_get_digest (crypto_hash, hash_dig, &dig_len); BOOST_CHECK (dig_len == hash_len); for (unsigned int i = 0; i < hash_len; ++i) BOOST_CHECK (hash_dig[i] == etalon1[i]); p_crypto_hash_reset (crypto_hash); /* Case 2 */ /* Check string */ p_crypto_hash_update (crypto_hash, (const puchar *) msg2, strlen (msg2)); hash_str = p_crypto_hash_get_string (crypto_hash); BOOST_CHECK (strcmp (hash_str, hash2) == 0); p_free (hash_str); p_crypto_hash_reset (crypto_hash); /* Check digest */ dig_len = hash_len; p_crypto_hash_update (crypto_hash, (const puchar *) msg2, strlen (msg2)); p_crypto_hash_get_digest (crypto_hash, hash_dig, &dig_len); BOOST_CHECK (dig_len == hash_len); for (unsigned int i = 0; i < hash_len; ++i) BOOST_CHECK (hash_dig[i] == etalon2[i]); p_crypto_hash_reset (crypto_hash); /* Case 3 */ /* Check string */ for (int i = 0; i < PCRYPTO_MAX_UPDATES; ++i) p_crypto_hash_update (crypto_hash, (const puchar *) "a", 1); hash_str = p_crypto_hash_get_string (crypto_hash); BOOST_CHECK (strcmp (hash_str, hash3) == 0); p_free (hash_str); p_crypto_hash_reset (crypto_hash); /* Check digest */ dig_len = hash_len; for (int i = 0; i < PCRYPTO_MAX_UPDATES; ++i) p_crypto_hash_update (crypto_hash, (const puchar *) "a", 1); p_crypto_hash_get_digest (crypto_hash, hash_dig, &dig_len); BOOST_CHECK (dig_len == hash_len); for (unsigned int i = 0; i < hash_len; ++i) BOOST_CHECK (hash_dig[i] == etalon3[i]); p_crypto_hash_reset (crypto_hash); /* Stress test */ p_crypto_hash_update (crypto_hash, (const puchar *) long_str, PCRYPTO_STRESS_LENGTH); hash_str = p_crypto_hash_get_string (crypto_hash); BOOST_CHECK (strcmp (hash_str, hash_stress) == 0); p_free (hash_str); p_crypto_hash_reset (crypto_hash); p_free (long_str); p_free (hash_dig); p_crypto_hash_free (crypto_hash); }