1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
32 static pthread_mutex_t getrtl_mutex
= PTHREAD_MUTEX_INITIALIZER
;
34 /* struct passwd differs on some platforms */
36 struct passwd
*getpwnam_r(const char* name
, struct passwd
* s
, char* buffer
, int size
)
40 pthread_mutex_lock(&getrtl_mutex
);
42 if ( (res
= getpwnam(name
)) )
44 int nname
, npasswd
, nclass
, ngecos
, ndir
;
46 nname
= strlen(res
->pw_name
)+1;
47 npasswd
= strlen(res
->pw_passwd
)+1;
48 nclass
= strlen(res
->pw_class
)+1;
49 ngecos
= strlen(res
->pw_gecos
)+1;
50 ndir
= strlen(res
->pw_dir
)+1;
52 if (nname
+npasswd
+nclass
+ngecos
53 +ndir
+strlen(res
->pw_shell
) < size
)
55 memcpy(s
, res
, sizeof(struct passwd
));
57 strcpy(buffer
, res
->pw_name
);
61 strcpy(buffer
, res
->pw_passwd
);
62 s
->pw_passwd
= buffer
;
65 strcpy(buffer
, res
->pw_class
);
69 strcpy(buffer
, res
->pw_gecos
);
73 strcpy(buffer
, res
->pw_dir
);
77 strcpy(buffer
, res
->pw_shell
);
86 pthread_mutex_unlock(&getrtl_mutex
);
91 int getpwuid_r(uid_t uid
, struct passwd
*pwd
, char *buffer
,
92 size_t buflen
, struct passwd
**result
)
97 pthread_mutex_lock(&getrtl_mutex
);
99 if ( (res
= getpwuid(uid
)) )
101 size_t pw_name
, pw_passwd
, pw_class
, pw_gecos
, pw_dir
, pw_shell
;
103 pw_name
= strlen(res
->pw_name
)+1;
104 pw_passwd
= strlen(res
->pw_passwd
)+1;
105 pw_class
= strlen(res
->pw_class
)+1;
106 pw_gecos
= strlen(res
->pw_gecos
)+1;
107 pw_dir
= strlen(res
->pw_dir
)+1;
108 pw_shell
= strlen(res
->pw_shell
)+1;
110 if (pw_name
+pw_passwd
+pw_class
+pw_gecos
111 +pw_dir
+pw_shell
< buflen
)
113 memcpy(pwd
, res
, sizeof(struct passwd
));
115 strncpy(buffer
, res
->pw_name
, pw_name
);
116 pwd
->pw_name
= buffer
;
119 strncpy(buffer
, res
->pw_passwd
, pw_passwd
);
120 pwd
->pw_passwd
= buffer
;
123 strncpy(buffer
, res
->pw_class
, pw_class
);
124 pwd
->pw_class
= buffer
;
127 strncpy(buffer
, res
->pw_gecos
, pw_gecos
);
128 pwd
->pw_gecos
= buffer
;
131 strncpy(buffer
, res
->pw_dir
, pw_dir
);
132 pwd
->pw_dir
= buffer
;
135 strncpy(buffer
, res
->pw_shell
, pw_shell
);
136 pwd
->pw_shell
= buffer
;
149 pthread_mutex_unlock(&getrtl_mutex
);
154 struct tm
*localtime_r(const time_t *timep
, struct tm
*buffer
)
158 pthread_mutex_lock(&getrtl_mutex
);
160 if ( (res
= localtime(timep
)))
162 memcpy(buffer
, res
, sizeof(struct tm
));
166 pthread_mutex_unlock(&getrtl_mutex
);
171 struct tm
*gmtime_r(const time_t *timep
, struct tm
*buffer
)
175 pthread_mutex_lock(&getrtl_mutex
);
177 if ( (res
= gmtime(timep
)) )
179 memcpy(buffer
, res
, sizeof(struct tm
));
183 pthread_mutex_unlock(&getrtl_mutex
);
187 #endif /* defined NETBSD */
192 #include <sys/types.h>
194 struct spwd
*getspnam_r(const char *name
, struct spwd
* s
, char* buffer
, int size
)
198 pthread_mutex_lock(&getrtl_mutex
);
200 if ( res
= getspnam(name
) )
204 nnamp
= strlen(res
->sp_namp
)+1;
206 if (nnamp
+strlen(res
->sp_pwdp
) < size
) {
207 memcpy(s
, res
, sizeof(struct spwd
));
209 strcpy(buffer
, res
->sp_namp
);
213 strcpy(buffer
, res
->sp_pwdp
);
222 pthread_mutex_unlock(&getrtl_mutex
);
227 struct passwd
*getpwnam_r(const char* name
, struct passwd
* s
, char* buffer
, int size
)
231 pthread_mutex_lock(&getrtl_mutex
);
233 if ( res
= getpwnam(name
) )
235 int nname
, npasswd
, nage
;
236 int ncomment
, ngecos
, ndir
;
238 nname
= strlen(res
->pw_name
)+1;
239 npasswd
= strlen(res
->pw_passwd
)+1;
240 nage
= strlen(res
->pw_age
)+1;
241 ncomment
= strlen(res
->pw_comment
)+1;
242 ngecos
= strlen(res
->pw_gecos
)+1;
243 ndir
= strlen(res
->pw_dir
)+1;
245 if (nname
+npasswd
+nage
+ncomment
+ngecos
+ndir
246 +strlen(res
->pw_shell
) < size
)
248 memcpy(s
, res
, sizeof(struct passwd
));
250 strcpy(buffer
, res
->pw_name
);
254 strcpy(buffer
, res
->pw_passwd
);
255 s
->pw_passwd
= buffer
;
258 strcpy(buffer
, res
->pw_age
);
262 strcpy(buffer
, res
->pw_comment
);
263 s
->pw_comment
= buffer
;
266 strcpy(buffer
, res
->pw_gecos
);
267 s
->pw_gecos
= buffer
;
270 strcpy(buffer
, res
->pw_dir
);
274 strcpy(buffer
, res
->pw_shell
);
275 s
->pw_shell
= buffer
;
283 pthread_mutex_unlock(&getrtl_mutex
);
287 #endif /* defined SCO */
289 #if !defined(FREEBSD) || (__FreeBSD_version < 601103)
293 struct hostent
*gethostbyname_r(const char *name
, struct hostent
*result
,
294 char *buffer
, int buflen
, int *h_errnop
)
296 /* buffer layout: name\0
297 * array_of_pointer_to_aliases
299 * alias1\0...aliasn\0
300 * array_of_pointer_to_addresses
302 * addr1addr2addr3...addrn
306 pthread_mutex_lock(&getrtl_mutex
);
308 if ( (res
= gethostbyname(name
)) )
310 int nname
, naliases
, naddr_list
, naliasesdata
, n
;
311 char **p
, **parray
, *data
;
313 /* Check buffer size before copying, we want to leave the
314 * buffers unmodified in case something goes wrong.
319 nname
= strlen(res
->h_name
)+1;
321 naliases
= naddr_list
= naliasesdata
= 0;
323 for ( p
= res
->h_aliases
; *p
!= NULL
; p
++) {
325 naliasesdata
+= strlen(*p
)+1;
328 for ( p
= res
->h_addr_list
; *p
!= NULL
; p
++)
332 + (naliases
+1)*sizeof(char*) + naliasesdata
333 + (naddr_list
+1)*sizeof(char*) + naddr_list
*res
->h_length
336 memcpy(result
, res
, sizeof(struct hostent
));
338 strcpy(buffer
, res
->h_name
);
339 result
->h_name
= buffer
;
342 parray
= (char**)buffer
;
343 result
->h_aliases
= parray
;
344 data
= buffer
+ (naliases
+1)*sizeof(char*);
345 for ( p
= res
->h_aliases
; *p
!= NULL
; p
++) {
353 parray
= (char**)buffer
;
354 result
->h_addr_list
= parray
;
355 data
= buffer
+ (naddr_list
+1)*sizeof(char*);
356 for ( p
= res
->h_addr_list
; *p
!= NULL
; p
++) {
358 memcpy(data
, *p
, res
->h_length
);
359 data
+= res
->h_length
;
376 pthread_mutex_unlock(&getrtl_mutex
);
380 #endif /* !defined(FREEBSD) || (__FreeBSD_version < 601103) */
384 * Add support for resolving Mac native alias files (not the same as unix alias files)
385 * returns 0 on success.
387 int macxp_resolveAlias(char *path
, int buflen
)
393 char *unprocessedPath
= path
;
395 if ( *unprocessedPath
== '/' )
399 while ( !nRet
&& unprocessedPath
&& *unprocessedPath
)
401 unprocessedPath
= strchr( unprocessedPath
, '/' );
402 if ( unprocessedPath
)
403 *unprocessedPath
= '\0';
408 if ( FSPathMakeRef( (const UInt8
*)path
, &aFSRef
, 0 ) == noErr
)
410 nErr
= FSResolveAliasFileWithMountFlags( &aFSRef
, TRUE
, &bFolder
, &bAliased
, kResolveAliasFileNoUI
);
411 if ( nErr
== nsvErr
)
416 else if ( nErr
== noErr
&& bAliased
)
418 char tmpPath
[ PATH_MAX
];
419 if ( FSRefMakePath( &aFSRef
, (UInt8
*)tmpPath
, PATH_MAX
) == noErr
)
421 int nLen
= strlen( tmpPath
) + ( unprocessedPath
? strlen( unprocessedPath
+ 1 ) + 1 : 0 );
422 if ( nLen
< buflen
&& nLen
< PATH_MAX
)
424 if ( unprocessedPath
)
426 int nTmpPathLen
= strlen( tmpPath
);
427 strcat( tmpPath
, "/" );
428 strcat( tmpPath
, unprocessedPath
+ 1 );
429 strcpy( path
, tmpPath
);
430 unprocessedPath
= path
+ nTmpPathLen
;
432 else if ( !unprocessedPath
)
434 strcpy( path
, tmpPath
);
439 errno
= ENAMETOOLONG
;
446 if ( unprocessedPath
)
447 *unprocessedPath
++ = '/';
453 #endif /* defined MACOSX */
455 #endif /* NO_PTHREAD_RTL */
457 #if (defined (LINUX) && (GLIBC >= 2))
458 /* The linux kernel thread implemention, always return the pid of the
459 thread subprocess and not of the main process. So we save the main
463 // Directly from libc.so.6, obviously missing from some unistd.h:
464 extern __pid_t
__getpid(void);
466 static pid_t pid
= -1;
468 static void savePid(void) __attribute__((constructor
));
470 static void savePid(void)
483 #endif /* (defined (LINUX) && (GLIBC >= 2)) */
485 #ifdef NO_PTHREAD_SEMAPHORES
486 int sem_init(sem_t
* sem
, int pshared
, unsigned int value
)
488 pthread_mutex_init(&sem
->mutex
, PTHREAD_MUTEXATTR_DEFAULT
);
489 pthread_cond_init(&sem
->increased
, PTHREAD_CONDATTR_DEFAULT
);
491 sem
->value
= (int)value
;
495 int sem_destroy(sem_t
* sem
)
497 pthread_mutex_destroy(&sem
->mutex
);
498 pthread_cond_destroy(&sem
->increased
);
503 int sem_wait(sem_t
* sem
)
505 pthread_mutex_lock(&sem
->mutex
);
507 while (sem
->value
<= 0)
509 pthread_cond_wait(&sem
->increased
, &sem
->mutex
);
513 pthread_mutex_unlock(&sem
->mutex
);
518 int sem_trywait(sem_t
* sem
)
522 pthread_mutex_lock(&sem
->mutex
);
534 pthread_mutex_unlock(&sem
->mutex
);
539 int sem_post(sem_t
* sem
)
541 pthread_mutex_lock(&sem
->mutex
);
545 pthread_mutex_unlock(&sem
->mutex
);
547 pthread_cond_signal(&sem
->increased
);
554 char *fcvt(double value
, int ndigit
, int *decpt
, int *sign
)
556 static char ret
[256];
557 char buf
[256],zahl
[256],format
[256]="%";
560 if (value
==0.0) value
=1e-30;
562 if (value
<0.0) *sign
=1; else *sign
=0;
566 *decpt
=(int)log10(value
);
567 value
*=pow(10.0,1-*decpt
);
569 if (ndigit
<0) ndigit
=0;
573 *decpt
=(int)log10(value
)+1;
576 sprintf(zahl
,"%d",ndigit
);
582 sprintf(buf
,format
,value
);