update dev300-m57
[ooovba.git] / sal / osl / unx / system.c
blobc82055e9c3669b3d0094a629544ea2182704fc03
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: system.c,v $
10 * $Revision: 1.16.60.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "system.h"
33 #ifdef NO_PTHREAD_RTL
35 static pthread_mutex_t getrtl_mutex = PTHREAD_MUTEX_INITIALIZER;
37 /* struct passwd differs on some platforms */
38 #if defined NETBSD
39 struct passwd *getpwnam_r(const char* name, struct passwd* s, char* buffer, int size )
41 struct passwd* res;
43 pthread_mutex_lock(&getrtl_mutex);
45 if ( (res = getpwnam(name)) )
47 int nname, npasswd, nclass, ngecos, ndir;
49 nname= strlen(res->pw_name)+1;
50 npasswd= strlen(res->pw_passwd)+1;
51 nclass= strlen(res->pw_class)+1;
52 ngecos= strlen(res->pw_gecos)+1;
53 ndir= strlen(res->pw_dir)+1;
55 if (nname+npasswd+nclass+ngecos
56 +ndir+strlen(res->pw_shell) < size)
58 memcpy(s, res, sizeof(struct passwd));
60 strcpy(buffer, res->pw_name);
61 s->pw_name = buffer;
62 buffer += nname;
64 strcpy(buffer, res->pw_passwd);
65 s->pw_passwd = buffer;
66 buffer += npasswd;
68 strcpy(buffer, res->pw_class);
69 s->pw_class = buffer;
70 buffer += nclass;
72 strcpy(buffer, res->pw_gecos);
73 s->pw_gecos = buffer;
74 buffer += ngecos;
76 strcpy(buffer, res->pw_dir);
77 s->pw_dir = buffer;
78 buffer += ndir;
80 strcpy(buffer, res->pw_shell);
81 s->pw_shell = buffer;
83 res = s;
85 else
86 res = 0;
89 pthread_mutex_unlock(&getrtl_mutex);
91 return(res);
94 int getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer,
95 size_t buflen, struct passwd **result)
97 struct passwd* res;
98 int retval = 0;
100 pthread_mutex_lock(&getrtl_mutex);
102 if ( (res = getpwuid(uid)) )
104 size_t pw_name, pw_passwd, pw_class, pw_gecos, pw_dir, pw_shell;
106 pw_name = strlen(res->pw_name)+1;
107 pw_passwd = strlen(res->pw_passwd)+1;
108 pw_class = strlen(res->pw_class)+1;
109 pw_gecos = strlen(res->pw_gecos)+1;
110 pw_dir = strlen(res->pw_dir)+1;
111 pw_shell = strlen(res->pw_shell)+1;
113 if (pw_name+pw_passwd+pw_class+pw_gecos
114 +pw_dir+pw_shell < buflen)
116 memcpy(pwd, res, sizeof(struct passwd));
118 strncpy(buffer, res->pw_name, pw_name);
119 pwd->pw_name = buffer;
120 buffer += pw_name;
122 strncpy(buffer, res->pw_passwd, pw_passwd);
123 pwd->pw_passwd = buffer;
124 buffer += pw_passwd;
126 strncpy(buffer, res->pw_class, pw_class);
127 pwd->pw_class = buffer;
128 buffer += pw_class;
130 strncpy(buffer, res->pw_gecos, pw_gecos);
131 pwd->pw_gecos = buffer;
132 buffer += pw_gecos;
134 strncpy(buffer, res->pw_dir, pw_dir);
135 pwd->pw_dir = buffer;
136 buffer += pw_dir;
138 strncpy(buffer, res->pw_shell, pw_shell);
139 pwd->pw_shell = buffer;
140 buffer += pw_shell;
142 *result = pwd ;
143 retval = 0 ;
146 else
147 retval = ENOMEM;
149 else
150 retval = errno ;
152 pthread_mutex_unlock(&getrtl_mutex);
154 return retval;
157 struct tm *localtime_r(const time_t *timep, struct tm *buffer)
159 struct tm* res;
161 pthread_mutex_lock(&getrtl_mutex);
163 if ( (res = localtime(timep)))
165 memcpy(buffer, res, sizeof(struct tm));
166 res = buffer;
169 pthread_mutex_unlock(&getrtl_mutex);
171 return res;
174 struct tm *gmtime_r(const time_t *timep, struct tm *buffer)
176 struct tm* res;
178 pthread_mutex_lock(&getrtl_mutex);
180 if ( (res = gmtime(timep)) )
182 memcpy(buffer, res, sizeof(struct tm));
183 res = buffer;
186 pthread_mutex_unlock(&getrtl_mutex);
188 return res;
190 #endif /* defined NETBSD */
192 #ifdef SCO
193 #include <pwd.h>
194 #include <shadow.h>
195 #include <sys/types.h>
197 struct spwd *getspnam_r(const char *name, struct spwd* s, char* buffer, int size )
199 struct spwd* res;
201 pthread_mutex_lock(&getrtl_mutex);
203 if ( res = getspnam(name) )
205 int nnamp;
207 nnamp = strlen(res->sp_namp)+1;
209 if (nnamp+strlen(res->sp_pwdp) < size) {
210 memcpy(s, res, sizeof(struct spwd));
212 strcpy(buffer, res->sp_namp);
213 s->sp_namp = buffer;
214 buffer += nnamp;
216 strcpy(buffer, res->sp_pwdp);
217 s->sp_pwdp = buffer;
219 res = s;
221 else
222 res = 0;
225 pthread_mutex_unlock(&getrtl_mutex);
227 return res;
230 struct passwd *getpwnam_r(const char* name, struct passwd* s, char* buffer, int size )
232 struct passwd* res;
234 pthread_mutex_lock(&getrtl_mutex);
236 if ( res = getpwnam(name) )
238 int nname, npasswd, nage;
239 int ncomment, ngecos, ndir;
241 nname= strlen(res->pw_name)+1;
242 npasswd= strlen(res->pw_passwd)+1;
243 nage= strlen(res->pw_age)+1;
244 ncomment= strlen(res->pw_comment)+1;
245 ngecos= strlen(res->pw_gecos)+1;
246 ndir= strlen(res->pw_dir)+1;
248 if (nname+npasswd+nage+ncomment+ngecos+ndir
249 +strlen(res->pw_shell) < size)
251 memcpy(s, res, sizeof(struct passwd));
253 strcpy(buffer, res->pw_name);
254 s->pw_name = buffer;
255 buffer += nname;
257 strcpy(buffer, res->pw_passwd);
258 s->pw_passwd = buffer;
259 buffer += npasswd;
261 strcpy(buffer, res->pw_age);
262 s->pw_age = buffer;
263 buffer += nage;
265 strcpy(buffer, res->pw_comment);
266 s->pw_comment = buffer;
267 buffer += ncomment;
269 strcpy(buffer, res->pw_gecos);
270 s->pw_gecos = buffer;
271 buffer += ngecos;
273 strcpy(buffer, res->pw_dir);
274 s->pw_dir = buffer;
275 buffer += ndir;
277 strcpy(buffer, res->pw_shell);
278 s->pw_shell = buffer;
280 res = s;
282 else
283 res = 0;
286 pthread_mutex_unlock(&getrtl_mutex);
288 return res;
290 #endif /* defined SCO */
292 #if !defined(FREEBSD) || (__FreeBSD_version < 601103)
294 extern int h_errno;
296 struct hostent *gethostbyname_r(const char *name, struct hostent *result,
297 char *buffer, int buflen, int *h_errnop)
299 /* buffer layout: name\0
300 * array_of_pointer_to_aliases
301 * NULL
302 * alias1\0...aliasn\0
303 * array_of_pointer_to_addresses
304 * NULL
305 * addr1addr2addr3...addrn
307 struct hostent* res;
309 pthread_mutex_lock(&getrtl_mutex);
311 if ( (res = gethostbyname(name)) )
313 int nname, naliases, naddr_list, naliasesdata, n;
314 char **p, **parray, *data;
316 /* Check buffer size before copying, we want to leave the
317 * buffers unmodified in case something goes wrong.
319 * Is this required?
322 nname= strlen(res->h_name)+1;
324 naliases = naddr_list = naliasesdata = 0;
326 for ( p = res->h_aliases; *p != NULL; p++) {
327 naliases++;
328 naliasesdata += strlen(*p)+1;
331 for ( p = res->h_addr_list; *p != NULL; p++)
332 naddr_list++;
334 if ( nname
335 + (naliases+1)*sizeof(char*) + naliasesdata
336 + (naddr_list+1)*sizeof(char*) + naddr_list*res->h_length
337 <= buflen )
339 memcpy(result, res, sizeof(struct hostent));
341 strcpy(buffer, res->h_name);
342 result->h_name = buffer;
343 buffer += nname;
345 parray = (char**)buffer;
346 result->h_aliases = parray;
347 data = buffer + (naliases+1)*sizeof(char*);
348 for ( p = res->h_aliases; *p != NULL; p++) {
349 n = strlen(*p)+1;
350 *parray++ = data;
351 memcpy(data, *p, n);
352 data += n;
354 *parray = NULL;
355 buffer = data;
356 parray = (char**)buffer;
357 result->h_addr_list = parray;
358 data = buffer + (naddr_list+1)*sizeof(char*);
359 for ( p = res->h_addr_list; *p != NULL; p++) {
360 *parray++ = data;
361 memcpy(data, *p, res->h_length);
362 data += res->h_length;
364 *parray = NULL;
366 res = result;
368 else
370 errno = ERANGE;
371 res = NULL;
374 else
376 *h_errnop = h_errno;
379 pthread_mutex_unlock(&getrtl_mutex);
381 return res;
383 #endif /* !defined(FREEBSD) || (__FreeBSD_version < 601103) */
385 #if defined(MACOSX)
387 * Add support for resolving Mac native alias files (not the same as unix alias files)
388 * returns 0 on success.
390 int macxp_resolveAlias(char *path, int buflen)
392 FSRef aFSRef;
393 OSStatus nErr;
394 Boolean bFolder;
395 Boolean bAliased;
396 char *unprocessedPath = path;
398 if ( *unprocessedPath == '/' )
399 unprocessedPath++;
401 int nRet = 0;
402 while ( !nRet && unprocessedPath && *unprocessedPath )
404 unprocessedPath = strchr( unprocessedPath, '/' );
405 if ( unprocessedPath )
406 *unprocessedPath = '\0';
408 nErr = noErr;
409 bFolder = FALSE;
410 bAliased = FALSE;
411 if ( FSPathMakeRef( (const UInt8 *)path, &aFSRef, 0 ) == noErr )
413 nErr = FSResolveAliasFileWithMountFlags( &aFSRef, TRUE, &bFolder, &bAliased, kResolveAliasFileNoUI );
414 if ( nErr == nsvErr )
416 errno = ENOENT;
417 nRet = -1;
419 else if ( nErr == noErr && bAliased )
421 char tmpPath[ PATH_MAX ];
422 if ( FSRefMakePath( &aFSRef, (UInt8 *)tmpPath, PATH_MAX ) == noErr )
424 int nLen = strlen( tmpPath ) + ( unprocessedPath ? strlen( unprocessedPath + 1 ) + 1 : 0 );
425 if ( nLen < buflen && nLen < PATH_MAX )
427 if ( unprocessedPath )
429 int nTmpPathLen = strlen( tmpPath );
430 strcat( tmpPath, "/" );
431 strcat( tmpPath, unprocessedPath + 1 );
432 strcpy( path, tmpPath);
433 unprocessedPath = path + nTmpPathLen;
435 else if ( !unprocessedPath )
437 strcpy( path, tmpPath);
440 else
442 errno = ENAMETOOLONG;
443 nRet = -1;
449 if ( unprocessedPath )
450 *unprocessedPath++ = '/';
453 return nRet;
456 #endif /* defined MACOSX */
458 #endif /* NO_PTHREAD_RTL */
460 #if (defined (LINUX) && (GLIBC >= 2))
461 /* The linux kernel thread implemention, always return the pid of the
462 thread subprocess and not of the main process. So we save the main
463 pid at startup
466 // Directly from libc.so.6, obviously missing from some unistd.h:
467 extern __pid_t __getpid(void);
469 static pid_t pid = -1;
471 static void savePid(void) __attribute__((constructor));
473 static void savePid(void)
475 if (pid == -1)
476 pid = __getpid();
479 pid_t getpid(void)
481 if (pid == -1)
482 savePid();
484 return (pid);
486 #endif /* (defined (LINUX) && (GLIBC >= 2)) */
488 #ifdef NO_PTHREAD_SEMAPHORES
489 int sem_init(sem_t* sem, int pshared, unsigned int value)
491 pthread_mutex_init(&sem->mutex, PTHREAD_MUTEXATTR_DEFAULT);
492 pthread_cond_init(&sem->increased, PTHREAD_CONDATTR_DEFAULT);
494 sem->value = (int)value;
495 return 0;
498 int sem_destroy(sem_t* sem)
500 pthread_mutex_destroy(&sem->mutex);
501 pthread_cond_destroy(&sem->increased);
502 sem->value = 0;
503 return 0;
506 int sem_wait(sem_t* sem)
508 pthread_mutex_lock(&sem->mutex);
510 while (sem->value <= 0)
512 pthread_cond_wait(&sem->increased, &sem->mutex);
515 sem->value--;
516 pthread_mutex_unlock(&sem->mutex);
518 return 0;
521 int sem_trywait(sem_t* sem)
523 int result = 0;
525 pthread_mutex_lock(&sem->mutex);
527 if (sem->value > 0)
529 sem->value--;
531 else
533 errno = EAGAIN;
534 result = -1;
537 pthread_mutex_unlock(&sem->mutex);
539 return result;
542 int sem_post(sem_t* sem)
544 pthread_mutex_lock(&sem->mutex);
546 sem->value++;
548 pthread_mutex_unlock(&sem->mutex);
550 pthread_cond_signal(&sem->increased);
552 return 0;
554 #endif
556 #if defined(FREEBSD)
557 char *fcvt(double value, int ndigit, int *decpt, int *sign)
559 static char ret[256];
560 char buf[256],zahl[256],format[256]="%";
561 char *v1,*v2;
563 if (value==0.0) value=1e-30;
565 if (value<0.0) *sign=1; else *sign=0;
567 if (value<1.0)
569 *decpt=(int)log10(value);
570 value*=pow(10.0,1-*decpt);
571 ndigit+=*decpt-1;
572 if (ndigit<0) ndigit=0;
574 else
576 *decpt=(int)log10(value)+1;
579 sprintf(zahl,"%d",ndigit);
580 strcat(format,zahl);
581 strcat(format,".");
582 strcat(format,zahl);
583 strcat(format,"f");
585 sprintf(buf,format,value);
587 if (ndigit!=0)
589 v1=strtok(buf,".");
590 v2=strtok(NULL,".");
591 strcpy(ret,v1);
592 strcat(ret,v2);
594 else
596 strcpy(ret,buf);
599 return(ret);
602 #endif