2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1998-2005
6 Copyright (C) Timur Bakeyev 2005
7 Copyright (C) Bjoern Jacke 2006-2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #ifdef HAVE_SYS_PRCTL_H
26 #include <sys/prctl.h>
30 The idea is that this file will eventually have wrappers around all
31 important system calls in samba. The aims are:
33 - to enable easier porting by putting OS dependent stuff in here
35 - to allow for hooks into other "pseudo-filesystems"
37 - to allow easier integration of things like the japanese extensions
39 - to support the philosophy of Samba to expose the features of
40 the OS within the SMB model. In general whatever file/printer/variable
41 expansions/etc make sense to the OS should be acceptable to Samba.
46 /*******************************************************************
47 A wrapper for memalign
48 ********************************************************************/
50 void *sys_memalign( size_t align
, size_t size
)
52 #if defined(HAVE_POSIX_MEMALIGN)
54 int ret
= posix_memalign( &p
, align
, size
);
59 #elif defined(HAVE_MEMALIGN)
60 return memalign( align
, size
);
62 /* On *BSD systems memaligns doesn't exist, but memory will
63 * be aligned on allocations of > pagesize. */
64 #if defined(SYSCONF_SC_PAGESIZE)
65 size_t pagesize
= (size_t)sysconf(_SC_PAGESIZE
);
66 #elif defined(HAVE_GETPAGESIZE)
67 size_t pagesize
= (size_t)getpagesize();
69 size_t pagesize
= (size_t)-1;
71 if (pagesize
== (size_t)-1) {
72 DEBUG(0,("memalign functionalaity not available on this platform!\n"));
75 if (size
< pagesize
) {
78 return SMB_MALLOC(size
);
82 /*******************************************************************
83 A wrapper for usleep in case we don't have one.
84 ********************************************************************/
86 int sys_usleep(long usecs
)
93 * We need this braindamage as the glibc usleep
94 * is not SPEC1170 complient... grumble... JRA.
97 if(usecs
< 0 || usecs
> 999999) {
105 #else /* HAVE_USLEEP */
107 * Fake it with select...
110 tval
.tv_usec
= usecs
/1000;
111 select(0,NULL
,NULL
,NULL
,&tval
);
113 #endif /* HAVE_USLEEP */
116 /*******************************************************************
117 A read wrapper that will deal with EINTR.
118 ********************************************************************/
120 ssize_t
sys_read(int fd
, void *buf
, size_t count
)
125 ret
= read(fd
, buf
, count
);
126 } while (ret
== -1 && errno
== EINTR
);
130 /*******************************************************************
131 A write wrapper that will deal with EINTR.
132 ********************************************************************/
134 ssize_t
sys_write(int fd
, const void *buf
, size_t count
)
139 ret
= write(fd
, buf
, count
);
140 } while (ret
== -1 && errno
== EINTR
);
144 /*******************************************************************
145 A writev wrapper that will deal with EINTR.
146 ********************************************************************/
148 ssize_t
sys_writev(int fd
, const struct iovec
*iov
, int iovcnt
)
153 /* Try to confuse write_data_iov a bit */
154 if ((random() % 5) == 0) {
155 return sys_write(fd
, iov
[0].iov_base
, iov
[0].iov_len
);
157 if (iov
[0].iov_len
> 1) {
158 return sys_write(fd
, iov
[0].iov_base
,
159 (random() % (iov
[0].iov_len
-1)) + 1);
164 ret
= writev(fd
, iov
, iovcnt
);
165 } while (ret
== -1 && errno
== EINTR
);
169 /*******************************************************************
170 A pread wrapper that will deal with EINTR and 64-bit file offsets.
171 ********************************************************************/
173 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
174 ssize_t
sys_pread(int fd
, void *buf
, size_t count
, SMB_OFF_T off
)
179 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
180 ret
= pread64(fd
, buf
, count
, off
);
182 ret
= pread(fd
, buf
, count
, off
);
184 } while (ret
== -1 && errno
== EINTR
);
189 /*******************************************************************
190 A write wrapper that will deal with EINTR and 64-bit file offsets.
191 ********************************************************************/
193 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
194 ssize_t
sys_pwrite(int fd
, const void *buf
, size_t count
, SMB_OFF_T off
)
199 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
200 ret
= pwrite64(fd
, buf
, count
, off
);
202 ret
= pwrite(fd
, buf
, count
, off
);
204 } while (ret
== -1 && errno
== EINTR
);
209 /*******************************************************************
210 A send wrapper that will deal with EINTR.
211 ********************************************************************/
213 ssize_t
sys_send(int s
, const void *msg
, size_t len
, int flags
)
218 ret
= send(s
, msg
, len
, flags
);
219 } while (ret
== -1 && errno
== EINTR
);
223 /*******************************************************************
224 A sendto wrapper that will deal with EINTR.
225 ********************************************************************/
227 ssize_t
sys_sendto(int s
, const void *msg
, size_t len
, int flags
, const struct sockaddr
*to
, socklen_t tolen
)
232 ret
= sendto(s
, msg
, len
, flags
, to
, tolen
);
233 } while (ret
== -1 && errno
== EINTR
);
237 /*******************************************************************
238 A recv wrapper that will deal with EINTR.
239 ********************************************************************/
241 ssize_t
sys_recv(int fd
, void *buf
, size_t count
, int flags
)
246 ret
= recv(fd
, buf
, count
, flags
);
247 } while (ret
== -1 && errno
== EINTR
);
251 /*******************************************************************
252 A recvfrom wrapper that will deal with EINTR.
253 ********************************************************************/
255 ssize_t
sys_recvfrom(int s
, void *buf
, size_t len
, int flags
, struct sockaddr
*from
, socklen_t
*fromlen
)
260 ret
= recvfrom(s
, buf
, len
, flags
, from
, fromlen
);
261 } while (ret
== -1 && errno
== EINTR
);
265 /*******************************************************************
266 A fcntl wrapper that will deal with EINTR.
267 ********************************************************************/
269 int sys_fcntl_ptr(int fd
, int cmd
, void *arg
)
274 ret
= fcntl(fd
, cmd
, arg
);
275 } while (ret
== -1 && errno
== EINTR
);
279 /*******************************************************************
280 A fcntl wrapper that will deal with EINTR.
281 ********************************************************************/
283 int sys_fcntl_long(int fd
, int cmd
, long arg
)
288 ret
= fcntl(fd
, cmd
, arg
);
289 } while (ret
== -1 && errno
== EINTR
);
293 /****************************************************************************
294 Get/Set all the possible time fields from a stat struct as a timespec.
295 ****************************************************************************/
297 static struct timespec
get_atimespec(const struct stat
*pst
)
299 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
302 /* Old system - no ns timestamp. */
303 ret
.tv_sec
= pst
->st_atime
;
307 #if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
309 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
311 ret
.tv_sec
= pst
->st_atime
;
312 ret
.tv_nsec
= pst
->st_atimensec
;
314 #elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
316 ret
.tv_sec
= pst
->st_atime
;
317 ret
.tv_nsec
= pst
->st_atime_n
;
319 #elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
321 ret
.tv_sec
= pst
->st_atime
;
322 ret
.tv_nsec
= pst
->st_uatime
* 1000;
324 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
325 return pst
->st_atimespec
;
327 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
332 static struct timespec
get_mtimespec(const struct stat
*pst
)
334 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
337 /* Old system - no ns timestamp. */
338 ret
.tv_sec
= pst
->st_mtime
;
342 #if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
344 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
346 ret
.tv_sec
= pst
->st_mtime
;
347 ret
.tv_nsec
= pst
->st_mtimensec
;
349 #elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
351 ret
.tv_sec
= pst
->st_mtime
;
352 ret
.tv_nsec
= pst
->st_mtime_n
;
354 #elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
356 ret
.tv_sec
= pst
->st_mtime
;
357 ret
.tv_nsec
= pst
->st_umtime
* 1000;
359 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
360 return pst
->st_mtimespec
;
362 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
367 static struct timespec
get_ctimespec(const struct stat
*pst
)
369 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
372 /* Old system - no ns timestamp. */
373 ret
.tv_sec
= pst
->st_ctime
;
377 #if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
379 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
381 ret
.tv_sec
= pst
->st_ctime
;
382 ret
.tv_nsec
= pst
->st_ctimensec
;
384 #elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
386 ret
.tv_sec
= pst
->st_ctime
;
387 ret
.tv_nsec
= pst
->st_ctime_n
;
389 #elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
391 ret
.tv_sec
= pst
->st_ctime
;
392 ret
.tv_nsec
= pst
->st_uctime
* 1000;
394 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
395 return pst
->st_ctimespec
;
397 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
402 /****************************************************************************
403 Return the best approximation to a 'create time' under UNIX from a stat
405 ****************************************************************************/
407 static struct timespec
calc_create_time_stat(const struct stat
*st
)
409 struct timespec ret
, ret1
;
410 struct timespec c_time
= get_ctimespec(st
);
411 struct timespec m_time
= get_mtimespec(st
);
412 struct timespec a_time
= get_atimespec(st
);
414 ret
= timespec_compare(&c_time
, &m_time
) < 0 ? c_time
: m_time
;
415 ret1
= timespec_compare(&ret
, &a_time
) < 0 ? ret
: a_time
;
417 if(!null_timespec(ret1
)) {
422 * One of ctime, mtime or atime was zero (probably atime).
423 * Just return MIN(ctime, mtime).
428 /****************************************************************************
429 Return the best approximation to a 'create time' under UNIX from a stat_ex
431 ****************************************************************************/
433 static struct timespec
calc_create_time_stat_ex(const struct stat_ex
*st
)
435 struct timespec ret
, ret1
;
436 struct timespec c_time
= st
->st_ex_ctime
;
437 struct timespec m_time
= st
->st_ex_mtime
;
438 struct timespec a_time
= st
->st_ex_atime
;
440 ret
= timespec_compare(&c_time
, &m_time
) < 0 ? c_time
: m_time
;
441 ret1
= timespec_compare(&ret
, &a_time
) < 0 ? ret
: a_time
;
443 if(!null_timespec(ret1
)) {
448 * One of ctime, mtime or atime was zero (probably atime).
449 * Just return MIN(ctime, mtime).
454 /****************************************************************************
455 Return the 'create time' from a stat struct if it exists (birthtime) or else
456 use the best approximation.
457 ****************************************************************************/
459 static void make_create_timespec(const struct stat
*pst
, struct stat_ex
*dst
,
460 bool fake_dir_create_times
)
462 if (S_ISDIR(pst
->st_mode
) && fake_dir_create_times
) {
463 dst
->st_ex_btime
.tv_sec
= 315493200L; /* 1/1/1980 */
464 dst
->st_ex_btime
.tv_nsec
= 0;
467 dst
->st_ex_calculated_birthtime
= false;
469 #if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC)
470 dst
->st_ex_btime
= pst
->st_birthtimespec
;
471 #elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
472 dst
->st_ex_btime
.tv_sec
= pst
->st_birthtime
;
473 dst
->st_ex_btime
.tv_nsec
= pst
->st_birthtimenspec
;
474 #elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
475 dst
->st_ex_btime
.tv_sec
= pst
->st_birthtime
;
476 dst
->st_ex_btime
.tv_nsec
= 0;
478 dst
->st_ex_btime
= calc_create_time_stat(pst
);
479 dst
->st_ex_calculated_birthtime
= true;
482 /* Deal with systems that don't initialize birthtime correctly.
483 * Pointed out by SATOH Fumiyasu <fumiyas@osstech.jp>.
485 if (null_timespec(dst
->st_ex_btime
)) {
486 dst
->st_ex_btime
= calc_create_time_stat(pst
);
487 dst
->st_ex_calculated_birthtime
= true;
491 /****************************************************************************
492 If we update a timestamp in a stat_ex struct we may have to recalculate
493 the birthtime. For now only implement this for write time, but we may
494 also need to do it for atime and ctime. JRA.
495 ****************************************************************************/
497 void update_stat_ex_mtime(struct stat_ex
*dst
,
498 struct timespec write_ts
)
500 dst
->st_ex_mtime
= write_ts
;
502 /* We may have to recalculate btime. */
503 if (dst
->st_ex_calculated_birthtime
) {
504 dst
->st_ex_btime
= calc_create_time_stat_ex(dst
);
508 void update_stat_ex_create_time(struct stat_ex
*dst
,
509 struct timespec create_time
)
511 dst
->st_ex_btime
= create_time
;
512 dst
->st_ex_calculated_birthtime
= false;
515 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
516 static void init_stat_ex_from_stat (struct stat_ex
*dst
,
517 const struct stat64
*src
,
518 bool fake_dir_create_times
)
520 static void init_stat_ex_from_stat (struct stat_ex
*dst
,
521 const struct stat
*src
,
522 bool fake_dir_create_times
)
525 dst
->st_ex_dev
= src
->st_dev
;
526 dst
->st_ex_ino
= src
->st_ino
;
527 dst
->st_ex_mode
= src
->st_mode
;
528 dst
->st_ex_nlink
= src
->st_nlink
;
529 dst
->st_ex_uid
= src
->st_uid
;
530 dst
->st_ex_gid
= src
->st_gid
;
531 dst
->st_ex_rdev
= src
->st_rdev
;
532 dst
->st_ex_size
= src
->st_size
;
533 dst
->st_ex_atime
= get_atimespec(src
);
534 dst
->st_ex_mtime
= get_mtimespec(src
);
535 dst
->st_ex_ctime
= get_ctimespec(src
);
536 make_create_timespec(src
, dst
, fake_dir_create_times
);
537 dst
->st_ex_blksize
= src
->st_blksize
;
538 dst
->st_ex_blocks
= src
->st_blocks
;
540 #ifdef HAVE_STAT_ST_FLAGS
541 dst
->st_ex_flags
= src
->st_flags
;
543 dst
->st_ex_flags
= 0;
547 /*******************************************************************
548 A stat() wrapper that will deal with 64 bit filesizes.
549 ********************************************************************/
551 int sys_stat(const char *fname
, SMB_STRUCT_STAT
*sbuf
,
552 bool fake_dir_create_times
)
555 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
556 struct stat64 statbuf
;
557 ret
= stat64(fname
, &statbuf
);
560 ret
= stat(fname
, &statbuf
);
563 /* we always want directories to appear zero size */
564 if (S_ISDIR(statbuf
.st_mode
)) {
567 init_stat_ex_from_stat(sbuf
, &statbuf
, fake_dir_create_times
);
572 /*******************************************************************
573 An fstat() wrapper that will deal with 64 bit filesizes.
574 ********************************************************************/
576 int sys_fstat(int fd
, SMB_STRUCT_STAT
*sbuf
, bool fake_dir_create_times
)
579 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
580 struct stat64 statbuf
;
581 ret
= fstat64(fd
, &statbuf
);
584 ret
= fstat(fd
, &statbuf
);
587 /* we always want directories to appear zero size */
588 if (S_ISDIR(statbuf
.st_mode
)) {
591 init_stat_ex_from_stat(sbuf
, &statbuf
, fake_dir_create_times
);
596 /*******************************************************************
597 An lstat() wrapper that will deal with 64 bit filesizes.
598 ********************************************************************/
600 int sys_lstat(const char *fname
,SMB_STRUCT_STAT
*sbuf
,
601 bool fake_dir_create_times
)
604 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
605 struct stat64 statbuf
;
606 ret
= lstat64(fname
, &statbuf
);
609 ret
= lstat(fname
, &statbuf
);
612 /* we always want directories to appear zero size */
613 if (S_ISDIR(statbuf
.st_mode
)) {
616 init_stat_ex_from_stat(sbuf
, &statbuf
, fake_dir_create_times
);
621 /*******************************************************************
622 An posix_fallocate() wrapper that will deal with 64 bit filesizes.
623 ********************************************************************/
624 int sys_posix_fallocate(int fd
, SMB_OFF_T offset
, SMB_OFF_T len
)
626 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_POSIX_FALLOCATE64) && !defined(HAVE_BROKEN_POSIX_FALLOCATE)
627 return posix_fallocate64(fd
, offset
, len
);
628 #elif defined(HAVE_POSIX_FALLOCATE) && !defined(HAVE_BROKEN_POSIX_FALLOCATE)
629 return posix_fallocate(fd
, offset
, len
);
635 /*******************************************************************
636 An ftruncate() wrapper that will deal with 64 bit filesizes.
637 ********************************************************************/
639 int sys_ftruncate(int fd
, SMB_OFF_T offset
)
641 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
642 return ftruncate64(fd
, offset
);
644 return ftruncate(fd
, offset
);
648 /*******************************************************************
649 An lseek() wrapper that will deal with 64 bit filesizes.
650 ********************************************************************/
652 SMB_OFF_T
sys_lseek(int fd
, SMB_OFF_T offset
, int whence
)
654 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
655 return lseek64(fd
, offset
, whence
);
657 return lseek(fd
, offset
, whence
);
661 /*******************************************************************
662 An fseek() wrapper that will deal with 64 bit filesizes.
663 ********************************************************************/
665 int sys_fseek(FILE *fp
, SMB_OFF_T offset
, int whence
)
667 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
668 return fseek64(fp
, offset
, whence
);
669 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
670 return fseeko64(fp
, offset
, whence
);
672 return fseek(fp
, offset
, whence
);
676 /*******************************************************************
677 An ftell() wrapper that will deal with 64 bit filesizes.
678 ********************************************************************/
680 SMB_OFF_T
sys_ftell(FILE *fp
)
682 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
683 return (SMB_OFF_T
)ftell64(fp
);
684 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
685 return (SMB_OFF_T
)ftello64(fp
);
687 return (SMB_OFF_T
)ftell(fp
);
691 /*******************************************************************
692 A creat() wrapper that will deal with 64 bit filesizes.
693 ********************************************************************/
695 int sys_creat(const char *path
, mode_t mode
)
697 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
698 return creat64(path
, mode
);
701 * If creat64 isn't defined then ensure we call a potential open64.
704 return sys_open(path
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
708 /*******************************************************************
709 An open() wrapper that will deal with 64 bit filesizes.
710 ********************************************************************/
712 int sys_open(const char *path
, int oflag
, mode_t mode
)
714 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
715 return open64(path
, oflag
, mode
);
717 return open(path
, oflag
, mode
);
721 /*******************************************************************
722 An fopen() wrapper that will deal with 64 bit filesizes.
723 ********************************************************************/
725 FILE *sys_fopen(const char *path
, const char *type
)
727 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
728 return fopen64(path
, type
);
730 return fopen(path
, type
);
735 /*******************************************************************
736 A flock() wrapper that will perform the kernel flock.
737 ********************************************************************/
739 void kernel_flock(int fd
, uint32 share_mode
, uint32 access_mask
)
741 #if HAVE_KERNEL_SHARE_MODES
743 if (share_mode
== FILE_SHARE_WRITE
) {
744 kernel_mode
= LOCK_MAND
|LOCK_WRITE
;
745 } else if (share_mode
== FILE_SHARE_READ
) {
746 kernel_mode
= LOCK_MAND
|LOCK_READ
;
747 } else if (share_mode
== FILE_SHARE_NONE
) {
748 kernel_mode
= LOCK_MAND
;
751 flock(fd
, kernel_mode
);
759 /*******************************************************************
760 An opendir wrapper that will deal with 64 bit filesizes.
761 ********************************************************************/
763 SMB_STRUCT_DIR
*sys_opendir(const char *name
)
765 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
766 return opendir64(name
);
768 return opendir(name
);
772 /*******************************************************************
773 A readdir wrapper that will deal with 64 bit filesizes.
774 ********************************************************************/
776 SMB_STRUCT_DIRENT
*sys_readdir(SMB_STRUCT_DIR
*dirp
)
778 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
779 return readdir64(dirp
);
781 return readdir(dirp
);
785 /*******************************************************************
786 A seekdir wrapper that will deal with 64 bit filesizes.
787 ********************************************************************/
789 void sys_seekdir(SMB_STRUCT_DIR
*dirp
, long offset
)
791 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
792 seekdir64(dirp
, offset
);
794 seekdir(dirp
, offset
);
798 /*******************************************************************
799 A telldir wrapper that will deal with 64 bit filesizes.
800 ********************************************************************/
802 long sys_telldir(SMB_STRUCT_DIR
*dirp
)
804 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
805 return (long)telldir64(dirp
);
807 return (long)telldir(dirp
);
811 /*******************************************************************
812 A rewinddir wrapper that will deal with 64 bit filesizes.
813 ********************************************************************/
815 void sys_rewinddir(SMB_STRUCT_DIR
*dirp
)
817 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
824 /*******************************************************************
825 A close wrapper that will deal with 64 bit filesizes.
826 ********************************************************************/
828 int sys_closedir(SMB_STRUCT_DIR
*dirp
)
830 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
831 return closedir64(dirp
);
833 return closedir(dirp
);
837 /*******************************************************************
838 An mknod() wrapper that will deal with 64 bit filesizes.
839 ********************************************************************/
841 int sys_mknod(const char *path
, mode_t mode
, SMB_DEV_T dev
)
843 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
844 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
845 return mknod64(path
, mode
, dev
);
847 return mknod(path
, mode
, dev
);
850 /* No mknod system call. */
856 /*******************************************************************
857 The wait() calls vary between systems
858 ********************************************************************/
860 int sys_waitpid(pid_t pid
,int *status
,int options
)
863 return waitpid(pid
,status
,options
);
864 #else /* HAVE_WAITPID */
865 return wait4(pid
, status
, options
, NULL
);
866 #endif /* HAVE_WAITPID */
869 /*******************************************************************
870 System wrapper for getwd
871 ********************************************************************/
873 char *sys_getwd(char *s
)
877 wd
= (char *)getcwd(s
, PATH_MAX
);
879 wd
= (char *)getwd(s
);
884 #if defined(HAVE_POSIX_CAPABILITIES)
886 /* This define hasn't made it into the glibc capabilities header yet. */
887 #ifndef SECURE_NO_SETUID_FIXUP
888 #define SECURE_NO_SETUID_FIXUP 2
891 /**************************************************************************
892 Try and abstract process capabilities (for systems that have them).
893 ****************************************************************************/
895 /* Set the POSIX capabilities needed for the given purpose into the effective
896 * capability set of the current process. Make sure they are always removed
897 * from the inheritable set, because there is no circumstance in which our
898 * children should inherit our elevated privileges.
900 static bool set_process_capability(enum smbd_capability capability
,
903 cap_value_t cap_vals
[2] = {0};
904 int num_cap_vals
= 0;
908 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
909 /* On Linux, make sure that any capabilities we grab are sticky
910 * across UID changes. We expect that this would allow us to keep both
911 * the effective and permitted capability sets, but as of circa 2.6.16,
912 * only the permitted set is kept. It is a bug (which we work around)
913 * that the effective set is lost, but we still require the effective
916 if (!prctl(PR_GET_KEEPCAPS
)) {
917 prctl(PR_SET_KEEPCAPS
, 1);
921 #if defined(HAVE_PRCTL) && defined(PR_SET_SECUREBITS) && defined(SECURE_NO_SETUID_FIXUP)
922 /* New way of setting capabilities as "sticky". */
925 * Use PR_SET_SECUREBITS to prevent setresuid()
926 * atomically dropping effective capabilities on
927 * uid change. Only available in Linux kernels
931 * http://www.kernel.org/doc/man-pages/online/pages/man7/capabilities.7.html
934 * Specifically the CAP_KILL capability we need
935 * to allow Linux threads under different euids
936 * to send signals to each other.
939 if (prctl(PR_SET_SECUREBITS
, 1 << SECURE_NO_SETUID_FIXUP
)) {
940 DEBUG(0,("set_process_capability: "
941 "prctl PR_SET_SECUREBITS failed with error %s\n",
947 cap
= cap_get_proc();
949 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
954 switch (capability
) {
955 case KERNEL_OPLOCK_CAPABILITY
:
956 #ifdef CAP_NETWORK_MGT
957 /* IRIX has CAP_NETWORK_MGT for oplocks. */
958 cap_vals
[num_cap_vals
++] = CAP_NETWORK_MGT
;
961 case DMAPI_ACCESS_CAPABILITY
:
962 #ifdef CAP_DEVICE_MGT
963 /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
964 cap_vals
[num_cap_vals
++] = CAP_DEVICE_MGT
;
966 /* Linux has CAP_MKNOD for DMAPI access. */
967 cap_vals
[num_cap_vals
++] = CAP_MKNOD
;
970 case LEASE_CAPABILITY
:
972 cap_vals
[num_cap_vals
++] = CAP_LEASE
;
975 case KILL_CAPABILITY
:
977 cap_vals
[num_cap_vals
++] = CAP_KILL
;
982 SMB_ASSERT(num_cap_vals
<= ARRAY_SIZE(cap_vals
));
984 if (num_cap_vals
== 0) {
990 * Ensure the capability is effective. We assume that as a root
991 * process it's always permitted.
994 if (cap_set_flag(cap
, CAP_EFFECTIVE
, num_cap_vals
, cap_vals
,
995 enable
? CAP_SET
: CAP_CLEAR
) == -1) {
996 DEBUG(0, ("set_process_capability: cap_set_flag effective "
1004 /* We never want to pass capabilities down to our children, so make
1005 * sure they are not inherited.
1007 if (cap_set_flag(cap
, CAP_INHERITABLE
, num_cap_vals
,
1008 cap_vals
, CAP_CLEAR
) == -1) {
1009 DEBUG(0, ("set_process_capability: cap_set_flag inheritable "
1010 "failed (%d): %s\n",
1017 if (cap_set_proc(cap
) == -1) {
1018 DEBUG(0, ("set_process_capability: cap_set_flag (%d) failed: %s\n",
1029 #endif /* HAVE_POSIX_CAPABILITIES */
1031 /****************************************************************************
1032 Gain the oplock capability from the kernel if possible.
1033 ****************************************************************************/
1035 void set_effective_capability(enum smbd_capability capability
)
1037 #if defined(HAVE_POSIX_CAPABILITIES)
1038 set_process_capability(capability
, True
);
1039 #endif /* HAVE_POSIX_CAPABILITIES */
1042 void drop_effective_capability(enum smbd_capability capability
)
1044 #if defined(HAVE_POSIX_CAPABILITIES)
1045 set_process_capability(capability
, False
);
1046 #endif /* HAVE_POSIX_CAPABILITIES */
1049 /**************************************************************************
1050 Wrapper for random().
1051 ****************************************************************************/
1053 long sys_random(void)
1055 #if defined(HAVE_RANDOM)
1056 return (long)random();
1057 #elif defined(HAVE_RAND)
1058 return (long)rand();
1060 DEBUG(0,("Error - no random function available !\n"));
1065 /**************************************************************************
1066 Wrapper for srandom().
1067 ****************************************************************************/
1069 void sys_srandom(unsigned int seed
)
1071 #if defined(HAVE_SRANDOM)
1073 #elif defined(HAVE_SRAND)
1076 DEBUG(0,("Error - no srandom function available !\n"));
1081 /**************************************************************************
1082 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
1083 ****************************************************************************/
1085 int groups_max(void)
1087 #if defined(SYSCONF_SC_NGROUPS_MAX)
1088 int ret
= sysconf(_SC_NGROUPS_MAX
);
1089 return (ret
== -1) ? NGROUPS_MAX
: ret
;
1095 /**************************************************************************
1096 Wrap setgroups and getgroups for systems that declare getgroups() as
1097 returning an array of gid_t, but actuall return an array of int.
1098 ****************************************************************************/
1100 #if defined(HAVE_BROKEN_GETGROUPS)
1101 static int sys_broken_getgroups(int setlen
, gid_t
*gidset
)
1108 return getgroups(setlen
, &gid
);
1112 * Broken case. We need to allocate a
1113 * GID_T array of size setlen.
1122 setlen
= groups_max();
1124 if((group_list
= SMB_MALLOC_ARRAY(GID_T
, setlen
)) == NULL
) {
1125 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
1129 if((ngroups
= getgroups(setlen
, group_list
)) < 0) {
1130 int saved_errno
= errno
;
1131 SAFE_FREE(group_list
);
1132 errno
= saved_errno
;
1136 for(i
= 0; i
< ngroups
; i
++)
1137 gidset
[i
] = (gid_t
)group_list
[i
];
1139 SAFE_FREE(group_list
);
1143 static int sys_broken_setgroups(int setlen
, gid_t
*gidset
)
1151 if (setlen
< 0 || setlen
> groups_max()) {
1157 * Broken case. We need to allocate a
1158 * GID_T array of size setlen.
1161 if((group_list
= SMB_MALLOC_ARRAY(GID_T
, setlen
)) == NULL
) {
1162 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
1166 for(i
= 0; i
< setlen
; i
++)
1167 group_list
[i
] = (GID_T
) gidset
[i
];
1169 if(setgroups(setlen
, group_list
) != 0) {
1170 int saved_errno
= errno
;
1171 SAFE_FREE(group_list
);
1172 errno
= saved_errno
;
1176 SAFE_FREE(group_list
);
1180 #endif /* HAVE_BROKEN_GETGROUPS */
1182 /* This is a list of systems that require the first GID passed to setgroups(2)
1183 * to be the effective GID. If your system is one of these, add it here.
1185 #if defined (FREEBSD) || defined (DARWINOS)
1186 #define USE_BSD_SETGROUPS
1189 #if defined(USE_BSD_SETGROUPS)
1190 /* Depending on the particular BSD implementation, the first GID that is
1191 * passed to setgroups(2) will either be ignored or will set the credential's
1192 * effective GID. In either case, the right thing to do is to guarantee that
1193 * gidset[0] is the effective GID.
1195 static int sys_bsd_setgroups(gid_t primary_gid
, int setlen
, const gid_t
*gidset
)
1197 gid_t
*new_gidset
= NULL
;
1201 /* setgroups(2) will fail with EINVAL if we pass too many groups. */
1204 /* No group list, just make sure we are setting the efective GID. */
1206 return setgroups(1, &primary_gid
);
1209 /* If the primary gid is not the first array element, grow the array
1210 * and insert it at the front.
1212 if (gidset
[0] != primary_gid
) {
1213 new_gidset
= SMB_MALLOC_ARRAY(gid_t
, setlen
+ 1);
1214 if (new_gidset
== NULL
) {
1218 memcpy(new_gidset
+ 1, gidset
, (setlen
* sizeof(gid_t
)));
1219 new_gidset
[0] = primary_gid
;
1224 DEBUG(3, ("forced to truncate group list from %d to %d\n",
1229 #if defined(HAVE_BROKEN_GETGROUPS)
1230 ret
= sys_broken_setgroups(setlen
, new_gidset
? new_gidset
: gidset
);
1232 ret
= setgroups(setlen
, new_gidset
? new_gidset
: gidset
);
1237 SAFE_FREE(new_gidset
);
1244 #endif /* USE_BSD_SETGROUPS */
1246 /**************************************************************************
1247 Wrapper for getgroups. Deals with broken (int) case.
1248 ****************************************************************************/
1250 int sys_getgroups(int setlen
, gid_t
*gidset
)
1252 #if defined(HAVE_BROKEN_GETGROUPS)
1253 return sys_broken_getgroups(setlen
, gidset
);
1255 return getgroups(setlen
, gidset
);
1259 /**************************************************************************
1260 Wrapper for setgroups. Deals with broken (int) case and BSD case.
1261 ****************************************************************************/
1263 int sys_setgroups(gid_t
UNUSED(primary_gid
), int setlen
, gid_t
*gidset
)
1265 #if !defined(HAVE_SETGROUPS)
1268 #endif /* HAVE_SETGROUPS */
1270 #if defined(USE_BSD_SETGROUPS)
1271 return sys_bsd_setgroups(primary_gid
, setlen
, gidset
);
1272 #elif defined(HAVE_BROKEN_GETGROUPS)
1273 return sys_broken_setgroups(setlen
, gidset
);
1275 return setgroups(setlen
, gidset
);
1279 /**************************************************************************
1280 Wrappers for setpwent(), getpwent() and endpwent()
1281 ****************************************************************************/
1283 void sys_setpwent(void)
1288 struct passwd
*sys_getpwent(void)
1293 void sys_endpwent(void)
1298 /**************************************************************************
1299 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
1300 ****************************************************************************/
1303 struct passwd
*sys_getpwnam(const char *name
)
1305 return getpwnam(name
);
1308 struct passwd
*sys_getpwuid(uid_t uid
)
1310 return getpwuid(uid
);
1313 struct group
*sys_getgrnam(const char *name
)
1315 return getgrnam(name
);
1318 struct group
*sys_getgrgid(gid_t gid
)
1320 return getgrgid(gid
);
1323 /**************************************************************************
1324 Extract a command into an arg list.
1325 ****************************************************************************/
1327 static char **extract_args(TALLOC_CTX
*mem_ctx
, const char *command
)
1336 if (!(trunc_cmd
= talloc_strdup(mem_ctx
, command
))) {
1337 DEBUG(0, ("talloc failed\n"));
1341 if(!(ptr
= strtok_r(trunc_cmd
, " \t", &saveptr
))) {
1342 TALLOC_FREE(trunc_cmd
);
1351 for( argcl
= 1; ptr
; ptr
= strtok_r(NULL
, " \t", &saveptr
))
1354 TALLOC_FREE(trunc_cmd
);
1356 if (!(argl
= TALLOC_ARRAY(mem_ctx
, char *, argcl
+ 1))) {
1361 * Now do the extraction.
1364 if (!(trunc_cmd
= talloc_strdup(mem_ctx
, command
))) {
1368 ptr
= strtok_r(trunc_cmd
, " \t", &saveptr
);
1371 if (!(argl
[i
++] = talloc_strdup(argl
, ptr
))) {
1375 while((ptr
= strtok_r(NULL
, " \t", &saveptr
)) != NULL
) {
1377 if (!(argl
[i
++] = talloc_strdup(argl
, ptr
))) {
1383 TALLOC_FREE(trunc_cmd
);
1387 DEBUG(0, ("talloc failed\n"));
1388 TALLOC_FREE(trunc_cmd
);
1394 /**************************************************************************
1395 Wrapper for popen. Safer as it doesn't search a path.
1396 Modified from the glibc sources.
1397 modified by tridge to return a file descriptor. We must kick our FILE* habit
1398 ****************************************************************************/
1400 typedef struct _popen_list
1404 struct _popen_list
*next
;
1407 static popen_list
*popen_chain
;
1409 int sys_popen(const char *command
)
1411 int parent_end
, child_end
;
1413 popen_list
*entry
= NULL
;
1416 if (pipe(pipe_fds
) < 0)
1419 parent_end
= pipe_fds
[0];
1420 child_end
= pipe_fds
[1];
1427 if((entry
= SMB_MALLOC_P(popen_list
)) == NULL
)
1430 ZERO_STRUCTP(entry
);
1433 * Extract the command and args into a NULL terminated array.
1436 if(!(argl
= extract_args(NULL
, command
)))
1439 entry
->child_pid
= sys_fork();
1441 if (entry
->child_pid
== -1) {
1445 if (entry
->child_pid
== 0) {
1451 int child_std_end
= STDOUT_FILENO
;
1455 if (child_end
!= child_std_end
) {
1456 dup2 (child_end
, child_std_end
);
1461 * POSIX.2: "popen() shall ensure that any streams from previous
1462 * popen() calls that remain open in the parent process are closed
1463 * in the new child process."
1466 for (p
= popen_chain
; p
; p
= p
->next
)
1469 execv(argl
[0], argl
);
1480 /* Link into popen_chain. */
1481 entry
->next
= popen_chain
;
1482 popen_chain
= entry
;
1483 entry
->fd
= parent_end
;
1496 /**************************************************************************
1497 Wrapper for pclose. Modified from the glibc sources.
1498 ****************************************************************************/
1500 int sys_pclose(int fd
)
1503 popen_list
**ptr
= &popen_chain
;
1504 popen_list
*entry
= NULL
;
1508 /* Unlink from popen_chain. */
1509 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
) {
1510 if ((*ptr
)->fd
== fd
) {
1512 *ptr
= (*ptr
)->next
;
1518 if (status
< 0 || close(entry
->fd
) < 0)
1522 * As Samba is catching and eating child process
1523 * exits we don't really care about the child exit
1524 * code, a -1 with errno = ECHILD will do fine for us.
1528 wait_pid
= sys_waitpid (entry
->child_pid
, &wstatus
, 0);
1529 } while (wait_pid
== -1 && errno
== EINTR
);
1538 /**************************************************************************
1539 Wrapper for Admin Logs.
1540 ****************************************************************************/
1542 void sys_adminlog(int priority
, const char *format_str
, ...)
1546 char *msgbuf
= NULL
;
1548 va_start( ap
, format_str
);
1549 ret
= vasprintf( &msgbuf
, format_str
, ap
);
1555 #if defined(HAVE_SYSLOG)
1556 syslog( priority
, "%s", msgbuf
);
1558 DEBUG(0,("%s", msgbuf
));
1563 /******** Solaris EA helper function prototypes ********/
1564 #ifdef HAVE_ATTROPEN
1565 #define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
1566 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
);
1567 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
);
1568 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
);
1569 static int solaris_unlinkat(int attrdirfd
, const char *name
);
1570 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
);
1571 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
);
1574 /**************************************************************************
1575 Wrappers for extented attribute calls. Based on the Linux package with
1576 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1577 ****************************************************************************/
1579 ssize_t
sys_getxattr (const char *path
, const char *name
, void *value
, size_t size
)
1581 #if defined(HAVE_GETXATTR)
1582 #ifndef XATTR_ADD_OPT
1583 return getxattr(path
, name
, value
, size
);
1586 return getxattr(path
, name
, value
, size
, 0, options
);
1588 #elif defined(HAVE_GETEA)
1589 return getea(path
, name
, value
, size
);
1590 #elif defined(HAVE_EXTATTR_GET_FILE)
1593 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1594 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1595 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1597 * The BSD implementation has a nasty habit of silently truncating
1598 * the returned value to the size of the buffer, so we have to check
1599 * that the buffer is large enough to fit the returned value.
1601 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1606 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1610 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno
)));
1612 #elif defined(HAVE_ATTR_GET)
1613 int retval
, flags
= 0;
1614 int valuelength
= (int)size
;
1615 char *attrname
= strchr(name
,'.') + 1;
1617 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1619 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1621 return retval
? retval
: valuelength
;
1622 #elif defined(HAVE_ATTROPEN)
1624 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
, 0);
1626 ret
= solaris_read_xattr(attrfd
, value
, size
);
1636 ssize_t
sys_lgetxattr (const char *path
, const char *name
, void *value
, size_t size
)
1638 #if defined(HAVE_LGETXATTR)
1639 return lgetxattr(path
, name
, value
, size
);
1640 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
1641 int options
= XATTR_NOFOLLOW
;
1642 return getxattr(path
, name
, value
, size
, 0, options
);
1643 #elif defined(HAVE_LGETEA)
1644 return lgetea(path
, name
, value
, size
);
1645 #elif defined(HAVE_EXTATTR_GET_LINK)
1648 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1649 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1650 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1652 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1657 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1661 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno
)));
1663 #elif defined(HAVE_ATTR_GET)
1664 int retval
, flags
= ATTR_DONTFOLLOW
;
1665 int valuelength
= (int)size
;
1666 char *attrname
= strchr(name
,'.') + 1;
1668 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1670 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1672 return retval
? retval
: valuelength
;
1673 #elif defined(HAVE_ATTROPEN)
1675 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1677 ret
= solaris_read_xattr(attrfd
, value
, size
);
1687 ssize_t
sys_fgetxattr (int filedes
, const char *name
, void *value
, size_t size
)
1689 #if defined(HAVE_FGETXATTR)
1690 #ifndef XATTR_ADD_OPT
1691 return fgetxattr(filedes
, name
, value
, size
);
1694 return fgetxattr(filedes
, name
, value
, size
, 0, options
);
1696 #elif defined(HAVE_FGETEA)
1697 return fgetea(filedes
, name
, value
, size
);
1698 #elif defined(HAVE_EXTATTR_GET_FD)
1701 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1702 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1703 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1705 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1710 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, value
, size
)) >= 0)
1714 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno
)));
1716 #elif defined(HAVE_ATTR_GETF)
1717 int retval
, flags
= 0;
1718 int valuelength
= (int)size
;
1719 char *attrname
= strchr(name
,'.') + 1;
1721 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1723 retval
= attr_getf(filedes
, attrname
, (char *)value
, &valuelength
, flags
);
1725 return retval
? retval
: valuelength
;
1726 #elif defined(HAVE_ATTROPEN)
1728 int attrfd
= solaris_openat(filedes
, name
, O_RDONLY
|O_XATTR
, 0);
1730 ret
= solaris_read_xattr(attrfd
, value
, size
);
1740 #if defined(HAVE_EXTATTR_LIST_FILE)
1742 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1750 { EXTATTR_NAMESPACE_SYSTEM
, EXTATTR_PREFIX("system.") },
1751 { EXTATTR_NAMESPACE_USER
, EXTATTR_PREFIX("user.") },
1759 static ssize_t
bsd_attr_list (int type
, extattr_arg arg
, char *list
, size_t size
)
1761 ssize_t list_size
, total_size
= 0;
1764 /* Iterate through extattr(2) namespaces */
1765 for(t
= 0; t
< (sizeof(extattr
)/sizeof(extattr
[0])); t
++) {
1767 #if defined(HAVE_EXTATTR_LIST_FILE)
1769 list_size
= extattr_list_file(arg
.path
, extattr
[t
].space
, list
, size
);
1772 #if defined(HAVE_EXTATTR_LIST_LINK)
1774 list_size
= extattr_list_link(arg
.path
, extattr
[t
].space
, list
, size
);
1777 #if defined(HAVE_EXTATTR_LIST_FD)
1779 list_size
= extattr_list_fd(arg
.filedes
, extattr
[t
].space
, list
, size
);
1786 /* Some error happend. Errno should be set by the previous call */
1792 /* XXX: Call with an empty buffer may be used to calculate
1793 necessary buffer size. Unfortunately, we can't say, how
1794 many attributes were returned, so here is the potential
1795 problem with the emulation.
1798 /* Take the worse case of one char attribute names -
1799 two bytes per name plus one more for sanity.
1801 total_size
+= list_size
+ (list_size
/2 + 1)*extattr
[t
].len
;
1804 /* Count necessary offset to fit namespace prefixes */
1806 for(i
= 0; i
< list_size
; i
+= list
[i
] + 1)
1807 len
+= extattr
[t
].len
;
1809 total_size
+= list_size
+ len
;
1810 /* Buffer is too small to fit the results */
1811 if(total_size
> size
) {
1815 /* Shift results back, so we can prepend prefixes */
1816 buf
= memmove(list
+ len
, list
, list_size
);
1818 for(i
= 0; i
< list_size
; i
+= len
+ 1) {
1820 strncpy(list
, extattr
[t
].name
, extattr
[t
].len
+ 1);
1821 list
+= extattr
[t
].len
;
1822 strncpy(list
, buf
+ i
+ 1, len
);
1833 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1834 static char attr_buffer
[ATTR_MAX_VALUELEN
];
1836 static ssize_t
irix_attr_list(const char *path
, int filedes
, char *list
, size_t size
, int flags
)
1838 int retval
= 0, index
;
1839 attrlist_cursor_t
*cursor
= 0;
1841 attrlist_t
* al
= (attrlist_t
*)attr_buffer
;
1843 size_t ent_size
, left
= size
;
1848 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1850 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1852 for (index
= 0; index
< al
->al_count
; index
++) {
1853 ae
= ATTR_ENTRY(attr_buffer
, index
);
1854 ent_size
= strlen(ae
->a_name
) + sizeof("user.");
1855 if (left
>= ent_size
) {
1856 strncpy(bp
, "user.", sizeof("user."));
1857 strncat(bp
, ae
->a_name
, ent_size
- sizeof("user."));
1865 total_size
+= ent_size
;
1867 if (al
->al_more
== 0) break;
1874 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1876 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1878 for (index
= 0; index
< al
->al_count
; index
++) {
1879 ae
= ATTR_ENTRY(attr_buffer
, index
);
1880 ent_size
= strlen(ae
->a_name
) + sizeof("system.");
1881 if (left
>= ent_size
) {
1882 strncpy(bp
, "system.", sizeof("system."));
1883 strncat(bp
, ae
->a_name
, ent_size
- sizeof("system."));
1891 total_size
+= ent_size
;
1893 if (al
->al_more
== 0) break;
1896 return (ssize_t
)(retval
? retval
: total_size
);
1901 ssize_t
sys_listxattr (const char *path
, char *list
, size_t size
)
1903 #if defined(HAVE_LISTXATTR)
1904 #ifndef XATTR_ADD_OPT
1905 return listxattr(path
, list
, size
);
1908 return listxattr(path
, list
, size
, options
);
1910 #elif defined(HAVE_LISTEA)
1911 return listea(path
, list
, size
);
1912 #elif defined(HAVE_EXTATTR_LIST_FILE)
1915 return bsd_attr_list(0, arg
, list
, size
);
1916 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1917 return irix_attr_list(path
, 0, list
, size
, 0);
1918 #elif defined(HAVE_ATTROPEN)
1920 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
1921 if (attrdirfd
>= 0) {
1922 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1932 ssize_t
sys_llistxattr (const char *path
, char *list
, size_t size
)
1934 #if defined(HAVE_LLISTXATTR)
1935 return llistxattr(path
, list
, size
);
1936 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
1937 int options
= XATTR_NOFOLLOW
;
1938 return listxattr(path
, list
, size
, options
);
1939 #elif defined(HAVE_LLISTEA)
1940 return llistea(path
, list
, size
);
1941 #elif defined(HAVE_EXTATTR_LIST_LINK)
1944 return bsd_attr_list(1, arg
, list
, size
);
1945 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1946 return irix_attr_list(path
, 0, list
, size
, ATTR_DONTFOLLOW
);
1947 #elif defined(HAVE_ATTROPEN)
1949 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1950 if (attrdirfd
>= 0) {
1951 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1961 ssize_t
sys_flistxattr (int filedes
, char *list
, size_t size
)
1963 #if defined(HAVE_FLISTXATTR)
1964 #ifndef XATTR_ADD_OPT
1965 return flistxattr(filedes
, list
, size
);
1968 return flistxattr(filedes
, list
, size
, options
);
1970 #elif defined(HAVE_FLISTEA)
1971 return flistea(filedes
, list
, size
);
1972 #elif defined(HAVE_EXTATTR_LIST_FD)
1974 arg
.filedes
= filedes
;
1975 return bsd_attr_list(2, arg
, list
, size
);
1976 #elif defined(HAVE_ATTR_LISTF)
1977 return irix_attr_list(NULL
, filedes
, list
, size
, 0);
1978 #elif defined(HAVE_ATTROPEN)
1980 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
1981 if (attrdirfd
>= 0) {
1982 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1992 int sys_removexattr (const char *path
, const char *name
)
1994 #if defined(HAVE_REMOVEXATTR)
1995 #ifndef XATTR_ADD_OPT
1996 return removexattr(path
, name
);
1999 return removexattr(path
, name
, options
);
2001 #elif defined(HAVE_REMOVEEA)
2002 return removeea(path
, name
);
2003 #elif defined(HAVE_EXTATTR_DELETE_FILE)
2005 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2006 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2007 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2009 return extattr_delete_file(path
, attrnamespace
, attrname
);
2010 #elif defined(HAVE_ATTR_REMOVE)
2012 char *attrname
= strchr(name
,'.') + 1;
2014 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2016 return attr_remove(path
, attrname
, flags
);
2017 #elif defined(HAVE_ATTROPEN)
2019 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
2020 if (attrdirfd
>= 0) {
2021 ret
= solaris_unlinkat(attrdirfd
, name
);
2031 int sys_lremovexattr (const char *path
, const char *name
)
2033 #if defined(HAVE_LREMOVEXATTR)
2034 return lremovexattr(path
, name
);
2035 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
2036 int options
= XATTR_NOFOLLOW
;
2037 return removexattr(path
, name
, options
);
2038 #elif defined(HAVE_LREMOVEEA)
2039 return lremoveea(path
, name
);
2040 #elif defined(HAVE_EXTATTR_DELETE_LINK)
2042 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2043 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2044 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2046 return extattr_delete_link(path
, attrnamespace
, attrname
);
2047 #elif defined(HAVE_ATTR_REMOVE)
2048 int flags
= ATTR_DONTFOLLOW
;
2049 char *attrname
= strchr(name
,'.') + 1;
2051 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2053 return attr_remove(path
, attrname
, flags
);
2054 #elif defined(HAVE_ATTROPEN)
2056 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
2057 if (attrdirfd
>= 0) {
2058 ret
= solaris_unlinkat(attrdirfd
, name
);
2068 int sys_fremovexattr (int filedes
, const char *name
)
2070 #if defined(HAVE_FREMOVEXATTR)
2071 #ifndef XATTR_ADD_OPT
2072 return fremovexattr(filedes
, name
);
2075 return fremovexattr(filedes
, name
, options
);
2077 #elif defined(HAVE_FREMOVEEA)
2078 return fremoveea(filedes
, name
);
2079 #elif defined(HAVE_EXTATTR_DELETE_FD)
2081 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2082 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2083 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2085 return extattr_delete_fd(filedes
, attrnamespace
, attrname
);
2086 #elif defined(HAVE_ATTR_REMOVEF)
2088 char *attrname
= strchr(name
,'.') + 1;
2090 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2092 return attr_removef(filedes
, attrname
, flags
);
2093 #elif defined(HAVE_ATTROPEN)
2095 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
2096 if (attrdirfd
>= 0) {
2097 ret
= solaris_unlinkat(attrdirfd
, name
);
2107 int sys_setxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2109 #if defined(HAVE_SETXATTR)
2110 #ifndef XATTR_ADD_OPT
2111 return setxattr(path
, name
, value
, size
, flags
);
2114 return setxattr(path
, name
, value
, size
, 0, options
);
2116 #elif defined(HAVE_SETEA)
2117 return setea(path
, name
, value
, size
, flags
);
2118 #elif defined(HAVE_EXTATTR_SET_FILE)
2121 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2122 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2123 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2125 /* Check attribute existence */
2126 retval
= extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0);
2128 /* REPLACE attribute, that doesn't exist */
2129 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2133 /* Ignore other errors */
2136 /* CREATE attribute, that already exists */
2137 if (flags
& XATTR_CREATE
) {
2143 retval
= extattr_set_file(path
, attrnamespace
, attrname
, value
, size
);
2144 return (retval
< 0) ? -1 : 0;
2145 #elif defined(HAVE_ATTR_SET)
2147 char *attrname
= strchr(name
,'.') + 1;
2149 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2150 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2151 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2153 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2154 #elif defined(HAVE_ATTROPEN)
2156 int myflags
= O_RDWR
;
2158 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2159 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2160 attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2162 ret
= solaris_write_xattr(attrfd
, value
, size
);
2172 int sys_lsetxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2174 #if defined(HAVE_LSETXATTR)
2175 return lsetxattr(path
, name
, value
, size
, flags
);
2176 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
2177 int options
= XATTR_NOFOLLOW
;
2178 return setxattr(path
, name
, value
, size
, 0, options
);
2179 #elif defined(LSETEA)
2180 return lsetea(path
, name
, value
, size
, flags
);
2181 #elif defined(HAVE_EXTATTR_SET_LINK)
2184 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2185 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2186 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2188 /* Check attribute existence */
2189 retval
= extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0);
2191 /* REPLACE attribute, that doesn't exist */
2192 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2196 /* Ignore other errors */
2199 /* CREATE attribute, that already exists */
2200 if (flags
& XATTR_CREATE
) {
2207 retval
= extattr_set_link(path
, attrnamespace
, attrname
, value
, size
);
2208 return (retval
< 0) ? -1 : 0;
2209 #elif defined(HAVE_ATTR_SET)
2210 int myflags
= ATTR_DONTFOLLOW
;
2211 char *attrname
= strchr(name
,'.') + 1;
2213 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2214 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2215 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2217 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2218 #elif defined(HAVE_ATTROPEN)
2220 int myflags
= O_RDWR
| AT_SYMLINK_NOFOLLOW
;
2222 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2223 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2224 attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2226 ret
= solaris_write_xattr(attrfd
, value
, size
);
2236 int sys_fsetxattr (int filedes
, const char *name
, const void *value
, size_t size
, int flags
)
2238 #if defined(HAVE_FSETXATTR)
2239 #ifndef XATTR_ADD_OPT
2240 return fsetxattr(filedes
, name
, value
, size
, flags
);
2243 return fsetxattr(filedes
, name
, value
, size
, 0, options
);
2245 #elif defined(HAVE_FSETEA)
2246 return fsetea(filedes
, name
, value
, size
, flags
);
2247 #elif defined(HAVE_EXTATTR_SET_FD)
2250 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2251 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2252 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2254 /* Check attribute existence */
2255 retval
= extattr_get_fd(filedes
, attrnamespace
, attrname
, NULL
, 0);
2257 /* REPLACE attribute, that doesn't exist */
2258 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2262 /* Ignore other errors */
2265 /* CREATE attribute, that already exists */
2266 if (flags
& XATTR_CREATE
) {
2272 retval
= extattr_set_fd(filedes
, attrnamespace
, attrname
, value
, size
);
2273 return (retval
< 0) ? -1 : 0;
2274 #elif defined(HAVE_ATTR_SETF)
2276 char *attrname
= strchr(name
,'.') + 1;
2278 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2279 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2280 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2282 return attr_setf(filedes
, attrname
, (const char *)value
, size
, myflags
);
2283 #elif defined(HAVE_ATTROPEN)
2285 int myflags
= O_RDWR
| O_XATTR
;
2287 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2288 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2289 attrfd
= solaris_openat(filedes
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2291 ret
= solaris_write_xattr(attrfd
, value
, size
);
2301 /**************************************************************************
2302 helper functions for Solaris' EA support
2303 ****************************************************************************/
2304 #ifdef HAVE_ATTROPEN
2305 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
)
2309 if (fstat(attrfd
, &sbuf
) == -1) {
2314 /* This is to return the current size of the named extended attribute */
2316 return sbuf
.st_size
;
2319 /* check size and read xattr */
2320 if (sbuf
.st_size
> size
) {
2325 return read(attrfd
, value
, sbuf
.st_size
);
2328 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
)
2333 int newfd
= dup(attrdirfd
);
2334 /* CAUTION: The originating file descriptor should not be
2335 used again following the call to fdopendir().
2336 For that reason we dup() the file descriptor
2337 here to make things more clear. */
2338 dirp
= fdopendir(newfd
);
2340 while ((de
= readdir(dirp
))) {
2341 size_t listlen
= strlen(de
->d_name
);
2342 if (!strcmp(de
->d_name
, ".") || !strcmp(de
->d_name
, "..")) {
2343 /* we don't want "." and ".." here: */
2344 DEBUG(10,("skipped EA %s\n",de
->d_name
));
2349 /* return the current size of the list of extended attribute names*/
2352 /* check size and copy entrieѕ + nul into list. */
2353 if ((len
+ listlen
+ 1) > size
) {
2358 safe_strcpy(list
+ len
, de
->d_name
, listlen
);
2366 if (closedir(dirp
) == -1) {
2367 DEBUG(0,("closedir dirp failed: %s\n",strerror(errno
)));
2373 static int solaris_unlinkat(int attrdirfd
, const char *name
)
2375 if (unlinkat(attrdirfd
, name
, 0) == -1) {
2376 if (errno
== ENOENT
) {
2384 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
)
2386 int filedes
= attropen(path
, attrpath
, oflag
, mode
);
2387 if (filedes
== -1) {
2388 DEBUG(10,("attropen FAILED: path: %s, name: %s, errno: %s\n",path
,attrpath
,strerror(errno
)));
2389 if (errno
== EINVAL
) {
2398 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
)
2400 int filedes
= openat(fildes
, path
, oflag
, mode
);
2401 if (filedes
== -1) {
2402 DEBUG(10,("openat FAILED: fd: %d, path: %s, errno: %s\n",filedes
,path
,strerror(errno
)));
2403 if (errno
== EINVAL
) {
2412 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
)
2414 if ((ftruncate(attrfd
, 0) == 0) && (write(attrfd
, value
, size
) == size
)) {
2417 DEBUG(10,("solaris_write_xattr FAILED!\n"));
2421 #endif /*HAVE_ATTROPEN*/
2424 /****************************************************************************
2425 Return the major devicenumber for UNIX extensions.
2426 ****************************************************************************/
2428 uint32
unix_dev_major(SMB_DEV_T dev
)
2430 #if defined(HAVE_DEVICE_MAJOR_FN)
2431 return (uint32
)major(dev
);
2433 return (uint32
)(dev
>> 8);
2437 /****************************************************************************
2438 Return the minor devicenumber for UNIX extensions.
2439 ****************************************************************************/
2441 uint32
unix_dev_minor(SMB_DEV_T dev
)
2443 #if defined(HAVE_DEVICE_MINOR_FN)
2444 return (uint32
)minor(dev
);
2446 return (uint32
)(dev
& 0xff);
2450 #if defined(WITH_AIO)
2452 /*******************************************************************
2453 An aio_read wrapper that will deal with 64-bit sizes.
2454 ********************************************************************/
2456 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2458 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2459 return aio_read64(aiocb
);
2460 #elif defined(HAVE_AIO_READ)
2461 return aio_read(aiocb
);
2468 /*******************************************************************
2469 An aio_write wrapper that will deal with 64-bit sizes.
2470 ********************************************************************/
2472 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2474 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2475 return aio_write64(aiocb
);
2476 #elif defined(HAVE_AIO_WRITE)
2477 return aio_write(aiocb
);
2484 /*******************************************************************
2485 An aio_return wrapper that will deal with 64-bit sizes.
2486 ********************************************************************/
2488 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2490 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2491 return aio_return64(aiocb
);
2492 #elif defined(HAVE_AIO_RETURN)
2493 return aio_return(aiocb
);
2500 /*******************************************************************
2501 An aio_cancel wrapper that will deal with 64-bit sizes.
2502 ********************************************************************/
2504 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2506 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2507 return aio_cancel64(fd
, aiocb
);
2508 #elif defined(HAVE_AIO_CANCEL)
2509 return aio_cancel(fd
, aiocb
);
2516 /*******************************************************************
2517 An aio_error wrapper that will deal with 64-bit sizes.
2518 ********************************************************************/
2520 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2522 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2523 return aio_error64(aiocb
);
2524 #elif defined(HAVE_AIO_ERROR)
2525 return aio_error(aiocb
);
2532 /*******************************************************************
2533 An aio_fsync wrapper that will deal with 64-bit sizes.
2534 ********************************************************************/
2536 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2538 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2539 return aio_fsync64(op
, aiocb
);
2540 #elif defined(HAVE_AIO_FSYNC)
2541 return aio_fsync(op
, aiocb
);
2548 /*******************************************************************
2549 An aio_fsync wrapper that will deal with 64-bit sizes.
2550 ********************************************************************/
2552 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2554 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2555 return aio_suspend64(cblist
, n
, timeout
);
2556 #elif defined(HAVE_AIO_FSYNC)
2557 return aio_suspend(cblist
, n
, timeout
);
2563 #else /* !WITH_AIO */
2565 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2571 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2577 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2583 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2589 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2595 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2601 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2606 #endif /* WITH_AIO */
2608 int sys_getpeereid( int s
, uid_t
*uid
)
2610 #if defined(HAVE_PEERCRED)
2612 socklen_t cred_len
= sizeof(struct ucred
);
2615 ret
= getsockopt(s
, SOL_SOCKET
, SO_PEERCRED
, (void *)&cred
, &cred_len
);
2620 if (cred_len
!= sizeof(struct ucred
)) {
2633 int sys_getnameinfo(const struct sockaddr
*psa
,
2642 * For Solaris we must make sure salen is the
2643 * correct length for the incoming sa_family.
2646 if (salen
== sizeof(struct sockaddr_storage
)) {
2647 salen
= sizeof(struct sockaddr_in
);
2648 #if defined(HAVE_IPV6)
2649 if (psa
->sa_family
== AF_INET6
) {
2650 salen
= sizeof(struct sockaddr_in6
);
2654 return getnameinfo(psa
, salen
, host
, hostlen
, service
, servlen
, flags
);
2657 int sys_connect(int fd
, const struct sockaddr
* addr
)
2659 socklen_t salen
= -1;
2661 if (addr
->sa_family
== AF_INET
) {
2662 salen
= sizeof(struct sockaddr_in
);
2663 } else if (addr
->sa_family
== AF_UNIX
) {
2664 salen
= sizeof(struct sockaddr_un
);
2666 #if defined(HAVE_IPV6)
2667 else if (addr
->sa_family
== AF_INET6
) {
2668 salen
= sizeof(struct sockaddr_in6
);
2672 return connect(fd
, addr
, salen
);