merged tag ooo/DEV300_m102
[LibreOffice.git] / sal / osl / unx / system.c
blob0ea3b819438c82cae87f342b9eb059d3e2f67667
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 ************************************************************************/
28 #include "system.h"
30 #ifdef NO_PTHREAD_RTL
32 static pthread_mutex_t getrtl_mutex = PTHREAD_MUTEX_INITIALIZER;
34 /* struct passwd differs on some platforms */
35 #if defined NETBSD
36 struct passwd *getpwnam_r(const char* name, struct passwd* s, char* buffer, int size )
38 struct passwd* res;
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);
58 s->pw_name = buffer;
59 buffer += nname;
61 strcpy(buffer, res->pw_passwd);
62 s->pw_passwd = buffer;
63 buffer += npasswd;
65 strcpy(buffer, res->pw_class);
66 s->pw_class = buffer;
67 buffer += nclass;
69 strcpy(buffer, res->pw_gecos);
70 s->pw_gecos = buffer;
71 buffer += ngecos;
73 strcpy(buffer, res->pw_dir);
74 s->pw_dir = buffer;
75 buffer += ndir;
77 strcpy(buffer, res->pw_shell);
78 s->pw_shell = buffer;
80 res = s;
82 else
83 res = 0;
86 pthread_mutex_unlock(&getrtl_mutex);
88 return(res);
91 int getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer,
92 size_t buflen, struct passwd **result)
94 struct passwd* res;
95 int retval = 0;
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;
117 buffer += pw_name;
119 strncpy(buffer, res->pw_passwd, pw_passwd);
120 pwd->pw_passwd = buffer;
121 buffer += pw_passwd;
123 strncpy(buffer, res->pw_class, pw_class);
124 pwd->pw_class = buffer;
125 buffer += pw_class;
127 strncpy(buffer, res->pw_gecos, pw_gecos);
128 pwd->pw_gecos = buffer;
129 buffer += pw_gecos;
131 strncpy(buffer, res->pw_dir, pw_dir);
132 pwd->pw_dir = buffer;
133 buffer += pw_dir;
135 strncpy(buffer, res->pw_shell, pw_shell);
136 pwd->pw_shell = buffer;
137 buffer += pw_shell;
139 *result = pwd ;
140 retval = 0 ;
143 else
144 retval = ENOMEM;
146 else
147 retval = errno ;
149 pthread_mutex_unlock(&getrtl_mutex);
151 return retval;
154 struct tm *localtime_r(const time_t *timep, struct tm *buffer)
156 struct tm* res;
158 pthread_mutex_lock(&getrtl_mutex);
160 if ( (res = localtime(timep)))
162 memcpy(buffer, res, sizeof(struct tm));
163 res = buffer;
166 pthread_mutex_unlock(&getrtl_mutex);
168 return res;
171 struct tm *gmtime_r(const time_t *timep, struct tm *buffer)
173 struct tm* res;
175 pthread_mutex_lock(&getrtl_mutex);
177 if ( (res = gmtime(timep)) )
179 memcpy(buffer, res, sizeof(struct tm));
180 res = buffer;
183 pthread_mutex_unlock(&getrtl_mutex);
185 return res;
187 #endif /* defined NETBSD */
189 #ifdef SCO
190 #include <pwd.h>
191 #include <shadow.h>
192 #include <sys/types.h>
194 struct spwd *getspnam_r(const char *name, struct spwd* s, char* buffer, int size )
196 struct spwd* res;
198 pthread_mutex_lock(&getrtl_mutex);
200 if ( res = getspnam(name) )
202 int nnamp;
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);
210 s->sp_namp = buffer;
211 buffer += nnamp;
213 strcpy(buffer, res->sp_pwdp);
214 s->sp_pwdp = buffer;
216 res = s;
218 else
219 res = 0;
222 pthread_mutex_unlock(&getrtl_mutex);
224 return res;
227 struct passwd *getpwnam_r(const char* name, struct passwd* s, char* buffer, int size )
229 struct passwd* res;
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);
251 s->pw_name = buffer;
252 buffer += nname;
254 strcpy(buffer, res->pw_passwd);
255 s->pw_passwd = buffer;
256 buffer += npasswd;
258 strcpy(buffer, res->pw_age);
259 s->pw_age = buffer;
260 buffer += nage;
262 strcpy(buffer, res->pw_comment);
263 s->pw_comment = buffer;
264 buffer += ncomment;
266 strcpy(buffer, res->pw_gecos);
267 s->pw_gecos = buffer;
268 buffer += ngecos;
270 strcpy(buffer, res->pw_dir);
271 s->pw_dir = buffer;
272 buffer += ndir;
274 strcpy(buffer, res->pw_shell);
275 s->pw_shell = buffer;
277 res = s;
279 else
280 res = 0;
283 pthread_mutex_unlock(&getrtl_mutex);
285 return res;
287 #endif /* defined SCO */
289 #if !defined(FREEBSD) || (__FreeBSD_version < 601103)
291 extern int h_errno;
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
298 * NULL
299 * alias1\0...aliasn\0
300 * array_of_pointer_to_addresses
301 * NULL
302 * addr1addr2addr3...addrn
304 struct hostent* res;
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.
316 * Is this required?
319 nname= strlen(res->h_name)+1;
321 naliases = naddr_list = naliasesdata = 0;
323 for ( p = res->h_aliases; *p != NULL; p++) {
324 naliases++;
325 naliasesdata += strlen(*p)+1;
328 for ( p = res->h_addr_list; *p != NULL; p++)
329 naddr_list++;
331 if ( nname
332 + (naliases+1)*sizeof(char*) + naliasesdata
333 + (naddr_list+1)*sizeof(char*) + naddr_list*res->h_length
334 <= buflen )
336 memcpy(result, res, sizeof(struct hostent));
338 strcpy(buffer, res->h_name);
339 result->h_name = buffer;
340 buffer += nname;
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++) {
346 n = strlen(*p)+1;
347 *parray++ = data;
348 memcpy(data, *p, n);
349 data += n;
351 *parray = NULL;
352 buffer = data;
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++) {
357 *parray++ = data;
358 memcpy(data, *p, res->h_length);
359 data += res->h_length;
361 *parray = NULL;
363 res = result;
365 else
367 errno = ERANGE;
368 res = NULL;
371 else
373 *h_errnop = h_errno;
376 pthread_mutex_unlock(&getrtl_mutex);
378 return res;
380 #endif /* !defined(FREEBSD) || (__FreeBSD_version < 601103) */
382 #if defined(MACOSX)
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)
389 FSRef aFSRef;
390 OSStatus nErr;
391 Boolean bFolder;
392 Boolean bAliased;
393 char *unprocessedPath = path;
395 if ( *unprocessedPath == '/' )
396 unprocessedPath++;
398 int nRet = 0;
399 while ( !nRet && unprocessedPath && *unprocessedPath )
401 unprocessedPath = strchr( unprocessedPath, '/' );
402 if ( unprocessedPath )
403 *unprocessedPath = '\0';
405 nErr = noErr;
406 bFolder = FALSE;
407 bAliased = FALSE;
408 if ( FSPathMakeRef( (const UInt8 *)path, &aFSRef, 0 ) == noErr )
410 nErr = FSResolveAliasFileWithMountFlags( &aFSRef, TRUE, &bFolder, &bAliased, kResolveAliasFileNoUI );
411 if ( nErr == nsvErr )
413 errno = ENOENT;
414 nRet = -1;
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);
437 else
439 errno = ENAMETOOLONG;
440 nRet = -1;
446 if ( unprocessedPath )
447 *unprocessedPath++ = '/';
450 return nRet;
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
460 pid at startup
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)
472 if (pid == -1)
473 pid = __getpid();
476 pid_t getpid(void)
478 if (pid == -1)
479 savePid();
481 return (pid);
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;
492 return 0;
495 int sem_destroy(sem_t* sem)
497 pthread_mutex_destroy(&sem->mutex);
498 pthread_cond_destroy(&sem->increased);
499 sem->value = 0;
500 return 0;
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);
512 sem->value--;
513 pthread_mutex_unlock(&sem->mutex);
515 return 0;
518 int sem_trywait(sem_t* sem)
520 int result = 0;
522 pthread_mutex_lock(&sem->mutex);
524 if (sem->value > 0)
526 sem->value--;
528 else
530 errno = EAGAIN;
531 result = -1;
534 pthread_mutex_unlock(&sem->mutex);
536 return result;
539 int sem_post(sem_t* sem)
541 pthread_mutex_lock(&sem->mutex);
543 sem->value++;
545 pthread_mutex_unlock(&sem->mutex);
547 pthread_cond_signal(&sem->increased);
549 return 0;
551 #endif
553 #if defined(FREEBSD)
554 char *fcvt(double value, int ndigit, int *decpt, int *sign)
556 static char ret[256];
557 char buf[256],zahl[256],format[256]="%";
558 char *v1,*v2;
560 if (value==0.0) value=1e-30;
562 if (value<0.0) *sign=1; else *sign=0;
564 if (value<1.0)
566 *decpt=(int)log10(value);
567 value*=pow(10.0,1-*decpt);
568 ndigit+=*decpt-1;
569 if (ndigit<0) ndigit=0;
571 else
573 *decpt=(int)log10(value)+1;
576 sprintf(zahl,"%d",ndigit);
577 strcat(format,zahl);
578 strcat(format,".");
579 strcat(format,zahl);
580 strcat(format,"f");
582 sprintf(buf,format,value);
584 if (ndigit!=0)
586 v1=strtok(buf,".");
587 v2=strtok(NULL,".");
588 strcpy(ret,v1);
589 strcat(ret,v2);
591 else
593 strcpy(ret,buf);
596 return(ret);
599 #endif