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
atoll(const char * str)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
K_CreateThread(K_ThreadFunc i_pFunc,void * i_pvData,int i_bIsDetached,K_THREAD_HANDLE * o_pNewThread)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
K_JoinThread(K_THREAD_HANDLE i_hThread)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
K_GetCurrentThreadId()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
K_CreateMutex(K_MUTEX_HANDLE * o_phandle)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
K_LockMutex(K_MUTEX_HANDLE i_handle)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
K_UnlockMutex(K_MUTEX_HANDLE i_handle)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
K_DestroyMutex(K_MUTEX_HANDLE i_handle)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
K_InitConditionalVariable(K_ConditionalVariable * i_pCond)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
K_DestroyConditionalVariable(K_ConditionalVariable * i_pCond)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
K_WaitConditionalVariable(K_ConditionalVariable * i_pCond,K_MUTEX_HANDLE i_handle)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
K_SignalConditionalVariable(K_ConditionalVariable * i_pCond)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
K_BroadcastConditionalVariable(K_ConditionalVariable * i_pCond)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
K_Sleep(int i_ms)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
K_GetTickCount()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
K_AdjustClock(long i_iAdjustmentInSeconds)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
K_IsLittleEndian()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
K_FileLength32(FILE * i_fpFile)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
K_StringCompareNoCase(const char * i_sString1,const char * i_sString2)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
K_StringCompareNoCaseWide(const wchar_t * i_wsString1,const wchar_t * i_wsString2)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
K_CreateDirectory(const char * i_sDirectoryName)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
K_DeleteFile(const char * i_sFilename)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
K_ReadFile(const char * i_sFilename,unsigned char ** o_ppFileData)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
K_ReadFileString(const char * i_sFilename,char ** o_psFileDataString)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
K_WriteFile(const char * i_sFilename,const unsigned char * i_pFileData,int i_iFileDataSize)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
K_WriteFileString(const char * i_sFilename,const char * i_sFileData)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
K_FileExists(const char * i_sFilename)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
K_CopyFile(const char * i_sSrcFilename,const char * i_sDestFilename,int * o_pbFileExists)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
fts_compare(const FTSENT ** i_ppF1,const FTSENT ** i_ppF2)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.
K_GetFilenameFromInfo(const K_FindInfo * 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.
K_FindFileFirst(const char * i_sDirectoryName,K_FindInfo * o_pFindInfo)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.
K_FindFileNext(K_FindInfo * io_pFindInfo)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
K_FindFileClose(K_FindInfo * io_pFindInfo)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
K_GetFilenamesInDirectoryCount(const char * i_sDirectoryName)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
K_GetFilenamesInDirectory(const char * i_sDirectoryName,char *** o_pasFilenames)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
K_FreeFilenames(char ** i_asFilenames)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
K_AdjustLocalClock(int i_iNumberOfSeconds)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
pam_tty_conv(int num_msg,struct pam_message ** mess,struct pam_response ** resp,void * my_data)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
K_SetRootPassword(const char * i_sPassword)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
K_Alarm(unsigned int i_iSeconds)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
K_GetExtendedVersionFromBase(unsigned int i_iBaseSchemaVersion)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
K_ParseTimestampFromExtendedVersion(unsigned int i_iExtendedSchemaVersion)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
K_ParseBaseFromExtendedVersion(unsigned int i_iExtendedSchemaVersion)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
K_System(const char * i_sCmd)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