| OLD | NEW |
| (Empty) |
| 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 | |
| 7 ** NOTE! The following LGPL license applies to the replace | |
| 8 ** library. This does NOT imply that all of Samba is released | |
| 9 ** under the LGPL | |
| 10 | |
| 11 This library is free software; you can redistribute it and/or | |
| 12 modify it under the terms of the GNU Lesser General Public | |
| 13 License as published by the Free Software Foundation; either | |
| 14 version 3 of the License, or (at your option) any later version. | |
| 15 | |
| 16 This library 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 GNU | |
| 19 Lesser General Public License for more details. | |
| 20 | |
| 21 You should have received a copy of the GNU Lesser General Public | |
| 22 License along with this library; if not, see <http://www.gnu.org/licenses/>. | |
| 23 */ | |
| 24 | |
| 25 #include "replace.h" | |
| 26 | |
| 27 #include "system/filesys.h" | |
| 28 #include "system/time.h" | |
| 29 #include "system/passwd.h" | |
| 30 #include "system/syslog.h" | |
| 31 #include "system/locale.h" | |
| 32 #include "system/wait.h" | |
| 33 | |
| 34 #ifdef _WIN32 | |
| 35 #define mkdir(d,m) _mkdir(d) | |
| 36 #endif | |
| 37 | |
| 38 void replace_dummy(void); | |
| 39 void replace_dummy(void) {} | |
| 40 | |
| 41 #ifndef HAVE_FTRUNCATE | |
| 42 /******************************************************************* | |
| 43 ftruncate for operating systems that don't have it | |
| 44 ********************************************************************/ | |
| 45 int rep_ftruncate(int f, off_t l) | |
| 46 { | |
| 47 #ifdef HAVE_CHSIZE | |
| 48 return chsize(f,l); | |
| 49 #elif defined(F_FREESP) | |
| 50 struct flock fl; | |
| 51 | |
| 52 fl.l_whence = 0; | |
| 53 fl.l_len = 0; | |
| 54 fl.l_start = l; | |
| 55 fl.l_type = F_WRLCK; | |
| 56 return fcntl(f, F_FREESP, &fl); | |
| 57 #else | |
| 58 #error "you must have a ftruncate function" | |
| 59 #endif | |
| 60 } | |
| 61 #endif /* HAVE_FTRUNCATE */ | |
| 62 | |
| 63 | |
| 64 #ifndef HAVE_STRLCPY | |
| 65 /* like strncpy but does not 0 fill the buffer and always null | |
| 66 terminates. bufsize is the size of the destination buffer */ | |
| 67 size_t rep_strlcpy(char *d, const char *s, size_t bufsize) | |
| 68 { | |
| 69 size_t len = strlen(s); | |
| 70 size_t ret = len; | |
| 71 if (bufsize <= 0) return 0; | |
| 72 if (len >= bufsize) len = bufsize-1; | |
| 73 memcpy(d, s, len); | |
| 74 d[len] = 0; | |
| 75 return ret; | |
| 76 } | |
| 77 #endif | |
| 78 | |
| 79 #ifndef HAVE_STRLCAT | |
| 80 /* like strncat but does not 0 fill the buffer and always null | |
| 81 terminates. bufsize is the length of the buffer, which should | |
| 82 be one more than the maximum resulting string length */ | |
| 83 size_t rep_strlcat(char *d, const char *s, size_t bufsize) | |
| 84 { | |
| 85 size_t len1 = strlen(d); | |
| 86 size_t len2 = strlen(s); | |
| 87 size_t ret = len1 + len2; | |
| 88 | |
| 89 if (len1+len2 >= bufsize) { | |
| 90 if (bufsize < (len1+1)) { | |
| 91 return ret; | |
| 92 } | |
| 93 len2 = bufsize - (len1+1); | |
| 94 } | |
| 95 if (len2 > 0) { | |
| 96 memcpy(d+len1, s, len2); | |
| 97 d[len1+len2] = 0; | |
| 98 } | |
| 99 return ret; | |
| 100 } | |
| 101 #endif | |
| 102 | |
| 103 #ifndef HAVE_MKTIME | |
| 104 /******************************************************************* | |
| 105 a mktime() replacement for those who don't have it - contributed by | |
| 106 C.A. Lademann <cal@zls.com> | |
| 107 Corrections by richard.kettlewell@kewill.com | |
| 108 ********************************************************************/ | |
| 109 | |
| 110 #define MINUTE 60 | |
| 111 #define HOUR 60*MINUTE | |
| 112 #define DAY 24*HOUR | |
| 113 #define YEAR 365*DAY | |
| 114 time_t rep_mktime(struct tm *t) | |
| 115 { | |
| 116 struct tm *u; | |
| 117 time_t epoch = 0; | |
| 118 int n; | |
| 119 int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, | |
| 120 y, m, i; | |
| 121 | |
| 122 if(t->tm_year < 70) | |
| 123 return((time_t)-1); | |
| 124 | |
| 125 n = t->tm_year + 1900 - 1; | |
| 126 epoch = (t->tm_year - 70) * YEAR + | |
| 127 ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY; | |
| 128 | |
| 129 y = t->tm_year + 1900; | |
| 130 m = 0; | |
| 131 | |
| 132 for(i = 0; i < t->tm_mon; i++) { | |
| 133 epoch += mon [m] * DAY; | |
| 134 if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) | |
| 135 epoch += DAY; | |
| 136 | |
| 137 if(++m > 11) { | |
| 138 m = 0; | |
| 139 y++; | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 epoch += (t->tm_mday - 1) * DAY; | |
| 144 epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec; | |
| 145 | |
| 146 if((u = localtime(&epoch)) != NULL) { | |
| 147 t->tm_sec = u->tm_sec; | |
| 148 t->tm_min = u->tm_min; | |
| 149 t->tm_hour = u->tm_hour; | |
| 150 t->tm_mday = u->tm_mday; | |
| 151 t->tm_mon = u->tm_mon; | |
| 152 t->tm_year = u->tm_year; | |
| 153 t->tm_wday = u->tm_wday; | |
| 154 t->tm_yday = u->tm_yday; | |
| 155 t->tm_isdst = u->tm_isdst; | |
| 156 } | |
| 157 | |
| 158 return(epoch); | |
| 159 } | |
| 160 #endif /* !HAVE_MKTIME */ | |
| 161 | |
| 162 | |
| 163 #ifndef HAVE_INITGROUPS | |
| 164 /**************************************************************************** | |
| 165 some systems don't have an initgroups call | |
| 166 ****************************************************************************/ | |
| 167 int rep_initgroups(char *name, gid_t id) | |
| 168 { | |
| 169 #ifndef HAVE_SETGROUPS | |
| 170 /* yikes! no SETGROUPS or INITGROUPS? how can this work? */ | |
| 171 errno = ENOSYS; | |
| 172 return -1; | |
| 173 #else /* HAVE_SETGROUPS */ | |
| 174 | |
| 175 #include <grp.h> | |
| 176 | |
| 177 gid_t *grouplst = NULL; | |
| 178 int max_gr = NGROUPS_MAX; | |
| 179 int ret; | |
| 180 int i,j; | |
| 181 struct group *g; | |
| 182 char *gr; | |
| 183 | |
| 184 if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) { | |
| 185 errno = ENOMEM; | |
| 186 return -1; | |
| 187 } | |
| 188 | |
| 189 grouplst[0] = id; | |
| 190 i = 1; | |
| 191 while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group
*)NULL)) { | |
| 192 if (g->gr_gid == id) | |
| 193 continue; | |
| 194 j = 0; | |
| 195 gr = g->gr_mem[0]; | |
| 196 while (gr && (*gr != (char)NULL)) { | |
| 197 if (strcmp(name,gr) == 0) { | |
| 198 grouplst[i] = g->gr_gid; | |
| 199 i++; | |
| 200 gr = (char *)NULL; | |
| 201 break; | |
| 202 } | |
| 203 gr = g->gr_mem[++j]; | |
| 204 } | |
| 205 } | |
| 206 endgrent(); | |
| 207 ret = setgroups(i, grouplst); | |
| 208 free(grouplst); | |
| 209 return ret; | |
| 210 #endif /* HAVE_SETGROUPS */ | |
| 211 } | |
| 212 #endif /* HAVE_INITGROUPS */ | |
| 213 | |
| 214 | |
| 215 #if (defined(SecureWare) && defined(SCO)) | |
| 216 /* This is needed due to needing the nap() function but we don't want | |
| 217 to include the Xenix libraries since that will break other things... | |
| 218 BTW: system call # 0x0c28 is the same as calling nap() */ | |
| 219 long nap(long milliseconds) { | |
| 220 return syscall(0x0c28, milliseconds); | |
| 221 } | |
| 222 #endif | |
| 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 completly hopeless */ | |
| 413 char *p = mktemp(template); | |
| 414 if (!p) | |
| 415 return -1; | |
| 416 return open(p, 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 #ifndef HAVE_STRTOLL | |
| 506 long long int rep_strtoll(const char *str, char **endptr, int base) | |
| 507 { | |
| 508 #ifdef HAVE_STRTOQ | |
| 509 return strtoq(str, endptr, base); | |
| 510 #elif defined(HAVE___STRTOLL) | |
| 511 return __strtoll(str, endptr, base); | |
| 512 #elif SIZEOF_LONG == SIZEOF_LONG_LONG | |
| 513 return (long long int) strtol(str, endptr, base); | |
| 514 #else | |
| 515 # error "You need a strtoll function" | |
| 516 #endif | |
| 517 } | |
| 518 #endif | |
| 519 | |
| 520 | |
| 521 #ifndef HAVE_STRTOULL | |
| 522 unsigned long long int rep_strtoull(const char *str, char **endptr, int base) | |
| 523 { | |
| 524 #ifdef HAVE_STRTOUQ | |
| 525 return strtouq(str, endptr, base); | |
| 526 #elif defined(HAVE___STRTOULL) | |
| 527 return __strtoull(str, endptr, base); | |
| 528 #elif SIZEOF_LONG == SIZEOF_LONG_LONG | |
| 529 return (unsigned long long int) strtoul(str, endptr, base); | |
| 530 #else | |
| 531 # error "You need a strtoull function" | |
| 532 #endif | |
| 533 } | |
| 534 #endif | |
| 535 | |
| 536 #ifndef HAVE_SETENV | |
| 537 int rep_setenv(const char *name, const char *value, int overwrite) | |
| 538 { | |
| 539 char *p; | |
| 540 size_t l1, l2; | |
| 541 int ret; | |
| 542 | |
| 543 if (!overwrite && getenv(name)) { | |
| 544 return 0; | |
| 545 } | |
| 546 | |
| 547 l1 = strlen(name); | |
| 548 l2 = strlen(value); | |
| 549 | |
| 550 p = malloc(l1+l2+2); | |
| 551 if (p == NULL) { | |
| 552 return -1; | |
| 553 } | |
| 554 memcpy(p, name, l1); | |
| 555 p[l1] = '='; | |
| 556 memcpy(p+l1+1, value, l2); | |
| 557 p[l1+l2+1] = 0; | |
| 558 | |
| 559 ret = putenv(p); | |
| 560 if (ret != 0) { | |
| 561 free(p); | |
| 562 } | |
| 563 | |
| 564 return ret; | |
| 565 } | |
| 566 #endif | |
| 567 | |
| 568 #ifndef HAVE_UNSETENV | |
| 569 int rep_unsetenv(const char *name) | |
| 570 { | |
| 571 extern char **environ; | |
| 572 size_t len = strlen(name); | |
| 573 size_t i, count; | |
| 574 | |
| 575 if (environ == NULL || getenv(name) == NULL) { | |
| 576 return 0; | |
| 577 } | |
| 578 | |
| 579 for (i=0;environ[i];i++) /* noop */ ; | |
| 580 | |
| 581 count=i; | |
| 582 | |
| 583 for (i=0;i<count;) { | |
| 584 if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=
') { | |
| 585 /* note: we do _not_ free the old variable here. It is u
nsafe to | |
| 586 do so, as the pointer may not have come from malloc *
/ | |
| 587 memmove(&environ[i], &environ[i+1], (count-i)*sizeof(cha
r *)); | |
| 588 count--; | |
| 589 } else { | |
| 590 i++; | |
| 591 } | |
| 592 } | |
| 593 | |
| 594 return 0; | |
| 595 } | |
| 596 #endif | |
| 597 | |
| 598 #ifndef HAVE_UTIME | |
| 599 int rep_utime(const char *filename, const struct utimbuf *buf) | |
| 600 { | |
| 601 errno = ENOSYS; | |
| 602 return -1; | |
| 603 } | |
| 604 #endif | |
| 605 | |
| 606 #ifndef HAVE_UTIMES | |
| 607 int rep_utimes(const char *filename, const struct timeval tv[2]) | |
| 608 { | |
| 609 struct utimbuf u; | |
| 610 | |
| 611 u.actime = tv[0].tv_sec; | |
| 612 if (tv[0].tv_usec > 500000) { | |
| 613 u.actime += 1; | |
| 614 } | |
| 615 | |
| 616 u.modtime = tv[1].tv_sec; | |
| 617 if (tv[1].tv_usec > 500000) { | |
| 618 u.modtime += 1; | |
| 619 } | |
| 620 | |
| 621 return utime(filename, &u); | |
| 622 } | |
| 623 #endif | |
| 624 | |
| 625 #ifndef HAVE_DUP2 | |
| 626 int rep_dup2(int oldfd, int newfd) | |
| 627 { | |
| 628 errno = ENOSYS; | |
| 629 return -1; | |
| 630 } | |
| 631 #endif | |
| 632 | |
| 633 #ifndef HAVE_CHOWN | |
| 634 /** | |
| 635 chown isn't used much but OS/2 doesn't have it | |
| 636 **/ | |
| 637 int rep_chown(const char *fname, uid_t uid, gid_t gid) | |
| 638 { | |
| 639 errno = ENOSYS; | |
| 640 return -1; | |
| 641 } | |
| 642 #endif | |
| 643 | |
| 644 #ifndef HAVE_LINK | |
| 645 int rep_link(const char *oldpath, const char *newpath) | |
| 646 { | |
| 647 errno = ENOSYS; | |
| 648 return -1; | |
| 649 } | |
| 650 #endif | |
| 651 | |
| 652 #ifndef HAVE_READLINK | |
| 653 int rep_readlink(const char *path, char *buf, size_t bufsiz) | |
| 654 { | |
| 655 errno = ENOSYS; | |
| 656 return -1; | |
| 657 } | |
| 658 #endif | |
| 659 | |
| 660 #ifndef HAVE_SYMLINK | |
| 661 int rep_symlink(const char *oldpath, const char *newpath) | |
| 662 { | |
| 663 errno = ENOSYS; | |
| 664 return -1; | |
| 665 } | |
| 666 #endif | |
| 667 | |
| 668 #ifndef HAVE_LCHOWN | |
| 669 int rep_lchown(const char *fname,uid_t uid,gid_t gid) | |
| 670 { | |
| 671 errno = ENOSYS; | |
| 672 return -1; | |
| 673 } | |
| 674 #endif | |
| 675 | |
| 676 #ifndef HAVE_REALPATH | |
| 677 char *rep_realpath(const char *path, char *resolved_path) | |
| 678 { | |
| 679 /* As realpath is not a system call we can't return ENOSYS. */ | |
| 680 errno = EINVAL; | |
| 681 return NULL; | |
| 682 } | |
| 683 #endif | |
| OLD | NEW |