1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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 ************************************************************************/
35 static pthread_mutex_t getrtl_mutex
= PTHREAD_MUTEX_INITIALIZER
;
37 /* struct passwd differs on some platforms */
39 struct passwd
*getpwnam_r(const char* name
, struct passwd
* s
, char* buffer
, int size
)
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
);
64 strcpy(buffer
, res
->pw_passwd
);
65 s
->pw_passwd
= buffer
;
68 strcpy(buffer
, res
->pw_class
);
72 strcpy(buffer
, res
->pw_gecos
);
76 strcpy(buffer
, res
->pw_dir
);
80 strcpy(buffer
, res
->pw_shell
);
89 pthread_mutex_unlock(&getrtl_mutex
);
94 int getpwuid_r(uid_t uid
, struct passwd
*pwd
, char *buffer
,
95 size_t buflen
, struct passwd
**result
)
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
;
122 strncpy(buffer
, res
->pw_passwd
, pw_passwd
);
123 pwd
->pw_passwd
= buffer
;
126 strncpy(buffer
, res
->pw_class
, pw_class
);
127 pwd
->pw_class
= buffer
;
130 strncpy(buffer
, res
->pw_gecos
, pw_gecos
);
131 pwd
->pw_gecos
= buffer
;
134 strncpy(buffer
, res
->pw_dir
, pw_dir
);
135 pwd
->pw_dir
= buffer
;
138 strncpy(buffer
, res
->pw_shell
, pw_shell
);
139 pwd
->pw_shell
= buffer
;
152 pthread_mutex_unlock(&getrtl_mutex
);
157 struct tm
*localtime_r(const time_t *timep
, struct tm
*buffer
)
161 pthread_mutex_lock(&getrtl_mutex
);
163 if ( (res
= localtime(timep
)))
165 memcpy(buffer
, res
, sizeof(struct tm
));
169 pthread_mutex_unlock(&getrtl_mutex
);
174 struct tm
*gmtime_r(const time_t *timep
, struct tm
*buffer
)
178 pthread_mutex_lock(&getrtl_mutex
);
180 if ( (res
= gmtime(timep
)) )
182 memcpy(buffer
, res
, sizeof(struct tm
));
186 pthread_mutex_unlock(&getrtl_mutex
);
190 #endif /* defined NETBSD */
195 #include <sys/types.h>
197 struct spwd
*getspnam_r(const char *name
, struct spwd
* s
, char* buffer
, int size
)
201 pthread_mutex_lock(&getrtl_mutex
);
203 if ( res
= getspnam(name
) )
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
);
216 strcpy(buffer
, res
->sp_pwdp
);
225 pthread_mutex_unlock(&getrtl_mutex
);
230 struct passwd
*getpwnam_r(const char* name
, struct passwd
* s
, char* buffer
, int size
)
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
);
257 strcpy(buffer
, res
->pw_passwd
);
258 s
->pw_passwd
= buffer
;
261 strcpy(buffer
, res
->pw_age
);
265 strcpy(buffer
, res
->pw_comment
);
266 s
->pw_comment
= buffer
;
269 strcpy(buffer
, res
->pw_gecos
);
270 s
->pw_gecos
= buffer
;
273 strcpy(buffer
, res
->pw_dir
);
277 strcpy(buffer
, res
->pw_shell
);
278 s
->pw_shell
= buffer
;
286 pthread_mutex_unlock(&getrtl_mutex
);
290 #endif /* defined SCO */
292 #if !defined(FREEBSD) || (__FreeBSD_version < 601103)
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
302 * alias1\0...aliasn\0
303 * array_of_pointer_to_addresses
305 * addr1addr2addr3...addrn
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.
322 nname
= strlen(res
->h_name
)+1;
324 naliases
= naddr_list
= naliasesdata
= 0;
326 for ( p
= res
->h_aliases
; *p
!= NULL
; p
++) {
328 naliasesdata
+= strlen(*p
)+1;
331 for ( p
= res
->h_addr_list
; *p
!= NULL
; p
++)
335 + (naliases
+1)*sizeof(char*) + naliasesdata
336 + (naddr_list
+1)*sizeof(char*) + naddr_list
*res
->h_length
339 memcpy(result
, res
, sizeof(struct hostent
));
341 strcpy(buffer
, res
->h_name
);
342 result
->h_name
= buffer
;
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
++) {
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
++) {
361 memcpy(data
, *p
, res
->h_length
);
362 data
+= res
->h_length
;
379 pthread_mutex_unlock(&getrtl_mutex
);
383 #endif /* !defined(FREEBSD) || (__FreeBSD_version < 601103) */
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
)
396 char *unprocessedPath
= path
;
398 if ( *unprocessedPath
== '/' )
402 while ( !nRet
&& unprocessedPath
&& *unprocessedPath
)
404 unprocessedPath
= strchr( unprocessedPath
, '/' );
405 if ( unprocessedPath
)
406 *unprocessedPath
= '\0';
411 if ( FSPathMakeRef( (const UInt8
*)path
, &aFSRef
, 0 ) == noErr
)
413 nErr
= FSResolveAliasFileWithMountFlags( &aFSRef
, TRUE
, &bFolder
, &bAliased
, kResolveAliasFileNoUI
);
414 if ( nErr
== nsvErr
)
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
);
442 errno
= ENAMETOOLONG
;
449 if ( unprocessedPath
)
450 *unprocessedPath
++ = '/';
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
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)
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
;
498 int sem_destroy(sem_t
* sem
)
500 pthread_mutex_destroy(&sem
->mutex
);
501 pthread_cond_destroy(&sem
->increased
);
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
);
516 pthread_mutex_unlock(&sem
->mutex
);
521 int sem_trywait(sem_t
* sem
)
525 pthread_mutex_lock(&sem
->mutex
);
537 pthread_mutex_unlock(&sem
->mutex
);
542 int sem_post(sem_t
* sem
)
544 pthread_mutex_lock(&sem
->mutex
);
548 pthread_mutex_unlock(&sem
->mutex
);
550 pthread_cond_signal(&sem
->increased
);
557 char *fcvt(double value
, int ndigit
, int *decpt
, int *sign
)
559 static char ret
[256];
560 char buf
[256],zahl
[256],format
[256]="%";
563 if (value
==0.0) value
=1e-30;
565 if (value
<0.0) *sign
=1; else *sign
=0;
569 *decpt
=(int)log10(value
);
570 value
*=pow(10.0,1-*decpt
);
572 if (ndigit
<0) ndigit
=0;
576 *decpt
=(int)log10(value
)+1;
579 sprintf(zahl
,"%d",ndigit
);
585 sprintf(buf
,format
,value
);