Bump for 3.6-28
[LibreOffice.git] / sal / osl / unx / system.c
blob720d1cd98a491eb2894249f831dd522bcf0897cf
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 ************************************************************************/
29 #include "system.h"
31 #ifdef NO_PTHREAD_RTL
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)
38 extern int h_errno;
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
45 * NULL
46 * alias1\0...aliasn\0
47 * array_of_pointer_to_addresses
48 * NULL
49 * addr1addr2addr3...addrn
51 struct hostent* res;
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.
63 * Is this required?
66 nname= strlen(res->h_name)+1;
68 naliases = naddr_list = naliasesdata = 0;
70 for ( p = res->h_aliases; *p != NULL; p++) {
71 naliases++;
72 naliasesdata += strlen(*p)+1;
75 for ( p = res->h_addr_list; *p != NULL; p++)
76 naddr_list++;
78 if ( nname
79 + (naliases+1)*sizeof(char*) + naliasesdata
80 + (naddr_list+1)*sizeof(char*) + naddr_list*res->h_length
81 <= buflen )
83 memcpy(result, res, sizeof(struct hostent));
85 strcpy(buffer, res->h_name);
86 result->h_name = buffer;
87 buffer += nname;
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++) {
93 n = strlen(*p)+1;
94 *parray++ = data;
95 memcpy(data, *p, n);
96 data += n;
98 *parray = NULL;
99 buffer = data;
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++) {
104 *parray++ = data;
105 memcpy(data, *p, res->h_length);
106 data += res->h_length;
108 *parray = NULL;
110 res = result;
112 else
114 errno = ERANGE;
115 res = NULL;
118 else
120 *h_errnop = h_errno;
123 pthread_mutex_unlock(&getrtl_mutex);
125 return res;
127 #endif // OSX || IOS || OPENBSD || NETBSD
129 #if defined(MACOSX)
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)
136 FSRef aFSRef;
137 OSStatus nErr;
138 Boolean bFolder;
139 Boolean bAliased;
140 char *unprocessedPath = path;
142 if ( *unprocessedPath == '/' )
143 unprocessedPath++;
145 int nRet = 0;
146 while ( !nRet && unprocessedPath && *unprocessedPath )
148 unprocessedPath = strchr( unprocessedPath, '/' );
149 if ( unprocessedPath )
150 *unprocessedPath = '\0';
152 nErr = noErr;
153 bFolder = FALSE;
154 bAliased = FALSE;
155 if ( FSPathMakeRef( (const UInt8 *)path, &aFSRef, 0 ) == noErr )
157 nErr = FSResolveAliasFileWithMountFlags( &aFSRef, TRUE, &bFolder, &bAliased, kResolveAliasFileNoUI );
158 if ( nErr == nsvErr )
160 errno = ENOENT;
161 nRet = -1;
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);
184 else
186 errno = ENAMETOOLONG;
187 nRet = -1;
193 if ( unprocessedPath )
194 *unprocessedPath++ = '/';
197 return nRet;
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)
225 if (pid == -1)
226 pid = __getpid();
229 pid_t getpid(void)
231 if (pid == -1)
232 savePid();
234 return (pid);
236 #endif /* defined LINUX */
238 #ifdef NO_PTHREAD_SEMAPHORES
239 int sem_init(sem_t* sem, int pshared, unsigned int value)
241 (void)pshared;
242 pthread_mutex_init(&sem->mutex, PTHREAD_MUTEXATTR_DEFAULT);
243 pthread_cond_init(&sem->increased, PTHREAD_CONDATTR_DEFAULT);
245 sem->value = (int)value;
246 return 0;
249 int sem_destroy(sem_t* sem)
251 pthread_mutex_destroy(&sem->mutex);
252 pthread_cond_destroy(&sem->increased);
253 sem->value = 0;
254 return 0;
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);
266 sem->value--;
267 pthread_mutex_unlock(&sem->mutex);
269 return 0;
272 int sem_trywait(sem_t* sem)
274 int result = 0;
276 pthread_mutex_lock(&sem->mutex);
278 if (sem->value > 0)
280 sem->value--;
282 else
284 errno = EAGAIN;
285 result = -1;
288 pthread_mutex_unlock(&sem->mutex);
290 return result;
293 int sem_post(sem_t* sem)
295 pthread_mutex_lock(&sem->mutex);
297 sem->value++;
299 pthread_mutex_unlock(&sem->mutex);
301 pthread_cond_signal(&sem->increased);
303 return 0;
305 #endif
307 #if defined(FREEBSD)
308 char *fcvt(double value, int ndigit, int *decpt, int *sign)
310 static char ret[256];
311 char buf[256],zahl[256],format[256]="%";
312 char *v1,*v2;
314 if (value==0.0) value=1e-30;
316 if (value<0.0) *sign=1; else *sign=0;
318 if (value<1.0)
320 *decpt=(int)log10(value);
321 value*=pow(10.0,1-*decpt);
322 ndigit+=*decpt-1;
323 if (ndigit<0) ndigit=0;
325 else
327 *decpt=(int)log10(value)+1;
330 sprintf(zahl,"%d",ndigit);
331 strcat(format,zahl);
332 strcat(format,".");
333 strcat(format,zahl);
334 strcat(format,"f");
336 sprintf(buf,format,value);
338 if (ndigit!=0)
340 v1=strtok(buf,".");
341 v2=strtok(NULL,".");
342 strcpy(ret,v1);
343 strcat(ret,v2);
345 else
347 strcpy(ret,buf);
350 return(ret);
353 #endif
355 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */