1*12720SWyllys.Ingersoll@Sun.COM /* 2*12720SWyllys.Ingersoll@Sun.COM * CDDL HEADER START 3*12720SWyllys.Ingersoll@Sun.COM * 4*12720SWyllys.Ingersoll@Sun.COM * The contents of this file are subject to the terms of the 5*12720SWyllys.Ingersoll@Sun.COM * Common Development and Distribution License (the "License"). 6*12720SWyllys.Ingersoll@Sun.COM * You may not use this file except in compliance with the License. 7*12720SWyllys.Ingersoll@Sun.COM * 8*12720SWyllys.Ingersoll@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*12720SWyllys.Ingersoll@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*12720SWyllys.Ingersoll@Sun.COM * See the License for the specific language governing permissions 11*12720SWyllys.Ingersoll@Sun.COM * and limitations under the License. 12*12720SWyllys.Ingersoll@Sun.COM * 13*12720SWyllys.Ingersoll@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*12720SWyllys.Ingersoll@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*12720SWyllys.Ingersoll@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*12720SWyllys.Ingersoll@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*12720SWyllys.Ingersoll@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*12720SWyllys.Ingersoll@Sun.COM * 19*12720SWyllys.Ingersoll@Sun.COM * CDDL HEADER END 20*12720SWyllys.Ingersoll@Sun.COM */ 21*12720SWyllys.Ingersoll@Sun.COM 22*12720SWyllys.Ingersoll@Sun.COM /* 23*12720SWyllys.Ingersoll@Sun.COM * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24*12720SWyllys.Ingersoll@Sun.COM */ 25*12720SWyllys.Ingersoll@Sun.COM 26*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 27*12720SWyllys.Ingersoll@Sun.COM * Module: SYSCommon.c 28*12720SWyllys.Ingersoll@Sun.COM *-------------------------------------------------------------------------*/ 29*12720SWyllys.Ingersoll@Sun.COM 30*12720SWyllys.Ingersoll@Sun.COM #include <stdio.h> 31*12720SWyllys.Ingersoll@Sun.COM #include "SYSCommon.h" 32*12720SWyllys.Ingersoll@Sun.COM #include <time.h> 33*12720SWyllys.Ingersoll@Sun.COM #include <errno.h> 34*12720SWyllys.Ingersoll@Sun.COM #include <sys/stat.h> 35*12720SWyllys.Ingersoll@Sun.COM #include <sys/types.h> 36*12720SWyllys.Ingersoll@Sun.COM #include <signal.h> 37*12720SWyllys.Ingersoll@Sun.COM 38*12720SWyllys.Ingersoll@Sun.COM #ifndef WIN32 39*12720SWyllys.Ingersoll@Sun.COM #include <unistd.h> 40*12720SWyllys.Ingersoll@Sun.COM #endif 41*12720SWyllys.Ingersoll@Sun.COM 42*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 43*12720SWyllys.Ingersoll@Sun.COM #include <io.h> 44*12720SWyllys.Ingersoll@Sun.COM #include <stdlib.h> /* for malloc, calloc, and free */ 45*12720SWyllys.Ingersoll@Sun.COM #elif defined K_LINUX_PLATFORM 46*12720SWyllys.Ingersoll@Sun.COM #include <unistd.h> /* it includes usleep(us) */ 47*12720SWyllys.Ingersoll@Sun.COM #include <sys/time.h> 48*12720SWyllys.Ingersoll@Sun.COM #include <fts.h> 49*12720SWyllys.Ingersoll@Sun.COM #else 50*12720SWyllys.Ingersoll@Sun.COM /* 51*12720SWyllys.Ingersoll@Sun.COM * Directory traversal code is not yet available for Solaris. 52*12720SWyllys.Ingersoll@Sun.COM * If such code will need to be written, then it will probably use ftw.h. 53*12720SWyllys.Ingersoll@Sun.COM */ 54*12720SWyllys.Ingersoll@Sun.COM #endif 55*12720SWyllys.Ingersoll@Sun.COM 56*12720SWyllys.Ingersoll@Sun.COM #ifdef K_SOLARIS_PLATFORM 57*12720SWyllys.Ingersoll@Sun.COM /* For K_AdjustLocalClock */ 58*12720SWyllys.Ingersoll@Sun.COM #include <unistd.h> 59*12720SWyllys.Ingersoll@Sun.COM /* For K_SetRootPassword */ 60*12720SWyllys.Ingersoll@Sun.COM #define __EXTENSIONS__ /* to expose flockfile and friends in stdio.h */ 61*12720SWyllys.Ingersoll@Sun.COM #include <errno.h> 62*12720SWyllys.Ingersoll@Sun.COM #include <libgen.h> 63*12720SWyllys.Ingersoll@Sun.COM #include <malloc.h> 64*12720SWyllys.Ingersoll@Sun.COM #include <signal.h> 65*12720SWyllys.Ingersoll@Sun.COM #include <stdio.h> 66*12720SWyllys.Ingersoll@Sun.COM #include <stdlib.h> 67*12720SWyllys.Ingersoll@Sun.COM #include <strings.h> 68*12720SWyllys.Ingersoll@Sun.COM #include <stropts.h> 69*12720SWyllys.Ingersoll@Sun.COM #include <unistd.h> 70*12720SWyllys.Ingersoll@Sun.COM #include <termio.h> 71*12720SWyllys.Ingersoll@Sun.COM #include <security/pam_appl.h> 72*12720SWyllys.Ingersoll@Sun.COM #include <widec.h> 73*12720SWyllys.Ingersoll@Sun.COM #endif 74*12720SWyllys.Ingersoll@Sun.COM 75*12720SWyllys.Ingersoll@Sun.COM #ifdef K_LINUX_PLATFORM 76*12720SWyllys.Ingersoll@Sun.COM extern int pthread_mutexattr_settype __P ((pthread_mutexattr_t *__attr, 77*12720SWyllys.Ingersoll@Sun.COM int __kind)); 78*12720SWyllys.Ingersoll@Sun.COM #endif 79*12720SWyllys.Ingersoll@Sun.COM 80*12720SWyllys.Ingersoll@Sun.COM #ifdef K_HPUX_PLATFORM 81*12720SWyllys.Ingersoll@Sun.COM int64 atoll(const char *str) 82*12720SWyllys.Ingersoll@Sun.COM { 83*12720SWyllys.Ingersoll@Sun.COM int64 tmp = 0; 84*12720SWyllys.Ingersoll@Sun.COM sscanf(str, "%lld", &tmp); 85*12720SWyllys.Ingersoll@Sun.COM return tmp; 86*12720SWyllys.Ingersoll@Sun.COM } 87*12720SWyllys.Ingersoll@Sun.COM 88*12720SWyllys.Ingersoll@Sun.COM #endif 89*12720SWyllys.Ingersoll@Sun.COM 90*12720SWyllys.Ingersoll@Sun.COM 91*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 92*12720SWyllys.Ingersoll@Sun.COM * Function: K_CreateThread 93*12720SWyllys.Ingersoll@Sun.COM * 94*12720SWyllys.Ingersoll@Sun.COM * Description: 95*12720SWyllys.Ingersoll@Sun.COM * Thread creation function "CreateThread" takes a thread function 96*12720SWyllys.Ingersoll@Sun.COM * and its parameter to create a thread. It also has a Boolean 97*12720SWyllys.Ingersoll@Sun.COM * parameter to indicate if the thread is detached or joinable. 98*12720SWyllys.Ingersoll@Sun.COM * A new thread's handle is returned through the output parameter. 99*12720SWyllys.Ingersoll@Sun.COM * 100*12720SWyllys.Ingersoll@Sun.COM * Input 101*12720SWyllys.Ingersoll@Sun.COM * ----- 102*12720SWyllys.Ingersoll@Sun.COM * i_pFunc Function pointer of the thread function 103*12720SWyllys.Ingersoll@Sun.COM * i_pvData The point of the parameter passed to the thread function 104*12720SWyllys.Ingersoll@Sun.COM * i_bIsDetached The thread is detached or not 105*12720SWyllys.Ingersoll@Sun.COM * (Note: It is not supported on Win32) 106*12720SWyllys.Ingersoll@Sun.COM * 107*12720SWyllys.Ingersoll@Sun.COM * Output 108*12720SWyllys.Ingersoll@Sun.COM * ------ 109*12720SWyllys.Ingersoll@Sun.COM * o_pNewThread The Thread handle 110*12720SWyllys.Ingersoll@Sun.COM * 111*12720SWyllys.Ingersoll@Sun.COM * Return value Error code 112*12720SWyllys.Ingersoll@Sun.COM * 113*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 114*12720SWyllys.Ingersoll@Sun.COM 115*12720SWyllys.Ingersoll@Sun.COM int K_CreateThread(K_ThreadFunc i_pFunc, 116*12720SWyllys.Ingersoll@Sun.COM void *i_pvData, 117*12720SWyllys.Ingersoll@Sun.COM int i_bIsDetached, 118*12720SWyllys.Ingersoll@Sun.COM K_THREAD_HANDLE *o_pNewThread) 119*12720SWyllys.Ingersoll@Sun.COM { 120*12720SWyllys.Ingersoll@Sun.COM int iOK = K_SYS_OK; 121*12720SWyllys.Ingersoll@Sun.COM int iReturn = 0; 122*12720SWyllys.Ingersoll@Sun.COM 123*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 124*12720SWyllys.Ingersoll@Sun.COM 125*12720SWyllys.Ingersoll@Sun.COM { 126*12720SWyllys.Ingersoll@Sun.COM unsigned id; 127*12720SWyllys.Ingersoll@Sun.COM 128*12720SWyllys.Ingersoll@Sun.COM *o_pNewThread = (HANDLE)_beginthreadex(NULL, 129*12720SWyllys.Ingersoll@Sun.COM 0, 130*12720SWyllys.Ingersoll@Sun.COM (int (_stdcall *) (void *vpData))i_pFunc, 131*12720SWyllys.Ingersoll@Sun.COM i_pvData, 132*12720SWyllys.Ingersoll@Sun.COM 0, 133*12720SWyllys.Ingersoll@Sun.COM &id); 134*12720SWyllys.Ingersoll@Sun.COM 135*12720SWyllys.Ingersoll@Sun.COM 136*12720SWyllys.Ingersoll@Sun.COM if(*o_pNewThread == 0) 137*12720SWyllys.Ingersoll@Sun.COM { 138*12720SWyllys.Ingersoll@Sun.COM #ifdef SYS_DEBUG 139*12720SWyllys.Ingersoll@Sun.COM printf(" (%s, %d): error creating pthread, error = %d\n", 140*12720SWyllys.Ingersoll@Sun.COM __FILE__, __LINE__, iReturn); 141*12720SWyllys.Ingersoll@Sun.COM #endif 142*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_CREATE_THREAD; 143*12720SWyllys.Ingersoll@Sun.COM } 144*12720SWyllys.Ingersoll@Sun.COM 145*12720SWyllys.Ingersoll@Sun.COM return K_SYS_OK; 146*12720SWyllys.Ingersoll@Sun.COM } 147*12720SWyllys.Ingersoll@Sun.COM 148*12720SWyllys.Ingersoll@Sun.COM #else 149*12720SWyllys.Ingersoll@Sun.COM pthread_attr_t attr; 150*12720SWyllys.Ingersoll@Sun.COM 151*12720SWyllys.Ingersoll@Sun.COM iReturn = pthread_attr_init(&attr); 152*12720SWyllys.Ingersoll@Sun.COM 153*12720SWyllys.Ingersoll@Sun.COM if ( iReturn == 0 ) 154*12720SWyllys.Ingersoll@Sun.COM { 155*12720SWyllys.Ingersoll@Sun.COM iReturn = pthread_attr_setdetachstate(&attr, (i_bIsDetached) ? 156*12720SWyllys.Ingersoll@Sun.COM PTHREAD_CREATE_DETACHED : 157*12720SWyllys.Ingersoll@Sun.COM PTHREAD_CREATE_JOINABLE); 158*12720SWyllys.Ingersoll@Sun.COM } 159*12720SWyllys.Ingersoll@Sun.COM 160*12720SWyllys.Ingersoll@Sun.COM #ifdef UNIX 161*12720SWyllys.Ingersoll@Sun.COM if ( iReturn == 0 ) 162*12720SWyllys.Ingersoll@Sun.COM { 163*12720SWyllys.Ingersoll@Sun.COM iReturn = pthread_attr_setstacksize(&attr, 1024*1024); 164*12720SWyllys.Ingersoll@Sun.COM } 165*12720SWyllys.Ingersoll@Sun.COM #endif 166*12720SWyllys.Ingersoll@Sun.COM 167*12720SWyllys.Ingersoll@Sun.COM if ( iReturn == 0 ) 168*12720SWyllys.Ingersoll@Sun.COM { 169*12720SWyllys.Ingersoll@Sun.COM iReturn = pthread_create(o_pNewThread, &attr, (void *(*)(void *)) i_pFunc, i_pvData); 170*12720SWyllys.Ingersoll@Sun.COM } 171*12720SWyllys.Ingersoll@Sun.COM 172*12720SWyllys.Ingersoll@Sun.COM if ( iReturn == 0 ) 173*12720SWyllys.Ingersoll@Sun.COM { 174*12720SWyllys.Ingersoll@Sun.COM iReturn = pthread_attr_destroy(&attr); 175*12720SWyllys.Ingersoll@Sun.COM } 176*12720SWyllys.Ingersoll@Sun.COM 177*12720SWyllys.Ingersoll@Sun.COM // TODO: Log error? 178*12720SWyllys.Ingersoll@Sun.COM if ( iReturn ) 179*12720SWyllys.Ingersoll@Sun.COM { 180*12720SWyllys.Ingersoll@Sun.COM #ifdef SYS_DEBUG 181*12720SWyllys.Ingersoll@Sun.COM printf(" (%s, %d): error creating pthread, error = %d\n", 182*12720SWyllys.Ingersoll@Sun.COM __FILE__, __LINE__, iReturn); 183*12720SWyllys.Ingersoll@Sun.COM #endif 184*12720SWyllys.Ingersoll@Sun.COM 185*12720SWyllys.Ingersoll@Sun.COM iOK = K_SYS_ERR_CREATE_THREAD; 186*12720SWyllys.Ingersoll@Sun.COM } 187*12720SWyllys.Ingersoll@Sun.COM 188*12720SWyllys.Ingersoll@Sun.COM return iOK; 189*12720SWyllys.Ingersoll@Sun.COM #endif 190*12720SWyllys.Ingersoll@Sun.COM } 191*12720SWyllys.Ingersoll@Sun.COM 192*12720SWyllys.Ingersoll@Sun.COM 193*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 194*12720SWyllys.Ingersoll@Sun.COM * Function: K_JoinThread 195*12720SWyllys.Ingersoll@Sun.COM * 196*12720SWyllys.Ingersoll@Sun.COM * Description: 197*12720SWyllys.Ingersoll@Sun.COM * Thread joining function is called when the current thread 198*12720SWyllys.Ingersoll@Sun.COM * waits another thread to terminate. 199*12720SWyllys.Ingersoll@Sun.COM * 200*12720SWyllys.Ingersoll@Sun.COM * Input 201*12720SWyllys.Ingersoll@Sun.COM * ----- 202*12720SWyllys.Ingersoll@Sun.COM * i_hThread The thread handle of the to-be-joined thread 203*12720SWyllys.Ingersoll@Sun.COM * 204*12720SWyllys.Ingersoll@Sun.COM * Output 205*12720SWyllys.Ingersoll@Sun.COM * ------ 206*12720SWyllys.Ingersoll@Sun.COM * (none) 207*12720SWyllys.Ingersoll@Sun.COM * 208*12720SWyllys.Ingersoll@Sun.COM * Return value Error code 209*12720SWyllys.Ingersoll@Sun.COM * 210*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 211*12720SWyllys.Ingersoll@Sun.COM 212*12720SWyllys.Ingersoll@Sun.COM int K_JoinThread(K_THREAD_HANDLE i_hThread) 213*12720SWyllys.Ingersoll@Sun.COM { 214*12720SWyllys.Ingersoll@Sun.COM int iOK = K_SYS_OK; 215*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 216*12720SWyllys.Ingersoll@Sun.COM 217*12720SWyllys.Ingersoll@Sun.COM WaitForSingleObject(i_hThread, INFINITE); 218*12720SWyllys.Ingersoll@Sun.COM 219*12720SWyllys.Ingersoll@Sun.COM #else 220*12720SWyllys.Ingersoll@Sun.COM { 221*12720SWyllys.Ingersoll@Sun.COM int iReturn; 222*12720SWyllys.Ingersoll@Sun.COM iReturn = pthread_join(i_hThread, NULL); 223*12720SWyllys.Ingersoll@Sun.COM 224*12720SWyllys.Ingersoll@Sun.COM if ( iReturn ) 225*12720SWyllys.Ingersoll@Sun.COM { 226*12720SWyllys.Ingersoll@Sun.COM 227*12720SWyllys.Ingersoll@Sun.COM #ifdef SYS_DEBUG 228*12720SWyllys.Ingersoll@Sun.COM printf(" (%s, %d): error creating pthread, error = %d\n", 229*12720SWyllys.Ingersoll@Sun.COM __FILE__, __LINE__, iReturn); 230*12720SWyllys.Ingersoll@Sun.COM #endif 231*12720SWyllys.Ingersoll@Sun.COM iOK = K_SYS_ERR_JOIN_THREAD; 232*12720SWyllys.Ingersoll@Sun.COM } 233*12720SWyllys.Ingersoll@Sun.COM } 234*12720SWyllys.Ingersoll@Sun.COM 235*12720SWyllys.Ingersoll@Sun.COM #endif 236*12720SWyllys.Ingersoll@Sun.COM return iOK; 237*12720SWyllys.Ingersoll@Sun.COM } 238*12720SWyllys.Ingersoll@Sun.COM 239*12720SWyllys.Ingersoll@Sun.COM 240*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 241*12720SWyllys.Ingersoll@Sun.COM * Function: K_GetCurrentThreadId 242*12720SWyllys.Ingersoll@Sun.COM * 243*12720SWyllys.Ingersoll@Sun.COM * Description: 244*12720SWyllys.Ingersoll@Sun.COM * Returns the thread ID of the current thread. 245*12720SWyllys.Ingersoll@Sun.COM * 246*12720SWyllys.Ingersoll@Sun.COM * Input 247*12720SWyllys.Ingersoll@Sun.COM * ----- 248*12720SWyllys.Ingersoll@Sun.COM * (none) 249*12720SWyllys.Ingersoll@Sun.COM * 250*12720SWyllys.Ingersoll@Sun.COM * Output 251*12720SWyllys.Ingersoll@Sun.COM * ------ 252*12720SWyllys.Ingersoll@Sun.COM * (none) 253*12720SWyllys.Ingersoll@Sun.COM * 254*12720SWyllys.Ingersoll@Sun.COM * Return value The thread ID 255*12720SWyllys.Ingersoll@Sun.COM * 256*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 257*12720SWyllys.Ingersoll@Sun.COM 258*12720SWyllys.Ingersoll@Sun.COM int K_GetCurrentThreadId() 259*12720SWyllys.Ingersoll@Sun.COM { 260*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 261*12720SWyllys.Ingersoll@Sun.COM return GetCurrentThreadId(); 262*12720SWyllys.Ingersoll@Sun.COM #else 263*12720SWyllys.Ingersoll@Sun.COM return pthread_self(); 264*12720SWyllys.Ingersoll@Sun.COM #endif 265*12720SWyllys.Ingersoll@Sun.COM 266*12720SWyllys.Ingersoll@Sun.COM } 267*12720SWyllys.Ingersoll@Sun.COM 268*12720SWyllys.Ingersoll@Sun.COM 269*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 270*12720SWyllys.Ingersoll@Sun.COM * Function: K_CreateMutex 271*12720SWyllys.Ingersoll@Sun.COM * 272*12720SWyllys.Ingersoll@Sun.COM * Description: 273*12720SWyllys.Ingersoll@Sun.COM * The mutex creation function creates a mutex according to the given 274*12720SWyllys.Ingersoll@Sun.COM * mutex type, and returns the mutex handle to the output parameter. 275*12720SWyllys.Ingersoll@Sun.COM * 276*12720SWyllys.Ingersoll@Sun.COM * Input 277*12720SWyllys.Ingersoll@Sun.COM * ----- 278*12720SWyllys.Ingersoll@Sun.COM * i_bIsRecursive Indication whether the mutex can be entered recursively 279*12720SWyllys.Ingersoll@Sun.COM * 280*12720SWyllys.Ingersoll@Sun.COM * Output 281*12720SWyllys.Ingersoll@Sun.COM * ------ 282*12720SWyllys.Ingersoll@Sun.COM * o_phandle the handle pointer to the mutex 283*12720SWyllys.Ingersoll@Sun.COM * 284*12720SWyllys.Ingersoll@Sun.COM * Return value Error Code 285*12720SWyllys.Ingersoll@Sun.COM * 286*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 287*12720SWyllys.Ingersoll@Sun.COM 288*12720SWyllys.Ingersoll@Sun.COM int K_CreateMutex( K_MUTEX_HANDLE *o_phandle ) 289*12720SWyllys.Ingersoll@Sun.COM { 290*12720SWyllys.Ingersoll@Sun.COM int iOK = K_SYS_OK; 291*12720SWyllys.Ingersoll@Sun.COM BOOL bIsRecursive = 1; // this used to be an input -- but why do we want this to be optional? 292*12720SWyllys.Ingersoll@Sun.COM 293*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 294*12720SWyllys.Ingersoll@Sun.COM { 295*12720SWyllys.Ingersoll@Sun.COM *o_phandle = (WIN32Mutex *)malloc(sizeof(WIN32Mutex)); 296*12720SWyllys.Ingersoll@Sun.COM if(*o_phandle == NULL) 297*12720SWyllys.Ingersoll@Sun.COM { 298*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_NO_MEMORY; 299*12720SWyllys.Ingersoll@Sun.COM } 300*12720SWyllys.Ingersoll@Sun.COM (*o_phandle)->m_bIsRecursive = bIsRecursive; 301*12720SWyllys.Ingersoll@Sun.COM if(bIsRecursive) 302*12720SWyllys.Ingersoll@Sun.COM { 303*12720SWyllys.Ingersoll@Sun.COM InitializeCriticalSection(&((*o_phandle)->m_stCriticalSection)); 304*12720SWyllys.Ingersoll@Sun.COM } 305*12720SWyllys.Ingersoll@Sun.COM else 306*12720SWyllys.Ingersoll@Sun.COM { 307*12720SWyllys.Ingersoll@Sun.COM (*o_phandle)->m_handle = CreateMutex(NULL, FALSE, NULL); 308*12720SWyllys.Ingersoll@Sun.COM } 309*12720SWyllys.Ingersoll@Sun.COM 310*12720SWyllys.Ingersoll@Sun.COM } 311*12720SWyllys.Ingersoll@Sun.COM #else 312*12720SWyllys.Ingersoll@Sun.COM { 313*12720SWyllys.Ingersoll@Sun.COM int iType; 314*12720SWyllys.Ingersoll@Sun.COM pthread_mutexattr_t attr; 315*12720SWyllys.Ingersoll@Sun.COM 316*12720SWyllys.Ingersoll@Sun.COM if ( pthread_mutexattr_init(&attr) ) 317*12720SWyllys.Ingersoll@Sun.COM { 318*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 319*12720SWyllys.Ingersoll@Sun.COM } 320*12720SWyllys.Ingersoll@Sun.COM 321*12720SWyllys.Ingersoll@Sun.COM if(bIsRecursive) 322*12720SWyllys.Ingersoll@Sun.COM { 323*12720SWyllys.Ingersoll@Sun.COM iType = 324*12720SWyllys.Ingersoll@Sun.COM #ifdef K_LINUX_PLATFORM 325*12720SWyllys.Ingersoll@Sun.COM PTHREAD_MUTEX_RECURSIVE_NP; 326*12720SWyllys.Ingersoll@Sun.COM #else 327*12720SWyllys.Ingersoll@Sun.COM PTHREAD_MUTEX_RECURSIVE; 328*12720SWyllys.Ingersoll@Sun.COM #endif 329*12720SWyllys.Ingersoll@Sun.COM 330*12720SWyllys.Ingersoll@Sun.COM if ( pthread_mutexattr_settype(&attr, iType) ) 331*12720SWyllys.Ingersoll@Sun.COM { 332*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 333*12720SWyllys.Ingersoll@Sun.COM } 334*12720SWyllys.Ingersoll@Sun.COM } 335*12720SWyllys.Ingersoll@Sun.COM 336*12720SWyllys.Ingersoll@Sun.COM *o_phandle = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); 337*12720SWyllys.Ingersoll@Sun.COM if(*o_phandle == NULL) 338*12720SWyllys.Ingersoll@Sun.COM { 339*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_NO_MEMORY; 340*12720SWyllys.Ingersoll@Sun.COM } 341*12720SWyllys.Ingersoll@Sun.COM 342*12720SWyllys.Ingersoll@Sun.COM if ( pthread_mutex_init(*o_phandle, &attr) ) 343*12720SWyllys.Ingersoll@Sun.COM { 344*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 345*12720SWyllys.Ingersoll@Sun.COM } 346*12720SWyllys.Ingersoll@Sun.COM 347*12720SWyllys.Ingersoll@Sun.COM if ( pthread_mutexattr_destroy(&attr) ) 348*12720SWyllys.Ingersoll@Sun.COM { 349*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 350*12720SWyllys.Ingersoll@Sun.COM } 351*12720SWyllys.Ingersoll@Sun.COM } 352*12720SWyllys.Ingersoll@Sun.COM #endif 353*12720SWyllys.Ingersoll@Sun.COM 354*12720SWyllys.Ingersoll@Sun.COM return iOK; 355*12720SWyllys.Ingersoll@Sun.COM } 356*12720SWyllys.Ingersoll@Sun.COM 357*12720SWyllys.Ingersoll@Sun.COM 358*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 359*12720SWyllys.Ingersoll@Sun.COM * Function: K_LockMutex 360*12720SWyllys.Ingersoll@Sun.COM * 361*12720SWyllys.Ingersoll@Sun.COM * Description: 362*12720SWyllys.Ingersoll@Sun.COM * K_LockMutex is used to lock the mutex, and K_UnlockMutex is 363*12720SWyllys.Ingersoll@Sun.COM * used to unlock it. 364*12720SWyllys.Ingersoll@Sun.COM * 365*12720SWyllys.Ingersoll@Sun.COM * Input 366*12720SWyllys.Ingersoll@Sun.COM * ----- 367*12720SWyllys.Ingersoll@Sun.COM * i_handle the mutex handle 368*12720SWyllys.Ingersoll@Sun.COM * 369*12720SWyllys.Ingersoll@Sun.COM * Output 370*12720SWyllys.Ingersoll@Sun.COM * ------ 371*12720SWyllys.Ingersoll@Sun.COM * (none) 372*12720SWyllys.Ingersoll@Sun.COM * 373*12720SWyllys.Ingersoll@Sun.COM * Return value Error Code 374*12720SWyllys.Ingersoll@Sun.COM * 375*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 376*12720SWyllys.Ingersoll@Sun.COM 377*12720SWyllys.Ingersoll@Sun.COM int K_LockMutex(K_MUTEX_HANDLE i_handle) 378*12720SWyllys.Ingersoll@Sun.COM { 379*12720SWyllys.Ingersoll@Sun.COM int iOK = K_SYS_OK; 380*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 381*12720SWyllys.Ingersoll@Sun.COM 382*12720SWyllys.Ingersoll@Sun.COM if(i_handle->m_bIsRecursive) 383*12720SWyllys.Ingersoll@Sun.COM { 384*12720SWyllys.Ingersoll@Sun.COM EnterCriticalSection(&(i_handle->m_stCriticalSection)); 385*12720SWyllys.Ingersoll@Sun.COM } 386*12720SWyllys.Ingersoll@Sun.COM else 387*12720SWyllys.Ingersoll@Sun.COM { 388*12720SWyllys.Ingersoll@Sun.COM WaitForSingleObject(i_handle->m_handle, INFINITE); 389*12720SWyllys.Ingersoll@Sun.COM } 390*12720SWyllys.Ingersoll@Sun.COM 391*12720SWyllys.Ingersoll@Sun.COM #else 392*12720SWyllys.Ingersoll@Sun.COM 393*12720SWyllys.Ingersoll@Sun.COM if ( pthread_mutex_lock(i_handle) ) 394*12720SWyllys.Ingersoll@Sun.COM { 395*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 396*12720SWyllys.Ingersoll@Sun.COM } 397*12720SWyllys.Ingersoll@Sun.COM 398*12720SWyllys.Ingersoll@Sun.COM #endif 399*12720SWyllys.Ingersoll@Sun.COM return iOK; // TODO: better error handling 400*12720SWyllys.Ingersoll@Sun.COM } 401*12720SWyllys.Ingersoll@Sun.COM 402*12720SWyllys.Ingersoll@Sun.COM 403*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 404*12720SWyllys.Ingersoll@Sun.COM * Function: K_UnlockMutex 405*12720SWyllys.Ingersoll@Sun.COM * 406*12720SWyllys.Ingersoll@Sun.COM * Description: 407*12720SWyllys.Ingersoll@Sun.COM * K_UnlockMutex is used to unlock the lock. 408*12720SWyllys.Ingersoll@Sun.COM * 409*12720SWyllys.Ingersoll@Sun.COM * Input 410*12720SWyllys.Ingersoll@Sun.COM * ----- 411*12720SWyllys.Ingersoll@Sun.COM * i_handle the mutex handle 412*12720SWyllys.Ingersoll@Sun.COM * 413*12720SWyllys.Ingersoll@Sun.COM * Output 414*12720SWyllys.Ingersoll@Sun.COM * ------ 415*12720SWyllys.Ingersoll@Sun.COM * (none) 416*12720SWyllys.Ingersoll@Sun.COM * 417*12720SWyllys.Ingersoll@Sun.COM * Return value Error Code 418*12720SWyllys.Ingersoll@Sun.COM * 419*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 420*12720SWyllys.Ingersoll@Sun.COM 421*12720SWyllys.Ingersoll@Sun.COM int K_UnlockMutex(K_MUTEX_HANDLE i_handle) 422*12720SWyllys.Ingersoll@Sun.COM { 423*12720SWyllys.Ingersoll@Sun.COM int iOK = K_SYS_OK; 424*12720SWyllys.Ingersoll@Sun.COM 425*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 426*12720SWyllys.Ingersoll@Sun.COM if(i_handle->m_bIsRecursive) 427*12720SWyllys.Ingersoll@Sun.COM { 428*12720SWyllys.Ingersoll@Sun.COM LeaveCriticalSection(&(i_handle->m_stCriticalSection)); 429*12720SWyllys.Ingersoll@Sun.COM } 430*12720SWyllys.Ingersoll@Sun.COM else 431*12720SWyllys.Ingersoll@Sun.COM { 432*12720SWyllys.Ingersoll@Sun.COM ReleaseMutex(i_handle->m_handle); 433*12720SWyllys.Ingersoll@Sun.COM } 434*12720SWyllys.Ingersoll@Sun.COM 435*12720SWyllys.Ingersoll@Sun.COM #else 436*12720SWyllys.Ingersoll@Sun.COM 437*12720SWyllys.Ingersoll@Sun.COM if ( pthread_mutex_unlock(i_handle) ) 438*12720SWyllys.Ingersoll@Sun.COM { 439*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 440*12720SWyllys.Ingersoll@Sun.COM } 441*12720SWyllys.Ingersoll@Sun.COM #endif 442*12720SWyllys.Ingersoll@Sun.COM 443*12720SWyllys.Ingersoll@Sun.COM return iOK; // TODO: better error handling 444*12720SWyllys.Ingersoll@Sun.COM } 445*12720SWyllys.Ingersoll@Sun.COM 446*12720SWyllys.Ingersoll@Sun.COM 447*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 448*12720SWyllys.Ingersoll@Sun.COM * Function: K_DestroyMutex 449*12720SWyllys.Ingersoll@Sun.COM * 450*12720SWyllys.Ingersoll@Sun.COM * Description: 451*12720SWyllys.Ingersoll@Sun.COM * When a mutex is no longer needed, K_DestroyMutex must be called 452*12720SWyllys.Ingersoll@Sun.COM * to destroy it. 453*12720SWyllys.Ingersoll@Sun.COM * 454*12720SWyllys.Ingersoll@Sun.COM * Input 455*12720SWyllys.Ingersoll@Sun.COM * ----- 456*12720SWyllys.Ingersoll@Sun.COM * i_handle the mutex handle 457*12720SWyllys.Ingersoll@Sun.COM * Output 458*12720SWyllys.Ingersoll@Sun.COM * ------ 459*12720SWyllys.Ingersoll@Sun.COM * (none) 460*12720SWyllys.Ingersoll@Sun.COM * 461*12720SWyllys.Ingersoll@Sun.COM * Return value Error Code 462*12720SWyllys.Ingersoll@Sun.COM * 463*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 464*12720SWyllys.Ingersoll@Sun.COM 465*12720SWyllys.Ingersoll@Sun.COM int K_DestroyMutex(K_MUTEX_HANDLE i_handle) 466*12720SWyllys.Ingersoll@Sun.COM { 467*12720SWyllys.Ingersoll@Sun.COM 468*12720SWyllys.Ingersoll@Sun.COM int iOK = K_SYS_OK; 469*12720SWyllys.Ingersoll@Sun.COM 470*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 471*12720SWyllys.Ingersoll@Sun.COM 472*12720SWyllys.Ingersoll@Sun.COM if(i_handle->m_bIsRecursive) 473*12720SWyllys.Ingersoll@Sun.COM { 474*12720SWyllys.Ingersoll@Sun.COM DeleteCriticalSection(&(i_handle->m_stCriticalSection)); 475*12720SWyllys.Ingersoll@Sun.COM } 476*12720SWyllys.Ingersoll@Sun.COM else 477*12720SWyllys.Ingersoll@Sun.COM { 478*12720SWyllys.Ingersoll@Sun.COM CloseHandle(i_handle->m_handle); 479*12720SWyllys.Ingersoll@Sun.COM } 480*12720SWyllys.Ingersoll@Sun.COM free(i_handle); 481*12720SWyllys.Ingersoll@Sun.COM 482*12720SWyllys.Ingersoll@Sun.COM #else 483*12720SWyllys.Ingersoll@Sun.COM pthread_mutex_destroy(i_handle); 484*12720SWyllys.Ingersoll@Sun.COM free(i_handle); 485*12720SWyllys.Ingersoll@Sun.COM #endif 486*12720SWyllys.Ingersoll@Sun.COM return iOK; // TODO: better error handling 487*12720SWyllys.Ingersoll@Sun.COM } 488*12720SWyllys.Ingersoll@Sun.COM 489*12720SWyllys.Ingersoll@Sun.COM 490*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 491*12720SWyllys.Ingersoll@Sun.COM * Function: K_InitConditionalVariable 492*12720SWyllys.Ingersoll@Sun.COM * 493*12720SWyllys.Ingersoll@Sun.COM * Description: 494*12720SWyllys.Ingersoll@Sun.COM * This function initializes a conditional variable. Upon successful 495*12720SWyllys.Ingersoll@Sun.COM * completion, the new condition variable is returned via the condition 496*12720SWyllys.Ingersoll@Sun.COM * parameter, and 0 is returned. Otherwise, an error code is returned. 497*12720SWyllys.Ingersoll@Sun.COM * 498*12720SWyllys.Ingersoll@Sun.COM * Input 499*12720SWyllys.Ingersoll@Sun.COM * ----- 500*12720SWyllys.Ingersoll@Sun.COM * i_pCond the pointer to the conditional variable which is to be 501*12720SWyllys.Ingersoll@Sun.COM * initialized 502*12720SWyllys.Ingersoll@Sun.COM * 503*12720SWyllys.Ingersoll@Sun.COM * Output 504*12720SWyllys.Ingersoll@Sun.COM * ------ 505*12720SWyllys.Ingersoll@Sun.COM * (none) 506*12720SWyllys.Ingersoll@Sun.COM * 507*12720SWyllys.Ingersoll@Sun.COM * Return value Error Code 508*12720SWyllys.Ingersoll@Sun.COM * 509*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 510*12720SWyllys.Ingersoll@Sun.COM 511*12720SWyllys.Ingersoll@Sun.COM int K_InitConditionalVariable (K_ConditionalVariable * i_pCond) 512*12720SWyllys.Ingersoll@Sun.COM { 513*12720SWyllys.Ingersoll@Sun.COM int iOK = K_SYS_OK; 514*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 515*12720SWyllys.Ingersoll@Sun.COM 516*12720SWyllys.Ingersoll@Sun.COM i_pCond->m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 517*12720SWyllys.Ingersoll@Sun.COM i_pCond->m_hMutex = CreateMutex(NULL, FALSE, NULL); 518*12720SWyllys.Ingersoll@Sun.COM i_pCond->m_iSignalAll = 0; 519*12720SWyllys.Ingersoll@Sun.COM i_pCond->m_iNumWaiting = 0; 520*12720SWyllys.Ingersoll@Sun.COM 521*12720SWyllys.Ingersoll@Sun.COM #else 522*12720SWyllys.Ingersoll@Sun.COM 523*12720SWyllys.Ingersoll@Sun.COM if ( pthread_cond_init(i_pCond, NULL) ) 524*12720SWyllys.Ingersoll@Sun.COM { 525*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 526*12720SWyllys.Ingersoll@Sun.COM } 527*12720SWyllys.Ingersoll@Sun.COM 528*12720SWyllys.Ingersoll@Sun.COM #endif 529*12720SWyllys.Ingersoll@Sun.COM 530*12720SWyllys.Ingersoll@Sun.COM return iOK; 531*12720SWyllys.Ingersoll@Sun.COM } 532*12720SWyllys.Ingersoll@Sun.COM 533*12720SWyllys.Ingersoll@Sun.COM 534*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 535*12720SWyllys.Ingersoll@Sun.COM * Function: K_DestroyConditionalVariable 536*12720SWyllys.Ingersoll@Sun.COM * 537*12720SWyllys.Ingersoll@Sun.COM * Description: 538*12720SWyllys.Ingersoll@Sun.COM * This function destroys a conditional variable. Upon successful 539*12720SWyllys.Ingersoll@Sun.COM * completion, the condition variable is destroyed, and 0 is returned. 540*12720SWyllys.Ingersoll@Sun.COM * Otherwise, an error code is returned. 541*12720SWyllys.Ingersoll@Sun.COM * After deletion of the condition variable, the condition parameter 542*12720SWyllys.Ingersoll@Sun.COM * is not valid until it is initialized again by a call to the 543*12720SWyllys.Ingersoll@Sun.COM * K_InitConditionalVariable subroutine. 544*12720SWyllys.Ingersoll@Sun.COM * 545*12720SWyllys.Ingersoll@Sun.COM * Input 546*12720SWyllys.Ingersoll@Sun.COM * ----- 547*12720SWyllys.Ingersoll@Sun.COM * i_pCond the pointer to the conditional variable which is to be 548*12720SWyllys.Ingersoll@Sun.COM * destroyed 549*12720SWyllys.Ingersoll@Sun.COM * Output 550*12720SWyllys.Ingersoll@Sun.COM * ------ 551*12720SWyllys.Ingersoll@Sun.COM * (none) 552*12720SWyllys.Ingersoll@Sun.COM * 553*12720SWyllys.Ingersoll@Sun.COM * Return value Error Code 554*12720SWyllys.Ingersoll@Sun.COM * 555*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 556*12720SWyllys.Ingersoll@Sun.COM 557*12720SWyllys.Ingersoll@Sun.COM int K_DestroyConditionalVariable(K_ConditionalVariable * i_pCond) 558*12720SWyllys.Ingersoll@Sun.COM { 559*12720SWyllys.Ingersoll@Sun.COM int iOK = K_SYS_OK; 560*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 561*12720SWyllys.Ingersoll@Sun.COM CloseHandle(i_pCond->m_hMutex); 562*12720SWyllys.Ingersoll@Sun.COM CloseHandle(i_pCond->m_hEvent); 563*12720SWyllys.Ingersoll@Sun.COM #else 564*12720SWyllys.Ingersoll@Sun.COM 565*12720SWyllys.Ingersoll@Sun.COM if ( pthread_cond_destroy(i_pCond) ) 566*12720SWyllys.Ingersoll@Sun.COM { 567*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 568*12720SWyllys.Ingersoll@Sun.COM } 569*12720SWyllys.Ingersoll@Sun.COM 570*12720SWyllys.Ingersoll@Sun.COM #endif 571*12720SWyllys.Ingersoll@Sun.COM return iOK; 572*12720SWyllys.Ingersoll@Sun.COM 573*12720SWyllys.Ingersoll@Sun.COM } 574*12720SWyllys.Ingersoll@Sun.COM 575*12720SWyllys.Ingersoll@Sun.COM 576*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 577*12720SWyllys.Ingersoll@Sun.COM * Function: K_WaitConditionalVariable 578*12720SWyllys.Ingersoll@Sun.COM * 579*12720SWyllys.Ingersoll@Sun.COM * Description: 580*12720SWyllys.Ingersoll@Sun.COM * This function is used to block on a condition variable. 581*12720SWyllys.Ingersoll@Sun.COM * They are called with mutex locked by the calling thread or undefined 582*12720SWyllys.Ingersoll@Sun.COM * behaviour will result. 583*12720SWyllys.Ingersoll@Sun.COM * 584*12720SWyllys.Ingersoll@Sun.COM * Input 585*12720SWyllys.Ingersoll@Sun.COM * ----- 586*12720SWyllys.Ingersoll@Sun.COM * i_pCond the pointer to the conditional variable 587*12720SWyllys.Ingersoll@Sun.COM * i_handle the companion mutex handle 588*12720SWyllys.Ingersoll@Sun.COM * 589*12720SWyllys.Ingersoll@Sun.COM * Output 590*12720SWyllys.Ingersoll@Sun.COM * ------ 591*12720SWyllys.Ingersoll@Sun.COM * (none) 592*12720SWyllys.Ingersoll@Sun.COM * 593*12720SWyllys.Ingersoll@Sun.COM * Return value Error Code 594*12720SWyllys.Ingersoll@Sun.COM * 595*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 596*12720SWyllys.Ingersoll@Sun.COM 597*12720SWyllys.Ingersoll@Sun.COM int K_WaitConditionalVariable(K_ConditionalVariable * i_pCond, 598*12720SWyllys.Ingersoll@Sun.COM K_MUTEX_HANDLE i_handle) 599*12720SWyllys.Ingersoll@Sun.COM { 600*12720SWyllys.Ingersoll@Sun.COM 601*12720SWyllys.Ingersoll@Sun.COM int iOK = K_SYS_OK; 602*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 603*12720SWyllys.Ingersoll@Sun.COM DWORD res; 604*12720SWyllys.Ingersoll@Sun.COM 605*12720SWyllys.Ingersoll@Sun.COM while (1) 606*12720SWyllys.Ingersoll@Sun.COM { 607*12720SWyllys.Ingersoll@Sun.COM iOK = WaitForSingleObject(i_pCond->m_hMutex, INFINITE); 608*12720SWyllys.Ingersoll@Sun.COM if (iOK != WAIT_OBJECT_0) 609*12720SWyllys.Ingersoll@Sun.COM { 610*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 611*12720SWyllys.Ingersoll@Sun.COM } 612*12720SWyllys.Ingersoll@Sun.COM i_pCond->m_iNumWaiting++; 613*12720SWyllys.Ingersoll@Sun.COM ReleaseMutex(i_pCond->m_hMutex); 614*12720SWyllys.Ingersoll@Sun.COM 615*12720SWyllys.Ingersoll@Sun.COM K_UnlockMutex(i_handle); 616*12720SWyllys.Ingersoll@Sun.COM res = WaitForSingleObject(i_pCond->m_hEvent, INFINITE); 617*12720SWyllys.Ingersoll@Sun.COM i_pCond->m_iNumWaiting--; 618*12720SWyllys.Ingersoll@Sun.COM 619*12720SWyllys.Ingersoll@Sun.COM if (res != WAIT_OBJECT_0) 620*12720SWyllys.Ingersoll@Sun.COM { 621*12720SWyllys.Ingersoll@Sun.COM ReleaseMutex(i_pCond->m_hMutex); 622*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 623*12720SWyllys.Ingersoll@Sun.COM } 624*12720SWyllys.Ingersoll@Sun.COM 625*12720SWyllys.Ingersoll@Sun.COM if (i_pCond->m_iSignalAll) 626*12720SWyllys.Ingersoll@Sun.COM { 627*12720SWyllys.Ingersoll@Sun.COM if (i_pCond->m_iNumWaiting == 0) 628*12720SWyllys.Ingersoll@Sun.COM { 629*12720SWyllys.Ingersoll@Sun.COM ResetEvent(i_pCond->m_hEvent); 630*12720SWyllys.Ingersoll@Sun.COM } 631*12720SWyllys.Ingersoll@Sun.COM break; 632*12720SWyllys.Ingersoll@Sun.COM } 633*12720SWyllys.Ingersoll@Sun.COM 634*12720SWyllys.Ingersoll@Sun.COM if (i_pCond->m_iSignalled) 635*12720SWyllys.Ingersoll@Sun.COM { 636*12720SWyllys.Ingersoll@Sun.COM i_pCond->m_iSignalled = 0; 637*12720SWyllys.Ingersoll@Sun.COM ResetEvent(i_pCond->m_hEvent); 638*12720SWyllys.Ingersoll@Sun.COM break; 639*12720SWyllys.Ingersoll@Sun.COM } 640*12720SWyllys.Ingersoll@Sun.COM ReleaseMutex(i_pCond->m_hMutex); 641*12720SWyllys.Ingersoll@Sun.COM } 642*12720SWyllys.Ingersoll@Sun.COM 643*12720SWyllys.Ingersoll@Sun.COM K_LockMutex(i_handle); 644*12720SWyllys.Ingersoll@Sun.COM 645*12720SWyllys.Ingersoll@Sun.COM return K_SYS_OK; 646*12720SWyllys.Ingersoll@Sun.COM #else 647*12720SWyllys.Ingersoll@Sun.COM 648*12720SWyllys.Ingersoll@Sun.COM if ( pthread_cond_wait(i_pCond, i_handle) ) 649*12720SWyllys.Ingersoll@Sun.COM { 650*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 651*12720SWyllys.Ingersoll@Sun.COM } 652*12720SWyllys.Ingersoll@Sun.COM 653*12720SWyllys.Ingersoll@Sun.COM #endif 654*12720SWyllys.Ingersoll@Sun.COM return iOK; // TODO: better error handling 655*12720SWyllys.Ingersoll@Sun.COM } 656*12720SWyllys.Ingersoll@Sun.COM 657*12720SWyllys.Ingersoll@Sun.COM 658*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 659*12720SWyllys.Ingersoll@Sun.COM * Function: K_SignalConditionalVariable 660*12720SWyllys.Ingersoll@Sun.COM * 661*12720SWyllys.Ingersoll@Sun.COM * Description: 662*12720SWyllys.Ingersoll@Sun.COM * This function is used to restart one of the threads that are waiting on 663*12720SWyllys.Ingersoll@Sun.COM * the condition variable. If no threads are waiting on it, nothing happens. 664*12720SWyllys.Ingersoll@Sun.COM * If several threads are waiting on it, exactly one is restarted. 665*12720SWyllys.Ingersoll@Sun.COM * 666*12720SWyllys.Ingersoll@Sun.COM * Input 667*12720SWyllys.Ingersoll@Sun.COM * ----- 668*12720SWyllys.Ingersoll@Sun.COM * i_pCond the pointer to the conditional variable 669*12720SWyllys.Ingersoll@Sun.COM * 670*12720SWyllys.Ingersoll@Sun.COM * Output 671*12720SWyllys.Ingersoll@Sun.COM * ------ 672*12720SWyllys.Ingersoll@Sun.COM * (none) 673*12720SWyllys.Ingersoll@Sun.COM * 674*12720SWyllys.Ingersoll@Sun.COM * Return value Error Code 675*12720SWyllys.Ingersoll@Sun.COM * 676*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 677*12720SWyllys.Ingersoll@Sun.COM 678*12720SWyllys.Ingersoll@Sun.COM int K_SignalConditionalVariable(K_ConditionalVariable * i_pCond) 679*12720SWyllys.Ingersoll@Sun.COM { 680*12720SWyllys.Ingersoll@Sun.COM int iOK = K_SYS_OK; 681*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 682*12720SWyllys.Ingersoll@Sun.COM 683*12720SWyllys.Ingersoll@Sun.COM int iReturn; 684*12720SWyllys.Ingersoll@Sun.COM 685*12720SWyllys.Ingersoll@Sun.COM iReturn = WaitForSingleObject(i_pCond->m_hMutex, INFINITE); 686*12720SWyllys.Ingersoll@Sun.COM if (iReturn != WAIT_OBJECT_0) 687*12720SWyllys.Ingersoll@Sun.COM { 688*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 689*12720SWyllys.Ingersoll@Sun.COM } 690*12720SWyllys.Ingersoll@Sun.COM 691*12720SWyllys.Ingersoll@Sun.COM i_pCond->m_iSignalled = 1; 692*12720SWyllys.Ingersoll@Sun.COM 693*12720SWyllys.Ingersoll@Sun.COM iReturn = SetEvent(i_pCond->m_hEvent); 694*12720SWyllys.Ingersoll@Sun.COM if (iReturn == 0) 695*12720SWyllys.Ingersoll@Sun.COM { 696*12720SWyllys.Ingersoll@Sun.COM iOK = K_SYS_ERR_COND; 697*12720SWyllys.Ingersoll@Sun.COM } 698*12720SWyllys.Ingersoll@Sun.COM ReleaseMutex(i_pCond->m_hMutex); 699*12720SWyllys.Ingersoll@Sun.COM 700*12720SWyllys.Ingersoll@Sun.COM return iOK; 701*12720SWyllys.Ingersoll@Sun.COM #else 702*12720SWyllys.Ingersoll@Sun.COM 703*12720SWyllys.Ingersoll@Sun.COM if ( pthread_cond_signal(i_pCond) ) 704*12720SWyllys.Ingersoll@Sun.COM { 705*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 706*12720SWyllys.Ingersoll@Sun.COM } 707*12720SWyllys.Ingersoll@Sun.COM 708*12720SWyllys.Ingersoll@Sun.COM #endif 709*12720SWyllys.Ingersoll@Sun.COM return iOK; 710*12720SWyllys.Ingersoll@Sun.COM } 711*12720SWyllys.Ingersoll@Sun.COM 712*12720SWyllys.Ingersoll@Sun.COM 713*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 714*12720SWyllys.Ingersoll@Sun.COM * Function: K_BroadcastConditionalVariable 715*12720SWyllys.Ingersoll@Sun.COM * 716*12720SWyllys.Ingersoll@Sun.COM * Description: 717*12720SWyllys.Ingersoll@Sun.COM * This function is used to restart all threads that are waiting on 718*12720SWyllys.Ingersoll@Sun.COM * the condition variable. 719*12720SWyllys.Ingersoll@Sun.COM * 720*12720SWyllys.Ingersoll@Sun.COM * Input 721*12720SWyllys.Ingersoll@Sun.COM * ----- 722*12720SWyllys.Ingersoll@Sun.COM * i_pCond the pointer to the conditional variable 723*12720SWyllys.Ingersoll@Sun.COM * 724*12720SWyllys.Ingersoll@Sun.COM * Output 725*12720SWyllys.Ingersoll@Sun.COM * ------ 726*12720SWyllys.Ingersoll@Sun.COM * (none) 727*12720SWyllys.Ingersoll@Sun.COM * 728*12720SWyllys.Ingersoll@Sun.COM * Return value Error Code 729*12720SWyllys.Ingersoll@Sun.COM * 730*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 731*12720SWyllys.Ingersoll@Sun.COM 732*12720SWyllys.Ingersoll@Sun.COM int K_BroadcastConditionalVariable(K_ConditionalVariable * i_pCond) 733*12720SWyllys.Ingersoll@Sun.COM { 734*12720SWyllys.Ingersoll@Sun.COM 735*12720SWyllys.Ingersoll@Sun.COM int iOK = K_SYS_OK; 736*12720SWyllys.Ingersoll@Sun.COM 737*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 738*12720SWyllys.Ingersoll@Sun.COM 739*12720SWyllys.Ingersoll@Sun.COM int iReturn; 740*12720SWyllys.Ingersoll@Sun.COM 741*12720SWyllys.Ingersoll@Sun.COM iReturn = WaitForSingleObject(i_pCond->m_hMutex, INFINITE); 742*12720SWyllys.Ingersoll@Sun.COM if (iReturn != WAIT_OBJECT_0) 743*12720SWyllys.Ingersoll@Sun.COM { 744*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 745*12720SWyllys.Ingersoll@Sun.COM } 746*12720SWyllys.Ingersoll@Sun.COM i_pCond->m_iSignalled = 1; 747*12720SWyllys.Ingersoll@Sun.COM i_pCond->m_iSignalAll = 1; 748*12720SWyllys.Ingersoll@Sun.COM 749*12720SWyllys.Ingersoll@Sun.COM iReturn = SetEvent(i_pCond->m_hEvent); 750*12720SWyllys.Ingersoll@Sun.COM 751*12720SWyllys.Ingersoll@Sun.COM if (iReturn == 0) 752*12720SWyllys.Ingersoll@Sun.COM { 753*12720SWyllys.Ingersoll@Sun.COM iOK = K_SYS_ERR_COND; 754*12720SWyllys.Ingersoll@Sun.COM } 755*12720SWyllys.Ingersoll@Sun.COM 756*12720SWyllys.Ingersoll@Sun.COM ReleaseMutex(i_pCond->m_hMutex); 757*12720SWyllys.Ingersoll@Sun.COM 758*12720SWyllys.Ingersoll@Sun.COM return iOK; 759*12720SWyllys.Ingersoll@Sun.COM 760*12720SWyllys.Ingersoll@Sun.COM #else 761*12720SWyllys.Ingersoll@Sun.COM 762*12720SWyllys.Ingersoll@Sun.COM if ( pthread_cond_broadcast(i_pCond) ) 763*12720SWyllys.Ingersoll@Sun.COM { 764*12720SWyllys.Ingersoll@Sun.COM return K_SYS_ERR_COND; 765*12720SWyllys.Ingersoll@Sun.COM } 766*12720SWyllys.Ingersoll@Sun.COM 767*12720SWyllys.Ingersoll@Sun.COM #endif 768*12720SWyllys.Ingersoll@Sun.COM return iOK; 769*12720SWyllys.Ingersoll@Sun.COM } 770*12720SWyllys.Ingersoll@Sun.COM 771*12720SWyllys.Ingersoll@Sun.COM 772*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 773*12720SWyllys.Ingersoll@Sun.COM * Function: K_Sleep 774*12720SWyllys.Ingersoll@Sun.COM * 775*12720SWyllys.Ingersoll@Sun.COM * Description: 776*12720SWyllys.Ingersoll@Sun.COM * Sleep for a given period in given milliseconds. 777*12720SWyllys.Ingersoll@Sun.COM * 778*12720SWyllys.Ingersoll@Sun.COM * Input 779*12720SWyllys.Ingersoll@Sun.COM * ----- 780*12720SWyllys.Ingersoll@Sun.COM * i_ms milliseconds 781*12720SWyllys.Ingersoll@Sun.COM * 782*12720SWyllys.Ingersoll@Sun.COM * Output 783*12720SWyllys.Ingersoll@Sun.COM * ------ 784*12720SWyllys.Ingersoll@Sun.COM * (none) 785*12720SWyllys.Ingersoll@Sun.COM * 786*12720SWyllys.Ingersoll@Sun.COM * Return value (none) 787*12720SWyllys.Ingersoll@Sun.COM * 788*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 789*12720SWyllys.Ingersoll@Sun.COM 790*12720SWyllys.Ingersoll@Sun.COM void K_Sleep(int i_ms) 791*12720SWyllys.Ingersoll@Sun.COM { 792*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 793*12720SWyllys.Ingersoll@Sun.COM Sleep(i_ms); 794*12720SWyllys.Ingersoll@Sun.COM #else 795*12720SWyllys.Ingersoll@Sun.COM usleep(i_ms * 1000); 796*12720SWyllys.Ingersoll@Sun.COM #endif 797*12720SWyllys.Ingersoll@Sun.COM } 798*12720SWyllys.Ingersoll@Sun.COM 799*12720SWyllys.Ingersoll@Sun.COM 800*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 801*12720SWyllys.Ingersoll@Sun.COM * Function: K_GetTickCount 802*12720SWyllys.Ingersoll@Sun.COM * 803*12720SWyllys.Ingersoll@Sun.COM * Description: 804*12720SWyllys.Ingersoll@Sun.COM * The K_GetTickCount function retrieves the number of 805*12720SWyllys.Ingersoll@Sun.COM * milliseconds that have elapsed since the system was started. 806*12720SWyllys.Ingersoll@Sun.COM * 807*12720SWyllys.Ingersoll@Sun.COM * Input 808*12720SWyllys.Ingersoll@Sun.COM * ----- 809*12720SWyllys.Ingersoll@Sun.COM * (none) 810*12720SWyllys.Ingersoll@Sun.COM * 811*12720SWyllys.Ingersoll@Sun.COM * Output 812*12720SWyllys.Ingersoll@Sun.COM * ------ 813*12720SWyllys.Ingersoll@Sun.COM * (none) 814*12720SWyllys.Ingersoll@Sun.COM * 815*12720SWyllys.Ingersoll@Sun.COM * Return value the elasped milliseconds since the system was started 816*12720SWyllys.Ingersoll@Sun.COM * 817*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 818*12720SWyllys.Ingersoll@Sun.COM 819*12720SWyllys.Ingersoll@Sun.COM unsigned int K_GetTickCount() 820*12720SWyllys.Ingersoll@Sun.COM { 821*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 822*12720SWyllys.Ingersoll@Sun.COM return (unsigned int)GetTickCount(); 823*12720SWyllys.Ingersoll@Sun.COM #else 824*12720SWyllys.Ingersoll@Sun.COM { 825*12720SWyllys.Ingersoll@Sun.COM struct timeval tv; 826*12720SWyllys.Ingersoll@Sun.COM gettimeofday( &tv, NULL ); 827*12720SWyllys.Ingersoll@Sun.COM /* this will rollover ~ every 49.7 days 828*12720SWyllys.Ingersoll@Sun.COM dont surprise when it returns negative values, since we are only interested 829*12720SWyllys.Ingersoll@Sun.COM in using sth like "tickCount2 - tickCount1" to get the time interval 830*12720SWyllys.Ingersoll@Sun.COM */ 831*12720SWyllys.Ingersoll@Sun.COM return ( tv.tv_sec * 1000 ) + ( tv.tv_usec / 1000 ); 832*12720SWyllys.Ingersoll@Sun.COM } 833*12720SWyllys.Ingersoll@Sun.COM #endif 834*12720SWyllys.Ingersoll@Sun.COM } 835*12720SWyllys.Ingersoll@Sun.COM 836*12720SWyllys.Ingersoll@Sun.COM 837*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 838*12720SWyllys.Ingersoll@Sun.COM * Function: K_AdjustClock 839*12720SWyllys.Ingersoll@Sun.COM * 840*12720SWyllys.Ingersoll@Sun.COM * Description: 841*12720SWyllys.Ingersoll@Sun.COM * The K_AdjustClock function immediately adjusts the system clock by 842*12720SWyllys.Ingersoll@Sun.COM * the given number of seconds. A positive number adjusts the system 843*12720SWyllys.Ingersoll@Sun.COM * clock forward; a negative number adjusts the system clock backward. 844*12720SWyllys.Ingersoll@Sun.COM * 845*12720SWyllys.Ingersoll@Sun.COM * Input 846*12720SWyllys.Ingersoll@Sun.COM * ----- 847*12720SWyllys.Ingersoll@Sun.COM * i_iAdjustmentInSeconds Number of seconds by which to adjust the 848*12720SWyllys.Ingersoll@Sun.COM * system clock 849*12720SWyllys.Ingersoll@Sun.COM * Output 850*12720SWyllys.Ingersoll@Sun.COM * ------ 851*12720SWyllys.Ingersoll@Sun.COM * (none) 852*12720SWyllys.Ingersoll@Sun.COM * 853*12720SWyllys.Ingersoll@Sun.COM * Return value 1 if successful, 0 on error 854*12720SWyllys.Ingersoll@Sun.COM * 855*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 856*12720SWyllys.Ingersoll@Sun.COM 857*12720SWyllys.Ingersoll@Sun.COM int K_AdjustClock( long i_iAdjustmentInSeconds ) 858*12720SWyllys.Ingersoll@Sun.COM { 859*12720SWyllys.Ingersoll@Sun.COM #ifndef WIN32 860*12720SWyllys.Ingersoll@Sun.COM struct timeval stDateTime; 861*12720SWyllys.Ingersoll@Sun.COM if ( 0 != gettimeofday(&stDateTime, NULL) ) 862*12720SWyllys.Ingersoll@Sun.COM { 863*12720SWyllys.Ingersoll@Sun.COM return FALSE; 864*12720SWyllys.Ingersoll@Sun.COM } 865*12720SWyllys.Ingersoll@Sun.COM 866*12720SWyllys.Ingersoll@Sun.COM stDateTime.tv_sec += i_iAdjustmentInSeconds; 867*12720SWyllys.Ingersoll@Sun.COM 868*12720SWyllys.Ingersoll@Sun.COM if ( 0 != settimeofday(&stDateTime, NULL) ) 869*12720SWyllys.Ingersoll@Sun.COM { 870*12720SWyllys.Ingersoll@Sun.COM return FALSE; 871*12720SWyllys.Ingersoll@Sun.COM } 872*12720SWyllys.Ingersoll@Sun.COM #else 873*12720SWyllys.Ingersoll@Sun.COM // TODO: implement for Windows 874*12720SWyllys.Ingersoll@Sun.COM return FALSE; 875*12720SWyllys.Ingersoll@Sun.COM #endif 876*12720SWyllys.Ingersoll@Sun.COM 877*12720SWyllys.Ingersoll@Sun.COM return TRUE; 878*12720SWyllys.Ingersoll@Sun.COM } 879*12720SWyllys.Ingersoll@Sun.COM 880*12720SWyllys.Ingersoll@Sun.COM 881*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 882*12720SWyllys.Ingersoll@Sun.COM * Function: K_IsLittleEndian 883*12720SWyllys.Ingersoll@Sun.COM * 884*12720SWyllys.Ingersoll@Sun.COM * Description: 885*12720SWyllys.Ingersoll@Sun.COM * Checks to see whether this platform uses little endian integer 886*12720SWyllys.Ingersoll@Sun.COM * representation. 887*12720SWyllys.Ingersoll@Sun.COM * 888*12720SWyllys.Ingersoll@Sun.COM * Input 889*12720SWyllys.Ingersoll@Sun.COM * ----- 890*12720SWyllys.Ingersoll@Sun.COM * (none) 891*12720SWyllys.Ingersoll@Sun.COM * 892*12720SWyllys.Ingersoll@Sun.COM * Output 893*12720SWyllys.Ingersoll@Sun.COM * ------ 894*12720SWyllys.Ingersoll@Sun.COM * (none) 895*12720SWyllys.Ingersoll@Sun.COM * 896*12720SWyllys.Ingersoll@Sun.COM * Return value 1 for little endian 897*12720SWyllys.Ingersoll@Sun.COM * 898*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 899*12720SWyllys.Ingersoll@Sun.COM 900*12720SWyllys.Ingersoll@Sun.COM int K_IsLittleEndian() 901*12720SWyllys.Ingersoll@Sun.COM { 902*12720SWyllys.Ingersoll@Sun.COM short iWord = 0x4321; 903*12720SWyllys.Ingersoll@Sun.COM return ((*(unsigned char*)&iWord) == 0x21); 904*12720SWyllys.Ingersoll@Sun.COM } 905*12720SWyllys.Ingersoll@Sun.COM 906*12720SWyllys.Ingersoll@Sun.COM 907*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 908*12720SWyllys.Ingersoll@Sun.COM * Function: K_FileLength32 909*12720SWyllys.Ingersoll@Sun.COM * 910*12720SWyllys.Ingersoll@Sun.COM * Description: 911*12720SWyllys.Ingersoll@Sun.COM * Gets the size in bytes of the file associated with the given FILE pointer. 912*12720SWyllys.Ingersoll@Sun.COM * 913*12720SWyllys.Ingersoll@Sun.COM * Input 914*12720SWyllys.Ingersoll@Sun.COM * ----- 915*12720SWyllys.Ingersoll@Sun.COM * i_fpFile File handle 916*12720SWyllys.Ingersoll@Sun.COM * 917*12720SWyllys.Ingersoll@Sun.COM * Output 918*12720SWyllys.Ingersoll@Sun.COM * ------ 919*12720SWyllys.Ingersoll@Sun.COM * (none) 920*12720SWyllys.Ingersoll@Sun.COM * 921*12720SWyllys.Ingersoll@Sun.COM * Return value File size in bytes, or -1L on error 922*12720SWyllys.Ingersoll@Sun.COM * 923*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 924*12720SWyllys.Ingersoll@Sun.COM 925*12720SWyllys.Ingersoll@Sun.COM long K_FileLength32( FILE* i_fpFile ) 926*12720SWyllys.Ingersoll@Sun.COM { 927*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 928*12720SWyllys.Ingersoll@Sun.COM int iFileDescriptor = _fileno( i_fpFile ); 929*12720SWyllys.Ingersoll@Sun.COM struct _stat stStat; 930*12720SWyllys.Ingersoll@Sun.COM 931*12720SWyllys.Ingersoll@Sun.COM if ( _fstat(iFileDescriptor, &stStat) != 0) 932*12720SWyllys.Ingersoll@Sun.COM { 933*12720SWyllys.Ingersoll@Sun.COM // error 934*12720SWyllys.Ingersoll@Sun.COM return -1L; 935*12720SWyllys.Ingersoll@Sun.COM } 936*12720SWyllys.Ingersoll@Sun.COM 937*12720SWyllys.Ingersoll@Sun.COM #else 938*12720SWyllys.Ingersoll@Sun.COM int iFileDescriptor = fileno( i_fpFile ); 939*12720SWyllys.Ingersoll@Sun.COM struct stat stStat; 940*12720SWyllys.Ingersoll@Sun.COM 941*12720SWyllys.Ingersoll@Sun.COM if ( fstat(iFileDescriptor, &stStat) != 0) 942*12720SWyllys.Ingersoll@Sun.COM { 943*12720SWyllys.Ingersoll@Sun.COM // error 944*12720SWyllys.Ingersoll@Sun.COM return -1L; 945*12720SWyllys.Ingersoll@Sun.COM } 946*12720SWyllys.Ingersoll@Sun.COM 947*12720SWyllys.Ingersoll@Sun.COM #endif 948*12720SWyllys.Ingersoll@Sun.COM 949*12720SWyllys.Ingersoll@Sun.COM return stStat.st_size; 950*12720SWyllys.Ingersoll@Sun.COM } 951*12720SWyllys.Ingersoll@Sun.COM 952*12720SWyllys.Ingersoll@Sun.COM 953*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 954*12720SWyllys.Ingersoll@Sun.COM * Function: K_StringCompareNoCase 955*12720SWyllys.Ingersoll@Sun.COM * 956*12720SWyllys.Ingersoll@Sun.COM * Description: 957*12720SWyllys.Ingersoll@Sun.COM * Compares the two given strings insensitive to case. 958*12720SWyllys.Ingersoll@Sun.COM * 959*12720SWyllys.Ingersoll@Sun.COM * Input 960*12720SWyllys.Ingersoll@Sun.COM * ----- 961*12720SWyllys.Ingersoll@Sun.COM * i_sString1 First string 962*12720SWyllys.Ingersoll@Sun.COM * i_sString2 Second string 963*12720SWyllys.Ingersoll@Sun.COM * 964*12720SWyllys.Ingersoll@Sun.COM * Output 965*12720SWyllys.Ingersoll@Sun.COM * ------ 966*12720SWyllys.Ingersoll@Sun.COM * (none) 967*12720SWyllys.Ingersoll@Sun.COM * 968*12720SWyllys.Ingersoll@Sun.COM * Return value 0 if identical, -1 if first string is less than second 969*12720SWyllys.Ingersoll@Sun.COM * string, or 1 if first string is greater than second 970*12720SWyllys.Ingersoll@Sun.COM * 971*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 972*12720SWyllys.Ingersoll@Sun.COM 973*12720SWyllys.Ingersoll@Sun.COM int K_StringCompareNoCase( const char* i_sString1, const char* i_sString2 ) 974*12720SWyllys.Ingersoll@Sun.COM { 975*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 976*12720SWyllys.Ingersoll@Sun.COM return _stricmp( i_sString1, i_sString2 ); 977*12720SWyllys.Ingersoll@Sun.COM #else 978*12720SWyllys.Ingersoll@Sun.COM return strcasecmp( i_sString1, i_sString2 ); 979*12720SWyllys.Ingersoll@Sun.COM #endif 980*12720SWyllys.Ingersoll@Sun.COM } 981*12720SWyllys.Ingersoll@Sun.COM 982*12720SWyllys.Ingersoll@Sun.COM 983*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 984*12720SWyllys.Ingersoll@Sun.COM * Function: K_StringCompareNoCaseWide 985*12720SWyllys.Ingersoll@Sun.COM * 986*12720SWyllys.Ingersoll@Sun.COM * Description: 987*12720SWyllys.Ingersoll@Sun.COM * Compares the two given wide strings insensitive to case. 988*12720SWyllys.Ingersoll@Sun.COM * 989*12720SWyllys.Ingersoll@Sun.COM * Input 990*12720SWyllys.Ingersoll@Sun.COM * ----- 991*12720SWyllys.Ingersoll@Sun.COM * i_wsString1 First wide string 992*12720SWyllys.Ingersoll@Sun.COM * i_wsString2 Second wide string 993*12720SWyllys.Ingersoll@Sun.COM * 994*12720SWyllys.Ingersoll@Sun.COM * Output 995*12720SWyllys.Ingersoll@Sun.COM * ------ 996*12720SWyllys.Ingersoll@Sun.COM * (none) 997*12720SWyllys.Ingersoll@Sun.COM * 998*12720SWyllys.Ingersoll@Sun.COM * Return value 0 if identical, -1 if first string is less than second 999*12720SWyllys.Ingersoll@Sun.COM * string, or 1 if first string is greater than second 1000*12720SWyllys.Ingersoll@Sun.COM * 1001*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1002*12720SWyllys.Ingersoll@Sun.COM 1003*12720SWyllys.Ingersoll@Sun.COM int K_StringCompareNoCaseWide( const wchar_t* i_wsString1, const wchar_t* i_wsString2 ) 1004*12720SWyllys.Ingersoll@Sun.COM { 1005*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 1006*12720SWyllys.Ingersoll@Sun.COM return _wcsicmp( i_wsString1, i_wsString2 ); 1007*12720SWyllys.Ingersoll@Sun.COM #elif defined K_SOLARIS_PLATFORM 1008*12720SWyllys.Ingersoll@Sun.COM return wscasecmp( i_wsString1, i_wsString2 ); 1009*12720SWyllys.Ingersoll@Sun.COM #else 1010*12720SWyllys.Ingersoll@Sun.COM return wcscasecmp( i_wsString1, i_wsString2 ); 1011*12720SWyllys.Ingersoll@Sun.COM #endif 1012*12720SWyllys.Ingersoll@Sun.COM } 1013*12720SWyllys.Ingersoll@Sun.COM 1014*12720SWyllys.Ingersoll@Sun.COM 1015*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1016*12720SWyllys.Ingersoll@Sun.COM * Function: K_CreateDirectory 1017*12720SWyllys.Ingersoll@Sun.COM * 1018*12720SWyllys.Ingersoll@Sun.COM * Description: 1019*12720SWyllys.Ingersoll@Sun.COM * Creates a directory with the given path name. 1020*12720SWyllys.Ingersoll@Sun.COM * 1021*12720SWyllys.Ingersoll@Sun.COM * Input 1022*12720SWyllys.Ingersoll@Sun.COM * ----- 1023*12720SWyllys.Ingersoll@Sun.COM * i_sDirectoryName Directory name 1024*12720SWyllys.Ingersoll@Sun.COM * 1025*12720SWyllys.Ingersoll@Sun.COM * Output 1026*12720SWyllys.Ingersoll@Sun.COM * ------ 1027*12720SWyllys.Ingersoll@Sun.COM * (none) 1028*12720SWyllys.Ingersoll@Sun.COM * 1029*12720SWyllys.Ingersoll@Sun.COM * Return value 0 on success, -1 on failure 1030*12720SWyllys.Ingersoll@Sun.COM * 1031*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1032*12720SWyllys.Ingersoll@Sun.COM 1033*12720SWyllys.Ingersoll@Sun.COM int K_CreateDirectory( const char* i_sDirectoryName ) 1034*12720SWyllys.Ingersoll@Sun.COM { 1035*12720SWyllys.Ingersoll@Sun.COM // TODO: make this build all parent directories as well. 1036*12720SWyllys.Ingersoll@Sun.COM 1037*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 1038*12720SWyllys.Ingersoll@Sun.COM if ( CreateDirectoryA( i_sDirectoryName, NULL ) ) 1039*12720SWyllys.Ingersoll@Sun.COM { 1040*12720SWyllys.Ingersoll@Sun.COM return 0; 1041*12720SWyllys.Ingersoll@Sun.COM } 1042*12720SWyllys.Ingersoll@Sun.COM else 1043*12720SWyllys.Ingersoll@Sun.COM { 1044*12720SWyllys.Ingersoll@Sun.COM DWORD dwError = GetLastError(); 1045*12720SWyllys.Ingersoll@Sun.COM return ( dwError == ERROR_ALREADY_EXISTS ) ? 0 : (dwError ? dwError : -1); 1046*12720SWyllys.Ingersoll@Sun.COM } 1047*12720SWyllys.Ingersoll@Sun.COM #else 1048*12720SWyllys.Ingersoll@Sun.COM if ( mkdir( i_sDirectoryName, S_IRWXU ) == 0 ) 1049*12720SWyllys.Ingersoll@Sun.COM { 1050*12720SWyllys.Ingersoll@Sun.COM return 0; 1051*12720SWyllys.Ingersoll@Sun.COM } 1052*12720SWyllys.Ingersoll@Sun.COM else 1053*12720SWyllys.Ingersoll@Sun.COM { 1054*12720SWyllys.Ingersoll@Sun.COM return ( errno == EEXIST ) ? 0 : (errno ? errno : -1); 1055*12720SWyllys.Ingersoll@Sun.COM } 1056*12720SWyllys.Ingersoll@Sun.COM #endif 1057*12720SWyllys.Ingersoll@Sun.COM } 1058*12720SWyllys.Ingersoll@Sun.COM 1059*12720SWyllys.Ingersoll@Sun.COM 1060*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1061*12720SWyllys.Ingersoll@Sun.COM * Function: K_DeleteFile 1062*12720SWyllys.Ingersoll@Sun.COM * 1063*12720SWyllys.Ingersoll@Sun.COM * Description: 1064*12720SWyllys.Ingersoll@Sun.COM * Deletes the given file. 1065*12720SWyllys.Ingersoll@Sun.COM * 1066*12720SWyllys.Ingersoll@Sun.COM * Input 1067*12720SWyllys.Ingersoll@Sun.COM * ----- 1068*12720SWyllys.Ingersoll@Sun.COM * i_sFilename Name of file to delete 1069*12720SWyllys.Ingersoll@Sun.COM * 1070*12720SWyllys.Ingersoll@Sun.COM * Output 1071*12720SWyllys.Ingersoll@Sun.COM * ------ 1072*12720SWyllys.Ingersoll@Sun.COM * (none) 1073*12720SWyllys.Ingersoll@Sun.COM * 1074*12720SWyllys.Ingersoll@Sun.COM * Return value 0 on success, errno on failure 1075*12720SWyllys.Ingersoll@Sun.COM * 1076*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1077*12720SWyllys.Ingersoll@Sun.COM 1078*12720SWyllys.Ingersoll@Sun.COM int K_DeleteFile( const char* i_sFilename ) 1079*12720SWyllys.Ingersoll@Sun.COM { 1080*12720SWyllys.Ingersoll@Sun.COM int bSuccess = 0; 1081*12720SWyllys.Ingersoll@Sun.COM 1082*12720SWyllys.Ingersoll@Sun.COM bSuccess = 1083*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 1084*12720SWyllys.Ingersoll@Sun.COM _unlink( 1085*12720SWyllys.Ingersoll@Sun.COM #else 1086*12720SWyllys.Ingersoll@Sun.COM unlink( 1087*12720SWyllys.Ingersoll@Sun.COM #endif 1088*12720SWyllys.Ingersoll@Sun.COM i_sFilename ) == 0; 1089*12720SWyllys.Ingersoll@Sun.COM 1090*12720SWyllys.Ingersoll@Sun.COM return bSuccess ? 0 : errno; 1091*12720SWyllys.Ingersoll@Sun.COM } 1092*12720SWyllys.Ingersoll@Sun.COM 1093*12720SWyllys.Ingersoll@Sun.COM 1094*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1095*12720SWyllys.Ingersoll@Sun.COM * Function: K_ReadFile 1096*12720SWyllys.Ingersoll@Sun.COM * 1097*12720SWyllys.Ingersoll@Sun.COM * Description: 1098*12720SWyllys.Ingersoll@Sun.COM * Reads from the given file and passes the bytes read back to the output 1099*12720SWyllys.Ingersoll@Sun.COM * parameter. The caller must deallocate o_ppFileData using free(). 1100*12720SWyllys.Ingersoll@Sun.COM * 1101*12720SWyllys.Ingersoll@Sun.COM * Input 1102*12720SWyllys.Ingersoll@Sun.COM * ----- 1103*12720SWyllys.Ingersoll@Sun.COM * i_sFilename Name of file from which to read 1104*12720SWyllys.Ingersoll@Sun.COM * 1105*12720SWyllys.Ingersoll@Sun.COM * Output 1106*12720SWyllys.Ingersoll@Sun.COM * ------ 1107*12720SWyllys.Ingersoll@Sun.COM * o_ppFileData Pointer to bytes read 1108*12720SWyllys.Ingersoll@Sun.COM * 1109*12720SWyllys.Ingersoll@Sun.COM * Return value Number of bytes read on success, -1 on failure 1110*12720SWyllys.Ingersoll@Sun.COM * 1111*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1112*12720SWyllys.Ingersoll@Sun.COM 1113*12720SWyllys.Ingersoll@Sun.COM int K_ReadFile( const char* i_sFilename, unsigned char** o_ppFileData ) 1114*12720SWyllys.Ingersoll@Sun.COM { 1115*12720SWyllys.Ingersoll@Sun.COM FILE* pFile = 0; 1116*12720SWyllys.Ingersoll@Sun.COM long iFileSize = 0; 1117*12720SWyllys.Ingersoll@Sun.COM 1118*12720SWyllys.Ingersoll@Sun.COM if ( !i_sFilename || (strlen(i_sFilename) <= 0) || !o_ppFileData ) 1119*12720SWyllys.Ingersoll@Sun.COM { 1120*12720SWyllys.Ingersoll@Sun.COM return -1; 1121*12720SWyllys.Ingersoll@Sun.COM } 1122*12720SWyllys.Ingersoll@Sun.COM 1123*12720SWyllys.Ingersoll@Sun.COM *o_ppFileData = 0; 1124*12720SWyllys.Ingersoll@Sun.COM 1125*12720SWyllys.Ingersoll@Sun.COM // Open the file 1126*12720SWyllys.Ingersoll@Sun.COM 1127*12720SWyllys.Ingersoll@Sun.COM pFile = fopen( i_sFilename, "rb" ); 1128*12720SWyllys.Ingersoll@Sun.COM if ( !pFile ) 1129*12720SWyllys.Ingersoll@Sun.COM { 1130*12720SWyllys.Ingersoll@Sun.COM return -1; 1131*12720SWyllys.Ingersoll@Sun.COM } 1132*12720SWyllys.Ingersoll@Sun.COM 1133*12720SWyllys.Ingersoll@Sun.COM // Determine the file size 1134*12720SWyllys.Ingersoll@Sun.COM 1135*12720SWyllys.Ingersoll@Sun.COM if ( fseek( pFile, 0, SEEK_END ) ) 1136*12720SWyllys.Ingersoll@Sun.COM { 1137*12720SWyllys.Ingersoll@Sun.COM (void) fclose( pFile ); 1138*12720SWyllys.Ingersoll@Sun.COM return -1; 1139*12720SWyllys.Ingersoll@Sun.COM } 1140*12720SWyllys.Ingersoll@Sun.COM 1141*12720SWyllys.Ingersoll@Sun.COM iFileSize = ftell( pFile ); 1142*12720SWyllys.Ingersoll@Sun.COM if ( iFileSize < 0 ) 1143*12720SWyllys.Ingersoll@Sun.COM { 1144*12720SWyllys.Ingersoll@Sun.COM (void) fclose( pFile ); 1145*12720SWyllys.Ingersoll@Sun.COM return -1; 1146*12720SWyllys.Ingersoll@Sun.COM } 1147*12720SWyllys.Ingersoll@Sun.COM else if ( iFileSize == 0 ) 1148*12720SWyllys.Ingersoll@Sun.COM { 1149*12720SWyllys.Ingersoll@Sun.COM (void) fclose( pFile ); 1150*12720SWyllys.Ingersoll@Sun.COM return 0; 1151*12720SWyllys.Ingersoll@Sun.COM } 1152*12720SWyllys.Ingersoll@Sun.COM 1153*12720SWyllys.Ingersoll@Sun.COM if ( fseek( pFile, 0, SEEK_SET ) ) 1154*12720SWyllys.Ingersoll@Sun.COM { 1155*12720SWyllys.Ingersoll@Sun.COM (void) fclose( pFile ); 1156*12720SWyllys.Ingersoll@Sun.COM return -1; 1157*12720SWyllys.Ingersoll@Sun.COM } 1158*12720SWyllys.Ingersoll@Sun.COM 1159*12720SWyllys.Ingersoll@Sun.COM *o_ppFileData = (unsigned char*)malloc( iFileSize ); 1160*12720SWyllys.Ingersoll@Sun.COM if ( !*o_ppFileData ) 1161*12720SWyllys.Ingersoll@Sun.COM { 1162*12720SWyllys.Ingersoll@Sun.COM // Out of memory. 1163*12720SWyllys.Ingersoll@Sun.COM (void) fclose( pFile ); 1164*12720SWyllys.Ingersoll@Sun.COM return -1; 1165*12720SWyllys.Ingersoll@Sun.COM } 1166*12720SWyllys.Ingersoll@Sun.COM 1167*12720SWyllys.Ingersoll@Sun.COM if ( iFileSize != (long)fread( *o_ppFileData, 1, iFileSize, pFile ) ) 1168*12720SWyllys.Ingersoll@Sun.COM { 1169*12720SWyllys.Ingersoll@Sun.COM free( *o_ppFileData ); 1170*12720SWyllys.Ingersoll@Sun.COM *o_ppFileData = 0; 1171*12720SWyllys.Ingersoll@Sun.COM (void) fclose( pFile ); 1172*12720SWyllys.Ingersoll@Sun.COM return -1; 1173*12720SWyllys.Ingersoll@Sun.COM } 1174*12720SWyllys.Ingersoll@Sun.COM 1175*12720SWyllys.Ingersoll@Sun.COM (void) fclose( pFile ); 1176*12720SWyllys.Ingersoll@Sun.COM 1177*12720SWyllys.Ingersoll@Sun.COM return iFileSize; 1178*12720SWyllys.Ingersoll@Sun.COM } 1179*12720SWyllys.Ingersoll@Sun.COM 1180*12720SWyllys.Ingersoll@Sun.COM 1181*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1182*12720SWyllys.Ingersoll@Sun.COM * Function: K_ReadFileString 1183*12720SWyllys.Ingersoll@Sun.COM * 1184*12720SWyllys.Ingersoll@Sun.COM * Description: 1185*12720SWyllys.Ingersoll@Sun.COM * Reads from the given file and passes the bytes read back to the output 1186*12720SWyllys.Ingersoll@Sun.COM * parameter, appending these bytes with a null terminator. There is no 1187*12720SWyllys.Ingersoll@Sun.COM * guarantee that there are no non-text characters in the returned "string". 1188*12720SWyllys.Ingersoll@Sun.COM * The caller must deallocate o_ppFileData using free(). 1189*12720SWyllys.Ingersoll@Sun.COM * 1190*12720SWyllys.Ingersoll@Sun.COM * Input 1191*12720SWyllys.Ingersoll@Sun.COM * ----- 1192*12720SWyllys.Ingersoll@Sun.COM * i_sFilename Name of file from which to read 1193*12720SWyllys.Ingersoll@Sun.COM * 1194*12720SWyllys.Ingersoll@Sun.COM * Output 1195*12720SWyllys.Ingersoll@Sun.COM * ------ 1196*12720SWyllys.Ingersoll@Sun.COM * o_psFileDataString Pointer to bytes read 1197*12720SWyllys.Ingersoll@Sun.COM * 1198*12720SWyllys.Ingersoll@Sun.COM * Return value Number of bytes read (including null terminator) on 1199*12720SWyllys.Ingersoll@Sun.COM * success (0 if file is empty), -1 on failure 1200*12720SWyllys.Ingersoll@Sun.COM * 1201*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1202*12720SWyllys.Ingersoll@Sun.COM 1203*12720SWyllys.Ingersoll@Sun.COM int K_ReadFileString( const char* i_sFilename, char** o_psFileDataString ) 1204*12720SWyllys.Ingersoll@Sun.COM { 1205*12720SWyllys.Ingersoll@Sun.COM unsigned char* pFileData = 0; 1206*12720SWyllys.Ingersoll@Sun.COM int iFileSize = 0; 1207*12720SWyllys.Ingersoll@Sun.COM 1208*12720SWyllys.Ingersoll@Sun.COM *o_psFileDataString = 0; 1209*12720SWyllys.Ingersoll@Sun.COM 1210*12720SWyllys.Ingersoll@Sun.COM iFileSize = K_ReadFile( i_sFilename, &pFileData ); 1211*12720SWyllys.Ingersoll@Sun.COM 1212*12720SWyllys.Ingersoll@Sun.COM if ( iFileSize <= 0 ) 1213*12720SWyllys.Ingersoll@Sun.COM { 1214*12720SWyllys.Ingersoll@Sun.COM return iFileSize; 1215*12720SWyllys.Ingersoll@Sun.COM } 1216*12720SWyllys.Ingersoll@Sun.COM 1217*12720SWyllys.Ingersoll@Sun.COM *o_psFileDataString = (char*)malloc( iFileSize+1 ); 1218*12720SWyllys.Ingersoll@Sun.COM 1219*12720SWyllys.Ingersoll@Sun.COM if ( !*o_psFileDataString ) 1220*12720SWyllys.Ingersoll@Sun.COM { 1221*12720SWyllys.Ingersoll@Sun.COM // Out of memory. 1222*12720SWyllys.Ingersoll@Sun.COM if ( pFileData ) 1223*12720SWyllys.Ingersoll@Sun.COM { 1224*12720SWyllys.Ingersoll@Sun.COM free( pFileData ); 1225*12720SWyllys.Ingersoll@Sun.COM } 1226*12720SWyllys.Ingersoll@Sun.COM return -1; 1227*12720SWyllys.Ingersoll@Sun.COM } 1228*12720SWyllys.Ingersoll@Sun.COM 1229*12720SWyllys.Ingersoll@Sun.COM memcpy( *o_psFileDataString, pFileData, iFileSize ); 1230*12720SWyllys.Ingersoll@Sun.COM 1231*12720SWyllys.Ingersoll@Sun.COM (*o_psFileDataString)[iFileSize] = '\0'; 1232*12720SWyllys.Ingersoll@Sun.COM 1233*12720SWyllys.Ingersoll@Sun.COM if ( pFileData ) 1234*12720SWyllys.Ingersoll@Sun.COM { 1235*12720SWyllys.Ingersoll@Sun.COM free( pFileData ); 1236*12720SWyllys.Ingersoll@Sun.COM } 1237*12720SWyllys.Ingersoll@Sun.COM 1238*12720SWyllys.Ingersoll@Sun.COM return iFileSize+1; 1239*12720SWyllys.Ingersoll@Sun.COM } 1240*12720SWyllys.Ingersoll@Sun.COM 1241*12720SWyllys.Ingersoll@Sun.COM 1242*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1243*12720SWyllys.Ingersoll@Sun.COM * Function: K_WriteFile 1244*12720SWyllys.Ingersoll@Sun.COM * 1245*12720SWyllys.Ingersoll@Sun.COM * Description: 1246*12720SWyllys.Ingersoll@Sun.COM * Writes the given bytes to the given file. 1247*12720SWyllys.Ingersoll@Sun.COM * 1248*12720SWyllys.Ingersoll@Sun.COM * Input 1249*12720SWyllys.Ingersoll@Sun.COM * ----- 1250*12720SWyllys.Ingersoll@Sun.COM * i_sFilename Name of file to which to write 1251*12720SWyllys.Ingersoll@Sun.COM * i_pFileData Bytes to write 1252*12720SWyllys.Ingersoll@Sun.COM * i_iFileDataSize Number of bytes to write 1253*12720SWyllys.Ingersoll@Sun.COM * 1254*12720SWyllys.Ingersoll@Sun.COM * Output 1255*12720SWyllys.Ingersoll@Sun.COM * ------ 1256*12720SWyllys.Ingersoll@Sun.COM * (none) 1257*12720SWyllys.Ingersoll@Sun.COM * 1258*12720SWyllys.Ingersoll@Sun.COM * Return value 0 on success, errno or -1 (generic error) on failure 1259*12720SWyllys.Ingersoll@Sun.COM * 1260*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1261*12720SWyllys.Ingersoll@Sun.COM 1262*12720SWyllys.Ingersoll@Sun.COM int K_WriteFile( const char* i_sFilename, const unsigned char* i_pFileData, int i_iFileDataSize ) 1263*12720SWyllys.Ingersoll@Sun.COM { 1264*12720SWyllys.Ingersoll@Sun.COM FILE* pFile = 0; 1265*12720SWyllys.Ingersoll@Sun.COM 1266*12720SWyllys.Ingersoll@Sun.COM if ( !i_sFilename || (strlen(i_sFilename) <= 0) || (!i_pFileData && (i_iFileDataSize > 0)) || (i_iFileDataSize < 0) ) 1267*12720SWyllys.Ingersoll@Sun.COM { 1268*12720SWyllys.Ingersoll@Sun.COM return -1; 1269*12720SWyllys.Ingersoll@Sun.COM } 1270*12720SWyllys.Ingersoll@Sun.COM 1271*12720SWyllys.Ingersoll@Sun.COM pFile = fopen( i_sFilename, "wb" ); 1272*12720SWyllys.Ingersoll@Sun.COM if ( !pFile ) 1273*12720SWyllys.Ingersoll@Sun.COM { 1274*12720SWyllys.Ingersoll@Sun.COM int iError = errno; 1275*12720SWyllys.Ingersoll@Sun.COM return (iError != 0) ? iError : -1; 1276*12720SWyllys.Ingersoll@Sun.COM } 1277*12720SWyllys.Ingersoll@Sun.COM 1278*12720SWyllys.Ingersoll@Sun.COM if ( i_iFileDataSize > 0 ) 1279*12720SWyllys.Ingersoll@Sun.COM { 1280*12720SWyllys.Ingersoll@Sun.COM if ( i_iFileDataSize != (int)fwrite( i_pFileData, 1, i_iFileDataSize, pFile ) ) 1281*12720SWyllys.Ingersoll@Sun.COM { 1282*12720SWyllys.Ingersoll@Sun.COM int iError = ferror( pFile ); 1283*12720SWyllys.Ingersoll@Sun.COM (void) fclose( pFile ); 1284*12720SWyllys.Ingersoll@Sun.COM return (iError != 0) ? iError : -1; 1285*12720SWyllys.Ingersoll@Sun.COM } 1286*12720SWyllys.Ingersoll@Sun.COM } 1287*12720SWyllys.Ingersoll@Sun.COM 1288*12720SWyllys.Ingersoll@Sun.COM (void) fclose( pFile ); 1289*12720SWyllys.Ingersoll@Sun.COM 1290*12720SWyllys.Ingersoll@Sun.COM return 0; 1291*12720SWyllys.Ingersoll@Sun.COM } 1292*12720SWyllys.Ingersoll@Sun.COM 1293*12720SWyllys.Ingersoll@Sun.COM 1294*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1295*12720SWyllys.Ingersoll@Sun.COM * Function: K_WriteFileString 1296*12720SWyllys.Ingersoll@Sun.COM * 1297*12720SWyllys.Ingersoll@Sun.COM * Description: 1298*12720SWyllys.Ingersoll@Sun.COM * Writes the given null-terminated bytes to the given file. The null 1299*12720SWyllys.Ingersoll@Sun.COM * terminator itself is not written to the file. 1300*12720SWyllys.Ingersoll@Sun.COM * 1301*12720SWyllys.Ingersoll@Sun.COM * Input 1302*12720SWyllys.Ingersoll@Sun.COM * ----- 1303*12720SWyllys.Ingersoll@Sun.COM * i_sFilename Name of file to which to write 1304*12720SWyllys.Ingersoll@Sun.COM * i_sFileData Bytes to write 1305*12720SWyllys.Ingersoll@Sun.COM * 1306*12720SWyllys.Ingersoll@Sun.COM * Output 1307*12720SWyllys.Ingersoll@Sun.COM * ------ 1308*12720SWyllys.Ingersoll@Sun.COM * (none) 1309*12720SWyllys.Ingersoll@Sun.COM * 1310*12720SWyllys.Ingersoll@Sun.COM * Return value 0 on success, errno or -1 (generic error) on failure 1311*12720SWyllys.Ingersoll@Sun.COM * 1312*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1313*12720SWyllys.Ingersoll@Sun.COM 1314*12720SWyllys.Ingersoll@Sun.COM int K_WriteFileString( const char* i_sFilename, const char* i_sFileData ) 1315*12720SWyllys.Ingersoll@Sun.COM { 1316*12720SWyllys.Ingersoll@Sun.COM if ( !i_sFilename || (strlen(i_sFilename) <= 0) || !i_sFileData || (strlen(i_sFileData) <= 0) ) 1317*12720SWyllys.Ingersoll@Sun.COM { 1318*12720SWyllys.Ingersoll@Sun.COM return -1; 1319*12720SWyllys.Ingersoll@Sun.COM } 1320*12720SWyllys.Ingersoll@Sun.COM 1321*12720SWyllys.Ingersoll@Sun.COM return K_WriteFile( i_sFilename, (const unsigned char*)i_sFileData, strlen(i_sFileData) ); 1322*12720SWyllys.Ingersoll@Sun.COM } 1323*12720SWyllys.Ingersoll@Sun.COM 1324*12720SWyllys.Ingersoll@Sun.COM 1325*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1326*12720SWyllys.Ingersoll@Sun.COM * Function: K_FileExists 1327*12720SWyllys.Ingersoll@Sun.COM * 1328*12720SWyllys.Ingersoll@Sun.COM * Description: 1329*12720SWyllys.Ingersoll@Sun.COM * Checks to see whehter the given file exists. 1330*12720SWyllys.Ingersoll@Sun.COM * 1331*12720SWyllys.Ingersoll@Sun.COM * Input 1332*12720SWyllys.Ingersoll@Sun.COM * ----- 1333*12720SWyllys.Ingersoll@Sun.COM * i_sFilename Name of file to check 1334*12720SWyllys.Ingersoll@Sun.COM * 1335*12720SWyllys.Ingersoll@Sun.COM * Output 1336*12720SWyllys.Ingersoll@Sun.COM * ------ 1337*12720SWyllys.Ingersoll@Sun.COM * (none) 1338*12720SWyllys.Ingersoll@Sun.COM * 1339*12720SWyllys.Ingersoll@Sun.COM * Return value 1 if file exists, 0 if not, -1 on failure 1340*12720SWyllys.Ingersoll@Sun.COM * 1341*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1342*12720SWyllys.Ingersoll@Sun.COM 1343*12720SWyllys.Ingersoll@Sun.COM int K_FileExists( const char* i_sFilename ) 1344*12720SWyllys.Ingersoll@Sun.COM { 1345*12720SWyllys.Ingersoll@Sun.COM FILE* pFile = 0; 1346*12720SWyllys.Ingersoll@Sun.COM 1347*12720SWyllys.Ingersoll@Sun.COM if ( !i_sFilename || (strlen(i_sFilename) <= 0) ) 1348*12720SWyllys.Ingersoll@Sun.COM { 1349*12720SWyllys.Ingersoll@Sun.COM return -1; 1350*12720SWyllys.Ingersoll@Sun.COM } 1351*12720SWyllys.Ingersoll@Sun.COM 1352*12720SWyllys.Ingersoll@Sun.COM pFile = fopen( i_sFilename, "r+" ); 1353*12720SWyllys.Ingersoll@Sun.COM 1354*12720SWyllys.Ingersoll@Sun.COM if ( !pFile ) 1355*12720SWyllys.Ingersoll@Sun.COM { 1356*12720SWyllys.Ingersoll@Sun.COM if ( errno == ENOENT ) 1357*12720SWyllys.Ingersoll@Sun.COM { 1358*12720SWyllys.Ingersoll@Sun.COM return 0; 1359*12720SWyllys.Ingersoll@Sun.COM } 1360*12720SWyllys.Ingersoll@Sun.COM 1361*12720SWyllys.Ingersoll@Sun.COM return -1; 1362*12720SWyllys.Ingersoll@Sun.COM } 1363*12720SWyllys.Ingersoll@Sun.COM 1364*12720SWyllys.Ingersoll@Sun.COM (void) fclose( pFile ); 1365*12720SWyllys.Ingersoll@Sun.COM 1366*12720SWyllys.Ingersoll@Sun.COM return 1; 1367*12720SWyllys.Ingersoll@Sun.COM } 1368*12720SWyllys.Ingersoll@Sun.COM 1369*12720SWyllys.Ingersoll@Sun.COM 1370*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1371*12720SWyllys.Ingersoll@Sun.COM * Function: K_CopyFile 1372*12720SWyllys.Ingersoll@Sun.COM * 1373*12720SWyllys.Ingersoll@Sun.COM * Description: 1374*12720SWyllys.Ingersoll@Sun.COM * Reads from the given source file and writes these bytes to the given 1375*12720SWyllys.Ingersoll@Sun.COM * destination file. 1376*12720SWyllys.Ingersoll@Sun.COM * 1377*12720SWyllys.Ingersoll@Sun.COM * Input 1378*12720SWyllys.Ingersoll@Sun.COM * ----- 1379*12720SWyllys.Ingersoll@Sun.COM * i_sSrcFilename Name of file from which to read 1380*12720SWyllys.Ingersoll@Sun.COM * i_sDestFilename Name of file to which to write 1381*12720SWyllys.Ingersoll@Sun.COM * 1382*12720SWyllys.Ingersoll@Sun.COM * Output 1383*12720SWyllys.Ingersoll@Sun.COM * ------ 1384*12720SWyllys.Ingersoll@Sun.COM * o_pbFileExists Non-zero if the destination file already exists 1385*12720SWyllys.Ingersoll@Sun.COM * 1386*12720SWyllys.Ingersoll@Sun.COM * Return value 0 on success, errno or -1 (generic error) on failure 1387*12720SWyllys.Ingersoll@Sun.COM * 1388*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1389*12720SWyllys.Ingersoll@Sun.COM 1390*12720SWyllys.Ingersoll@Sun.COM int K_CopyFile( const char* i_sSrcFilename, const char* i_sDestFilename, int* o_pbFileExists ) 1391*12720SWyllys.Ingersoll@Sun.COM { 1392*12720SWyllys.Ingersoll@Sun.COM unsigned char* pFileData = 0; 1393*12720SWyllys.Ingersoll@Sun.COM int iFileSize = 0; 1394*12720SWyllys.Ingersoll@Sun.COM int iError, iFileExists; 1395*12720SWyllys.Ingersoll@Sun.COM 1396*12720SWyllys.Ingersoll@Sun.COM if ( !i_sSrcFilename || (strlen(i_sSrcFilename) <= 0) 1397*12720SWyllys.Ingersoll@Sun.COM || !i_sDestFilename || (strlen(i_sDestFilename) <= 0) 1398*12720SWyllys.Ingersoll@Sun.COM || !o_pbFileExists ) 1399*12720SWyllys.Ingersoll@Sun.COM { 1400*12720SWyllys.Ingersoll@Sun.COM return -1; 1401*12720SWyllys.Ingersoll@Sun.COM } 1402*12720SWyllys.Ingersoll@Sun.COM 1403*12720SWyllys.Ingersoll@Sun.COM *o_pbFileExists = 0; 1404*12720SWyllys.Ingersoll@Sun.COM 1405*12720SWyllys.Ingersoll@Sun.COM iFileExists = K_FileExists( i_sDestFilename ); 1406*12720SWyllys.Ingersoll@Sun.COM 1407*12720SWyllys.Ingersoll@Sun.COM if ( iFileExists < 0 ) 1408*12720SWyllys.Ingersoll@Sun.COM { 1409*12720SWyllys.Ingersoll@Sun.COM iError = errno; 1410*12720SWyllys.Ingersoll@Sun.COM return (iError == 0) ? -1 : iError; 1411*12720SWyllys.Ingersoll@Sun.COM } 1412*12720SWyllys.Ingersoll@Sun.COM else if ( iFileExists > 0 ) 1413*12720SWyllys.Ingersoll@Sun.COM { 1414*12720SWyllys.Ingersoll@Sun.COM *o_pbFileExists = 1; 1415*12720SWyllys.Ingersoll@Sun.COM return -1; 1416*12720SWyllys.Ingersoll@Sun.COM } 1417*12720SWyllys.Ingersoll@Sun.COM 1418*12720SWyllys.Ingersoll@Sun.COM iFileSize = K_ReadFile( i_sSrcFilename, &pFileData ); 1419*12720SWyllys.Ingersoll@Sun.COM if ( iFileSize < 0 ) 1420*12720SWyllys.Ingersoll@Sun.COM { 1421*12720SWyllys.Ingersoll@Sun.COM iError = errno; 1422*12720SWyllys.Ingersoll@Sun.COM return (iError == 0) ? -1 : iError; 1423*12720SWyllys.Ingersoll@Sun.COM } 1424*12720SWyllys.Ingersoll@Sun.COM 1425*12720SWyllys.Ingersoll@Sun.COM iError = K_WriteFile( i_sDestFilename, pFileData, iFileSize ); 1426*12720SWyllys.Ingersoll@Sun.COM 1427*12720SWyllys.Ingersoll@Sun.COM if ( pFileData ) 1428*12720SWyllys.Ingersoll@Sun.COM { 1429*12720SWyllys.Ingersoll@Sun.COM free( pFileData ); 1430*12720SWyllys.Ingersoll@Sun.COM } 1431*12720SWyllys.Ingersoll@Sun.COM 1432*12720SWyllys.Ingersoll@Sun.COM return iError; 1433*12720SWyllys.Ingersoll@Sun.COM } 1434*12720SWyllys.Ingersoll@Sun.COM 1435*12720SWyllys.Ingersoll@Sun.COM 1436*12720SWyllys.Ingersoll@Sun.COM #ifdef K_LINUX_PLATFORM 1437*12720SWyllys.Ingersoll@Sun.COM static int fts_compare( const FTSENT** i_ppF1, const FTSENT** i_ppF2 ) 1438*12720SWyllys.Ingersoll@Sun.COM { 1439*12720SWyllys.Ingersoll@Sun.COM return strcmp( (*i_ppF1)->fts_name, (*i_ppF2)->fts_name ); 1440*12720SWyllys.Ingersoll@Sun.COM } 1441*12720SWyllys.Ingersoll@Sun.COM #else 1442*12720SWyllys.Ingersoll@Sun.COM /* 1443*12720SWyllys.Ingersoll@Sun.COM * Directory traversal code is not yet available for Solaris. 1444*12720SWyllys.Ingersoll@Sun.COM * If such code will need to be written, then it will probably use ftw.h. 1445*12720SWyllys.Ingersoll@Sun.COM */ 1446*12720SWyllys.Ingersoll@Sun.COM #endif 1447*12720SWyllys.Ingersoll@Sun.COM 1448*12720SWyllys.Ingersoll@Sun.COM 1449*12720SWyllys.Ingersoll@Sun.COM /* 1450*12720SWyllys.Ingersoll@Sun.COM * TODO: Set up functions for platform-specific find-file operations to 1451*12720SWyllys.Ingersoll@Sun.COM * help clean up the code below. 1452*12720SWyllys.Ingersoll@Sun.COM */ 1453*12720SWyllys.Ingersoll@Sun.COM 1454*12720SWyllys.Ingersoll@Sun.COM typedef struct K_FindInfo 1455*12720SWyllys.Ingersoll@Sun.COM { 1456*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 1457*12720SWyllys.Ingersoll@Sun.COM struct _finddata_t m_stFindData; 1458*12720SWyllys.Ingersoll@Sun.COM long m_hFile; 1459*12720SWyllys.Ingersoll@Sun.COM #elif defined K_LINUX_PLATFORM 1460*12720SWyllys.Ingersoll@Sun.COM FTS* m_pFTS; 1461*12720SWyllys.Ingersoll@Sun.COM FTSENT* m_pFTSENT; 1462*12720SWyllys.Ingersoll@Sun.COM #else 1463*12720SWyllys.Ingersoll@Sun.COM /* 1464*12720SWyllys.Ingersoll@Sun.COM * Directory traversal code is not yet available for Solaris. 1465*12720SWyllys.Ingersoll@Sun.COM * If such code will need to be written, then it will probably use ftw.h. 1466*12720SWyllys.Ingersoll@Sun.COM */ 1467*12720SWyllys.Ingersoll@Sun.COM int unused; 1468*12720SWyllys.Ingersoll@Sun.COM #endif 1469*12720SWyllys.Ingersoll@Sun.COM } K_FindInfo; 1470*12720SWyllys.Ingersoll@Sun.COM 1471*12720SWyllys.Ingersoll@Sun.COM // Memory for filename is held in i_pFindInfo. 1472*12720SWyllys.Ingersoll@Sun.COM const char* K_GetFilenameFromInfo( const K_FindInfo* i_pFindInfo ) 1473*12720SWyllys.Ingersoll@Sun.COM { 1474*12720SWyllys.Ingersoll@Sun.COM if( !i_pFindInfo ) 1475*12720SWyllys.Ingersoll@Sun.COM { 1476*12720SWyllys.Ingersoll@Sun.COM return 0; 1477*12720SWyllys.Ingersoll@Sun.COM } 1478*12720SWyllys.Ingersoll@Sun.COM 1479*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 1480*12720SWyllys.Ingersoll@Sun.COM return i_pFindInfo->m_stFindData.name; 1481*12720SWyllys.Ingersoll@Sun.COM #elif defined K_LINUX_PLATFORM 1482*12720SWyllys.Ingersoll@Sun.COM return i_pFindInfo->m_pFTSENT->fts_name; 1483*12720SWyllys.Ingersoll@Sun.COM #else 1484*12720SWyllys.Ingersoll@Sun.COM /* 1485*12720SWyllys.Ingersoll@Sun.COM * Directory traversal code is not yet available for Solaris. 1486*12720SWyllys.Ingersoll@Sun.COM * If such code will need to be written, then it will probably use ftw.h. 1487*12720SWyllys.Ingersoll@Sun.COM */ 1488*12720SWyllys.Ingersoll@Sun.COM FATAL_ASSERT( 0 ); 1489*12720SWyllys.Ingersoll@Sun.COM return 0; 1490*12720SWyllys.Ingersoll@Sun.COM #endif 1491*12720SWyllys.Ingersoll@Sun.COM } 1492*12720SWyllys.Ingersoll@Sun.COM 1493*12720SWyllys.Ingersoll@Sun.COM // Forward declarations 1494*12720SWyllys.Ingersoll@Sun.COM int K_FindFileNext( K_FindInfo* io_pFindInfo ); 1495*12720SWyllys.Ingersoll@Sun.COM void K_FindFileClose( K_FindInfo* io_pFindInfo ); 1496*12720SWyllys.Ingersoll@Sun.COM 1497*12720SWyllys.Ingersoll@Sun.COM // Returns 0 if successful, 1 if not found, -1 if error. 1498*12720SWyllys.Ingersoll@Sun.COM // If not error, K_FindFileClose must be called. 1499*12720SWyllys.Ingersoll@Sun.COM // o_pFindInfo must not be null. 1500*12720SWyllys.Ingersoll@Sun.COM int K_FindFileFirst( const char* i_sDirectoryName, K_FindInfo* o_pFindInfo ) 1501*12720SWyllys.Ingersoll@Sun.COM { 1502*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 1503*12720SWyllys.Ingersoll@Sun.COM char* sSearchString = 0; 1504*12720SWyllys.Ingersoll@Sun.COM int iSearchStringIndex = 0; 1505*12720SWyllys.Ingersoll@Sun.COM #endif 1506*12720SWyllys.Ingersoll@Sun.COM 1507*12720SWyllys.Ingersoll@Sun.COM if ( !i_sDirectoryName || (strlen(i_sDirectoryName) <= 0) || !o_pFindInfo ) 1508*12720SWyllys.Ingersoll@Sun.COM { 1509*12720SWyllys.Ingersoll@Sun.COM return -1; 1510*12720SWyllys.Ingersoll@Sun.COM } 1511*12720SWyllys.Ingersoll@Sun.COM 1512*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 1513*12720SWyllys.Ingersoll@Sun.COM memset( o_pFindInfo, 0, sizeof(K_FindInfo) ); 1514*12720SWyllys.Ingersoll@Sun.COM 1515*12720SWyllys.Ingersoll@Sun.COM iSearchStringIndex = strlen(i_sDirectoryName); 1516*12720SWyllys.Ingersoll@Sun.COM if ( i_sDirectoryName[iSearchStringIndex-1] == PATH_SEPARATOR ) 1517*12720SWyllys.Ingersoll@Sun.COM { 1518*12720SWyllys.Ingersoll@Sun.COM iSearchStringIndex += 2; 1519*12720SWyllys.Ingersoll@Sun.COM } 1520*12720SWyllys.Ingersoll@Sun.COM else 1521*12720SWyllys.Ingersoll@Sun.COM { 1522*12720SWyllys.Ingersoll@Sun.COM iSearchStringIndex += 3; 1523*12720SWyllys.Ingersoll@Sun.COM } 1524*12720SWyllys.Ingersoll@Sun.COM 1525*12720SWyllys.Ingersoll@Sun.COM sSearchString = (char*)calloc( iSearchStringIndex, 1 ); 1526*12720SWyllys.Ingersoll@Sun.COM if ( !sSearchString ) 1527*12720SWyllys.Ingersoll@Sun.COM { 1528*12720SWyllys.Ingersoll@Sun.COM return -1; 1529*12720SWyllys.Ingersoll@Sun.COM } 1530*12720SWyllys.Ingersoll@Sun.COM 1531*12720SWyllys.Ingersoll@Sun.COM strcpy( sSearchString, i_sDirectoryName ); 1532*12720SWyllys.Ingersoll@Sun.COM iSearchStringIndex--; 1533*12720SWyllys.Ingersoll@Sun.COM sSearchString[iSearchStringIndex] = '\0'; 1534*12720SWyllys.Ingersoll@Sun.COM iSearchStringIndex--; 1535*12720SWyllys.Ingersoll@Sun.COM sSearchString[iSearchStringIndex] = '*'; 1536*12720SWyllys.Ingersoll@Sun.COM iSearchStringIndex--; 1537*12720SWyllys.Ingersoll@Sun.COM sSearchString[iSearchStringIndex] = PATH_SEPARATOR; 1538*12720SWyllys.Ingersoll@Sun.COM 1539*12720SWyllys.Ingersoll@Sun.COM o_pFindInfo->m_hFile = _findfirst( sSearchString, &o_pFindInfo->m_stFindData ); 1540*12720SWyllys.Ingersoll@Sun.COM free( sSearchString ); 1541*12720SWyllys.Ingersoll@Sun.COM if ( o_pFindInfo->m_hFile == -1 ) 1542*12720SWyllys.Ingersoll@Sun.COM { 1543*12720SWyllys.Ingersoll@Sun.COM if ( errno == ENOENT ) 1544*12720SWyllys.Ingersoll@Sun.COM { 1545*12720SWyllys.Ingersoll@Sun.COM return 1; 1546*12720SWyllys.Ingersoll@Sun.COM } 1547*12720SWyllys.Ingersoll@Sun.COM else 1548*12720SWyllys.Ingersoll@Sun.COM { 1549*12720SWyllys.Ingersoll@Sun.COM return -1; 1550*12720SWyllys.Ingersoll@Sun.COM } 1551*12720SWyllys.Ingersoll@Sun.COM } 1552*12720SWyllys.Ingersoll@Sun.COM #elif defined K_LINUX_PLATFORM 1553*12720SWyllys.Ingersoll@Sun.COM memset( o_pFindInfo, 0, sizeof(K_FindInfo) ); 1554*12720SWyllys.Ingersoll@Sun.COM 1555*12720SWyllys.Ingersoll@Sun.COM o_pFindInfo->m_pFTS = fts_open( aPath, FTS_PHYSICAL | FTS_NOSTAT, fts_compare ); 1556*12720SWyllys.Ingersoll@Sun.COM if ( !o_pFindInfo->m_pFTS ) 1557*12720SWyllys.Ingersoll@Sun.COM { 1558*12720SWyllys.Ingersoll@Sun.COM return -1; 1559*12720SWyllys.Ingersoll@Sun.COM } 1560*12720SWyllys.Ingersoll@Sun.COM 1561*12720SWyllys.Ingersoll@Sun.COM o_pFindInfo->m_pFTSENT = fts_read( o_pFindInfo->m_pFTS ); 1562*12720SWyllys.Ingersoll@Sun.COM if ( !o_pFindInfo->m_pFTSENT ) 1563*12720SWyllys.Ingersoll@Sun.COM { 1564*12720SWyllys.Ingersoll@Sun.COM if ( errno == 0 ) 1565*12720SWyllys.Ingersoll@Sun.COM { 1566*12720SWyllys.Ingersoll@Sun.COM return 1; 1567*12720SWyllys.Ingersoll@Sun.COM } 1568*12720SWyllys.Ingersoll@Sun.COM else 1569*12720SWyllys.Ingersoll@Sun.COM { 1570*12720SWyllys.Ingersoll@Sun.COM fts_close( o_pFindInfo->m_pFTS ); 1571*12720SWyllys.Ingersoll@Sun.COM return -1; 1572*12720SWyllys.Ingersoll@Sun.COM } 1573*12720SWyllys.Ingersoll@Sun.COM } 1574*12720SWyllys.Ingersoll@Sun.COM #else 1575*12720SWyllys.Ingersoll@Sun.COM /* 1576*12720SWyllys.Ingersoll@Sun.COM * Directory traversal code is not yet available for Solaris. 1577*12720SWyllys.Ingersoll@Sun.COM * If such code will need to be written, then it will probably use ftw.h. 1578*12720SWyllys.Ingersoll@Sun.COM */ 1579*12720SWyllys.Ingersoll@Sun.COM #endif 1580*12720SWyllys.Ingersoll@Sun.COM 1581*12720SWyllys.Ingersoll@Sun.COM // If what we found is not actually a file, get the next hit. 1582*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 1583*12720SWyllys.Ingersoll@Sun.COM if ( (o_pFindInfo->m_stFindData.attrib & _A_SUBDIR) ) 1584*12720SWyllys.Ingersoll@Sun.COM #elif defined K_LINUX_PLATFORM 1585*12720SWyllys.Ingersoll@Sun.COM if ( !(o_pFindInfo->m_pFTSENT->fts_info & FTS_F) ) 1586*12720SWyllys.Ingersoll@Sun.COM #else 1587*12720SWyllys.Ingersoll@Sun.COM /* 1588*12720SWyllys.Ingersoll@Sun.COM * Directory traversal code is not yet available for Solaris. 1589*12720SWyllys.Ingersoll@Sun.COM * If such code will need to be written, then it will probably use ftw.h. 1590*12720SWyllys.Ingersoll@Sun.COM */ 1591*12720SWyllys.Ingersoll@Sun.COM #endif 1592*12720SWyllys.Ingersoll@Sun.COM { 1593*12720SWyllys.Ingersoll@Sun.COM int iNextReturn = K_FindFileNext( o_pFindInfo ); 1594*12720SWyllys.Ingersoll@Sun.COM if ( iNextReturn < 0 ) 1595*12720SWyllys.Ingersoll@Sun.COM { 1596*12720SWyllys.Ingersoll@Sun.COM K_FindFileClose( o_pFindInfo ); 1597*12720SWyllys.Ingersoll@Sun.COM return -1; 1598*12720SWyllys.Ingersoll@Sun.COM } 1599*12720SWyllys.Ingersoll@Sun.COM else 1600*12720SWyllys.Ingersoll@Sun.COM { 1601*12720SWyllys.Ingersoll@Sun.COM return iNextReturn; 1602*12720SWyllys.Ingersoll@Sun.COM } 1603*12720SWyllys.Ingersoll@Sun.COM } 1604*12720SWyllys.Ingersoll@Sun.COM 1605*12720SWyllys.Ingersoll@Sun.COM #if defined(WIN32) || defined(K_LINUX_PLATFORM) 1606*12720SWyllys.Ingersoll@Sun.COM return 0; 1607*12720SWyllys.Ingersoll@Sun.COM #endif 1608*12720SWyllys.Ingersoll@Sun.COM } 1609*12720SWyllys.Ingersoll@Sun.COM 1610*12720SWyllys.Ingersoll@Sun.COM // Returns 0 if successful, 1 if not found, -1 if error. 1611*12720SWyllys.Ingersoll@Sun.COM int K_FindFileNext( K_FindInfo* io_pFindInfo ) 1612*12720SWyllys.Ingersoll@Sun.COM { 1613*12720SWyllys.Ingersoll@Sun.COM if ( !io_pFindInfo ) 1614*12720SWyllys.Ingersoll@Sun.COM { 1615*12720SWyllys.Ingersoll@Sun.COM return -1; 1616*12720SWyllys.Ingersoll@Sun.COM } 1617*12720SWyllys.Ingersoll@Sun.COM 1618*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 1619*12720SWyllys.Ingersoll@Sun.COM if ( _findnext( io_pFindInfo->m_hFile, &io_pFindInfo->m_stFindData ) != 0 ) 1620*12720SWyllys.Ingersoll@Sun.COM { 1621*12720SWyllys.Ingersoll@Sun.COM return (errno == ENOENT) ? 1 : -1; 1622*12720SWyllys.Ingersoll@Sun.COM } 1623*12720SWyllys.Ingersoll@Sun.COM #elif defined K_LINUX_PLATFORM 1624*12720SWyllys.Ingersoll@Sun.COM io_pFindInfo->m_pFTSENT = fts_read( io_pFindInfo->m_pFTS ); 1625*12720SWyllys.Ingersoll@Sun.COM if ( !io_pFindInfo->m_pFTSENT ) 1626*12720SWyllys.Ingersoll@Sun.COM { 1627*12720SWyllys.Ingersoll@Sun.COM return (errno == 0) ? 1 : -1; 1628*12720SWyllys.Ingersoll@Sun.COM } 1629*12720SWyllys.Ingersoll@Sun.COM #else 1630*12720SWyllys.Ingersoll@Sun.COM /* 1631*12720SWyllys.Ingersoll@Sun.COM * Directory traversal code is not yet available for Solaris. 1632*12720SWyllys.Ingersoll@Sun.COM * If such code will need to be written, then it will probably use ftw.h. 1633*12720SWyllys.Ingersoll@Sun.COM */ 1634*12720SWyllys.Ingersoll@Sun.COM #endif 1635*12720SWyllys.Ingersoll@Sun.COM 1636*12720SWyllys.Ingersoll@Sun.COM // If what we found is not actually a file, get the next hit. 1637*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 1638*12720SWyllys.Ingersoll@Sun.COM if ( (io_pFindInfo->m_stFindData.attrib & _A_SUBDIR) ) 1639*12720SWyllys.Ingersoll@Sun.COM #elif defined K_LINUX_PLATFORM 1640*12720SWyllys.Ingersoll@Sun.COM if ( !(io_pFindInfo->m_pFTSENT->fts_info & FTS_F) ) 1641*12720SWyllys.Ingersoll@Sun.COM #else 1642*12720SWyllys.Ingersoll@Sun.COM /* 1643*12720SWyllys.Ingersoll@Sun.COM * Directory traversal code is not yet available for Solaris. 1644*12720SWyllys.Ingersoll@Sun.COM * If such code will need to be written, then it will probably use ftw.h. 1645*12720SWyllys.Ingersoll@Sun.COM */ 1646*12720SWyllys.Ingersoll@Sun.COM #endif 1647*12720SWyllys.Ingersoll@Sun.COM { 1648*12720SWyllys.Ingersoll@Sun.COM return K_FindFileNext( io_pFindInfo ); 1649*12720SWyllys.Ingersoll@Sun.COM } 1650*12720SWyllys.Ingersoll@Sun.COM 1651*12720SWyllys.Ingersoll@Sun.COM #if defined(WIN32) || defined(K_LINUX_PLATFORM) 1652*12720SWyllys.Ingersoll@Sun.COM return 0; 1653*12720SWyllys.Ingersoll@Sun.COM #endif 1654*12720SWyllys.Ingersoll@Sun.COM } 1655*12720SWyllys.Ingersoll@Sun.COM 1656*12720SWyllys.Ingersoll@Sun.COM void K_FindFileClose( K_FindInfo* io_pFindInfo ) 1657*12720SWyllys.Ingersoll@Sun.COM { 1658*12720SWyllys.Ingersoll@Sun.COM if ( !io_pFindInfo ) 1659*12720SWyllys.Ingersoll@Sun.COM { 1660*12720SWyllys.Ingersoll@Sun.COM return; 1661*12720SWyllys.Ingersoll@Sun.COM } 1662*12720SWyllys.Ingersoll@Sun.COM 1663*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 1664*12720SWyllys.Ingersoll@Sun.COM _findclose( io_pFindInfo->m_hFile ); 1665*12720SWyllys.Ingersoll@Sun.COM #elif defined K_LINUX_PLATFORM 1666*12720SWyllys.Ingersoll@Sun.COM fts_close( io_pFindInfo->m_pFTS ); 1667*12720SWyllys.Ingersoll@Sun.COM #else 1668*12720SWyllys.Ingersoll@Sun.COM /* 1669*12720SWyllys.Ingersoll@Sun.COM * Directory traversal code is not yet available for Solaris. 1670*12720SWyllys.Ingersoll@Sun.COM * If such code will need to be written, then it will probably use ftw.h. 1671*12720SWyllys.Ingersoll@Sun.COM */ 1672*12720SWyllys.Ingersoll@Sun.COM #endif 1673*12720SWyllys.Ingersoll@Sun.COM } 1674*12720SWyllys.Ingersoll@Sun.COM 1675*12720SWyllys.Ingersoll@Sun.COM 1676*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1677*12720SWyllys.Ingersoll@Sun.COM * Function: K_GetFilenamesInDirectoryCount 1678*12720SWyllys.Ingersoll@Sun.COM * 1679*12720SWyllys.Ingersoll@Sun.COM * Description: 1680*12720SWyllys.Ingersoll@Sun.COM * Reads the given directory and returns the number of files that it contains. 1681*12720SWyllys.Ingersoll@Sun.COM * 1682*12720SWyllys.Ingersoll@Sun.COM * Input 1683*12720SWyllys.Ingersoll@Sun.COM * ----- 1684*12720SWyllys.Ingersoll@Sun.COM * i_sDirectoryName Name of directory 1685*12720SWyllys.Ingersoll@Sun.COM * 1686*12720SWyllys.Ingersoll@Sun.COM * Output 1687*12720SWyllys.Ingersoll@Sun.COM * ------ 1688*12720SWyllys.Ingersoll@Sun.COM * (none) 1689*12720SWyllys.Ingersoll@Sun.COM * 1690*12720SWyllys.Ingersoll@Sun.COM * Return value Number of files on success, -1 on failure 1691*12720SWyllys.Ingersoll@Sun.COM * 1692*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1693*12720SWyllys.Ingersoll@Sun.COM 1694*12720SWyllys.Ingersoll@Sun.COM int K_GetFilenamesInDirectoryCount( const char* i_sDirectoryName ) 1695*12720SWyllys.Ingersoll@Sun.COM { 1696*12720SWyllys.Ingersoll@Sun.COM K_FindInfo stFindInfo; 1697*12720SWyllys.Ingersoll@Sun.COM int iCurrentFile = 0; 1698*12720SWyllys.Ingersoll@Sun.COM int iError = 0; 1699*12720SWyllys.Ingersoll@Sun.COM 1700*12720SWyllys.Ingersoll@Sun.COM if ( !i_sDirectoryName || (strlen(i_sDirectoryName) <= 0) ) 1701*12720SWyllys.Ingersoll@Sun.COM { 1702*12720SWyllys.Ingersoll@Sun.COM return -1; 1703*12720SWyllys.Ingersoll@Sun.COM } 1704*12720SWyllys.Ingersoll@Sun.COM 1705*12720SWyllys.Ingersoll@Sun.COM iError = K_FindFileFirst( i_sDirectoryName, &stFindInfo ); 1706*12720SWyllys.Ingersoll@Sun.COM if ( iError < 0 ) 1707*12720SWyllys.Ingersoll@Sun.COM { 1708*12720SWyllys.Ingersoll@Sun.COM // error 1709*12720SWyllys.Ingersoll@Sun.COM return -1; 1710*12720SWyllys.Ingersoll@Sun.COM } 1711*12720SWyllys.Ingersoll@Sun.COM else if ( iError > 0 ) 1712*12720SWyllys.Ingersoll@Sun.COM { 1713*12720SWyllys.Ingersoll@Sun.COM // no files found 1714*12720SWyllys.Ingersoll@Sun.COM K_FindFileClose( &stFindInfo ); 1715*12720SWyllys.Ingersoll@Sun.COM return 0; 1716*12720SWyllys.Ingersoll@Sun.COM } 1717*12720SWyllys.Ingersoll@Sun.COM 1718*12720SWyllys.Ingersoll@Sun.COM while ( 1 ) 1719*12720SWyllys.Ingersoll@Sun.COM { 1720*12720SWyllys.Ingersoll@Sun.COM iCurrentFile++; 1721*12720SWyllys.Ingersoll@Sun.COM 1722*12720SWyllys.Ingersoll@Sun.COM iError = K_FindFileNext( &stFindInfo ); 1723*12720SWyllys.Ingersoll@Sun.COM if ( iError < 0 ) 1724*12720SWyllys.Ingersoll@Sun.COM { 1725*12720SWyllys.Ingersoll@Sun.COM // error 1726*12720SWyllys.Ingersoll@Sun.COM K_FindFileClose( &stFindInfo ); 1727*12720SWyllys.Ingersoll@Sun.COM return -1; 1728*12720SWyllys.Ingersoll@Sun.COM } 1729*12720SWyllys.Ingersoll@Sun.COM else if ( iError > 0 ) 1730*12720SWyllys.Ingersoll@Sun.COM { 1731*12720SWyllys.Ingersoll@Sun.COM // no more files found 1732*12720SWyllys.Ingersoll@Sun.COM break; 1733*12720SWyllys.Ingersoll@Sun.COM } 1734*12720SWyllys.Ingersoll@Sun.COM } 1735*12720SWyllys.Ingersoll@Sun.COM 1736*12720SWyllys.Ingersoll@Sun.COM K_FindFileClose( &stFindInfo ); 1737*12720SWyllys.Ingersoll@Sun.COM 1738*12720SWyllys.Ingersoll@Sun.COM return iCurrentFile; 1739*12720SWyllys.Ingersoll@Sun.COM } 1740*12720SWyllys.Ingersoll@Sun.COM 1741*12720SWyllys.Ingersoll@Sun.COM 1742*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1743*12720SWyllys.Ingersoll@Sun.COM * Function: K_GetFilenamesInDirectory 1744*12720SWyllys.Ingersoll@Sun.COM * 1745*12720SWyllys.Ingersoll@Sun.COM * Description: 1746*12720SWyllys.Ingersoll@Sun.COM * Reads the given directory and returns an array of names of files that it 1747*12720SWyllys.Ingersoll@Sun.COM * contains. A null pointer appears at the last item in the array. The 1748*12720SWyllys.Ingersoll@Sun.COM * caller must deallocate o_pasFilenames by using K_FreeFilenames or by 1749*12720SWyllys.Ingersoll@Sun.COM * calling free() for each file name and then calling free() on the array 1750*12720SWyllys.Ingersoll@Sun.COM * itself. 1751*12720SWyllys.Ingersoll@Sun.COM * 1752*12720SWyllys.Ingersoll@Sun.COM * Input 1753*12720SWyllys.Ingersoll@Sun.COM * ----- 1754*12720SWyllys.Ingersoll@Sun.COM * i_sDirectoryName Name of directory 1755*12720SWyllys.Ingersoll@Sun.COM * 1756*12720SWyllys.Ingersoll@Sun.COM * Output 1757*12720SWyllys.Ingersoll@Sun.COM * ------ 1758*12720SWyllys.Ingersoll@Sun.COM * o_pasFilenames Array of names of files found in this directory 1759*12720SWyllys.Ingersoll@Sun.COM * 1760*12720SWyllys.Ingersoll@Sun.COM * Return value Number of files on success, -1 on failure 1761*12720SWyllys.Ingersoll@Sun.COM * 1762*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1763*12720SWyllys.Ingersoll@Sun.COM 1764*12720SWyllys.Ingersoll@Sun.COM int K_GetFilenamesInDirectory( 1765*12720SWyllys.Ingersoll@Sun.COM const char* i_sDirectoryName, 1766*12720SWyllys.Ingersoll@Sun.COM char*** o_pasFilenames ) 1767*12720SWyllys.Ingersoll@Sun.COM { 1768*12720SWyllys.Ingersoll@Sun.COM // Note that we iterate through the filenames twice -- once to get the count 1769*12720SWyllys.Ingersoll@Sun.COM // (K_GetFilenamesInDirectoryCount) and then once to get all the names. But 1770*12720SWyllys.Ingersoll@Sun.COM // it may happen that the count changes between these calls. So we'll retrieve 1771*12720SWyllys.Ingersoll@Sun.COM // at most the number of files that's returned in the first pass. 1772*12720SWyllys.Ingersoll@Sun.COM 1773*12720SWyllys.Ingersoll@Sun.COM K_FindInfo stFindInfo; 1774*12720SWyllys.Ingersoll@Sun.COM int iFilenameCount = 0, iCurrentFile = 0; 1775*12720SWyllys.Ingersoll@Sun.COM int iError = 0; 1776*12720SWyllys.Ingersoll@Sun.COM 1777*12720SWyllys.Ingersoll@Sun.COM if ( !i_sDirectoryName || (strlen(i_sDirectoryName) <= 0) || !o_pasFilenames ) 1778*12720SWyllys.Ingersoll@Sun.COM { 1779*12720SWyllys.Ingersoll@Sun.COM return -1; 1780*12720SWyllys.Ingersoll@Sun.COM } 1781*12720SWyllys.Ingersoll@Sun.COM 1782*12720SWyllys.Ingersoll@Sun.COM *o_pasFilenames = 0; 1783*12720SWyllys.Ingersoll@Sun.COM 1784*12720SWyllys.Ingersoll@Sun.COM iFilenameCount = K_GetFilenamesInDirectoryCount( i_sDirectoryName ); 1785*12720SWyllys.Ingersoll@Sun.COM 1786*12720SWyllys.Ingersoll@Sun.COM if ( iFilenameCount < 0 ) 1787*12720SWyllys.Ingersoll@Sun.COM { 1788*12720SWyllys.Ingersoll@Sun.COM return -1; 1789*12720SWyllys.Ingersoll@Sun.COM } 1790*12720SWyllys.Ingersoll@Sun.COM 1791*12720SWyllys.Ingersoll@Sun.COM iError = K_FindFileFirst( i_sDirectoryName, &stFindInfo ); 1792*12720SWyllys.Ingersoll@Sun.COM if ( iError < 0 ) 1793*12720SWyllys.Ingersoll@Sun.COM { 1794*12720SWyllys.Ingersoll@Sun.COM // error 1795*12720SWyllys.Ingersoll@Sun.COM return -1; 1796*12720SWyllys.Ingersoll@Sun.COM } 1797*12720SWyllys.Ingersoll@Sun.COM else if ( iError > 0 ) 1798*12720SWyllys.Ingersoll@Sun.COM { 1799*12720SWyllys.Ingersoll@Sun.COM // No files found 1800*12720SWyllys.Ingersoll@Sun.COM K_FindFileClose( &stFindInfo ); 1801*12720SWyllys.Ingersoll@Sun.COM return 0; 1802*12720SWyllys.Ingersoll@Sun.COM } 1803*12720SWyllys.Ingersoll@Sun.COM 1804*12720SWyllys.Ingersoll@Sun.COM *o_pasFilenames = (char**)calloc( (iFilenameCount+1), sizeof(char*) ); // +1 for the null last one 1805*12720SWyllys.Ingersoll@Sun.COM if ( !*o_pasFilenames ) 1806*12720SWyllys.Ingersoll@Sun.COM { 1807*12720SWyllys.Ingersoll@Sun.COM // Out of memory 1808*12720SWyllys.Ingersoll@Sun.COM K_FindFileClose( &stFindInfo ); 1809*12720SWyllys.Ingersoll@Sun.COM return -1; 1810*12720SWyllys.Ingersoll@Sun.COM } 1811*12720SWyllys.Ingersoll@Sun.COM 1812*12720SWyllys.Ingersoll@Sun.COM while ( 1 ) 1813*12720SWyllys.Ingersoll@Sun.COM { 1814*12720SWyllys.Ingersoll@Sun.COM const char* sFilename = K_GetFilenameFromInfo( &stFindInfo ); 1815*12720SWyllys.Ingersoll@Sun.COM 1816*12720SWyllys.Ingersoll@Sun.COM size_t iFilenameLength = sFilename ? strlen( sFilename ) : 0; 1817*12720SWyllys.Ingersoll@Sun.COM 1818*12720SWyllys.Ingersoll@Sun.COM if ( iFilenameLength <= 0 ) 1819*12720SWyllys.Ingersoll@Sun.COM { 1820*12720SWyllys.Ingersoll@Sun.COM K_FreeFilenames( *o_pasFilenames ); 1821*12720SWyllys.Ingersoll@Sun.COM K_FindFileClose( &stFindInfo ); 1822*12720SWyllys.Ingersoll@Sun.COM return -1; 1823*12720SWyllys.Ingersoll@Sun.COM } 1824*12720SWyllys.Ingersoll@Sun.COM 1825*12720SWyllys.Ingersoll@Sun.COM (*o_pasFilenames)[iCurrentFile] = (char*)calloc( (iFilenameLength+1), sizeof(char) ); 1826*12720SWyllys.Ingersoll@Sun.COM if ( !(*o_pasFilenames)[iCurrentFile] ) 1827*12720SWyllys.Ingersoll@Sun.COM { 1828*12720SWyllys.Ingersoll@Sun.COM K_FreeFilenames( *o_pasFilenames ); 1829*12720SWyllys.Ingersoll@Sun.COM K_FindFileClose( &stFindInfo ); 1830*12720SWyllys.Ingersoll@Sun.COM return -1; 1831*12720SWyllys.Ingersoll@Sun.COM } 1832*12720SWyllys.Ingersoll@Sun.COM 1833*12720SWyllys.Ingersoll@Sun.COM strncpy( (*o_pasFilenames)[iCurrentFile], sFilename, iFilenameLength ); 1834*12720SWyllys.Ingersoll@Sun.COM (*o_pasFilenames)[iCurrentFile][iFilenameLength] = '\0'; 1835*12720SWyllys.Ingersoll@Sun.COM 1836*12720SWyllys.Ingersoll@Sun.COM iCurrentFile++; 1837*12720SWyllys.Ingersoll@Sun.COM 1838*12720SWyllys.Ingersoll@Sun.COM if ( iCurrentFile >= iFilenameCount ) 1839*12720SWyllys.Ingersoll@Sun.COM { 1840*12720SWyllys.Ingersoll@Sun.COM break; 1841*12720SWyllys.Ingersoll@Sun.COM } 1842*12720SWyllys.Ingersoll@Sun.COM 1843*12720SWyllys.Ingersoll@Sun.COM iError = K_FindFileNext( &stFindInfo ); 1844*12720SWyllys.Ingersoll@Sun.COM if ( iError < 0 ) 1845*12720SWyllys.Ingersoll@Sun.COM { 1846*12720SWyllys.Ingersoll@Sun.COM // error 1847*12720SWyllys.Ingersoll@Sun.COM K_FindFileClose( &stFindInfo ); 1848*12720SWyllys.Ingersoll@Sun.COM return -1; 1849*12720SWyllys.Ingersoll@Sun.COM } 1850*12720SWyllys.Ingersoll@Sun.COM else if ( iError > 0 ) 1851*12720SWyllys.Ingersoll@Sun.COM { 1852*12720SWyllys.Ingersoll@Sun.COM // no more files found 1853*12720SWyllys.Ingersoll@Sun.COM break; 1854*12720SWyllys.Ingersoll@Sun.COM } 1855*12720SWyllys.Ingersoll@Sun.COM } 1856*12720SWyllys.Ingersoll@Sun.COM 1857*12720SWyllys.Ingersoll@Sun.COM K_FindFileClose( &stFindInfo ); 1858*12720SWyllys.Ingersoll@Sun.COM 1859*12720SWyllys.Ingersoll@Sun.COM return iCurrentFile; 1860*12720SWyllys.Ingersoll@Sun.COM } 1861*12720SWyllys.Ingersoll@Sun.COM 1862*12720SWyllys.Ingersoll@Sun.COM 1863*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1864*12720SWyllys.Ingersoll@Sun.COM * Function: K_FreeFilenames 1865*12720SWyllys.Ingersoll@Sun.COM * 1866*12720SWyllys.Ingersoll@Sun.COM * Description: 1867*12720SWyllys.Ingersoll@Sun.COM * Deallocates the memory allocated in a successful call to 1868*12720SWyllys.Ingersoll@Sun.COM * K_GetFilenamesInDirectory. 1869*12720SWyllys.Ingersoll@Sun.COM * 1870*12720SWyllys.Ingersoll@Sun.COM * Input 1871*12720SWyllys.Ingersoll@Sun.COM * ----- 1872*12720SWyllys.Ingersoll@Sun.COM * i_asFilenames Array of names of files 1873*12720SWyllys.Ingersoll@Sun.COM * 1874*12720SWyllys.Ingersoll@Sun.COM * Output 1875*12720SWyllys.Ingersoll@Sun.COM * ------ 1876*12720SWyllys.Ingersoll@Sun.COM * (none) 1877*12720SWyllys.Ingersoll@Sun.COM * 1878*12720SWyllys.Ingersoll@Sun.COM * Return value (none) 1879*12720SWyllys.Ingersoll@Sun.COM * 1880*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1881*12720SWyllys.Ingersoll@Sun.COM 1882*12720SWyllys.Ingersoll@Sun.COM void K_FreeFilenames( char** i_asFilenames ) 1883*12720SWyllys.Ingersoll@Sun.COM { 1884*12720SWyllys.Ingersoll@Sun.COM int i; 1885*12720SWyllys.Ingersoll@Sun.COM 1886*12720SWyllys.Ingersoll@Sun.COM if ( !i_asFilenames ) 1887*12720SWyllys.Ingersoll@Sun.COM { 1888*12720SWyllys.Ingersoll@Sun.COM return; 1889*12720SWyllys.Ingersoll@Sun.COM } 1890*12720SWyllys.Ingersoll@Sun.COM 1891*12720SWyllys.Ingersoll@Sun.COM for ( i = 0; (i_asFilenames[i] != 0); i++ ) 1892*12720SWyllys.Ingersoll@Sun.COM { 1893*12720SWyllys.Ingersoll@Sun.COM free( i_asFilenames[i] ); 1894*12720SWyllys.Ingersoll@Sun.COM i_asFilenames[i] = 0; 1895*12720SWyllys.Ingersoll@Sun.COM } 1896*12720SWyllys.Ingersoll@Sun.COM 1897*12720SWyllys.Ingersoll@Sun.COM free( i_asFilenames ); 1898*12720SWyllys.Ingersoll@Sun.COM } 1899*12720SWyllys.Ingersoll@Sun.COM 1900*12720SWyllys.Ingersoll@Sun.COM 1901*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 1902*12720SWyllys.Ingersoll@Sun.COM * Function: K_AdjustLocalClock 1903*12720SWyllys.Ingersoll@Sun.COM * 1904*12720SWyllys.Ingersoll@Sun.COM * Description: 1905*12720SWyllys.Ingersoll@Sun.COM * The K_AdjustLocalClock function gradually adjusts the system clock by 1906*12720SWyllys.Ingersoll@Sun.COM * the given number of seconds. A positive number adjusts the system 1907*12720SWyllys.Ingersoll@Sun.COM * clock forward; a negative number adjusts the system clock backward. 1908*12720SWyllys.Ingersoll@Sun.COM * 1909*12720SWyllys.Ingersoll@Sun.COM * Input 1910*12720SWyllys.Ingersoll@Sun.COM * ----- 1911*12720SWyllys.Ingersoll@Sun.COM * i_iAdjustmentInSeconds Number of seconds by which to adjust the 1912*12720SWyllys.Ingersoll@Sun.COM * system clock 1913*12720SWyllys.Ingersoll@Sun.COM * Output 1914*12720SWyllys.Ingersoll@Sun.COM * ------ 1915*12720SWyllys.Ingersoll@Sun.COM * (none) 1916*12720SWyllys.Ingersoll@Sun.COM * 1917*12720SWyllys.Ingersoll@Sun.COM * Return value 1 if successful, 0 on error 1918*12720SWyllys.Ingersoll@Sun.COM * 1919*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 1920*12720SWyllys.Ingersoll@Sun.COM 1921*12720SWyllys.Ingersoll@Sun.COM int K_AdjustLocalClock( int i_iNumberOfSeconds ) 1922*12720SWyllys.Ingersoll@Sun.COM { 1923*12720SWyllys.Ingersoll@Sun.COM struct timeval delta, lastchange; 1924*12720SWyllys.Ingersoll@Sun.COM 1925*12720SWyllys.Ingersoll@Sun.COM #ifndef K_SOLARIS_PLATFORM 1926*12720SWyllys.Ingersoll@Sun.COM /* Only supported/tested on Solaris at the moment */ 1927*12720SWyllys.Ingersoll@Sun.COM 1928*12720SWyllys.Ingersoll@Sun.COM return -1; 1929*12720SWyllys.Ingersoll@Sun.COM #else 1930*12720SWyllys.Ingersoll@Sun.COM /* WARNING: uses standard C time functions with Year 2038 limitations */ 1931*12720SWyllys.Ingersoll@Sun.COM time_t now; 1932*12720SWyllys.Ingersoll@Sun.COM 1933*12720SWyllys.Ingersoll@Sun.COM if ( (now = time(NULL)) == ((time_t)-1) ) 1934*12720SWyllys.Ingersoll@Sun.COM { 1935*12720SWyllys.Ingersoll@Sun.COM return -1; 1936*12720SWyllys.Ingersoll@Sun.COM } 1937*12720SWyllys.Ingersoll@Sun.COM 1938*12720SWyllys.Ingersoll@Sun.COM delta.tv_sec = i_iNumberOfSeconds; 1939*12720SWyllys.Ingersoll@Sun.COM delta.tv_usec = 0; 1940*12720SWyllys.Ingersoll@Sun.COM 1941*12720SWyllys.Ingersoll@Sun.COM return adjtime(&delta, &lastchange); 1942*12720SWyllys.Ingersoll@Sun.COM #endif 1943*12720SWyllys.Ingersoll@Sun.COM } 1944*12720SWyllys.Ingersoll@Sun.COM 1945*12720SWyllys.Ingersoll@Sun.COM 1946*12720SWyllys.Ingersoll@Sun.COM #ifdef K_SOLARIS_PLATFORM 1947*12720SWyllys.Ingersoll@Sun.COM static int pam_tty_conv( 1948*12720SWyllys.Ingersoll@Sun.COM int num_msg, 1949*12720SWyllys.Ingersoll@Sun.COM struct pam_message** mess, 1950*12720SWyllys.Ingersoll@Sun.COM struct pam_response** resp, 1951*12720SWyllys.Ingersoll@Sun.COM void* my_data) 1952*12720SWyllys.Ingersoll@Sun.COM { 1953*12720SWyllys.Ingersoll@Sun.COM // Following code implements a console-based PAM "conversation" function 1954*12720SWyllys.Ingersoll@Sun.COM // (based sample code from Solaris 10 Software Developer Collection >> 1955*12720SWyllys.Ingersoll@Sun.COM // Solaris Security for Developers Guide >> 1956*12720SWyllys.Ingersoll@Sun.COM // 3. Writing PAM Applications and Services) 1957*12720SWyllys.Ingersoll@Sun.COM 1958*12720SWyllys.Ingersoll@Sun.COM struct pam_message* m = *mess; 1959*12720SWyllys.Ingersoll@Sun.COM struct pam_response* r; 1960*12720SWyllys.Ingersoll@Sun.COM int i, j; 1961*12720SWyllys.Ingersoll@Sun.COM const char* sPassword = (const char*)my_data; 1962*12720SWyllys.Ingersoll@Sun.COM int error = PAM_CONV_ERR; 1963*12720SWyllys.Ingersoll@Sun.COM 1964*12720SWyllys.Ingersoll@Sun.COM if (num_msg <= 0 || num_msg >= PAM_MAX_NUM_MSG) 1965*12720SWyllys.Ingersoll@Sun.COM { 1966*12720SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, "PAM error: bad number of messages"); 1967*12720SWyllys.Ingersoll@Sun.COM *resp = NULL; 1968*12720SWyllys.Ingersoll@Sun.COM return (PAM_CONV_ERR); 1969*12720SWyllys.Ingersoll@Sun.COM } 1970*12720SWyllys.Ingersoll@Sun.COM 1971*12720SWyllys.Ingersoll@Sun.COM if ((*resp = r = calloc(num_msg, sizeof (struct pam_response))) == NULL) 1972*12720SWyllys.Ingersoll@Sun.COM { 1973*12720SWyllys.Ingersoll@Sun.COM return (PAM_BUF_ERR); 1974*12720SWyllys.Ingersoll@Sun.COM } 1975*12720SWyllys.Ingersoll@Sun.COM 1976*12720SWyllys.Ingersoll@Sun.COM // Loop through messages 1977*12720SWyllys.Ingersoll@Sun.COM for (i = 0; i < num_msg; i++) { 1978*12720SWyllys.Ingersoll@Sun.COM 1979*12720SWyllys.Ingersoll@Sun.COM // bad message from service module 1980*12720SWyllys.Ingersoll@Sun.COM if (m->msg == NULL) 1981*12720SWyllys.Ingersoll@Sun.COM { 1982*12720SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, "PAM error: bad message"); 1983*12720SWyllys.Ingersoll@Sun.COM goto err; 1984*12720SWyllys.Ingersoll@Sun.COM } 1985*12720SWyllys.Ingersoll@Sun.COM 1986*12720SWyllys.Ingersoll@Sun.COM // fix up final newline: removed for prompts, added back for messages 1987*12720SWyllys.Ingersoll@Sun.COM if (m->msg[strlen(m->msg)] == '\n') 1988*12720SWyllys.Ingersoll@Sun.COM { 1989*12720SWyllys.Ingersoll@Sun.COM m->msg[strlen(m->msg)] = '\0'; 1990*12720SWyllys.Ingersoll@Sun.COM } 1991*12720SWyllys.Ingersoll@Sun.COM 1992*12720SWyllys.Ingersoll@Sun.COM // Since the KMA has its own password prompts and enforces its own rule checks, we already have the 1993*12720SWyllys.Ingersoll@Sun.COM // new password in memory. So instead of displaying PAM prompts and collecting user responses, we 1994*12720SWyllys.Ingersoll@Sun.COM // "automate" by assuming that the prompts correspond to the standard sequence of "New password:" 1995*12720SWyllys.Ingersoll@Sun.COM // followed by "Confirm password:" and so in each case we immediately return the password we already 1996*12720SWyllys.Ingersoll@Sun.COM // have in memory. This violates the PAM "conversation" function instructions (which say, basically, 1997*12720SWyllys.Ingersoll@Sun.COM // not to assume any particular sequence of prompts since there could be any number of underlying 1998*12720SWyllys.Ingersoll@Sun.COM // password managers), but since the KMA is running on an appliance with a fixed password manager, 1999*12720SWyllys.Ingersoll@Sun.COM // our assumptions should hold. 2000*12720SWyllys.Ingersoll@Sun.COM 2001*12720SWyllys.Ingersoll@Sun.COM r->resp = NULL; 2002*12720SWyllys.Ingersoll@Sun.COM r->resp_retcode = 0; 2003*12720SWyllys.Ingersoll@Sun.COM switch (m->msg_style) 2004*12720SWyllys.Ingersoll@Sun.COM { 2005*12720SWyllys.Ingersoll@Sun.COM case PAM_PROMPT_ECHO_OFF: 2006*12720SWyllys.Ingersoll@Sun.COM case PAM_PROMPT_ECHO_ON: 2007*12720SWyllys.Ingersoll@Sun.COM // Assume the prompt asked for New/Confirm password, so return password. 2008*12720SWyllys.Ingersoll@Sun.COM if ( (r->resp = strdup(sPassword)) == NULL ) 2009*12720SWyllys.Ingersoll@Sun.COM { 2010*12720SWyllys.Ingersoll@Sun.COM error = PAM_BUF_ERR; 2011*12720SWyllys.Ingersoll@Sun.COM goto err; 2012*12720SWyllys.Ingersoll@Sun.COM } 2013*12720SWyllys.Ingersoll@Sun.COM break; 2014*12720SWyllys.Ingersoll@Sun.COM 2015*12720SWyllys.Ingersoll@Sun.COM case PAM_ERROR_MSG: 2016*12720SWyllys.Ingersoll@Sun.COM // Assuming the system is configured properly and the KMA password prompts enforce password strength rules, 2017*12720SWyllys.Ingersoll@Sun.COM // there should not be errors because of weak passwords, etc. Still, print errors so users/support can 2018*12720SWyllys.Ingersoll@Sun.COM // diagnose problems. 2019*12720SWyllys.Ingersoll@Sun.COM (void) fputs(m->msg, stderr); 2020*12720SWyllys.Ingersoll@Sun.COM (void) fputc('\n', stderr); 2021*12720SWyllys.Ingersoll@Sun.COM break; 2022*12720SWyllys.Ingersoll@Sun.COM 2023*12720SWyllys.Ingersoll@Sun.COM case PAM_TEXT_INFO: 2024*12720SWyllys.Ingersoll@Sun.COM // Supress prompts (again, making assumptions). 2025*12720SWyllys.Ingersoll@Sun.COM break; 2026*12720SWyllys.Ingersoll@Sun.COM 2027*12720SWyllys.Ingersoll@Sun.COM default: 2028*12720SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, "PAM error: unknown message"); 2029*12720SWyllys.Ingersoll@Sun.COM goto err; 2030*12720SWyllys.Ingersoll@Sun.COM } 2031*12720SWyllys.Ingersoll@Sun.COM if (errno == EINTR) 2032*12720SWyllys.Ingersoll@Sun.COM { 2033*12720SWyllys.Ingersoll@Sun.COM goto err; 2034*12720SWyllys.Ingersoll@Sun.COM } 2035*12720SWyllys.Ingersoll@Sun.COM 2036*12720SWyllys.Ingersoll@Sun.COM // next message/response 2037*12720SWyllys.Ingersoll@Sun.COM m++; 2038*12720SWyllys.Ingersoll@Sun.COM r++; 2039*12720SWyllys.Ingersoll@Sun.COM } 2040*12720SWyllys.Ingersoll@Sun.COM return (PAM_SUCCESS); 2041*12720SWyllys.Ingersoll@Sun.COM 2042*12720SWyllys.Ingersoll@Sun.COM err: 2043*12720SWyllys.Ingersoll@Sun.COM // Service modules do not clean up responses if an error is returned. 2044*12720SWyllys.Ingersoll@Sun.COM // Free responses here. 2045*12720SWyllys.Ingersoll@Sun.COM for (j = 0; j < i; j++, r++) 2046*12720SWyllys.Ingersoll@Sun.COM { 2047*12720SWyllys.Ingersoll@Sun.COM if (r->resp) 2048*12720SWyllys.Ingersoll@Sun.COM { 2049*12720SWyllys.Ingersoll@Sun.COM // clear before freeing -- may be a password 2050*12720SWyllys.Ingersoll@Sun.COM bzero(r->resp, strlen(r->resp)); 2051*12720SWyllys.Ingersoll@Sun.COM free(r->resp); 2052*12720SWyllys.Ingersoll@Sun.COM r->resp = NULL; 2053*12720SWyllys.Ingersoll@Sun.COM } 2054*12720SWyllys.Ingersoll@Sun.COM } 2055*12720SWyllys.Ingersoll@Sun.COM free(r); 2056*12720SWyllys.Ingersoll@Sun.COM *resp = NULL; 2057*12720SWyllys.Ingersoll@Sun.COM return error; 2058*12720SWyllys.Ingersoll@Sun.COM } 2059*12720SWyllys.Ingersoll@Sun.COM #endif 2060*12720SWyllys.Ingersoll@Sun.COM 2061*12720SWyllys.Ingersoll@Sun.COM 2062*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 2063*12720SWyllys.Ingersoll@Sun.COM * Function: K_SetRootPassword 2064*12720SWyllys.Ingersoll@Sun.COM * 2065*12720SWyllys.Ingersoll@Sun.COM * Description: 2066*12720SWyllys.Ingersoll@Sun.COM * The K_SetRootPassword function sets the password for the root user via 2067*12720SWyllys.Ingersoll@Sun.COM * Pluggable Authentication Module (PAM). This function is interactive. 2068*12720SWyllys.Ingersoll@Sun.COM * 2069*12720SWyllys.Ingersoll@Sun.COM * Input 2070*12720SWyllys.Ingersoll@Sun.COM * ----- 2071*12720SWyllys.Ingersoll@Sun.COM * i_sPassword Password to set 2072*12720SWyllys.Ingersoll@Sun.COM * 2073*12720SWyllys.Ingersoll@Sun.COM * Output 2074*12720SWyllys.Ingersoll@Sun.COM * ------ 2075*12720SWyllys.Ingersoll@Sun.COM * (none) 2076*12720SWyllys.Ingersoll@Sun.COM * 2077*12720SWyllys.Ingersoll@Sun.COM * Return value 0 if successful, -1 on error 2078*12720SWyllys.Ingersoll@Sun.COM * 2079*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 2080*12720SWyllys.Ingersoll@Sun.COM 2081*12720SWyllys.Ingersoll@Sun.COM int K_SetRootPassword( const char* i_sPassword ) 2082*12720SWyllys.Ingersoll@Sun.COM { 2083*12720SWyllys.Ingersoll@Sun.COM // Only supported/tested on Solaris at the moment 2084*12720SWyllys.Ingersoll@Sun.COM #ifndef K_SOLARIS_PLATFORM 2085*12720SWyllys.Ingersoll@Sun.COM return -1; 2086*12720SWyllys.Ingersoll@Sun.COM #else 2087*12720SWyllys.Ingersoll@Sun.COM // Based on sample code from Solaris 10 Software Developer Collection >> 2088*12720SWyllys.Ingersoll@Sun.COM // Solaris Security for Developers Guide >> 2089*12720SWyllys.Ingersoll@Sun.COM // 3. Writing PAM Applications and Services 2090*12720SWyllys.Ingersoll@Sun.COM 2091*12720SWyllys.Ingersoll@Sun.COM // TODO: Return PAM error codes (to be logged) instead of emitting 2092*12720SWyllys.Ingersoll@Sun.COM // messages to screen? 2093*12720SWyllys.Ingersoll@Sun.COM 2094*12720SWyllys.Ingersoll@Sun.COM struct pam_conv conv; 2095*12720SWyllys.Ingersoll@Sun.COM pam_handle_t *pamh; 2096*12720SWyllys.Ingersoll@Sun.COM int err; 2097*12720SWyllys.Ingersoll@Sun.COM 2098*12720SWyllys.Ingersoll@Sun.COM conv.conv = pam_tty_conv; 2099*12720SWyllys.Ingersoll@Sun.COM conv.appdata_ptr = (void*)i_sPassword; 2100*12720SWyllys.Ingersoll@Sun.COM 2101*12720SWyllys.Ingersoll@Sun.COM // Initialize PAM framework 2102*12720SWyllys.Ingersoll@Sun.COM err = pam_start("KeyMgr", "root", &conv, &pamh); 2103*12720SWyllys.Ingersoll@Sun.COM if (err != PAM_SUCCESS) 2104*12720SWyllys.Ingersoll@Sun.COM { 2105*12720SWyllys.Ingersoll@Sun.COM fprintf(stderr, "PAM error: %s\n", pam_strerror(pamh, err)); 2106*12720SWyllys.Ingersoll@Sun.COM return -1; 2107*12720SWyllys.Ingersoll@Sun.COM } 2108*12720SWyllys.Ingersoll@Sun.COM 2109*12720SWyllys.Ingersoll@Sun.COM // Change password 2110*12720SWyllys.Ingersoll@Sun.COM err = pam_chauthtok(pamh, 0); 2111*12720SWyllys.Ingersoll@Sun.COM if (err != PAM_SUCCESS) 2112*12720SWyllys.Ingersoll@Sun.COM { 2113*12720SWyllys.Ingersoll@Sun.COM fprintf(stderr, "PAM error: %s\n", pam_strerror(pamh, err)); 2114*12720SWyllys.Ingersoll@Sun.COM // fall through to cleanup 2115*12720SWyllys.Ingersoll@Sun.COM } 2116*12720SWyllys.Ingersoll@Sun.COM 2117*12720SWyllys.Ingersoll@Sun.COM // Cleanup session 2118*12720SWyllys.Ingersoll@Sun.COM pam_end(pamh, 0); 2119*12720SWyllys.Ingersoll@Sun.COM 2120*12720SWyllys.Ingersoll@Sun.COM return (err == PAM_SUCCESS) ? 0 : -1; 2121*12720SWyllys.Ingersoll@Sun.COM #endif 2122*12720SWyllys.Ingersoll@Sun.COM } 2123*12720SWyllys.Ingersoll@Sun.COM 2124*12720SWyllys.Ingersoll@Sun.COM 2125*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 2126*12720SWyllys.Ingersoll@Sun.COM * Function: K_Alarm 2127*12720SWyllys.Ingersoll@Sun.COM * 2128*12720SWyllys.Ingersoll@Sun.COM * Description: 2129*12720SWyllys.Ingersoll@Sun.COM * Calls alarm(2) on Unix in order to cause the operating system to generate 2130*12720SWyllys.Ingersoll@Sun.COM * a SIGALRM signal for this process after the given number of real-time 2131*12720SWyllys.Ingersoll@Sun.COM * seconds. Does nothing on Windows. 2132*12720SWyllys.Ingersoll@Sun.COM * 2133*12720SWyllys.Ingersoll@Sun.COM * Input 2134*12720SWyllys.Ingersoll@Sun.COM * ----- 2135*12720SWyllys.Ingersoll@Sun.COM * i_iSeconds Number of seconds after which to generate a SIGALRM 2136*12720SWyllys.Ingersoll@Sun.COM * signal 2137*12720SWyllys.Ingersoll@Sun.COM * 2138*12720SWyllys.Ingersoll@Sun.COM * Output 2139*12720SWyllys.Ingersoll@Sun.COM * ------ 2140*12720SWyllys.Ingersoll@Sun.COM * (none) 2141*12720SWyllys.Ingersoll@Sun.COM * 2142*12720SWyllys.Ingersoll@Sun.COM * Return value If a previous alarm request is pending, then it returns 2143*12720SWyllys.Ingersoll@Sun.COM * the number of seconds until this previous request would 2144*12720SWyllys.Ingersoll@Sun.COM * have generated a SIGALRM signal. Otherwise, returns 0. 2145*12720SWyllys.Ingersoll@Sun.COM * 2146*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 2147*12720SWyllys.Ingersoll@Sun.COM 2148*12720SWyllys.Ingersoll@Sun.COM unsigned int K_Alarm( unsigned int i_iSeconds ) 2149*12720SWyllys.Ingersoll@Sun.COM { 2150*12720SWyllys.Ingersoll@Sun.COM #ifndef WIN32 2151*12720SWyllys.Ingersoll@Sun.COM return alarm( i_iSeconds ); 2152*12720SWyllys.Ingersoll@Sun.COM #else 2153*12720SWyllys.Ingersoll@Sun.COM return 0; 2154*12720SWyllys.Ingersoll@Sun.COM #endif 2155*12720SWyllys.Ingersoll@Sun.COM } 2156*12720SWyllys.Ingersoll@Sun.COM 2157*12720SWyllys.Ingersoll@Sun.COM 2158*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 2159*12720SWyllys.Ingersoll@Sun.COM * Function: K_GetExtendedVersionFromBase 2160*12720SWyllys.Ingersoll@Sun.COM * 2161*12720SWyllys.Ingersoll@Sun.COM * Description: 2162*12720SWyllys.Ingersoll@Sun.COM * This KMS-specific function prepends the timestamp value to the specified 2163*12720SWyllys.Ingersoll@Sun.COM * base replication schema version and returns this value as an extended 2164*12720SWyllys.Ingersoll@Sun.COM * replication schema version. 2165*12720SWyllys.Ingersoll@Sun.COM * 2166*12720SWyllys.Ingersoll@Sun.COM * Input 2167*12720SWyllys.Ingersoll@Sun.COM * ----- 2168*12720SWyllys.Ingersoll@Sun.COM * i_iBaseSchemaVersion Base replication schema version 2169*12720SWyllys.Ingersoll@Sun.COM * 2170*12720SWyllys.Ingersoll@Sun.COM * Output 2171*12720SWyllys.Ingersoll@Sun.COM * ------ 2172*12720SWyllys.Ingersoll@Sun.COM * (none) 2173*12720SWyllys.Ingersoll@Sun.COM * 2174*12720SWyllys.Ingersoll@Sun.COM * Return value Extended replication schema version 2175*12720SWyllys.Ingersoll@Sun.COM * 2176*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 2177*12720SWyllys.Ingersoll@Sun.COM 2178*12720SWyllys.Ingersoll@Sun.COM unsigned int K_GetExtendedVersionFromBase( unsigned int i_iBaseSchemaVersion ) 2179*12720SWyllys.Ingersoll@Sun.COM { 2180*12720SWyllys.Ingersoll@Sun.COM // seconds since 1970, force to 32-bit 2181*12720SWyllys.Ingersoll@Sun.COM #ifdef WIN32 2182*12720SWyllys.Ingersoll@Sun.COM INT32 iTimeStamp = (INT32) time(NULL); 2183*12720SWyllys.Ingersoll@Sun.COM #else 2184*12720SWyllys.Ingersoll@Sun.COM int32_t iTimeStamp = (int32_t) time(NULL); 2185*12720SWyllys.Ingersoll@Sun.COM #endif 2186*12720SWyllys.Ingersoll@Sun.COM // minutes since 1970 2187*12720SWyllys.Ingersoll@Sun.COM iTimeStamp = iTimeStamp / 60; 2188*12720SWyllys.Ingersoll@Sun.COM // minutes since 2000 (approximately) 2189*12720SWyllys.Ingersoll@Sun.COM iTimeStamp -= (30*365*24*60); 2190*12720SWyllys.Ingersoll@Sun.COM // shift 8 bits to clear out room for schema version # 2191*12720SWyllys.Ingersoll@Sun.COM iTimeStamp = iTimeStamp << 8; 2192*12720SWyllys.Ingersoll@Sun.COM // add schema version # to lower end 2193*12720SWyllys.Ingersoll@Sun.COM iTimeStamp |= i_iBaseSchemaVersion; 2194*12720SWyllys.Ingersoll@Sun.COM 2195*12720SWyllys.Ingersoll@Sun.COM return (unsigned int) iTimeStamp; 2196*12720SWyllys.Ingersoll@Sun.COM 2197*12720SWyllys.Ingersoll@Sun.COM } 2198*12720SWyllys.Ingersoll@Sun.COM 2199*12720SWyllys.Ingersoll@Sun.COM 2200*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 2201*12720SWyllys.Ingersoll@Sun.COM * Function: K_ParseTimestampFromExtendedVersion 2202*12720SWyllys.Ingersoll@Sun.COM * 2203*12720SWyllys.Ingersoll@Sun.COM * Description: 2204*12720SWyllys.Ingersoll@Sun.COM * This KMS-specific function parses the timestamp value from the given 2205*12720SWyllys.Ingersoll@Sun.COM * extended replication schema version and returns this timestamp value. 2206*12720SWyllys.Ingersoll@Sun.COM * 2207*12720SWyllys.Ingersoll@Sun.COM * Input 2208*12720SWyllys.Ingersoll@Sun.COM * ----- 2209*12720SWyllys.Ingersoll@Sun.COM * i_iExtendedSchemaVersion Extended replication schema version 2210*12720SWyllys.Ingersoll@Sun.COM * 2211*12720SWyllys.Ingersoll@Sun.COM * Output 2212*12720SWyllys.Ingersoll@Sun.COM * ------ 2213*12720SWyllys.Ingersoll@Sun.COM * (none) 2214*12720SWyllys.Ingersoll@Sun.COM * 2215*12720SWyllys.Ingersoll@Sun.COM * Return value Timestamp value 2216*12720SWyllys.Ingersoll@Sun.COM * 2217*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 2218*12720SWyllys.Ingersoll@Sun.COM 2219*12720SWyllys.Ingersoll@Sun.COM unsigned int K_ParseTimestampFromExtendedVersion( 2220*12720SWyllys.Ingersoll@Sun.COM unsigned int i_iExtendedSchemaVersion ) 2221*12720SWyllys.Ingersoll@Sun.COM { 2222*12720SWyllys.Ingersoll@Sun.COM unsigned int iTimeStamp = i_iExtendedSchemaVersion >> 8; 2223*12720SWyllys.Ingersoll@Sun.COM 2224*12720SWyllys.Ingersoll@Sun.COM return iTimeStamp; 2225*12720SWyllys.Ingersoll@Sun.COM } 2226*12720SWyllys.Ingersoll@Sun.COM 2227*12720SWyllys.Ingersoll@Sun.COM 2228*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 2229*12720SWyllys.Ingersoll@Sun.COM * Function: K_ParseBaseFromExtendedVersion 2230*12720SWyllys.Ingersoll@Sun.COM * 2231*12720SWyllys.Ingersoll@Sun.COM * Description: 2232*12720SWyllys.Ingersoll@Sun.COM * This KMS-specific function parses the base replication schema value from 2233*12720SWyllys.Ingersoll@Sun.COM * the given extended replication schema version and returns this base value. 2234*12720SWyllys.Ingersoll@Sun.COM * 2235*12720SWyllys.Ingersoll@Sun.COM * Input 2236*12720SWyllys.Ingersoll@Sun.COM * ----- 2237*12720SWyllys.Ingersoll@Sun.COM * i_iExtendedSchemaVersion Extended replication schema version 2238*12720SWyllys.Ingersoll@Sun.COM * 2239*12720SWyllys.Ingersoll@Sun.COM * Output 2240*12720SWyllys.Ingersoll@Sun.COM * ------ 2241*12720SWyllys.Ingersoll@Sun.COM * (none) 2242*12720SWyllys.Ingersoll@Sun.COM * 2243*12720SWyllys.Ingersoll@Sun.COM * Return value Base replication schema value 2244*12720SWyllys.Ingersoll@Sun.COM * 2245*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 2246*12720SWyllys.Ingersoll@Sun.COM 2247*12720SWyllys.Ingersoll@Sun.COM unsigned int K_ParseBaseFromExtendedVersion( 2248*12720SWyllys.Ingersoll@Sun.COM unsigned int i_iExtendedSchemaVersion ) 2249*12720SWyllys.Ingersoll@Sun.COM { 2250*12720SWyllys.Ingersoll@Sun.COM unsigned int iBaseSchemaVersion = i_iExtendedSchemaVersion & 0x000000FF; 2251*12720SWyllys.Ingersoll@Sun.COM 2252*12720SWyllys.Ingersoll@Sun.COM return iBaseSchemaVersion; 2253*12720SWyllys.Ingersoll@Sun.COM } 2254*12720SWyllys.Ingersoll@Sun.COM 2255*12720SWyllys.Ingersoll@Sun.COM 2256*12720SWyllys.Ingersoll@Sun.COM /*--------------------------------------------------------------------------- 2257*12720SWyllys.Ingersoll@Sun.COM * Function: K_System 2258*12720SWyllys.Ingersoll@Sun.COM * 2259*12720SWyllys.Ingersoll@Sun.COM * Description: 2260*12720SWyllys.Ingersoll@Sun.COM * This function is a thread-safe replacement for the unsafe system(3C) call. 2261*12720SWyllys.Ingersoll@Sun.COM * See the popen(3C) man page for more information. 2262*12720SWyllys.Ingersoll@Sun.COM * 2263*12720SWyllys.Ingersoll@Sun.COM * Input 2264*12720SWyllys.Ingersoll@Sun.COM * ----- 2265*12720SWyllys.Ingersoll@Sun.COM * i_sCmd Command to execute 2266*12720SWyllys.Ingersoll@Sun.COM * 2267*12720SWyllys.Ingersoll@Sun.COM * Output 2268*12720SWyllys.Ingersoll@Sun.COM * ------ 2269*12720SWyllys.Ingersoll@Sun.COM * (none) 2270*12720SWyllys.Ingersoll@Sun.COM * 2271*12720SWyllys.Ingersoll@Sun.COM * Return value Termination status of the command language interpreter 2272*12720SWyllys.Ingersoll@Sun.COM * if successful, -1 on failure 2273*12720SWyllys.Ingersoll@Sun.COM * 2274*12720SWyllys.Ingersoll@Sun.COM *--------------------------------------------------------------------------*/ 2275*12720SWyllys.Ingersoll@Sun.COM 2276*12720SWyllys.Ingersoll@Sun.COM int K_System( const char *i_sCmd ) 2277*12720SWyllys.Ingersoll@Sun.COM { 2278*12720SWyllys.Ingersoll@Sun.COM #ifndef WIN32 2279*12720SWyllys.Ingersoll@Sun.COM FILE *p; 2280*12720SWyllys.Ingersoll@Sun.COM int rc; 2281*12720SWyllys.Ingersoll@Sun.COM struct sigaction sOldAction; 2282*12720SWyllys.Ingersoll@Sun.COM 2283*12720SWyllys.Ingersoll@Sun.COM // Save signal handler 2284*12720SWyllys.Ingersoll@Sun.COM sigaction( SIGCHLD, NULL, &sOldAction ); 2285*12720SWyllys.Ingersoll@Sun.COM 2286*12720SWyllys.Ingersoll@Sun.COM // Use default child signal handler 2287*12720SWyllys.Ingersoll@Sun.COM sigset( SIGCHLD, SIG_DFL ); 2288*12720SWyllys.Ingersoll@Sun.COM 2289*12720SWyllys.Ingersoll@Sun.COM p = popen( i_sCmd, "w" ); 2290*12720SWyllys.Ingersoll@Sun.COM if ( p == NULL ) 2291*12720SWyllys.Ingersoll@Sun.COM { 2292*12720SWyllys.Ingersoll@Sun.COM rc = -1; 2293*12720SWyllys.Ingersoll@Sun.COM } 2294*12720SWyllys.Ingersoll@Sun.COM else 2295*12720SWyllys.Ingersoll@Sun.COM { 2296*12720SWyllys.Ingersoll@Sun.COM rc = pclose( p ); 2297*12720SWyllys.Ingersoll@Sun.COM } 2298*12720SWyllys.Ingersoll@Sun.COM 2299*12720SWyllys.Ingersoll@Sun.COM // Reset signal handler 2300*12720SWyllys.Ingersoll@Sun.COM sigset( SIGCHLD, sOldAction.sa_handler ); 2301*12720SWyllys.Ingersoll@Sun.COM 2302*12720SWyllys.Ingersoll@Sun.COM return rc; 2303*12720SWyllys.Ingersoll@Sun.COM #else 2304*12720SWyllys.Ingersoll@Sun.COM return system( i_sCmd ); 2305*12720SWyllys.Ingersoll@Sun.COM #endif 2306*12720SWyllys.Ingersoll@Sun.COM } 2307*12720SWyllys.Ingersoll@Sun.COM 2308