1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
33 static pthread_mutex_t getrtl_mutex
= PTHREAD_MUTEX_INITIALIZER
;
35 /* struct passwd differs on some platforms */
36 #if defined(MACOSX) || defined(IOS) || defined(OPENBSD) || defined(NETBSD)
40 struct hostent
*gethostbyname_r(const char *name
, struct hostent
*result
,
41 char *buffer
, size_t buflen
, int *h_errnop
)
43 /* buffer layout: name\0
44 * array_of_pointer_to_aliases
47 * array_of_pointer_to_addresses
49 * addr1addr2addr3...addrn
53 pthread_mutex_lock(&getrtl_mutex
);
55 if ( (res
= gethostbyname(name
)) )
57 int nname
, naliases
, naddr_list
, naliasesdata
, n
;
58 char **p
, **parray
, *data
;
60 /* Check buffer size before copying, we want to leave the
61 * buffers unmodified in case something goes wrong.
66 nname
= strlen(res
->h_name
)+1;
68 naliases
= naddr_list
= naliasesdata
= 0;
70 for ( p
= res
->h_aliases
; *p
!= NULL
; p
++) {
72 naliasesdata
+= strlen(*p
)+1;
75 for ( p
= res
->h_addr_list
; *p
!= NULL
; p
++)
79 + (naliases
+1)*sizeof(char*) + naliasesdata
80 + (naddr_list
+1)*sizeof(char*) + naddr_list
*res
->h_length
83 memcpy(result
, res
, sizeof(struct hostent
));
85 strcpy(buffer
, res
->h_name
);
86 result
->h_name
= buffer
;
89 parray
= (char**)buffer
;
90 result
->h_aliases
= parray
;
91 data
= buffer
+ (naliases
+1)*sizeof(char*);
92 for ( p
= res
->h_aliases
; *p
!= NULL
; p
++) {
100 parray
= (char**)buffer
;
101 result
->h_addr_list
= parray
;
102 data
= buffer
+ (naddr_list
+1)*sizeof(char*);
103 for ( p
= res
->h_addr_list
; *p
!= NULL
; p
++) {
105 memcpy(data
, *p
, res
->h_length
);
106 data
+= res
->h_length
;
123 pthread_mutex_unlock(&getrtl_mutex
);
127 #endif // OSX || IOS || OPENBSD || NETBSD
131 * Add support for resolving Mac native alias files (not the same as unix alias files)
132 * returns 0 on success.
134 int macxp_resolveAlias(char *path
, int buflen
)
140 char *unprocessedPath
= path
;
142 if ( *unprocessedPath
== '/' )
146 while ( !nRet
&& unprocessedPath
&& *unprocessedPath
)
148 unprocessedPath
= strchr( unprocessedPath
, '/' );
149 if ( unprocessedPath
)
150 *unprocessedPath
= '\0';
155 if ( FSPathMakeRef( (const UInt8
*)path
, &aFSRef
, 0 ) == noErr
)
157 nErr
= FSResolveAliasFileWithMountFlags( &aFSRef
, TRUE
, &bFolder
, &bAliased
, kResolveAliasFileNoUI
);
158 if ( nErr
== nsvErr
)
163 else if ( nErr
== noErr
&& bAliased
)
165 char tmpPath
[ PATH_MAX
];
166 if ( FSRefMakePath( &aFSRef
, (UInt8
*)tmpPath
, PATH_MAX
) == noErr
)
168 int nLen
= strlen( tmpPath
) + ( unprocessedPath
? strlen( unprocessedPath
+ 1 ) + 1 : 0 );
169 if ( nLen
< buflen
&& nLen
< PATH_MAX
)
171 if ( unprocessedPath
)
173 int nTmpPathLen
= strlen( tmpPath
);
174 strcat( tmpPath
, "/" );
175 strcat( tmpPath
, unprocessedPath
+ 1 );
176 strcpy( path
, tmpPath
);
177 unprocessedPath
= path
+ nTmpPathLen
;
179 else if ( !unprocessedPath
)
181 strcpy( path
, tmpPath
);
186 errno
= ENAMETOOLONG
;
193 if ( unprocessedPath
)
194 *unprocessedPath
++ = '/';
200 #endif /* defined MACOSX */
202 #endif /* NO_PTHREAD_RTL */
204 #if defined(LINUX) && defined (__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 4
205 /* The linux kernel 2.4 getpid implemention always return the pid of the
206 thread subprocess and not of the main process, the NPTL implementation
207 with a Linux kernel 2.6 kernel return the pid. So when possibly
208 there is the wrong implementation of getpid, we save the pid at startup.
209 FIXME: when our Linux base-line is above:
210 + Linux kernel version 2.6 or higher; -> clone() for NTPL
211 + glibc2 version 2.4 or higher; -> No longer LinuxThreads, only NPTL
212 Then we get a working getpid() and can remove this hack.
213 FIXME: getppid is also wrong in this situation
216 // Directly from libc.so.6, obviously missing from some unistd.h:
217 extern __pid_t
__getpid(void);
219 static pid_t pid
= -1;
221 static void savePid(void) __attribute__((constructor
));
223 static void savePid(void)
236 #endif /* defined LINUX */
238 #ifdef NO_PTHREAD_SEMAPHORES
239 int sem_init(sem_t
* sem
, int pshared
, unsigned int value
)
242 pthread_mutex_init(&sem
->mutex
, PTHREAD_MUTEXATTR_DEFAULT
);
243 pthread_cond_init(&sem
->increased
, PTHREAD_CONDATTR_DEFAULT
);
245 sem
->value
= (int)value
;
249 int sem_destroy(sem_t
* sem
)
251 pthread_mutex_destroy(&sem
->mutex
);
252 pthread_cond_destroy(&sem
->increased
);
257 int sem_wait(sem_t
* sem
)
259 pthread_mutex_lock(&sem
->mutex
);
261 while (sem
->value
<= 0)
263 pthread_cond_wait(&sem
->increased
, &sem
->mutex
);
267 pthread_mutex_unlock(&sem
->mutex
);
272 int sem_trywait(sem_t
* sem
)
276 pthread_mutex_lock(&sem
->mutex
);
288 pthread_mutex_unlock(&sem
->mutex
);
293 int sem_post(sem_t
* sem
)
295 pthread_mutex_lock(&sem
->mutex
);
299 pthread_mutex_unlock(&sem
->mutex
);
301 pthread_cond_signal(&sem
->increased
);
308 char *fcvt(double value
, int ndigit
, int *decpt
, int *sign
)
310 static char ret
[256];
311 char buf
[256],zahl
[256],format
[256]="%";
314 if (value
==0.0) value
=1e-30;
316 if (value
<0.0) *sign
=1; else *sign
=0;
320 *decpt
=(int)log10(value
);
321 value
*=pow(10.0,1-*decpt
);
323 if (ndigit
<0) ndigit
=0;
327 *decpt
=(int)log10(value
)+1;
330 sprintf(zahl
,"%d",ndigit
);
336 sprintf(buf
,format
,value
);
355 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */