1/* 2 Unix SMB/Netbios implementation. 3 Version 2.0 4 SMB wrapper functions 5 Copyright (C) Andrew Tridgell 1998 6 Copyright (C) Derrell Lipman 2002-2005 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21*/ 22 23/* 24 * This is a rewrite of the original wrapped.c file, using libdl to obtain 25 * pointers into the C library rather than attempting to find undocumented 26 * functions in the C library to call for native file access. The problem 27 * with the original implementation's paradigm is that samba manipulates 28 * defines such that it gets the sizes of structures that it wants 29 * (e.g. mapping 32-bit functions to 64-bit functions with their associated 30 * 64-bit structure fields), but programs run under smbsh or using 31 * smbwrapper.so were not necessarily compiled with the same flags. As an 32 * example of the problem, a program calling stat() passes a pointer to a 33 * "struct stat" but the fields in that structure are different in samba than 34 * they are in the calling program if the calling program was not compiled to 35 * force stat() to be mapped to stat64(). 36 * 37 * In this version, we provide an interface to each of the native functions, 38 * not just the ones that samba is compiled to map to. We obtain the function 39 * pointers from the C library using dlsym(), and for native file operations, 40 * directly call the same function that the calling application was 41 * requesting. Since the size of the calling application's structures vary 42 * depending on what function was called, we use our own internal structures 43 * for passing information to/from the SMB equivalent functions, and map them 44 * back to the native structures before returning the result to the caller. 45 * 46 * This implementation was completed 25 December 2002. 47 * Derrell Lipman 48 */ 49 50/* We do not want auto munging of 32->64 bit names in this file (only) */ 51#undef _FILE_OFFSET_BITS 52#undef _GNU_SOURCE 53 54#include <sys/types.h> 55#include <sys/stat.h> 56#include <sys/time.h> 57#include <stdlib.h> 58#include <fcntl.h> 59#include <unistd.h> 60#include <utime.h> 61#include <stdio.h> 62#include <dirent.h> 63#include <signal.h> 64#include <stdarg.h> 65#ifdef __USE_GNU 66# define SMBW_USE_GNU 67#endif 68#define __USE_GNU /* need this to have RTLD_NEXT defined */ 69#include <dlfcn.h> 70#ifndef SMBW_USE_GNU 71# undef __USE_GNU 72#endif 73#include <errno.h> 74#include "libsmbclient.h" 75#include "bsd-strlfunc.h" 76#include "wrapper.h" 77 78/* 79 * Debug bits: 80 * 0x0 = none 81 * 0x1 = display symbol definitions not found in C library 82 * 0x2 = show wrapper functions being called 83 * 0x4 = log to file SMBW_DEBUG_FILE instead of stderr 84 */ 85#define SMBW_DEBUG 0x0 86#define SMBW_DEBUG_FILE "/tmp/smbw.log" 87 88int smbw_debug = 0; 89 90#if SMBW_DEBUG & 0x2 91static int debugFd = 2; 92#endif 93 94#ifndef ENOTSUP 95#define ENOTSUP EOPNOTSUPP 96#endif 97 98/* 99 * None of the methods of having the initialization function called 100 * automatically upon shared library startup are effective in all situations. 101 * We provide the "-init" parameter to the linker which is effective most of 102 * the time, but fails for applications that provide their own shared 103 * libraries with _init() functions (e.g. ps). We can't use "-z initfirst" 104 * because the environment isn't yet set up at that point, so we can't find 105 * our shared memory identifier (see shared.c). We therefore must resort to 106 * this tried-and-true method of keeping an "initialized" flag. We check it 107 * prior to calling the initialize() function to save a function call (a slow 108 * operation on x86). 109 */ 110#if SMBW_DEBUG & 0x2 111# define check_init(buf) \ 112 do { \ 113 int saved_errno = errno; \ 114 if (! initialized) initialize(); \ 115 (* smbw_libc.write)(debugFd, "["buf"]", sizeof(buf)+1); \ 116 errno = saved_errno; \ 117 } while (0) 118#else 119# define check_init(buf) \ 120 do { \ 121 if (! initialized) smbw_initialize(); \ 122 } while (0) 123#endif 124 125static void initialize(void); 126 127static int initialized = 0; 128 129SMBW_libc_pointers smbw_libc; 130 131/* 132 * A public entry point used by the "-init" option to the linker. 133 */ 134void smbw_initialize(void) 135{ 136 initialize(); 137} 138 139static void initialize(void) 140{ 141 int saved_errno; 142#if SMBW_DEBUG & 0x1 143 char *error; 144#endif 145 146 saved_errno = errno; 147 148 if (initialized) { 149 return; 150 } 151 initialized = 1; 152 153#if SMBW_DEBUG & 0x1 154# define GETSYM(symname, symstring) \ 155 if ((smbw_libc.symname = dlsym(RTLD_NEXT, symstring)) == NULL) { \ 156 if (smbw_libc.write != NULL && \ 157 (error = dlerror()) != NULL) { \ 158 (* smbw_libc.write)(1, error, strlen(error)); \ 159 (* smbw_libc.write)(1, "\n", 1); \ 160 } \ 161 } 162#else 163# define GETSYM(symname, symstring) \ 164 smbw_libc.symname = dlsym(RTLD_NEXT, symstring); 165#endif 166 167 /* 168 * Get pointers to each of the symbols we'll need, from the C library 169 * 170 * Some of these symbols may not be found in the C library. That's 171 * fine. We declare all of them here, and if the C library supports 172 * them, they may be called so we have the wrappers for them. If the 173 * C library doesn't support them, then the wrapper function will 174 * never be called, and the null pointer will never be dereferenced. 175 */ 176 GETSYM(write, "write"); /* first, to allow debugging */ 177 GETSYM(open, "open"); 178 GETSYM(_open, "_open"); 179 GETSYM(__open, "__open"); 180 GETSYM(open64, "open64"); 181 GETSYM(_open64, "_open64"); 182 GETSYM(__open64, "__open64"); 183 GETSYM(pread, "pread"); 184 GETSYM(pread64, "pread64"); 185 GETSYM(pwrite, "pwrite"); 186 GETSYM(pwrite64, "pwrite64"); 187 GETSYM(close, "close"); 188 GETSYM(__close, "__close"); 189 GETSYM(_close, "_close"); 190 GETSYM(fcntl, "fcntl"); 191 GETSYM(__fcntl, "__fcntl"); 192 GETSYM(_fcntl, "_fcntl"); 193 GETSYM(getdents, "getdents"); 194 GETSYM(__getdents, "__getdents"); 195 GETSYM(_getdents, "_getdents"); 196 GETSYM(getdents64, "getdents64"); 197 GETSYM(lseek, "lseek"); 198 GETSYM(__lseek, "__lseek"); 199 GETSYM(_lseek, "_lseek"); 200 GETSYM(lseek64, "lseek64"); 201 GETSYM(__lseek64, "__lseek64"); 202 GETSYM(_lseek64, "_lseek64"); 203 GETSYM(read, "read"); 204 GETSYM(__read, "__read"); 205 GETSYM(_read, "_read"); 206 GETSYM(__write, "__write"); 207 GETSYM(_write, "_write"); 208 GETSYM(access, "access"); 209 GETSYM(chmod, "chmod"); 210 GETSYM(fchmod, "fchmod"); 211 GETSYM(chown, "chown"); 212 GETSYM(fchown, "fchown"); 213 GETSYM(__xstat, "__xstat"); 214 GETSYM(getcwd, "getcwd"); 215 GETSYM(mkdir, "mkdir"); 216 GETSYM(__fxstat, "__fxstat"); 217 GETSYM(__lxstat, "__lxstat"); 218 GETSYM(stat, "stat"); 219 GETSYM(lstat, "lstat"); 220 GETSYM(fstat, "fstat"); 221 GETSYM(unlink, "unlink"); 222 GETSYM(utime, "utime"); 223 GETSYM(utimes, "utimes"); 224 GETSYM(readlink, "readlink"); 225 GETSYM(rename, "rename"); 226 GETSYM(rmdir, "rmdir"); 227 GETSYM(symlink, "symlink"); 228 GETSYM(dup, "dup"); 229 GETSYM(dup2, "dup2"); 230 GETSYM(opendir, "opendir"); 231 GETSYM(readdir, "readdir"); 232 GETSYM(closedir, "closedir"); 233 GETSYM(telldir, "telldir"); 234 GETSYM(seekdir, "seekdir"); 235 GETSYM(creat, "creat"); 236 GETSYM(creat64, "creat64"); 237 GETSYM(__xstat64, "__xstat64"); 238 GETSYM(stat64, "stat64"); 239 GETSYM(__fxstat64, "__fxstat64"); 240 GETSYM(fstat64, "fstat64"); 241 GETSYM(__lxstat64, "__lxstat64"); 242 GETSYM(lstat64, "lstat64"); 243 GETSYM(_llseek, "_llseek"); 244 GETSYM(readdir64, "readdir64"); 245 GETSYM(readdir_r, "readdir_r"); 246 GETSYM(readdir64_r, "readdir64_r"); 247 GETSYM(setxattr, "setxattr"); 248 GETSYM(lsetxattr, "lsetxattr"); 249 GETSYM(fsetxattr, "fsetxattr"); 250 GETSYM(getxattr, "getxattr"); 251 GETSYM(lgetxattr, "lgetxattr"); 252 GETSYM(fgetxattr, "fgetxattr"); 253 GETSYM(removexattr, "removexattr"); 254 GETSYM(lremovexattr, "lremovexattr"); 255 GETSYM(fremovexattr, "fremovexattr"); 256 GETSYM(listxattr, "listxattr"); 257 GETSYM(llistxattr, "llistxattr"); 258 GETSYM(flistxattr, "flistxattr"); 259 GETSYM(chdir, "chdir"); 260 GETSYM(fchdir, "fchdir"); 261 GETSYM(fork, "fork"); 262 GETSYM(select, "select"); 263 GETSYM(_select, "_select"); 264 GETSYM(__select, "__select"); 265 266#if SMBW_DEBUG & 4 267 { 268 if ((debugFd = 269 open(SMBW_DEBUG_FILE, O_WRONLY | O_CREAT | O_APPEND)) < 0) 270 { 271# define SMBW_MESSAGE "Could not create " SMBW_DEBUG_FILE "\n" 272 (* smbw_libc.write)(1, SMBW_MESSAGE, sizeof(SMBW_MESSAGE)); 273# undef SMBW_MESSAGE 274 exit(1); 275 } 276 } 277#endif 278 279 errno = saved_errno; 280} 281 282/** 283 ** Static Functions 284 **/ 285 286static void stat_convert(struct SMBW_stat *src, struct stat *dest) 287{ 288 memset(dest, '\0', sizeof(*dest)); 289 dest->st_size = src->s_size; 290 dest->st_mode = src->s_mode; 291 dest->st_ino = src->s_ino; 292 dest->st_dev = src->s_dev; 293 dest->st_rdev = src->s_rdev; 294 dest->st_nlink = src->s_nlink; 295 dest->st_uid = src->s_uid; 296 dest->st_gid = src->s_gid; 297 dest->st_atime = src->s_atime; 298 dest->st_mtime = src->s_mtime; 299 dest->st_ctime = src->s_ctime; 300 dest->st_blksize = src->s_blksize; 301 dest->st_blocks = src->s_blocks; 302} 303 304static void stat64_convert(struct SMBW_stat *src, struct stat64 *dest) 305{ 306 memset(dest, '\0', sizeof(*dest)); 307 dest->st_size = src->s_size; 308 dest->st_mode = src->s_mode; 309 dest->st_ino = src->s_ino; 310 dest->st_dev = src->s_dev; 311 dest->st_rdev = src->s_rdev; 312 dest->st_nlink = src->s_nlink; 313 dest->st_uid = src->s_uid; 314 dest->st_gid = src->s_gid; 315 dest->st_atime = src->s_atime; 316 dest->st_mtime = src->s_mtime; 317 dest->st_ctime = src->s_ctime; 318 dest->st_blksize = src->s_blksize; 319 dest->st_blocks = src->s_blocks; 320} 321 322static void dirent_convert(struct SMBW_dirent *src, struct dirent *dest) 323{ 324 char *p; 325 326 memset(dest, '\0', sizeof(*dest)); 327 dest->d_ino = src->d_ino; 328 dest->d_off = src->d_off; 329 330 switch(src->d_type) 331 { 332 case SMBC_WORKGROUP: 333 case SMBC_SERVER: 334 case SMBC_FILE_SHARE: 335 case SMBC_DIR: 336 dest->d_type = DT_DIR; 337 break; 338 339 case SMBC_FILE: 340 dest->d_type = DT_REG; 341 break; 342 343 case SMBC_PRINTER_SHARE: 344 dest->d_type = DT_CHR; 345 break; 346 347 case SMBC_COMMS_SHARE: 348 dest->d_type = DT_SOCK; 349 break; 350 351 case SMBC_IPC_SHARE: 352 dest->d_type = DT_FIFO; 353 break; 354 355 case SMBC_LINK: 356 dest->d_type = DT_LNK; 357 break; 358 } 359 360 dest->d_reclen = src->d_reclen; 361 smbw_strlcpy(dest->d_name, src->d_name, sizeof(dest->d_name)); 362 p = dest->d_name + strlen(dest->d_name) + 1; 363 smbw_strlcpy(p, 364 src->d_comment, 365 sizeof(dest->d_name) - (p - dest->d_name)); 366} 367 368static void dirent64_convert(struct SMBW_dirent *src, struct dirent64 *dest) 369{ 370 char *p; 371 372 memset(dest, '\0', sizeof(*dest)); 373 dest->d_ino = src->d_ino; 374 dest->d_off = src->d_off; 375 376 switch(src->d_type) 377 { 378 case SMBC_WORKGROUP: 379 case SMBC_SERVER: 380 case SMBC_FILE_SHARE: 381 case SMBC_DIR: 382 dest->d_type = DT_DIR; 383 break; 384 385 case SMBC_FILE: 386 dest->d_type = DT_REG; 387 break; 388 389 case SMBC_PRINTER_SHARE: 390 dest->d_type = DT_CHR; 391 break; 392 393 case SMBC_COMMS_SHARE: 394 dest->d_type = DT_SOCK; 395 break; 396 397 case SMBC_IPC_SHARE: 398 dest->d_type = DT_FIFO; 399 break; 400 401 case SMBC_LINK: 402 dest->d_type = DT_LNK; 403 break; 404 } 405 406 dest->d_reclen = src->d_reclen; 407 smbw_strlcpy(dest->d_name, src->d_name, sizeof(dest->d_name)); 408 p = dest->d_name + strlen(dest->d_name) + 1; 409 smbw_strlcpy(p, 410 src->d_comment, 411 sizeof(dest->d_name) - (p - dest->d_name)); 412} 413 414static int openx(char *name, int flags, mode_t mode, int (* f)(char *, int, mode_t)) 415{ 416 if (smbw_path(name)) { 417 return smbw_open(name, flags, mode); 418 } 419 420 return (* f)(name, flags, mode); 421} 422 423static int closex(int fd, int (* f)(int fd)) 424{ 425 if (smbw_fd(fd)) { 426 return smbw_close(fd); 427 } 428 429 return (* f)(fd); 430} 431 432static int fcntlx(int fd, int cmd, long arg, int (* f)(int, int, long)) 433{ 434 if (smbw_fd(fd)) { 435 return smbw_fcntl(fd, cmd, arg); 436 } 437 438 return (* f)(fd, cmd, arg); 439} 440 441static int getdentsx(int fd, struct dirent *external, unsigned int count, int (* f)(int, struct dirent *, unsigned int)) 442{ 443 if (smbw_fd(fd)) { 444 int i; 445 int internal_count; 446 struct SMBW_dirent *internal; 447 int ret; 448 int n; 449 450 /* 451 * LIMITATION: If they pass a count which is not a multiple of 452 * the size of struct dirent, they will not get a partial 453 * structure; we ignore the excess count. 454 */ 455 n = (count / sizeof(struct dirent)); 456 457 internal_count = sizeof(struct SMBW_dirent) * n; 458 internal = malloc(internal_count); 459 if (internal == NULL) { 460 errno = ENOMEM; 461 return -1; 462 } 463 ret = smbw_getdents(fd, internal, internal_count); 464 if (ret <= 0) 465 return ret; 466 467 ret = sizeof(struct dirent) * n; 468 469 for (i = 0; i < n; i++) 470 dirent_convert(&internal[i], &external[i]); 471 472 return ret; 473 } 474 475 return (* f)(fd, external, count); 476} 477 478static off_t lseekx(int fd, 479 off_t offset, 480 int whence, 481 off_t (* f)(int, off_t, int)) 482{ 483 off_t ret; 484 485 /* 486 * We have left the definitions of the smbw_ functions undefined, 487 * because types such as off_t can differ in meaning betweent his 488 * function and smbw.c et al. Functions that return other than an 489 * integer value, however, MUST have their return value defined. 490 */ 491 off64_t smbw_lseek(); 492 493 if (smbw_fd(fd)) { 494 return (off_t) smbw_lseek(fd, offset, whence); 495 } 496 497 ret = (* f)(fd, offset, whence); 498 if (smbw_debug) 499 { 500 printf("lseekx(%d, 0x%llx) returned 0x%llx\n", 501 fd, 502 (unsigned long long) offset, 503 (unsigned long long) ret); 504 } 505 return ret; 506} 507 508static off64_t lseek64x(int fd, 509 off64_t offset, 510 int whence, 511 off64_t (* f)(int, off64_t, int)) 512{ 513 off64_t ret; 514 515 /* 516 * We have left the definitions of the smbw_ functions undefined, 517 * because types such as off_t can differ in meaning betweent his 518 * function and smbw.c et al. Functions that return other than an 519 * integer value, however, MUST have their return value defined. 520 */ 521 off64_t smbw_lseek(); 522 523 if (smbw_fd(fd)) 524 ret = smbw_lseek(fd, offset, whence); 525 else 526 ret = (* f)(fd, offset, whence); 527 if (smbw_debug) 528 { 529 printf("lseek64x(%d, 0x%llx) returned 0x%llx\n", 530 fd, 531 (unsigned long long) offset, 532 (unsigned long long) ret); 533 } 534 return ret; 535} 536 537static ssize_t readx(int fd, void *buf, size_t count, ssize_t (* f)(int, void *, size_t)) 538{ 539 if (smbw_fd(fd)) { 540 return smbw_read(fd, buf, count); 541 } 542 543 return (* f)(fd, buf, count); 544} 545 546static ssize_t writex(int fd, void *buf, size_t count, ssize_t (* f)(int, void *, size_t)) 547{ 548 if (smbw_fd(fd)) { 549 return smbw_write(fd, buf, count); 550 } 551 552 return (* f)(fd, buf, count); 553} 554 555 556/** 557 ** Wrapper Functions 558 **/ 559 560int open(__const char *name, int flags, ...) 561{ 562 va_list ap; 563 mode_t mode; 564 565 va_start(ap, flags); 566 mode = va_arg(ap, mode_t); 567 va_end(ap); 568 569 check_init("open"); 570 571 return openx((char *) name, flags, mode, smbw_libc.open); 572} 573 574int _open(char *name, int flags, mode_t mode) 575{ 576 check_init("open"); 577 578 return openx(name, flags, mode, smbw_libc._open); 579} 580 581int __open(char *name, int flags, mode_t mode) 582{ 583 check_init("open"); 584 585 return openx(name, flags, mode, smbw_libc.__open); 586} 587 588int open64 (__const char *name, int flags, ...) 589{ 590 va_list ap; 591 mode_t mode; 592 593 va_start(ap, flags); 594 mode = va_arg(ap, mode_t); 595 va_end(ap); 596 597 check_init("open64"); 598 return openx((char *) name, flags, mode, smbw_libc.open64); 599} 600 601int _open64(char *name, int flags, mode_t mode) 602{ 603 check_init("_open64"); 604 return openx(name, flags, mode, smbw_libc._open64); 605} 606 607int __open64(char *name, int flags, mode_t mode) 608{ 609 check_init("__open64"); 610 return openx(name, flags, mode, smbw_libc.__open64); 611} 612 613ssize_t pread(int fd, void *buf, size_t size, off_t ofs) 614{ 615 check_init("pread"); 616 617 if (smbw_fd(fd)) { 618 return smbw_pread(fd, buf, size, ofs); 619 } 620 621 return (* smbw_libc.pread)(fd, buf, size, ofs); 622} 623 624ssize_t pread64(int fd, void *buf, size_t size, off64_t ofs) 625{ 626 check_init("pread64"); 627 628 if (smbw_fd(fd)) { 629 return smbw_pread(fd, buf, size, (off_t) ofs); 630 } 631 632 return (* smbw_libc.pread64)(fd, buf, size, ofs); 633} 634 635ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs) 636{ 637 check_init("pwrite"); 638 639 if (smbw_fd(fd)) { 640 return smbw_pwrite(fd, (void *) buf, size, ofs); 641 } 642 643 return (* smbw_libc.pwrite)(fd, (void *) buf, size, ofs); 644} 645 646ssize_t pwrite64(int fd, const void *buf, size_t size, off64_t ofs) 647{ 648 check_init("pwrite64"); 649 650 if (smbw_fd(fd)) { 651 return smbw_pwrite(fd, (void *) buf, size, (off_t) ofs); 652 } 653 654 return (* smbw_libc.pwrite64)(fd, (void *) buf, size, ofs); 655} 656 657int chdir(const char *name) 658{ 659 check_init("chdir"); 660 return smbw_chdir((char *) name);; 661} 662 663int __chdir(char *name) 664{ 665 check_init("__chdir"); 666 return smbw_chdir(name); 667} 668 669int _chdir(char *name) 670{ 671 check_init("_chdir"); 672 return smbw_chdir(name); 673} 674 675int close(int fd) 676{ 677 check_init("close"); 678 return closex(fd, smbw_libc.close); 679} 680 681int __close(int fd) 682{ 683 check_init("__close"); 684 return closex(fd, smbw_libc.__close); 685} 686 687int _close(int fd) 688{ 689 check_init("_close"); 690 return closex(fd, smbw_libc._close); 691} 692 693int fchdir(int fd) 694{ 695 check_init("fchdir"); 696 return smbw_fchdir(fd); 697} 698 699int __fchdir(int fd) 700{ 701 check_init("__fchdir"); 702 return fchdir(fd); 703} 704 705int _fchdir(int fd) 706{ 707 check_init("_fchdir"); 708 return fchdir(fd); 709} 710 711int fcntl (int fd, int cmd, ...) 712{ 713 va_list ap; 714 long arg; 715 716 va_start(ap, cmd); 717 arg = va_arg(ap, long); 718 va_end(ap); 719 720 check_init("fcntl"); 721 return fcntlx(fd, cmd, arg, smbw_libc.fcntl); 722} 723 724int __fcntl(int fd, int cmd, ...) 725{ 726 va_list ap; 727 long arg; 728 729 va_start(ap, cmd); 730 arg = va_arg(ap, long); 731 va_end(ap); 732 733 check_init("__fcntl"); 734 return fcntlx(fd, cmd, arg, smbw_libc.__fcntl); 735} 736 737int _fcntl(int fd, int cmd, ...) 738{ 739 va_list ap; 740 long arg; 741 742 va_start(ap, cmd); 743 arg = va_arg(ap, long); 744 va_end(ap); 745 746 check_init("_fcntl"); 747 return fcntlx(fd, cmd, arg, smbw_libc._fcntl); 748} 749 750int getdents(int fd, struct dirent *dirp, unsigned int count) 751{ 752 check_init("getdents"); 753 return getdentsx(fd, dirp, count, smbw_libc.getdents); 754} 755 756int __getdents(int fd, struct dirent *dirp, unsigned int count) 757{ 758 check_init("__getdents"); 759 return getdentsx(fd, dirp, count, smbw_libc.__getdents); 760} 761 762int _getdents(int fd, struct dirent *dirp, unsigned int count) 763{ 764 check_init("_getdents"); 765 return getdentsx(fd, dirp, count, smbw_libc._getdents); 766} 767 768int getdents64(int fd, struct dirent64 *external, unsigned int count) 769{ 770 check_init("getdents64"); 771 if (smbw_fd(fd)) { 772 int i; 773 struct SMBW_dirent *internal; 774 int ret; 775 int n; 776 777 /* 778 * LIMITATION: If they pass a count which is not a multiple of 779 * the size of struct dirent, they will not get a partial 780 * structure; we ignore the excess count. 781 */ 782 n = (count / sizeof(struct dirent64)); 783 784 internal = malloc(sizeof(struct SMBW_dirent) * n); 785 if (internal == NULL) { 786 errno = ENOMEM; 787 return -1; 788 } 789 ret = smbw_getdents(fd, internal, count); 790 if (ret <= 0) 791 return ret; 792 793 ret = sizeof(struct dirent) * count; 794 795 for (i = 0; count; i++, count--) 796 dirent64_convert(&internal[i], &external[i]); 797 798 return ret; 799 } 800 801 return (* smbw_libc.getdents64)(fd, external, count); 802} 803 804off_t lseek(int fd, off_t offset, int whence) 805{ 806 off_t ret; 807 check_init("lseek"); 808 ret = lseekx(fd, offset, whence, smbw_libc.lseek); 809 if (smbw_debug) 810 { 811 printf("lseek(%d, 0x%llx) returned 0x%llx\n", 812 fd, 813 (unsigned long long) offset, 814 (unsigned long long) ret); 815 } 816 return ret; 817} 818 819off_t __lseek(int fd, off_t offset, int whence) 820{ 821 off_t ret; 822 check_init("__lseek"); 823 ret = lseekx(fd, offset, whence, smbw_libc.__lseek); 824 if (smbw_debug) 825 { 826 printf("__lseek(%d, 0x%llx) returned 0x%llx\n", 827 fd, 828 (unsigned long long) offset, 829 (unsigned long long) ret); 830 } 831 return ret; 832} 833 834off_t _lseek(int fd, off_t offset, int whence) 835{ 836 off_t ret; 837 check_init("_lseek"); 838 ret = lseekx(fd, offset, whence, smbw_libc._lseek); 839 if (smbw_debug) 840 { 841 printf("_lseek(%d, 0x%llx) returned 0x%llx\n", 842 fd, 843 (unsigned long long) offset, 844 (unsigned long long) ret); 845 } 846 return ret; 847} 848 849off64_t lseek64(int fd, off64_t offset, int whence) 850{ 851 off64_t ret; 852 check_init("lseek64"); 853 ret = lseek64x(fd, offset, whence, smbw_libc.lseek64); 854 if (smbw_debug) 855 { 856 printf("lseek64(%d, 0x%llx) returned 0x%llx\n", 857 fd, 858 (unsigned long long) offset, 859 (unsigned long long) ret); 860 } 861 return ret; 862} 863 864off64_t __lseek64(int fd, off64_t offset, int whence) 865{ 866 check_init("__lseek64"); 867 return lseek64x(fd, offset, whence, smbw_libc.__lseek64); 868} 869 870off64_t _lseek64(int fd, off64_t offset, int whence) 871{ 872 off64_t ret; 873 check_init("_lseek64"); 874 ret = lseek64x(fd, offset, whence, smbw_libc._lseek64); 875 if (smbw_debug) 876 { 877 printf("_lseek64(%d, 0x%llx) returned 0x%llx\n", 878 fd, 879 (unsigned long long) offset, 880 (unsigned long long) ret); 881 } 882 return ret; 883} 884 885ssize_t read(int fd, void *buf, size_t count) 886{ 887 check_init("read"); 888 return readx(fd, buf, count, smbw_libc.read); 889} 890 891ssize_t __read(int fd, void *buf, size_t count) 892{ 893 check_init("__read"); 894 return readx(fd, buf, count, smbw_libc.__read); 895} 896 897ssize_t _read(int fd, void *buf, size_t count) 898{ 899 check_init("_read"); 900 return readx(fd, buf, count, smbw_libc._read); 901} 902 903ssize_t write(int fd, const void *buf, size_t count) 904{ 905 check_init("write"); 906 return writex(fd, (void *) buf, count, smbw_libc.write); 907} 908 909ssize_t __write(int fd, const void *buf, size_t count) 910{ 911 check_init("__write"); 912 return writex(fd, (void *) buf, count, smbw_libc.__write); 913} 914 915ssize_t _write(int fd, const void *buf, size_t count) 916{ 917 check_init("_write"); 918 return writex(fd, (void *) buf, count, smbw_libc._write); 919} 920 921int access(const char *name, int mode) 922{ 923 check_init("access"); 924 925 if (smbw_path((char *) name)) { 926 return smbw_access((char *) name, mode); 927 } 928 929 return (* smbw_libc.access)((char *) name, mode); 930} 931 932int chmod(const char *name, mode_t mode) 933{ 934 check_init("chmod"); 935 936 if (smbw_path((char *) name)) { 937 return smbw_chmod((char *) name, mode); 938 } 939 940 return (* smbw_libc.chmod)((char *) name, mode); 941} 942 943int fchmod(int fd, mode_t mode) 944{ 945 check_init("fchmod"); 946 947 if (smbw_fd(fd)) { 948 /* Not yet implemented in libsmbclient */ 949 return ENOTSUP; 950 } 951 952 return (* smbw_libc.fchmod)(fd, mode); 953} 954 955int chown(const char *name, uid_t owner, gid_t group) 956{ 957 check_init("chown"); 958 959 if (smbw_path((char *) name)) { 960 return smbw_chown((char *) name, owner, group); 961 } 962 963 return (* smbw_libc.chown)((char *) name, owner, group); 964} 965 966int fchown(int fd, uid_t owner, gid_t group) 967{ 968 check_init("fchown"); 969 970 if (smbw_fd(fd)) { 971 /* Not yet implemented in libsmbclient */ 972 return ENOTSUP; 973 } 974 975 return (* smbw_libc.fchown)(fd, owner, group); 976} 977 978char *getcwd(char *buf, size_t size) 979{ 980 check_init("getcwd"); 981 return (char *)smbw_getcwd(buf, size); 982} 983 984int mkdir(const char *name, mode_t mode) 985{ 986 check_init("mkdir"); 987 988 if (smbw_path((char *) name)) { 989 return smbw_mkdir((char *) name, mode); 990 } 991 992 return (* smbw_libc.mkdir)((char *) name, mode); 993} 994 995int __fxstat(int vers, int fd, struct stat *st) 996{ 997 check_init("__fxstat"); 998 999 if (smbw_fd(fd)) { 1000 struct SMBW_stat statbuf; 1001 int ret = smbw_fstat(fd, &statbuf); 1002 stat_convert(&statbuf, st); 1003 return ret; 1004 } 1005 1006 return (* smbw_libc.__fxstat)(vers, fd, st); 1007} 1008 1009int __xstat(int vers, const char *name, struct stat *st) 1010{ 1011 check_init("__xstat"); 1012 1013 if (smbw_path((char *) name)) { 1014 struct SMBW_stat statbuf; 1015 int ret = smbw_stat((char *) name, &statbuf); 1016 stat_convert(&statbuf, st); 1017 return ret; 1018 } 1019 1020 return (* smbw_libc.__xstat)(vers, (char *) name, st); 1021} 1022 1023int __lxstat(int vers, const char *name, struct stat *st) 1024{ 1025 check_init("__lxstat"); 1026 1027 if (smbw_path((char *) name)) { 1028 struct SMBW_stat statbuf; 1029 int ret = smbw_stat((char *) name, &statbuf); 1030 stat_convert(&statbuf, st); 1031 return ret; 1032 } 1033 1034 return (* smbw_libc.__lxstat)(vers, (char *) name, st); 1035} 1036 1037int stat(const char *name, struct stat *st) 1038{ 1039 check_init("stat"); 1040 1041 if (smbw_path((char *) name)) { 1042 struct SMBW_stat statbuf; 1043 int ret = smbw_stat((char *) name, &statbuf); 1044 stat_convert(&statbuf, st); 1045 return ret; 1046 } 1047 1048 return (* smbw_libc.stat)((char *) name, st); 1049} 1050 1051int lstat(const char *name, struct stat *st) 1052{ 1053 check_init("lstat"); 1054 1055 if (smbw_path((char *) name)) { 1056 struct SMBW_stat statbuf; 1057 int ret = smbw_stat((char *) name, &statbuf); 1058 stat_convert(&statbuf, st); 1059 return ret; 1060 } 1061 1062 return (* smbw_libc.lstat)((char *) name, st); 1063} 1064 1065int fstat(int fd, struct stat *st) 1066{ 1067 check_init("fstat"); 1068 1069 if (smbw_fd(fd)) { 1070 struct SMBW_stat statbuf; 1071 int ret = smbw_fstat(fd, &statbuf); 1072 stat_convert(&statbuf, st); 1073 return ret; 1074 } 1075 1076 return (* smbw_libc.fstat)(fd, st); 1077} 1078 1079int unlink(const char *name) 1080{ 1081 check_init("unlink"); 1082 1083 if (smbw_path((char *) name)) { 1084 return smbw_unlink((char *) name); 1085 } 1086 1087 return (* smbw_libc.unlink)((char *) name); 1088} 1089 1090int utime(const char *name, const struct utimbuf *tvp) 1091{ 1092 check_init("utime"); 1093 1094 if (smbw_path(name)) { 1095 return smbw_utime(name, (struct utimbuf *) tvp); 1096 } 1097 1098 return (* smbw_libc.utime)((char *) name, (struct utimbuf *) tvp); 1099} 1100 1101int utimes(const char *name, const struct timeval *tvp) 1102{ 1103 check_init("utimes"); 1104 1105 if (smbw_path(name)) { 1106 return smbw_utimes(name, (struct timeval *) tvp); 1107 } 1108 1109 return (* smbw_libc.utimes)((char *) name, (struct timeval *) tvp); 1110} 1111 1112int readlink(const char *path, char *buf, size_t bufsize) 1113{ 1114 check_init("readlink"); 1115 1116 if (smbw_path((char *) path)) { 1117 return smbw_readlink(path, (char *) buf, bufsize); 1118 } 1119 1120 return (* smbw_libc.readlink)((char *) path, buf, bufsize); 1121} 1122 1123int rename(const char *oldname, const char *newname) 1124{ 1125 int p1, p2; 1126 1127 check_init("rename"); 1128 1129 p1 = smbw_path((char *) oldname); 1130 p2 = smbw_path((char *) newname); 1131 if (p1 ^ p2) { 1132 /* can't cross filesystem boundaries */ 1133 errno = EXDEV; 1134 return -1; 1135 } 1136 if (p1 && p2) { 1137 return smbw_rename((char *) oldname, (char *) newname); 1138 } 1139 1140 return (* smbw_libc.rename)((char *) oldname, (char *) newname); 1141} 1142 1143int rmdir(const char *name) 1144{ 1145 check_init("rmdir"); 1146 1147 if (smbw_path((char *) name)) { 1148 return smbw_rmdir((char *) name); 1149 } 1150 1151 return (* smbw_libc.rmdir)((char *) name); 1152} 1153 1154int symlink(const char *topath, const char *frompath) 1155{ 1156 int p1, p2; 1157 1158 check_init("symlink"); 1159 1160 p1 = smbw_path((char *) topath); 1161 p2 = smbw_path((char *) frompath); 1162 if (p1 || p2) { 1163 /* can't handle symlinks */ 1164 errno = EPERM; 1165 return -1; 1166 } 1167 1168 return (* smbw_libc.symlink)((char *) topath, (char *) frompath); 1169} 1170 1171int dup(int fd) 1172{ 1173 check_init("dup"); 1174 1175 if (smbw_fd(fd)) { 1176 return smbw_dup(fd); 1177 } 1178 1179 return (* smbw_libc.dup)(fd); 1180} 1181 1182int dup2(int oldfd, int newfd) 1183{ 1184 check_init("dup2"); 1185 1186 if (smbw_fd(newfd)) { 1187 (* smbw_libc.close)(newfd); 1188 } 1189 1190 if (smbw_fd(oldfd)) { 1191 return smbw_dup2(oldfd, newfd); 1192 } 1193 1194 return (* smbw_libc.dup2)(oldfd, newfd); 1195} 1196 1197 1198DIR *opendir(const char *name) 1199{ 1200 check_init("opendir"); 1201 1202 if (smbw_path((char *) name)) { 1203 return (void *)smbw_opendir((char *) name); 1204 } 1205 1206 return (* smbw_libc.opendir)((char *) name); 1207} 1208 1209struct dirent *readdir(DIR *dir) 1210{ 1211 check_init("readdir"); 1212 1213 if (smbw_dirp(dir)) { 1214 static struct dirent external; 1215 struct SMBW_dirent * internal = (void *)smbw_readdir(dir); 1216 if (internal != NULL) { 1217 dirent_convert(internal, &external); 1218 return &external; 1219 } 1220 return NULL; 1221 } 1222 return (* smbw_libc.readdir)(dir); 1223} 1224 1225int closedir(DIR *dir) 1226{ 1227 check_init("closedir"); 1228 1229 if (smbw_dirp(dir)) { 1230 return smbw_closedir(dir); 1231 } 1232 1233 return (* smbw_libc.closedir)(dir); 1234} 1235 1236long telldir(DIR *dir) 1237{ 1238 check_init("telldir"); 1239 1240 if (smbw_dirp(dir)) { 1241 return (long) smbw_telldir(dir); 1242 } 1243 1244 return (* smbw_libc.telldir)(dir); 1245} 1246 1247void seekdir(DIR *dir, long offset) 1248{ 1249 check_init("seekdir"); 1250 1251 if (smbw_dirp(dir)) { 1252 smbw_seekdir(dir, (long long) offset); 1253 return; 1254 } 1255 1256 (* smbw_libc.seekdir)(dir, offset); 1257} 1258 1259int creat(const char *path, mode_t mode) 1260{ 1261 extern int creat_bits; 1262 1263 check_init("creat"); 1264 return openx((char *) path, creat_bits, mode, smbw_libc.open); 1265} 1266 1267int creat64(const char *path, mode_t mode) 1268{ 1269 extern int creat_bits; 1270 1271 check_init("creat64"); 1272 return openx((char *) path, creat_bits, mode, smbw_libc.open64); 1273} 1274 1275int __xstat64 (int ver, const char *name, struct stat64 *st64) 1276{ 1277 check_init("__xstat64"); 1278 1279 if (smbw_path((char *) name)) { 1280 struct SMBW_stat statbuf; 1281 int ret = smbw_stat((char *) name, &statbuf); 1282 stat64_convert(&statbuf, st64); 1283 return ret; 1284 } 1285 1286 return (* smbw_libc.__xstat64)(ver, (char *) name, st64); 1287} 1288 1289int stat64(const char *name, struct stat64 *st64) 1290{ 1291 check_init("stat64"); 1292 1293 if (smbw_path((char *) name)) { 1294 struct SMBW_stat statbuf; 1295 int ret = smbw_stat((char *) name, &statbuf); 1296 stat64_convert(&statbuf, st64); 1297 return ret; 1298 } 1299 1300 return (* smbw_libc.stat64)((char *) name, st64); 1301} 1302 1303int __fxstat64(int ver, int fd, struct stat64 *st64) 1304{ 1305 check_init("__fxstat64"); 1306 1307 if (smbw_fd(fd)) { 1308 struct SMBW_stat statbuf; 1309 int ret = smbw_fstat(fd, &statbuf); 1310 stat64_convert(&statbuf, st64); 1311 return ret; 1312 } 1313 1314 return (* smbw_libc.__fxstat64)(ver, fd, st64); 1315} 1316 1317int fstat64(int fd, struct stat64 *st64) 1318{ 1319 check_init("fstat64"); 1320 1321 if (smbw_fd(fd)) { 1322 struct SMBW_stat statbuf; 1323 int ret = smbw_fstat(fd, &statbuf); 1324 stat64_convert(&statbuf, st64); 1325 return ret; 1326 } 1327 1328 return (* smbw_libc.fstat64)(fd, st64); 1329} 1330 1331int __lxstat64(int ver, const char *name, struct stat64 *st64) 1332{ 1333 check_init("__lxstat64"); 1334 1335 if (smbw_path((char *) name)) { 1336 struct SMBW_stat statbuf; 1337 int ret = smbw_stat(name, &statbuf); 1338 stat64_convert(&statbuf, st64); 1339 return ret; 1340 } 1341 1342 return (* smbw_libc.__lxstat64)(ver, (char *) name, st64); 1343} 1344 1345int lstat64(const char *name, struct stat64 *st64) 1346{ 1347 check_init("lstat64"); 1348 1349 if (smbw_path((char *) name)) { 1350 struct SMBW_stat statbuf; 1351 int ret = smbw_stat((char *) name, &statbuf); 1352 stat64_convert(&statbuf, st64); 1353 return ret; 1354 } 1355 1356 return (* smbw_libc.lstat64)((char *) name, st64); 1357} 1358 1359int _llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t *result, unsigned int whence) 1360{ 1361 check_init("_llseek"); 1362 1363 if (smbw_fd(fd)) { 1364 *result = lseek(fd, offset_low, whence); 1365 return (*result < 0 ? -1 : 0); 1366 } 1367 1368 return (* smbw_libc._llseek)(fd, offset_high, offset_low, result, whence); 1369} 1370 1371struct dirent64 *readdir64(DIR *dir) 1372{ 1373 check_init("readdir64"); 1374 1375 if (smbw_dirp(dir)) { 1376 static struct dirent64 external; 1377 struct SMBW_dirent * internal = (void *)smbw_readdir(dir); 1378 if (internal != NULL) { 1379 dirent64_convert(internal, &external); 1380 return &external; 1381 } 1382 return NULL; 1383 } 1384 1385 return (* smbw_libc.readdir64)(dir); 1386} 1387 1388int readdir_r(DIR *dir, struct dirent *external, struct dirent **result) 1389{ 1390 check_init("readdir_r"); 1391 1392 if (smbw_dirp(dir)) { 1393 struct SMBW_dirent internal; 1394 int ret = smbw_readdir_r(dir, &internal, NULL); 1395 if (ret == 0) { 1396 dirent_convert(&internal, external); 1397 *result = external; 1398 } 1399 return ret; 1400 } 1401 1402 return (* smbw_libc.readdir_r)(dir, external, result); 1403} 1404 1405int readdir64_r(DIR *dir, struct dirent64 *external, struct dirent64 **result) 1406{ 1407 check_init("readdir64_r"); 1408 1409 if (smbw_dirp(dir)) { 1410 struct SMBW_dirent internal; 1411 int ret = smbw_readdir_r(dir, &internal, NULL); 1412 if (ret == 0) { 1413 dirent64_convert(&internal, external); 1414 *result = external; 1415 } 1416 return ret; 1417 } 1418 1419 return (* smbw_libc.readdir64_r)(dir, external, result); 1420} 1421 1422int fork(void) 1423{ 1424 check_init("fork"); 1425 return smbw_fork(); 1426} 1427 1428int setxattr(const char *fname, 1429 const char *name, 1430 const void *value, 1431 size_t size, 1432 int flags) 1433{ 1434 if (smbw_path(fname)) { 1435 return smbw_setxattr(fname, name, value, size, flags); 1436 } 1437 1438 return (* smbw_libc.setxattr)(fname, name, value, size, flags); 1439} 1440 1441int lsetxattr(const char *fname, 1442 const char *name, 1443 const void *value, 1444 size_t size, 1445 int flags) 1446{ 1447 if (smbw_path(fname)) { 1448 return smbw_lsetxattr(fname, name, value, size, flags); 1449 } 1450 1451 return (* smbw_libc.lsetxattr)(fname, name, value, size, flags); 1452} 1453 1454int fsetxattr(int fd, 1455 const char *name, 1456 const void *value, 1457 size_t size, 1458 int flags) 1459{ 1460 if (smbw_fd(fd)) { 1461 return smbw_fsetxattr(fd, name, value, size, flags); 1462 } 1463 1464 return (* smbw_libc.fsetxattr)(fd, name, value, size, flags); 1465} 1466 1467int getxattr(const char *fname, 1468 const char *name, 1469 const void *value, 1470 size_t size) 1471{ 1472 if (smbw_path(fname)) { 1473 return smbw_getxattr(fname, name, value, size); 1474 } 1475 1476 return (* smbw_libc.getxattr)(fname, name, value, size); 1477} 1478 1479int lgetxattr(const char *fname, 1480 const char *name, 1481 const void *value, 1482 size_t size) 1483{ 1484 if (smbw_path(fname)) { 1485 return smbw_lgetxattr(fname, name, value, size); 1486 } 1487 1488 return (* smbw_libc.lgetxattr)(fname, name, value, size); 1489} 1490 1491int fgetxattr(int fd, 1492 const char *name, 1493 const void *value, 1494 size_t size) 1495{ 1496 if (smbw_fd(fd)) { 1497 return smbw_fgetxattr(fd, name, value, size); 1498 } 1499 1500 return (* smbw_libc.fgetxattr)(fd, name, value, size); 1501} 1502 1503int removexattr(const char *fname, 1504 const char *name) 1505{ 1506 if (smbw_path(fname)) { 1507 return smbw_removexattr(fname, name); 1508 } 1509 1510 return (* smbw_libc.removexattr)(fname, name); 1511} 1512 1513int lremovexattr(const char *fname, 1514 const char *name) 1515{ 1516 if (smbw_path(fname)) { 1517 return smbw_lremovexattr(fname, name); 1518 } 1519 1520 return (* smbw_libc.lremovexattr)(fname, name); 1521} 1522 1523int fremovexattr(int fd, 1524 const char *name) 1525{ 1526 if (smbw_fd(fd)) { 1527 return smbw_fremovexattr(fd, name); 1528 } 1529 1530 return (* smbw_libc.fremovexattr)(fd, name); 1531} 1532 1533int listxattr(const char *fname, 1534 char *list, 1535 size_t size) 1536{ 1537 if (smbw_path(fname)) { 1538 return smbw_listxattr(fname, list, size); 1539 } 1540 1541 return (* smbw_libc.listxattr)(fname, list, size); 1542} 1543 1544int llistxattr(const char *fname, 1545 char *list, 1546 size_t size) 1547{ 1548 if (smbw_path(fname)) { 1549 return smbw_llistxattr(fname, list, size); 1550 } 1551 1552 return (* smbw_libc.llistxattr)(fname, list, size); 1553} 1554 1555int flistxattr(int fd, 1556 char *list, 1557 size_t size) 1558{ 1559 if (smbw_fd(fd)) { 1560 return smbw_flistxattr(fd, list, size); 1561 } 1562 1563 return (* smbw_libc.flistxattr)(fd, list, size); 1564} 1565 1566 1567/* 1568 * We're ending up with a different implementation of malloc() with smbwrapper 1569 * than without it. The one with it does not support returning a non-NULL 1570 * pointer from a call to malloc(0), and many apps depend on getting a valid 1571 * pointer when requesting zero length (e.g. df, emacs). 1572 * 1573 * Unfortunately, initializing the smbw_libc[] array via the dynamic link 1574 * library (libdl) requires malloc so we can't just do the same type of 1575 * mapping to the C library as we do with everything else. We need to 1576 * implement a different way of allocating memory that ensures that the C 1577 * library version of malloc() gets used. This is the only place where we 1578 * kludge the code to use an undocumented interface to the C library. 1579 * 1580 * If anyone can come up with a way to dynamically link to the C library 1581 * rather than using this undocumented interface, I'd sure love to hear about 1582 * it. Better yet, if you can figure out where the alternate malloc() 1583 * functions are coming from and arrange for them not to be called, that would 1584 * be even better. We should try to avoid wrapping functions that don't 1585 * really require it. 1586 */ 1587 1588void *malloc(size_t size) 1589{ 1590 void *__libc_malloc(size_t size); 1591 return __libc_malloc(size); 1592} 1593 1594void *calloc(size_t nmemb, size_t size) 1595{ 1596 void *__libc_calloc(size_t nmemb, size_t size); 1597 return __libc_calloc(nmemb, size); 1598} 1599 1600void *realloc(void *ptr, size_t size) 1601{ 1602 void *__libc_realloc(void *ptr, size_t size); 1603 return __libc_realloc(ptr, size); 1604} 1605 1606void free(void *ptr) 1607{ 1608 static int in_progress = 0; 1609 void __libc_free(void *ptr); 1610 1611 if (in_progress) return; 1612 in_progress = 1; 1613 __libc_free(ptr); 1614 in_progress = 0; 1615} 1616 1617 1618#if 0 /* SELECT */ 1619 1620static struct sigaction user_action[_NSIG]; 1621 1622static void 1623smbw_sigaction_handler(int signum, 1624 siginfo_t *info, 1625 void *context) 1626{ 1627 /* Our entire purpose for trapping signals is to call this! */ 1628 sys_select_signal(); 1629 1630 /* Call the user's handler */ 1631 if (user_action[signum].sa_handler != SIG_IGN && 1632 user_action[signum].sa_handler != SIG_DFL && 1633 user_action[signum].sa_handler != SIG_ERR) { 1634 (* user_action[signum].sa_sigaction)(signum, info, context); 1635 } 1636} 1637 1638 1639/* 1640 * Every Samba signal handler must call sys_select_signal() to avoid a race 1641 * condition, so we'll take whatever signal handler is currently assigned, 1642 * call call sys_select_signal() in addition to their call. 1643 */ 1644static int 1645do_select(int n, 1646 fd_set *readfds, 1647 fd_set *writefds, 1648 fd_set *exceptfds, 1649 struct timeval *timeout, 1650 int (* select_fn)(int n, 1651 fd_set *readfds, 1652 fd_set *writefds, 1653 fd_set *exceptfds, 1654 struct timeval *timeout)) 1655{ 1656 int i; 1657 int ret; 1658 int saved_errno; 1659 sigset_t sigset; 1660 struct sigaction new_action; 1661 1662 saved_errno = errno; 1663 for (i=1; i<_NSIG; i++) { 1664 sigemptyset(&sigset); 1665 new_action.sa_mask = sigset; 1666 new_action.sa_flags = SA_SIGINFO; 1667 new_action.sa_sigaction = smbw_sigaction_handler; 1668 1669 if (sigaction(i, &new_action, &user_action[i]) < 0) { 1670 if (errno != EINVAL) { 1671 return -1; 1672 } 1673 } 1674 } 1675 errno = saved_errno; 1676 1677 ret = (* select_fn)(n, readfds, writefds, exceptfds, timeout); 1678 saved_errno = errno; 1679 1680 for (i=0; i<_NSIG; i++) { 1681 (void) sigaction(i, &user_action[i], NULL); 1682 } 1683 1684 errno = saved_errno; 1685 return ret; 1686} 1687 1688int 1689select(int n, 1690 fd_set *readfds, 1691 fd_set *writefds, 1692 fd_set *exceptfds, 1693 struct timeval *timeout) 1694{ 1695 check_init("select"); 1696 1697 return do_select(n, readfds, writefds, exceptfds, 1698 timeout, smbw_libc.select); 1699} 1700 1701int 1702_select(int n, 1703 fd_set *readfds, 1704 fd_set *writefds, 1705 fd_set *exceptfds, 1706 struct timeval *timeout) 1707{ 1708 check_init("_select"); 1709 1710 return do_select(n, readfds, writefds, exceptfds, 1711 timeout, smbw_libc._select); 1712} 1713 1714int 1715__select(int n, 1716 fd_set *readfds, 1717 fd_set *writefds, 1718 fd_set *exceptfds, 1719 struct timeval *timeout) 1720{ 1721 check_init("__select"); 1722 1723 return do_select(n, readfds, writefds, exceptfds, 1724 timeout, smbw_libc.__select); 1725} 1726 1727#endif 1728