lib/replace: fix PTHREAD_MUTEX_ROBUST fallback to PTHREAD_MUTEX_ROBUST_NP on solaris 11
[kamenim/samba-autobuild/.git] / lib / replace / replace.c
1 /* 
2    Unix SMB/CIFS implementation.
3    replacement routines for broken systems
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jelmer Vernooij 2005-2008
6    Copyright (C) Matthieu Patou  2010
7
8      ** NOTE! The following LGPL license applies to the replace
9      ** library. This does NOT imply that all of Samba is released
10      ** under the LGPL
11    
12    This library is free software; you can redistribute it and/or
13    modify it under the terms of the GNU Lesser General Public
14    License as published by the Free Software Foundation; either
15    version 3 of the License, or (at your option) any later version.
16
17    This library is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    Lesser General Public License for more details.
21
22    You should have received a copy of the GNU Lesser General Public
23    License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "replace.h"
27
28 #include "system/filesys.h"
29 #include "system/time.h"
30 #include "system/network.h"
31 #include "system/passwd.h"
32 #include "system/syslog.h"
33 #include "system/locale.h"
34 #include "system/wait.h"
35
36 #ifdef _WIN32
37 #define mkdir(d,m) _mkdir(d)
38 #endif
39
40 void replace_dummy(void);
41 void replace_dummy(void) {}
42
43 #ifndef HAVE_FTRUNCATE
44  /*******************************************************************
45 ftruncate for operating systems that don't have it
46 ********************************************************************/
47 int rep_ftruncate(int f, off_t l)
48 {
49 #ifdef HAVE_CHSIZE
50       return chsize(f,l);
51 #elif defined(F_FREESP)
52       struct  flock   fl;
53
54       fl.l_whence = 0;
55       fl.l_len = 0;
56       fl.l_start = l;
57       fl.l_type = F_WRLCK;
58       return fcntl(f, F_FREESP, &fl);
59 #else
60 #error "you must have a ftruncate function"
61 #endif
62 }
63 #endif /* HAVE_FTRUNCATE */
64
65
66 #ifndef HAVE_STRLCPY
67 /*
68  * Like strncpy but does not 0 fill the buffer and always null
69  * terminates. bufsize is the size of the destination buffer.
70  * Returns the length of s.
71  */
72 size_t rep_strlcpy(char *d, const char *s, size_t bufsize)
73 {
74         size_t len = strlen(s);
75         size_t ret = len;
76
77         if (bufsize <= 0) {
78                 return 0;
79         }
80         if (len >= bufsize) {
81                 len = bufsize - 1;
82         }
83         memcpy(d, s, len);
84         d[len] = 0;
85         return ret;
86 }
87 #endif
88
89 #ifndef HAVE_STRLCAT
90 /* like strncat but does not 0 fill the buffer and always null 
91    terminates. bufsize is the length of the buffer, which should
92    be one more than the maximum resulting string length */
93 size_t rep_strlcat(char *d, const char *s, size_t bufsize)
94 {
95         size_t len1 = strnlen(d, bufsize);
96         size_t len2 = strlen(s);
97         size_t ret = len1 + len2;
98
99         if (len1+len2 >= bufsize) {
100                 if (bufsize < (len1+1)) {
101                         return ret;
102                 }
103                 len2 = bufsize - (len1+1);
104         }
105         if (len2 > 0) {
106                 memcpy(d+len1, s, len2);
107                 d[len1+len2] = 0;
108         }
109         return ret;
110 }
111 #endif
112
113 #ifndef HAVE_MKTIME
114 /*******************************************************************
115 a mktime() replacement for those who don't have it - contributed by 
116 C.A. Lademann <cal@zls.com>
117 Corrections by richard.kettlewell@kewill.com
118 ********************************************************************/
119
120 #define  MINUTE  60
121 #define  HOUR    60*MINUTE
122 #define  DAY             24*HOUR
123 #define  YEAR    365*DAY
124 time_t rep_mktime(struct tm *t)
125 {
126   struct tm       *u;
127   time_t  epoch = 0;
128   int n;
129   int             mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
130   y, m, i;
131
132   if(t->tm_year < 70)
133     return((time_t)-1);
134
135   n = t->tm_year + 1900 - 1;
136   epoch = (t->tm_year - 70) * YEAR + 
137     ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY;
138
139   y = t->tm_year + 1900;
140   m = 0;
141
142   for(i = 0; i < t->tm_mon; i++) {
143     epoch += mon [m] * DAY;
144     if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
145       epoch += DAY;
146     
147     if(++m > 11) {
148       m = 0;
149       y++;
150     }
151   }
152
153   epoch += (t->tm_mday - 1) * DAY;
154   epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
155   
156   if((u = localtime(&epoch)) != NULL) {
157     t->tm_sec = u->tm_sec;
158     t->tm_min = u->tm_min;
159     t->tm_hour = u->tm_hour;
160     t->tm_mday = u->tm_mday;
161     t->tm_mon = u->tm_mon;
162     t->tm_year = u->tm_year;
163     t->tm_wday = u->tm_wday;
164     t->tm_yday = u->tm_yday;
165     t->tm_isdst = u->tm_isdst;
166   }
167
168   return(epoch);
169 }
170 #endif /* !HAVE_MKTIME */
171
172
173 #ifndef HAVE_INITGROUPS
174 /****************************************************************************
175  some systems don't have an initgroups call 
176 ****************************************************************************/
177 int rep_initgroups(char *name, gid_t id)
178 {
179 #ifndef HAVE_SETGROUPS
180         /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
181         errno = ENOSYS;
182         return -1;
183 #else /* HAVE_SETGROUPS */
184
185 #include <grp.h>
186
187         gid_t *grouplst = NULL;
188         int max_gr = NGROUPS_MAX;
189         int ret;
190         int    i,j;
191         struct group *g;
192         char   *gr;
193         
194         if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) {
195                 errno = ENOMEM;
196                 return -1;
197         }
198
199         grouplst[0] = id;
200         i = 1;
201         while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
202                 if (g->gr_gid == id)
203                         continue;
204                 j = 0;
205                 gr = g->gr_mem[0];
206                 while (gr && (*gr != (char)NULL)) {
207                         if (strcmp(name,gr) == 0) {
208                                 grouplst[i] = g->gr_gid;
209                                 i++;
210                                 gr = (char *)NULL;
211                                 break;
212                         }
213                         gr = g->gr_mem[++j];
214                 }
215         }
216         endgrent();
217         ret = setgroups(i, grouplst);
218         free(grouplst);
219         return ret;
220 #endif /* HAVE_SETGROUPS */
221 }
222 #endif /* HAVE_INITGROUPS */
223
224
225 #ifndef HAVE_MEMMOVE
226 /*******************************************************************
227 safely copies memory, ensuring no overlap problems.
228 this is only used if the machine does not have its own memmove().
229 this is not the fastest algorithm in town, but it will do for our
230 needs.
231 ********************************************************************/
232 void *rep_memmove(void *dest,const void *src,int size)
233 {
234         unsigned long d,s;
235         int i;
236         if (dest==src || !size) return(dest);
237
238         d = (unsigned long)dest;
239         s = (unsigned long)src;
240
241         if ((d >= (s+size)) || (s >= (d+size))) {
242                 /* no overlap */
243                 memcpy(dest,src,size);
244                 return(dest);
245         }
246
247         if (d < s) {
248                 /* we can forward copy */
249                 if (s-d >= sizeof(int) && 
250                     !(s%sizeof(int)) && 
251                     !(d%sizeof(int)) && 
252                     !(size%sizeof(int))) {
253                         /* do it all as words */
254                         int *idest = (int *)dest;
255                         int *isrc = (int *)src;
256                         size /= sizeof(int);
257                         for (i=0;i<size;i++) idest[i] = isrc[i];
258                 } else {
259                         /* simplest */
260                         char *cdest = (char *)dest;
261                         char *csrc = (char *)src;
262                         for (i=0;i<size;i++) cdest[i] = csrc[i];
263                 }
264         } else {
265                 /* must backward copy */
266                 if (d-s >= sizeof(int) && 
267                     !(s%sizeof(int)) && 
268                     !(d%sizeof(int)) && 
269                     !(size%sizeof(int))) {
270                         /* do it all as words */
271                         int *idest = (int *)dest;
272                         int *isrc = (int *)src;
273                         size /= sizeof(int);
274                         for (i=size-1;i>=0;i--) idest[i] = isrc[i];
275                 } else {
276                         /* simplest */
277                         char *cdest = (char *)dest;
278                         char *csrc = (char *)src;
279                         for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
280                 }      
281         }
282         return(dest);
283 }
284 #endif /* HAVE_MEMMOVE */
285
286 #ifndef HAVE_STRDUP
287 /****************************************************************************
288 duplicate a string
289 ****************************************************************************/
290 char *rep_strdup(const char *s)
291 {
292         size_t len;
293         char *ret;
294
295         if (!s) return(NULL);
296
297         len = strlen(s)+1;
298         ret = (char *)malloc(len);
299         if (!ret) return(NULL);
300         memcpy(ret,s,len);
301         return(ret);
302 }
303 #endif /* HAVE_STRDUP */
304
305 #ifndef HAVE_SETLINEBUF
306 void rep_setlinebuf(FILE *stream)
307 {
308         setvbuf(stream, (char *)NULL, _IOLBF, 0);
309 }
310 #endif /* HAVE_SETLINEBUF */
311
312 #ifndef HAVE_VSYSLOG
313 #ifdef HAVE_SYSLOG
314 void rep_vsyslog (int facility_priority, const char *format, va_list arglist)
315 {
316         char *msg = NULL;
317         vasprintf(&msg, format, arglist);
318         if (!msg)
319                 return;
320         syslog(facility_priority, "%s", msg);
321         free(msg);
322 }
323 #endif /* HAVE_SYSLOG */
324 #endif /* HAVE_VSYSLOG */
325
326 #ifndef HAVE_STRNLEN
327 /**
328  Some platforms don't have strnlen
329 **/
330  size_t rep_strnlen(const char *s, size_t max)
331 {
332         size_t len;
333   
334         for (len = 0; len < max; len++) {
335                 if (s[len] == '\0') {
336                         break;
337                 }
338         }
339         return len;  
340 }
341 #endif
342   
343 #ifndef HAVE_STRNDUP
344 /**
345  Some platforms don't have strndup.
346 **/
347 char *rep_strndup(const char *s, size_t n)
348 {
349         char *ret;
350         
351         n = strnlen(s, n);
352         ret = malloc(n+1);
353         if (!ret)
354                 return NULL;
355         memcpy(ret, s, n);
356         ret[n] = 0;
357
358         return ret;
359 }
360 #endif
361
362 #if !defined(HAVE_WAITPID) && defined(HAVE_WAIT4)
363 int rep_waitpid(pid_t pid,int *status,int options)
364 {
365   return wait4(pid, status, options, NULL);
366 }
367 #endif
368
369 #ifndef HAVE_SETEUID
370 int rep_seteuid(uid_t euid)
371 {
372 #ifdef HAVE_SETRESUID
373         return setresuid(-1, euid, -1);
374 #else
375         errno = ENOSYS;
376         return -1;
377 #endif
378 }
379 #endif
380
381 #ifndef HAVE_SETEGID
382 int rep_setegid(gid_t egid)
383 {
384 #ifdef HAVE_SETRESGID
385         return setresgid(-1, egid, -1);
386 #else
387         errno = ENOSYS;
388         return -1;
389 #endif
390 }
391 #endif
392
393 /*******************************************************************
394 os/2 also doesn't have chroot
395 ********************************************************************/
396 #ifndef HAVE_CHROOT
397 int rep_chroot(const char *dname)
398 {
399         errno = ENOSYS;
400         return -1;
401 }
402 #endif
403
404 /*****************************************************************
405  Possibly replace mkstemp if it is broken.
406 *****************************************************************/  
407
408 #ifndef HAVE_SECURE_MKSTEMP
409 int rep_mkstemp(char *template)
410 {
411         /* have a reasonable go at emulating it. Hope that
412            the system mktemp() isn't completely hopeless */
413         mktemp(template);
414         if (template[0] == 0)
415                 return -1;
416         return open(template, O_CREAT|O_EXCL|O_RDWR, 0600);
417 }
418 #endif
419
420 #ifndef HAVE_MKDTEMP
421 char *rep_mkdtemp(char *template)
422 {
423         char *dname;
424         
425         if ((dname = mktemp(template))) {
426                 if (mkdir(dname, 0700) >= 0) {
427                         return dname;
428                 }
429         }
430
431         return NULL;
432 }
433 #endif
434
435 /*****************************************************************
436  Watch out: this is not thread safe.
437 *****************************************************************/
438
439 #ifndef HAVE_PREAD
440 ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset)
441 {
442         if (lseek(__fd, __offset, SEEK_SET) != __offset) {
443                 return -1;
444         }
445         return read(__fd, __buf, __nbytes);
446 }
447 #endif
448
449 /*****************************************************************
450  Watch out: this is not thread safe.
451 *****************************************************************/
452
453 #ifndef HAVE_PWRITE
454 ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
455 {
456         if (lseek(__fd, __offset, SEEK_SET) != __offset) {
457                 return -1;
458         }
459         return write(__fd, __buf, __nbytes);
460 }
461 #endif
462
463 #ifndef HAVE_STRCASESTR
464 char *rep_strcasestr(const char *haystack, const char *needle)
465 {
466         const char *s;
467         size_t nlen = strlen(needle);
468         for (s=haystack;*s;s++) {
469                 if (toupper(*needle) == toupper(*s) &&
470                     strncasecmp(s, needle, nlen) == 0) {
471                         return (char *)((uintptr_t)s);
472                 }
473         }
474         return NULL;
475 }
476 #endif
477
478 #ifndef HAVE_STRTOK_R
479 /* based on GLIBC version, copyright Free Software Foundation */
480 char *rep_strtok_r(char *s, const char *delim, char **save_ptr)
481 {
482         char *token;
483
484         if (s == NULL) s = *save_ptr;
485
486         s += strspn(s, delim);
487         if (*s == '\0') {
488                 *save_ptr = s;
489                 return NULL;
490         }
491
492         token = s;
493         s = strpbrk(token, delim);
494         if (s == NULL) {
495                 *save_ptr = token + strlen(token);
496         } else {
497                 *s = '\0';
498                 *save_ptr = s + 1;
499         }
500
501         return token;
502 }
503 #endif
504
505
506 #ifndef HAVE_STRTOLL
507 long long int rep_strtoll(const char *str, char **endptr, int base)
508 {
509 #ifdef HAVE_STRTOQ
510         return strtoq(str, endptr, base);
511 #elif defined(HAVE___STRTOLL) 
512         return __strtoll(str, endptr, base);
513 #elif SIZEOF_LONG == SIZEOF_LONG_LONG
514         return (long long int) strtol(str, endptr, base);
515 #else
516 # error "You need a strtoll function"
517 #endif
518 }
519 #else
520 #ifdef HAVE_BSD_STRTOLL
521 #ifdef HAVE_STRTOQ
522 long long int rep_strtoll(const char *str, char **endptr, int base)
523 {
524         long long int nb = strtoq(str, endptr, base);
525         /* In linux EINVAL is only returned if base is not ok */
526         if (errno == EINVAL) {
527                 if (base == 0 || (base >1 && base <37)) {
528                         /* Base was ok so it's because we were not
529                          * able to make the convertion.
530                          * Let's reset errno.
531                          */
532                         errno = 0;
533                 }
534         }
535         return nb;
536 }
537 #else
538 #error "You need the strtoq function"
539 #endif /* HAVE_STRTOQ */
540 #endif /* HAVE_BSD_STRTOLL */
541 #endif /* HAVE_STRTOLL */
542
543
544 #ifndef HAVE_STRTOULL
545 unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
546 {
547 #ifdef HAVE_STRTOUQ
548         return strtouq(str, endptr, base);
549 #elif defined(HAVE___STRTOULL) 
550         return __strtoull(str, endptr, base);
551 #elif SIZEOF_LONG == SIZEOF_LONG_LONG
552         return (unsigned long long int) strtoul(str, endptr, base);
553 #else
554 # error "You need a strtoull function"
555 #endif
556 }
557 #else
558 #ifdef HAVE_BSD_STRTOLL
559 #ifdef HAVE_STRTOUQ
560 unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
561 {
562         unsigned long long int nb = strtouq(str, endptr, base);
563         /* In linux EINVAL is only returned if base is not ok */
564         if (errno == EINVAL) {
565                 if (base == 0 || (base >1 && base <37)) {
566                         /* Base was ok so it's because we were not
567                          * able to make the convertion.
568                          * Let's reset errno.
569                          */
570                         errno = 0;
571                 }
572         }
573         return nb;
574 }
575 #else
576 #error "You need the strtouq function"
577 #endif /* HAVE_STRTOUQ */
578 #endif /* HAVE_BSD_STRTOLL */
579 #endif /* HAVE_STRTOULL */
580
581 #ifndef HAVE_SETENV
582 int rep_setenv(const char *name, const char *value, int overwrite) 
583 {
584         char *p;
585         size_t l1, l2;
586         int ret;
587
588         if (!overwrite && getenv(name)) {
589                 return 0;
590         }
591
592         l1 = strlen(name);
593         l2 = strlen(value);
594
595         p = malloc(l1+l2+2);
596         if (p == NULL) {
597                 return -1;
598         }
599         memcpy(p, name, l1);
600         p[l1] = '=';
601         memcpy(p+l1+1, value, l2);
602         p[l1+l2+1] = 0;
603
604         ret = putenv(p);
605         if (ret != 0) {
606                 free(p);
607         }
608
609         return ret;
610 }
611 #endif
612
613 #ifndef HAVE_UNSETENV
614 int rep_unsetenv(const char *name)
615 {
616         extern char **environ;
617         size_t len = strlen(name);
618         size_t i, count;
619
620         if (environ == NULL || getenv(name) == NULL) {
621                 return 0;
622         }
623
624         for (i=0;environ[i];i++) /* noop */ ;
625
626         count=i;
627         
628         for (i=0;i<count;) {
629                 if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
630                         /* note: we do _not_ free the old variable here. It is unsafe to 
631                            do so, as the pointer may not have come from malloc */
632                         memmove(&environ[i], &environ[i+1], (count-i)*sizeof(char *));
633                         count--;
634                 } else {
635                         i++;
636                 }
637         }
638
639         return 0;
640 }
641 #endif
642
643 #ifndef HAVE_UTIME
644 int rep_utime(const char *filename, const struct utimbuf *buf)
645 {
646         errno = ENOSYS;
647         return -1;
648 }
649 #endif
650
651 #ifndef HAVE_UTIMES
652 int rep_utimes(const char *filename, const struct timeval tv[2])
653 {
654         struct utimbuf u;
655
656         u.actime = tv[0].tv_sec;
657         if (tv[0].tv_usec > 500000) {
658                 u.actime += 1;
659         }
660
661         u.modtime = tv[1].tv_sec;
662         if (tv[1].tv_usec > 500000) {
663                 u.modtime += 1;
664         }
665
666         return utime(filename, &u);
667 }
668 #endif
669
670 #ifndef HAVE_DUP2
671 int rep_dup2(int oldfd, int newfd) 
672 {
673         errno = ENOSYS;
674         return -1;
675 }
676 #endif
677
678 #ifndef HAVE_CHOWN
679 /**
680 chown isn't used much but OS/2 doesn't have it
681 **/
682 int rep_chown(const char *fname, uid_t uid, gid_t gid)
683 {
684         errno = ENOSYS;
685         return -1;
686 }
687 #endif
688
689 #ifndef HAVE_LINK
690 int rep_link(const char *oldpath, const char *newpath)
691 {
692         errno = ENOSYS;
693         return -1;
694 }
695 #endif
696
697 #ifndef HAVE_READLINK
698 int rep_readlink(const char *path, char *buf, size_t bufsiz)
699 {
700         errno = ENOSYS;
701         return -1;
702 }
703 #endif
704
705 #ifndef HAVE_SYMLINK
706 int rep_symlink(const char *oldpath, const char *newpath)
707 {
708         errno = ENOSYS;
709         return -1;
710 }
711 #endif
712
713 #ifndef HAVE_LCHOWN
714 int rep_lchown(const char *fname,uid_t uid,gid_t gid)
715 {
716         errno = ENOSYS;
717         return -1;
718 }
719 #endif
720
721 #ifndef HAVE_REALPATH
722 char *rep_realpath(const char *path, char *resolved_path)
723 {
724         /* As realpath is not a system call we can't return ENOSYS. */
725         errno = EINVAL;
726         return NULL;
727 }
728 #endif
729
730
731 #ifndef HAVE_MEMMEM
732 void *rep_memmem(const void *haystack, size_t haystacklen,
733                  const void *needle, size_t needlelen)
734 {
735         if (needlelen == 0) {
736                 return discard_const(haystack);
737         }
738         while (haystacklen >= needlelen) {
739                 char *p = (char *)memchr(haystack, *(const char *)needle,
740                                          haystacklen-(needlelen-1));
741                 if (!p) return NULL;
742                 if (memcmp(p, needle, needlelen) == 0) {
743                         return p;
744                 }
745                 haystack = p+1;
746                 haystacklen -= (p - (const char *)haystack) + 1;
747         }
748         return NULL;
749 }
750 #endif
751
752 #if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF)
753 int rep_vdprintf(int fd, const char *format, va_list ap)
754 {
755         char *s = NULL;
756         int ret;
757
758         vasprintf(&s, format, ap);
759         if (s == NULL) {
760                 errno = ENOMEM;
761                 return -1;
762         }
763         ret = write(fd, s, strlen(s));
764         free(s);
765         return ret;
766 }
767 #endif
768
769 #if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF)
770 int rep_dprintf(int fd, const char *format, ...)
771 {
772         int ret;
773         va_list ap;
774
775         va_start(ap, format);
776         ret = vdprintf(fd, format, ap);
777         va_end(ap);
778
779         return ret;
780 }
781 #endif
782
783 #ifndef HAVE_GET_CURRENT_DIR_NAME
784 char *rep_get_current_dir_name(void)
785 {
786         char buf[PATH_MAX+1];
787         char *p;
788         p = getcwd(buf, sizeof(buf));
789         if (p == NULL) {
790                 return NULL;
791         }
792         return strdup(p);
793 }
794 #endif
795
796 #ifndef HAVE_STRERROR_R
797 int rep_strerror_r(int errnum, char *buf, size_t buflen)
798 {
799         char *s = strerror(errnum);
800         if (strlen(s)+1 > buflen) {
801                 errno = ERANGE;
802                 return -1;
803         }
804         strncpy(buf, s, buflen);
805         return 0;
806 }
807 #endif
808
809 #ifndef HAVE_CLOCK_GETTIME
810 int rep_clock_gettime(clockid_t clk_id, struct timespec *tp)
811 {
812         struct timeval tval;
813         switch (clk_id) {
814                 case 0: /* CLOCK_REALTIME :*/
815 #ifdef HAVE_GETTIMEOFDAY_TZ
816                         gettimeofday(&tval,NULL);
817 #else
818                         gettimeofday(&tval);
819 #endif
820                         tp->tv_sec = tval.tv_sec;
821                         tp->tv_nsec = tval.tv_usec * 1000;
822                         break;
823                 default:
824                         errno = EINVAL;
825                         return -1;
826         }
827         return 0;
828 }
829 #endif
830
831 #ifndef HAVE_MEMALIGN
832 void *rep_memalign( size_t align, size_t size )
833 {
834 #if defined(HAVE_POSIX_MEMALIGN)
835         void *p = NULL;
836         int ret = posix_memalign( &p, align, size );
837         if ( ret == 0 )
838                 return p;
839
840         return NULL;
841 #else
842         /* On *BSD systems memaligns doesn't exist, but memory will
843          * be aligned on allocations of > pagesize. */
844 #if defined(SYSCONF_SC_PAGESIZE)
845         size_t pagesize = (size_t)sysconf(_SC_PAGESIZE);
846 #elif defined(HAVE_GETPAGESIZE)
847         size_t pagesize = (size_t)getpagesize();
848 #else
849         size_t pagesize = (size_t)-1;
850 #endif
851         if (pagesize == (size_t)-1) {
852                 errno = ENOSYS;
853                 return NULL;
854         }
855         if (size < pagesize) {
856                 size = pagesize;
857         }
858         return malloc(size);
859 #endif
860 }
861 #endif
862
863 #ifndef HAVE_GETPEEREID
864 int rep_getpeereid(int s, uid_t *uid, gid_t *gid)
865 {
866 #if defined(HAVE_PEERCRED)
867         struct ucred cred;
868         socklen_t cred_len = sizeof(struct ucred);
869         int ret;
870
871 #undef getsockopt
872         ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
873         if (ret != 0) {
874                 return -1;
875         }
876
877         if (cred_len != sizeof(struct ucred)) {
878                 errno = EINVAL;
879                 return -1;
880         }
881
882         *uid = cred.uid;
883         *gid = cred.gid;
884         return 0;
885 #else
886         errno = ENOSYS;
887         return -1;
888 #endif
889 }
890 #endif
891
892 #ifndef HAVE_USLEEP
893 int rep_usleep(useconds_t sec)
894 {
895         struct timeval tval;
896         /*
897          * Fake it with select...
898          */
899         tval.tv_sec = 0;
900         tval.tv_usec = usecs/1000;
901         select(0,NULL,NULL,NULL,&tval);
902         return 0;
903 }
904 #endif /* HAVE_USLEEP */
905
906 #ifndef HAVE_SETPROCTITLE
907 void rep_setproctitle(const char *fmt, ...)
908 {
909 }
910 #endif