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 static void init_stat_ex_from_stat (struct stat_ex
*dst
,
516 const struct stat
*src
,
517 bool fake_dir_create_times
)
519 dst
->st_ex_dev
= src
->st_dev
;
520 dst
->st_ex_ino
= src
->st_ino
;
521 dst
->st_ex_mode
= src
->st_mode
;
522 dst
->st_ex_nlink
= src
->st_nlink
;
523 dst
->st_ex_uid
= src
->st_uid
;
524 dst
->st_ex_gid
= src
->st_gid
;
525 dst
->st_ex_rdev
= src
->st_rdev
;
526 dst
->st_ex_size
= src
->st_size
;
527 dst
->st_ex_atime
= get_atimespec(src
);
528 dst
->st_ex_mtime
= get_mtimespec(src
);
529 dst
->st_ex_ctime
= get_ctimespec(src
);
530 make_create_timespec(src
, dst
, fake_dir_create_times
);
531 dst
->st_ex_blksize
= src
->st_blksize
;
532 dst
->st_ex_blocks
= src
->st_blocks
;
534 #ifdef HAVE_STAT_ST_FLAGS
535 dst
->st_ex_flags
= src
->st_flags
;
537 dst
->st_ex_flags
= 0;
541 /*******************************************************************
542 A stat() wrapper that will deal with 64 bit filesizes.
543 ********************************************************************/
545 int sys_stat(const char *fname
, SMB_STRUCT_STAT
*sbuf
,
546 bool fake_dir_create_times
)
549 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
550 ret
= stat64(fname
, sbuf
);
553 ret
= stat(fname
, &statbuf
);
556 /* we always want directories to appear zero size */
557 if (S_ISDIR(statbuf
.st_mode
)) {
560 init_stat_ex_from_stat(sbuf
, &statbuf
, fake_dir_create_times
);
565 /*******************************************************************
566 An fstat() wrapper that will deal with 64 bit filesizes.
567 ********************************************************************/
569 int sys_fstat(int fd
, SMB_STRUCT_STAT
*sbuf
, bool fake_dir_create_times
)
572 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
573 ret
= fstat64(fd
, sbuf
);
576 ret
= fstat(fd
, &statbuf
);
579 /* we always want directories to appear zero size */
580 if (S_ISDIR(statbuf
.st_mode
)) {
583 init_stat_ex_from_stat(sbuf
, &statbuf
, fake_dir_create_times
);
588 /*******************************************************************
589 An lstat() wrapper that will deal with 64 bit filesizes.
590 ********************************************************************/
592 int sys_lstat(const char *fname
,SMB_STRUCT_STAT
*sbuf
,
593 bool fake_dir_create_times
)
596 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
597 ret
= lstat64(fname
, sbuf
);
600 ret
= lstat(fname
, &statbuf
);
603 /* we always want directories to appear zero size */
604 if (S_ISDIR(statbuf
.st_mode
)) {
607 init_stat_ex_from_stat(sbuf
, &statbuf
, fake_dir_create_times
);
612 /*******************************************************************
613 An posix_fallocate() wrapper that will deal with 64 bit filesizes.
614 ********************************************************************/
615 #if defined(HAVE_POSIX_FALLOCATE64) || defined(HAVE_POSIX_FALLOCATE)
616 int sys_posix_fallocate(int fd
, SMB_OFF_T offset
, SMB_OFF_T len
)
618 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_POSIX_FALLOCATE64)
619 return posix_fallocate64(fd
, offset
, len
);
621 return posix_fallocate(fd
, offset
, len
);
626 /*******************************************************************
627 An ftruncate() wrapper that will deal with 64 bit filesizes.
628 ********************************************************************/
630 int sys_ftruncate(int fd
, SMB_OFF_T offset
)
632 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
633 return ftruncate64(fd
, offset
);
635 return ftruncate(fd
, offset
);
639 /*******************************************************************
640 An lseek() wrapper that will deal with 64 bit filesizes.
641 ********************************************************************/
643 SMB_OFF_T
sys_lseek(int fd
, SMB_OFF_T offset
, int whence
)
645 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
646 return lseek64(fd
, offset
, whence
);
648 return lseek(fd
, offset
, whence
);
652 /*******************************************************************
653 An fseek() wrapper that will deal with 64 bit filesizes.
654 ********************************************************************/
656 int sys_fseek(FILE *fp
, SMB_OFF_T offset
, int whence
)
658 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
659 return fseek64(fp
, offset
, whence
);
660 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
661 return fseeko64(fp
, offset
, whence
);
663 return fseek(fp
, offset
, whence
);
667 /*******************************************************************
668 An ftell() wrapper that will deal with 64 bit filesizes.
669 ********************************************************************/
671 SMB_OFF_T
sys_ftell(FILE *fp
)
673 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
674 return (SMB_OFF_T
)ftell64(fp
);
675 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
676 return (SMB_OFF_T
)ftello64(fp
);
678 return (SMB_OFF_T
)ftell(fp
);
682 /*******************************************************************
683 A creat() wrapper that will deal with 64 bit filesizes.
684 ********************************************************************/
686 int sys_creat(const char *path
, mode_t mode
)
688 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
689 return creat64(path
, mode
);
692 * If creat64 isn't defined then ensure we call a potential open64.
695 return sys_open(path
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
699 /*******************************************************************
700 An open() wrapper that will deal with 64 bit filesizes.
701 ********************************************************************/
703 int sys_open(const char *path
, int oflag
, mode_t mode
)
705 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
706 return open64(path
, oflag
, mode
);
708 return open(path
, oflag
, mode
);
712 /*******************************************************************
713 An fopen() wrapper that will deal with 64 bit filesizes.
714 ********************************************************************/
716 FILE *sys_fopen(const char *path
, const char *type
)
718 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
719 return fopen64(path
, type
);
721 return fopen(path
, type
);
726 /*******************************************************************
727 A flock() wrapper that will perform the kernel flock.
728 ********************************************************************/
730 void kernel_flock(int fd
, uint32 share_mode
, uint32 access_mask
)
732 #if HAVE_KERNEL_SHARE_MODES
734 if (share_mode
== FILE_SHARE_WRITE
) {
735 kernel_mode
= LOCK_MAND
|LOCK_WRITE
;
736 } else if (share_mode
== FILE_SHARE_READ
) {
737 kernel_mode
= LOCK_MAND
|LOCK_READ
;
738 } else if (share_mode
== FILE_SHARE_NONE
) {
739 kernel_mode
= LOCK_MAND
;
742 flock(fd
, kernel_mode
);
750 /*******************************************************************
751 An opendir wrapper that will deal with 64 bit filesizes.
752 ********************************************************************/
754 SMB_STRUCT_DIR
*sys_opendir(const char *name
)
756 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
757 return opendir64(name
);
759 return opendir(name
);
763 /*******************************************************************
764 A readdir wrapper that will deal with 64 bit filesizes.
765 ********************************************************************/
767 SMB_STRUCT_DIRENT
*sys_readdir(SMB_STRUCT_DIR
*dirp
)
769 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
770 return readdir64(dirp
);
772 return readdir(dirp
);
776 /*******************************************************************
777 A seekdir wrapper that will deal with 64 bit filesizes.
778 ********************************************************************/
780 void sys_seekdir(SMB_STRUCT_DIR
*dirp
, long offset
)
782 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
783 seekdir64(dirp
, offset
);
785 seekdir(dirp
, offset
);
789 /*******************************************************************
790 A telldir wrapper that will deal with 64 bit filesizes.
791 ********************************************************************/
793 long sys_telldir(SMB_STRUCT_DIR
*dirp
)
795 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
796 return (long)telldir64(dirp
);
798 return (long)telldir(dirp
);
802 /*******************************************************************
803 A rewinddir wrapper that will deal with 64 bit filesizes.
804 ********************************************************************/
806 void sys_rewinddir(SMB_STRUCT_DIR
*dirp
)
808 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
815 /*******************************************************************
816 A close wrapper that will deal with 64 bit filesizes.
817 ********************************************************************/
819 int sys_closedir(SMB_STRUCT_DIR
*dirp
)
821 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
822 return closedir64(dirp
);
824 return closedir(dirp
);
828 /*******************************************************************
829 An mknod() wrapper that will deal with 64 bit filesizes.
830 ********************************************************************/
832 int sys_mknod(const char *path
, mode_t mode
, SMB_DEV_T dev
)
834 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
835 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
836 return mknod64(path
, mode
, dev
);
838 return mknod(path
, mode
, dev
);
841 /* No mknod system call. */
847 /*******************************************************************
848 The wait() calls vary between systems
849 ********************************************************************/
851 int sys_waitpid(pid_t pid
,int *status
,int options
)
854 return waitpid(pid
,status
,options
);
855 #else /* HAVE_WAITPID */
856 return wait4(pid
, status
, options
, NULL
);
857 #endif /* HAVE_WAITPID */
860 /*******************************************************************
861 System wrapper for getwd
862 ********************************************************************/
864 char *sys_getwd(char *s
)
868 wd
= (char *)getcwd(s
, PATH_MAX
);
870 wd
= (char *)getwd(s
);
875 #if defined(HAVE_POSIX_CAPABILITIES)
877 /**************************************************************************
878 Try and abstract process capabilities (for systems that have them).
879 ****************************************************************************/
881 /* Set the POSIX capabilities needed for the given purpose into the effective
882 * capability set of the current process. Make sure they are always removed
883 * from the inheritable set, because there is no circumstance in which our
884 * children should inherit our elevated privileges.
886 static bool set_process_capability(enum smbd_capability capability
,
889 cap_value_t cap_vals
[2] = {0};
890 int num_cap_vals
= 0;
894 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
895 /* On Linux, make sure that any capabilities we grab are sticky
896 * across UID changes. We expect that this would allow us to keep both
897 * the effective and permitted capability sets, but as of circa 2.6.16,
898 * only the permitted set is kept. It is a bug (which we work around)
899 * that the effective set is lost, but we still require the effective
902 if (!prctl(PR_GET_KEEPCAPS
)) {
903 prctl(PR_SET_KEEPCAPS
, 1);
907 cap
= cap_get_proc();
909 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
914 switch (capability
) {
915 case KERNEL_OPLOCK_CAPABILITY
:
916 #ifdef CAP_NETWORK_MGT
917 /* IRIX has CAP_NETWORK_MGT for oplocks. */
918 cap_vals
[num_cap_vals
++] = CAP_NETWORK_MGT
;
921 case DMAPI_ACCESS_CAPABILITY
:
922 #ifdef CAP_DEVICE_MGT
923 /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
924 cap_vals
[num_cap_vals
++] = CAP_DEVICE_MGT
;
926 /* Linux has CAP_MKNOD for DMAPI access. */
927 cap_vals
[num_cap_vals
++] = CAP_MKNOD
;
930 case LEASE_CAPABILITY
:
932 cap_vals
[num_cap_vals
++] = CAP_LEASE
;
937 SMB_ASSERT(num_cap_vals
<= ARRAY_SIZE(cap_vals
));
939 if (num_cap_vals
== 0) {
944 cap_set_flag(cap
, CAP_EFFECTIVE
, num_cap_vals
, cap_vals
,
945 enable
? CAP_SET
: CAP_CLEAR
);
947 /* We never want to pass capabilities down to our children, so make
948 * sure they are not inherited.
950 cap_set_flag(cap
, CAP_INHERITABLE
, num_cap_vals
, cap_vals
, CAP_CLEAR
);
952 if (cap_set_proc(cap
) == -1) {
953 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
963 #endif /* HAVE_POSIX_CAPABILITIES */
965 /****************************************************************************
966 Gain the oplock capability from the kernel if possible.
967 ****************************************************************************/
969 void set_effective_capability(enum smbd_capability capability
)
971 #if defined(HAVE_POSIX_CAPABILITIES)
972 set_process_capability(capability
, True
);
973 #endif /* HAVE_POSIX_CAPABILITIES */
976 void drop_effective_capability(enum smbd_capability capability
)
978 #if defined(HAVE_POSIX_CAPABILITIES)
979 set_process_capability(capability
, False
);
980 #endif /* HAVE_POSIX_CAPABILITIES */
983 /**************************************************************************
984 Wrapper for random().
985 ****************************************************************************/
987 long sys_random(void)
989 #if defined(HAVE_RANDOM)
990 return (long)random();
991 #elif defined(HAVE_RAND)
994 DEBUG(0,("Error - no random function available !\n"));
999 /**************************************************************************
1000 Wrapper for srandom().
1001 ****************************************************************************/
1003 void sys_srandom(unsigned int seed
)
1005 #if defined(HAVE_SRANDOM)
1007 #elif defined(HAVE_SRAND)
1010 DEBUG(0,("Error - no srandom function available !\n"));
1015 /**************************************************************************
1016 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
1017 ****************************************************************************/
1019 int groups_max(void)
1021 #if defined(SYSCONF_SC_NGROUPS_MAX)
1022 int ret
= sysconf(_SC_NGROUPS_MAX
);
1023 return (ret
== -1) ? NGROUPS_MAX
: ret
;
1029 /**************************************************************************
1030 Wrap setgroups and getgroups for systems that declare getgroups() as
1031 returning an array of gid_t, but actuall return an array of int.
1032 ****************************************************************************/
1034 #if defined(HAVE_BROKEN_GETGROUPS)
1035 static int sys_broken_getgroups(int setlen
, gid_t
*gidset
)
1042 return getgroups(setlen
, &gid
);
1046 * Broken case. We need to allocate a
1047 * GID_T array of size setlen.
1056 setlen
= groups_max();
1058 if((group_list
= SMB_MALLOC_ARRAY(GID_T
, setlen
)) == NULL
) {
1059 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
1063 if((ngroups
= getgroups(setlen
, group_list
)) < 0) {
1064 int saved_errno
= errno
;
1065 SAFE_FREE(group_list
);
1066 errno
= saved_errno
;
1070 for(i
= 0; i
< ngroups
; i
++)
1071 gidset
[i
] = (gid_t
)group_list
[i
];
1073 SAFE_FREE(group_list
);
1077 static int sys_broken_setgroups(int setlen
, gid_t
*gidset
)
1085 if (setlen
< 0 || setlen
> groups_max()) {
1091 * Broken case. We need to allocate a
1092 * GID_T array of size setlen.
1095 if((group_list
= SMB_MALLOC_ARRAY(GID_T
, setlen
)) == NULL
) {
1096 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
1100 for(i
= 0; i
< setlen
; i
++)
1101 group_list
[i
] = (GID_T
) gidset
[i
];
1103 if(setgroups(setlen
, group_list
) != 0) {
1104 int saved_errno
= errno
;
1105 SAFE_FREE(group_list
);
1106 errno
= saved_errno
;
1110 SAFE_FREE(group_list
);
1114 #endif /* HAVE_BROKEN_GETGROUPS */
1116 /* This is a list of systems that require the first GID passed to setgroups(2)
1117 * to be the effective GID. If your system is one of these, add it here.
1119 #if defined (FREEBSD) || defined (DARWINOS)
1120 #define USE_BSD_SETGROUPS
1123 #if defined(USE_BSD_SETGROUPS)
1124 /* Depending on the particular BSD implementation, the first GID that is
1125 * passed to setgroups(2) will either be ignored or will set the credential's
1126 * effective GID. In either case, the right thing to do is to guarantee that
1127 * gidset[0] is the effective GID.
1129 static int sys_bsd_setgroups(gid_t primary_gid
, int setlen
, const gid_t
*gidset
)
1131 gid_t
*new_gidset
= NULL
;
1135 /* setgroups(2) will fail with EINVAL if we pass too many groups. */
1138 /* No group list, just make sure we are setting the efective GID. */
1140 return setgroups(1, &primary_gid
);
1143 /* If the primary gid is not the first array element, grow the array
1144 * and insert it at the front.
1146 if (gidset
[0] != primary_gid
) {
1147 new_gidset
= SMB_MALLOC_ARRAY(gid_t
, setlen
+ 1);
1148 if (new_gidset
== NULL
) {
1152 memcpy(new_gidset
+ 1, gidset
, (setlen
* sizeof(gid_t
)));
1153 new_gidset
[0] = primary_gid
;
1158 DEBUG(3, ("forced to truncate group list from %d to %d\n",
1163 #if defined(HAVE_BROKEN_GETGROUPS)
1164 ret
= sys_broken_setgroups(setlen
, new_gidset
? new_gidset
: gidset
);
1166 ret
= setgroups(setlen
, new_gidset
? new_gidset
: gidset
);
1171 SAFE_FREE(new_gidset
);
1178 #endif /* USE_BSD_SETGROUPS */
1180 /**************************************************************************
1181 Wrapper for getgroups. Deals with broken (int) case.
1182 ****************************************************************************/
1184 int sys_getgroups(int setlen
, gid_t
*gidset
)
1186 #if defined(HAVE_BROKEN_GETGROUPS)
1187 return sys_broken_getgroups(setlen
, gidset
);
1189 return getgroups(setlen
, gidset
);
1193 /**************************************************************************
1194 Wrapper for setgroups. Deals with broken (int) case and BSD case.
1195 ****************************************************************************/
1197 int sys_setgroups(gid_t
UNUSED(primary_gid
), int setlen
, gid_t
*gidset
)
1199 #if !defined(HAVE_SETGROUPS)
1202 #endif /* HAVE_SETGROUPS */
1204 #if defined(USE_BSD_SETGROUPS)
1205 return sys_bsd_setgroups(primary_gid
, setlen
, gidset
);
1206 #elif defined(HAVE_BROKEN_GETGROUPS)
1207 return sys_broken_setgroups(setlen
, gidset
);
1209 return setgroups(setlen
, gidset
);
1213 /**************************************************************************
1214 Wrappers for setpwent(), getpwent() and endpwent()
1215 ****************************************************************************/
1217 void sys_setpwent(void)
1222 struct passwd
*sys_getpwent(void)
1227 void sys_endpwent(void)
1232 /**************************************************************************
1233 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
1234 ****************************************************************************/
1237 struct passwd
*sys_getpwnam(const char *name
)
1239 return getpwnam(name
);
1242 struct passwd
*sys_getpwuid(uid_t uid
)
1244 return getpwuid(uid
);
1247 struct group
*sys_getgrnam(const char *name
)
1249 return getgrnam(name
);
1252 struct group
*sys_getgrgid(gid_t gid
)
1254 return getgrgid(gid
);
1257 /**************************************************************************
1258 Extract a command into an arg list.
1259 ****************************************************************************/
1261 static char **extract_args(TALLOC_CTX
*mem_ctx
, const char *command
)
1270 if (!(trunc_cmd
= talloc_strdup(mem_ctx
, command
))) {
1271 DEBUG(0, ("talloc failed\n"));
1275 if(!(ptr
= strtok_r(trunc_cmd
, " \t", &saveptr
))) {
1276 TALLOC_FREE(trunc_cmd
);
1285 for( argcl
= 1; ptr
; ptr
= strtok_r(NULL
, " \t", &saveptr
))
1288 TALLOC_FREE(trunc_cmd
);
1290 if (!(argl
= TALLOC_ARRAY(mem_ctx
, char *, argcl
+ 1))) {
1295 * Now do the extraction.
1298 if (!(trunc_cmd
= talloc_strdup(mem_ctx
, command
))) {
1302 ptr
= strtok_r(trunc_cmd
, " \t", &saveptr
);
1305 if (!(argl
[i
++] = talloc_strdup(argl
, ptr
))) {
1309 while((ptr
= strtok_r(NULL
, " \t", &saveptr
)) != NULL
) {
1311 if (!(argl
[i
++] = talloc_strdup(argl
, ptr
))) {
1317 TALLOC_FREE(trunc_cmd
);
1321 DEBUG(0, ("talloc failed\n"));
1322 TALLOC_FREE(trunc_cmd
);
1328 /**************************************************************************
1329 Wrapper for popen. Safer as it doesn't search a path.
1330 Modified from the glibc sources.
1331 modified by tridge to return a file descriptor. We must kick our FILE* habit
1332 ****************************************************************************/
1334 typedef struct _popen_list
1338 struct _popen_list
*next
;
1341 static popen_list
*popen_chain
;
1343 int sys_popen(const char *command
)
1345 int parent_end
, child_end
;
1347 popen_list
*entry
= NULL
;
1350 if (pipe(pipe_fds
) < 0)
1353 parent_end
= pipe_fds
[0];
1354 child_end
= pipe_fds
[1];
1361 if((entry
= SMB_MALLOC_P(popen_list
)) == NULL
)
1364 ZERO_STRUCTP(entry
);
1367 * Extract the command and args into a NULL terminated array.
1370 if(!(argl
= extract_args(NULL
, command
)))
1373 entry
->child_pid
= sys_fork();
1375 if (entry
->child_pid
== -1) {
1379 if (entry
->child_pid
== 0) {
1385 int child_std_end
= STDOUT_FILENO
;
1389 if (child_end
!= child_std_end
) {
1390 dup2 (child_end
, child_std_end
);
1395 * POSIX.2: "popen() shall ensure that any streams from previous
1396 * popen() calls that remain open in the parent process are closed
1397 * in the new child process."
1400 for (p
= popen_chain
; p
; p
= p
->next
)
1403 execv(argl
[0], argl
);
1414 /* Link into popen_chain. */
1415 entry
->next
= popen_chain
;
1416 popen_chain
= entry
;
1417 entry
->fd
= parent_end
;
1430 /**************************************************************************
1431 Wrapper for pclose. Modified from the glibc sources.
1432 ****************************************************************************/
1434 int sys_pclose(int fd
)
1437 popen_list
**ptr
= &popen_chain
;
1438 popen_list
*entry
= NULL
;
1442 /* Unlink from popen_chain. */
1443 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
) {
1444 if ((*ptr
)->fd
== fd
) {
1446 *ptr
= (*ptr
)->next
;
1452 if (status
< 0 || close(entry
->fd
) < 0)
1456 * As Samba is catching and eating child process
1457 * exits we don't really care about the child exit
1458 * code, a -1 with errno = ECHILD will do fine for us.
1462 wait_pid
= sys_waitpid (entry
->child_pid
, &wstatus
, 0);
1463 } while (wait_pid
== -1 && errno
== EINTR
);
1472 /**************************************************************************
1473 Wrapper for Admin Logs.
1474 ****************************************************************************/
1476 void sys_adminlog(int priority
, const char *format_str
, ...)
1480 char *msgbuf
= NULL
;
1482 va_start( ap
, format_str
);
1483 ret
= vasprintf( &msgbuf
, format_str
, ap
);
1489 #if defined(HAVE_SYSLOG)
1490 syslog( priority
, "%s", msgbuf
);
1492 DEBUG(0,("%s", msgbuf
));
1497 /******** Solaris EA helper function prototypes ********/
1498 #ifdef HAVE_ATTROPEN
1499 #define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
1500 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
);
1501 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
);
1502 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
);
1503 static int solaris_unlinkat(int attrdirfd
, const char *name
);
1504 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
);
1505 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
);
1508 /**************************************************************************
1509 Wrappers for extented attribute calls. Based on the Linux package with
1510 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1511 ****************************************************************************/
1513 ssize_t
sys_getxattr (const char *path
, const char *name
, void *value
, size_t size
)
1515 #if defined(HAVE_GETXATTR)
1516 #ifndef XATTR_ADD_OPT
1517 return getxattr(path
, name
, value
, size
);
1520 return getxattr(path
, name
, value
, size
, 0, options
);
1522 #elif defined(HAVE_GETEA)
1523 return getea(path
, name
, value
, size
);
1524 #elif defined(HAVE_EXTATTR_GET_FILE)
1527 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1528 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1529 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1531 * The BSD implementation has a nasty habit of silently truncating
1532 * the returned value to the size of the buffer, so we have to check
1533 * that the buffer is large enough to fit the returned value.
1535 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1540 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1544 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno
)));
1546 #elif defined(HAVE_ATTR_GET)
1547 int retval
, flags
= 0;
1548 int valuelength
= (int)size
;
1549 char *attrname
= strchr(name
,'.') + 1;
1551 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1553 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1555 return retval
? retval
: valuelength
;
1556 #elif defined(HAVE_ATTROPEN)
1558 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
, 0);
1560 ret
= solaris_read_xattr(attrfd
, value
, size
);
1570 ssize_t
sys_lgetxattr (const char *path
, const char *name
, void *value
, size_t size
)
1572 #if defined(HAVE_LGETXATTR)
1573 return lgetxattr(path
, name
, value
, size
);
1574 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
1575 int options
= XATTR_NOFOLLOW
;
1576 return getxattr(path
, name
, value
, size
, 0, options
);
1577 #elif defined(HAVE_LGETEA)
1578 return lgetea(path
, name
, value
, size
);
1579 #elif defined(HAVE_EXTATTR_GET_LINK)
1582 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1583 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1584 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1586 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1591 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1595 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno
)));
1597 #elif defined(HAVE_ATTR_GET)
1598 int retval
, flags
= ATTR_DONTFOLLOW
;
1599 int valuelength
= (int)size
;
1600 char *attrname
= strchr(name
,'.') + 1;
1602 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1604 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1606 return retval
? retval
: valuelength
;
1607 #elif defined(HAVE_ATTROPEN)
1609 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1611 ret
= solaris_read_xattr(attrfd
, value
, size
);
1621 ssize_t
sys_fgetxattr (int filedes
, const char *name
, void *value
, size_t size
)
1623 #if defined(HAVE_FGETXATTR)
1624 #ifndef XATTR_ADD_OPT
1625 return fgetxattr(filedes
, name
, value
, size
);
1628 return fgetxattr(filedes
, name
, value
, size
, 0, options
);
1630 #elif defined(HAVE_FGETEA)
1631 return fgetea(filedes
, name
, value
, size
);
1632 #elif defined(HAVE_EXTATTR_GET_FD)
1635 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1636 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1637 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1639 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1644 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, value
, size
)) >= 0)
1648 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno
)));
1650 #elif defined(HAVE_ATTR_GETF)
1651 int retval
, flags
= 0;
1652 int valuelength
= (int)size
;
1653 char *attrname
= strchr(name
,'.') + 1;
1655 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1657 retval
= attr_getf(filedes
, attrname
, (char *)value
, &valuelength
, flags
);
1659 return retval
? retval
: valuelength
;
1660 #elif defined(HAVE_ATTROPEN)
1662 int attrfd
= solaris_openat(filedes
, name
, O_RDONLY
|O_XATTR
, 0);
1664 ret
= solaris_read_xattr(attrfd
, value
, size
);
1674 #if defined(HAVE_EXTATTR_LIST_FILE)
1676 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1684 { EXTATTR_NAMESPACE_SYSTEM
, EXTATTR_PREFIX("system.") },
1685 { EXTATTR_NAMESPACE_USER
, EXTATTR_PREFIX("user.") },
1693 static ssize_t
bsd_attr_list (int type
, extattr_arg arg
, char *list
, size_t size
)
1695 ssize_t list_size
, total_size
= 0;
1698 /* Iterate through extattr(2) namespaces */
1699 for(t
= 0; t
< (sizeof(extattr
)/sizeof(extattr
[0])); t
++) {
1701 #if defined(HAVE_EXTATTR_LIST_FILE)
1703 list_size
= extattr_list_file(arg
.path
, extattr
[t
].space
, list
, size
);
1706 #if defined(HAVE_EXTATTR_LIST_LINK)
1708 list_size
= extattr_list_link(arg
.path
, extattr
[t
].space
, list
, size
);
1711 #if defined(HAVE_EXTATTR_LIST_FD)
1713 list_size
= extattr_list_fd(arg
.filedes
, extattr
[t
].space
, list
, size
);
1720 /* Some error happend. Errno should be set by the previous call */
1726 /* XXX: Call with an empty buffer may be used to calculate
1727 necessary buffer size. Unfortunately, we can't say, how
1728 many attributes were returned, so here is the potential
1729 problem with the emulation.
1732 /* Take the worse case of one char attribute names -
1733 two bytes per name plus one more for sanity.
1735 total_size
+= list_size
+ (list_size
/2 + 1)*extattr
[t
].len
;
1738 /* Count necessary offset to fit namespace prefixes */
1740 for(i
= 0; i
< list_size
; i
+= list
[i
] + 1)
1741 len
+= extattr
[t
].len
;
1743 total_size
+= list_size
+ len
;
1744 /* Buffer is too small to fit the results */
1745 if(total_size
> size
) {
1749 /* Shift results back, so we can prepend prefixes */
1750 buf
= memmove(list
+ len
, list
, list_size
);
1752 for(i
= 0; i
< list_size
; i
+= len
+ 1) {
1754 strncpy(list
, extattr
[t
].name
, extattr
[t
].len
+ 1);
1755 list
+= extattr
[t
].len
;
1756 strncpy(list
, buf
+ i
+ 1, len
);
1767 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1768 static char attr_buffer
[ATTR_MAX_VALUELEN
];
1770 static ssize_t
irix_attr_list(const char *path
, int filedes
, char *list
, size_t size
, int flags
)
1772 int retval
= 0, index
;
1773 attrlist_cursor_t
*cursor
= 0;
1775 attrlist_t
* al
= (attrlist_t
*)attr_buffer
;
1777 size_t ent_size
, left
= size
;
1782 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1784 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1786 for (index
= 0; index
< al
->al_count
; index
++) {
1787 ae
= ATTR_ENTRY(attr_buffer
, index
);
1788 ent_size
= strlen(ae
->a_name
) + sizeof("user.");
1789 if (left
>= ent_size
) {
1790 strncpy(bp
, "user.", sizeof("user."));
1791 strncat(bp
, ae
->a_name
, ent_size
- sizeof("user."));
1799 total_size
+= ent_size
;
1801 if (al
->al_more
== 0) break;
1808 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1810 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1812 for (index
= 0; index
< al
->al_count
; index
++) {
1813 ae
= ATTR_ENTRY(attr_buffer
, index
);
1814 ent_size
= strlen(ae
->a_name
) + sizeof("system.");
1815 if (left
>= ent_size
) {
1816 strncpy(bp
, "system.", sizeof("system."));
1817 strncat(bp
, ae
->a_name
, ent_size
- sizeof("system."));
1825 total_size
+= ent_size
;
1827 if (al
->al_more
== 0) break;
1830 return (ssize_t
)(retval
? retval
: total_size
);
1835 ssize_t
sys_listxattr (const char *path
, char *list
, size_t size
)
1837 #if defined(HAVE_LISTXATTR)
1838 #ifndef XATTR_ADD_OPT
1839 return listxattr(path
, list
, size
);
1842 return listxattr(path
, list
, size
, options
);
1844 #elif defined(HAVE_LISTEA)
1845 return listea(path
, list
, size
);
1846 #elif defined(HAVE_EXTATTR_LIST_FILE)
1849 return bsd_attr_list(0, arg
, list
, size
);
1850 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1851 return irix_attr_list(path
, 0, list
, size
, 0);
1852 #elif defined(HAVE_ATTROPEN)
1854 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
1855 if (attrdirfd
>= 0) {
1856 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1866 ssize_t
sys_llistxattr (const char *path
, char *list
, size_t size
)
1868 #if defined(HAVE_LLISTXATTR)
1869 return llistxattr(path
, list
, size
);
1870 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
1871 int options
= XATTR_NOFOLLOW
;
1872 return listxattr(path
, list
, size
, options
);
1873 #elif defined(HAVE_LLISTEA)
1874 return llistea(path
, list
, size
);
1875 #elif defined(HAVE_EXTATTR_LIST_LINK)
1878 return bsd_attr_list(1, arg
, list
, size
);
1879 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1880 return irix_attr_list(path
, 0, list
, size
, ATTR_DONTFOLLOW
);
1881 #elif defined(HAVE_ATTROPEN)
1883 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1884 if (attrdirfd
>= 0) {
1885 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1895 ssize_t
sys_flistxattr (int filedes
, char *list
, size_t size
)
1897 #if defined(HAVE_FLISTXATTR)
1898 #ifndef XATTR_ADD_OPT
1899 return flistxattr(filedes
, list
, size
);
1902 return flistxattr(filedes
, list
, size
, options
);
1904 #elif defined(HAVE_FLISTEA)
1905 return flistea(filedes
, list
, size
);
1906 #elif defined(HAVE_EXTATTR_LIST_FD)
1908 arg
.filedes
= filedes
;
1909 return bsd_attr_list(2, arg
, list
, size
);
1910 #elif defined(HAVE_ATTR_LISTF)
1911 return irix_attr_list(NULL
, filedes
, list
, size
, 0);
1912 #elif defined(HAVE_ATTROPEN)
1914 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
1915 if (attrdirfd
>= 0) {
1916 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1926 int sys_removexattr (const char *path
, const char *name
)
1928 #if defined(HAVE_REMOVEXATTR)
1929 #ifndef XATTR_ADD_OPT
1930 return removexattr(path
, name
);
1933 return removexattr(path
, name
, options
);
1935 #elif defined(HAVE_REMOVEEA)
1936 return removeea(path
, name
);
1937 #elif defined(HAVE_EXTATTR_DELETE_FILE)
1939 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1940 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1941 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1943 return extattr_delete_file(path
, attrnamespace
, attrname
);
1944 #elif defined(HAVE_ATTR_REMOVE)
1946 char *attrname
= strchr(name
,'.') + 1;
1948 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1950 return attr_remove(path
, attrname
, flags
);
1951 #elif defined(HAVE_ATTROPEN)
1953 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
1954 if (attrdirfd
>= 0) {
1955 ret
= solaris_unlinkat(attrdirfd
, name
);
1965 int sys_lremovexattr (const char *path
, const char *name
)
1967 #if defined(HAVE_LREMOVEXATTR)
1968 return lremovexattr(path
, name
);
1969 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
1970 int options
= XATTR_NOFOLLOW
;
1971 return removexattr(path
, name
, options
);
1972 #elif defined(HAVE_LREMOVEEA)
1973 return lremoveea(path
, name
);
1974 #elif defined(HAVE_EXTATTR_DELETE_LINK)
1976 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1977 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1978 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1980 return extattr_delete_link(path
, attrnamespace
, attrname
);
1981 #elif defined(HAVE_ATTR_REMOVE)
1982 int flags
= ATTR_DONTFOLLOW
;
1983 char *attrname
= strchr(name
,'.') + 1;
1985 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1987 return attr_remove(path
, attrname
, flags
);
1988 #elif defined(HAVE_ATTROPEN)
1990 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1991 if (attrdirfd
>= 0) {
1992 ret
= solaris_unlinkat(attrdirfd
, name
);
2002 int sys_fremovexattr (int filedes
, const char *name
)
2004 #if defined(HAVE_FREMOVEXATTR)
2005 #ifndef XATTR_ADD_OPT
2006 return fremovexattr(filedes
, name
);
2009 return fremovexattr(filedes
, name
, options
);
2011 #elif defined(HAVE_FREMOVEEA)
2012 return fremoveea(filedes
, name
);
2013 #elif defined(HAVE_EXTATTR_DELETE_FD)
2015 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2016 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2017 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2019 return extattr_delete_fd(filedes
, attrnamespace
, attrname
);
2020 #elif defined(HAVE_ATTR_REMOVEF)
2022 char *attrname
= strchr(name
,'.') + 1;
2024 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2026 return attr_removef(filedes
, attrname
, flags
);
2027 #elif defined(HAVE_ATTROPEN)
2029 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
2030 if (attrdirfd
>= 0) {
2031 ret
= solaris_unlinkat(attrdirfd
, name
);
2041 int sys_setxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2043 #if defined(HAVE_SETXATTR)
2044 #ifndef XATTR_ADD_OPT
2045 return setxattr(path
, name
, value
, size
, flags
);
2048 return setxattr(path
, name
, value
, size
, 0, options
);
2050 #elif defined(HAVE_SETEA)
2051 return setea(path
, name
, value
, size
, flags
);
2052 #elif defined(HAVE_EXTATTR_SET_FILE)
2055 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2056 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2057 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2059 /* Check attribute existence */
2060 retval
= extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0);
2062 /* REPLACE attribute, that doesn't exist */
2063 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2067 /* Ignore other errors */
2070 /* CREATE attribute, that already exists */
2071 if (flags
& XATTR_CREATE
) {
2077 retval
= extattr_set_file(path
, attrnamespace
, attrname
, value
, size
);
2078 return (retval
< 0) ? -1 : 0;
2079 #elif defined(HAVE_ATTR_SET)
2081 char *attrname
= strchr(name
,'.') + 1;
2083 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2084 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2085 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2087 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2088 #elif defined(HAVE_ATTROPEN)
2090 int myflags
= O_RDWR
;
2092 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2093 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2094 attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2096 ret
= solaris_write_xattr(attrfd
, value
, size
);
2106 int sys_lsetxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2108 #if defined(HAVE_LSETXATTR)
2109 return lsetxattr(path
, name
, value
, size
, flags
);
2110 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
2111 int options
= XATTR_NOFOLLOW
;
2112 return setxattr(path
, name
, value
, size
, 0, options
);
2113 #elif defined(LSETEA)
2114 return lsetea(path
, name
, value
, size
, flags
);
2115 #elif defined(HAVE_EXTATTR_SET_LINK)
2118 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2119 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2120 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2122 /* Check attribute existence */
2123 retval
= extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0);
2125 /* REPLACE attribute, that doesn't exist */
2126 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2130 /* Ignore other errors */
2133 /* CREATE attribute, that already exists */
2134 if (flags
& XATTR_CREATE
) {
2141 retval
= extattr_set_link(path
, attrnamespace
, attrname
, value
, size
);
2142 return (retval
< 0) ? -1 : 0;
2143 #elif defined(HAVE_ATTR_SET)
2144 int myflags
= ATTR_DONTFOLLOW
;
2145 char *attrname
= strchr(name
,'.') + 1;
2147 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2148 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2149 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2151 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2152 #elif defined(HAVE_ATTROPEN)
2154 int myflags
= O_RDWR
| AT_SYMLINK_NOFOLLOW
;
2156 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2157 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2158 attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2160 ret
= solaris_write_xattr(attrfd
, value
, size
);
2170 int sys_fsetxattr (int filedes
, const char *name
, const void *value
, size_t size
, int flags
)
2172 #if defined(HAVE_FSETXATTR)
2173 #ifndef XATTR_ADD_OPT
2174 return fsetxattr(filedes
, name
, value
, size
, flags
);
2177 return fsetxattr(filedes
, name
, value
, size
, 0, options
);
2179 #elif defined(HAVE_FSETEA)
2180 return fsetea(filedes
, name
, value
, size
, flags
);
2181 #elif defined(HAVE_EXTATTR_SET_FD)
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_fd(filedes
, 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
) {
2206 retval
= extattr_set_fd(filedes
, attrnamespace
, attrname
, value
, size
);
2207 return (retval
< 0) ? -1 : 0;
2208 #elif defined(HAVE_ATTR_SETF)
2210 char *attrname
= strchr(name
,'.') + 1;
2212 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2213 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2214 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2216 return attr_setf(filedes
, attrname
, (const char *)value
, size
, myflags
);
2217 #elif defined(HAVE_ATTROPEN)
2219 int myflags
= O_RDWR
| O_XATTR
;
2221 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2222 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2223 attrfd
= solaris_openat(filedes
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2225 ret
= solaris_write_xattr(attrfd
, value
, size
);
2235 /**************************************************************************
2236 helper functions for Solaris' EA support
2237 ****************************************************************************/
2238 #ifdef HAVE_ATTROPEN
2239 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
)
2243 if (fstat(attrfd
, &sbuf
) == -1) {
2248 /* This is to return the current size of the named extended attribute */
2250 return sbuf
.st_size
;
2253 /* check size and read xattr */
2254 if (sbuf
.st_size
> size
) {
2259 return read(attrfd
, value
, sbuf
.st_size
);
2262 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
)
2267 int newfd
= dup(attrdirfd
);
2268 /* CAUTION: The originating file descriptor should not be
2269 used again following the call to fdopendir().
2270 For that reason we dup() the file descriptor
2271 here to make things more clear. */
2272 dirp
= fdopendir(newfd
);
2274 while ((de
= readdir(dirp
))) {
2275 size_t listlen
= strlen(de
->d_name
);
2276 if (!strcmp(de
->d_name
, ".") || !strcmp(de
->d_name
, "..")) {
2277 /* we don't want "." and ".." here: */
2278 DEBUG(10,("skipped EA %s\n",de
->d_name
));
2283 /* return the current size of the list of extended attribute names*/
2286 /* check size and copy entrieѕ + nul into list. */
2287 if ((len
+ listlen
+ 1) > size
) {
2292 safe_strcpy(list
+ len
, de
->d_name
, listlen
);
2300 if (closedir(dirp
) == -1) {
2301 DEBUG(0,("closedir dirp failed: %s\n",strerror(errno
)));
2307 static int solaris_unlinkat(int attrdirfd
, const char *name
)
2309 if (unlinkat(attrdirfd
, name
, 0) == -1) {
2310 if (errno
== ENOENT
) {
2318 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
)
2320 int filedes
= attropen(path
, attrpath
, oflag
, mode
);
2321 if (filedes
== -1) {
2322 DEBUG(10,("attropen FAILED: path: %s, name: %s, errno: %s\n",path
,attrpath
,strerror(errno
)));
2323 if (errno
== EINVAL
) {
2332 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
)
2334 int filedes
= openat(fildes
, path
, oflag
, mode
);
2335 if (filedes
== -1) {
2336 DEBUG(10,("openat FAILED: fd: %d, path: %s, errno: %s\n",filedes
,path
,strerror(errno
)));
2337 if (errno
== EINVAL
) {
2346 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
)
2348 if ((ftruncate(attrfd
, 0) == 0) && (write(attrfd
, value
, size
) == size
)) {
2351 DEBUG(10,("solaris_write_xattr FAILED!\n"));
2355 #endif /*HAVE_ATTROPEN*/
2358 /****************************************************************************
2359 Return the major devicenumber for UNIX extensions.
2360 ****************************************************************************/
2362 uint32
unix_dev_major(SMB_DEV_T dev
)
2364 #if defined(HAVE_DEVICE_MAJOR_FN)
2365 return (uint32
)major(dev
);
2367 return (uint32
)(dev
>> 8);
2371 /****************************************************************************
2372 Return the minor devicenumber for UNIX extensions.
2373 ****************************************************************************/
2375 uint32
unix_dev_minor(SMB_DEV_T dev
)
2377 #if defined(HAVE_DEVICE_MINOR_FN)
2378 return (uint32
)minor(dev
);
2380 return (uint32
)(dev
& 0xff);
2384 #if defined(WITH_AIO)
2386 /*******************************************************************
2387 An aio_read wrapper that will deal with 64-bit sizes.
2388 ********************************************************************/
2390 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2392 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2393 return aio_read64(aiocb
);
2394 #elif defined(HAVE_AIO_READ)
2395 return aio_read(aiocb
);
2402 /*******************************************************************
2403 An aio_write wrapper that will deal with 64-bit sizes.
2404 ********************************************************************/
2406 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2408 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2409 return aio_write64(aiocb
);
2410 #elif defined(HAVE_AIO_WRITE)
2411 return aio_write(aiocb
);
2418 /*******************************************************************
2419 An aio_return wrapper that will deal with 64-bit sizes.
2420 ********************************************************************/
2422 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2424 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2425 return aio_return64(aiocb
);
2426 #elif defined(HAVE_AIO_RETURN)
2427 return aio_return(aiocb
);
2434 /*******************************************************************
2435 An aio_cancel wrapper that will deal with 64-bit sizes.
2436 ********************************************************************/
2438 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2440 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2441 return aio_cancel64(fd
, aiocb
);
2442 #elif defined(HAVE_AIO_CANCEL)
2443 return aio_cancel(fd
, aiocb
);
2450 /*******************************************************************
2451 An aio_error wrapper that will deal with 64-bit sizes.
2452 ********************************************************************/
2454 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2456 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2457 return aio_error64(aiocb
);
2458 #elif defined(HAVE_AIO_ERROR)
2459 return aio_error(aiocb
);
2466 /*******************************************************************
2467 An aio_fsync wrapper that will deal with 64-bit sizes.
2468 ********************************************************************/
2470 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2472 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2473 return aio_fsync64(op
, aiocb
);
2474 #elif defined(HAVE_AIO_FSYNC)
2475 return aio_fsync(op
, aiocb
);
2482 /*******************************************************************
2483 An aio_fsync wrapper that will deal with 64-bit sizes.
2484 ********************************************************************/
2486 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2488 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2489 return aio_suspend64(cblist
, n
, timeout
);
2490 #elif defined(HAVE_AIO_FSYNC)
2491 return aio_suspend(cblist
, n
, timeout
);
2497 #else /* !WITH_AIO */
2499 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2505 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2511 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2517 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2523 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2529 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2535 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2540 #endif /* WITH_AIO */
2542 int sys_getpeereid( int s
, uid_t
*uid
)
2544 #if defined(HAVE_PEERCRED)
2546 socklen_t cred_len
= sizeof(struct ucred
);
2549 ret
= getsockopt(s
, SOL_SOCKET
, SO_PEERCRED
, (void *)&cred
, &cred_len
);
2554 if (cred_len
!= sizeof(struct ucred
)) {
2567 int sys_getnameinfo(const struct sockaddr
*psa
,
2576 * For Solaris we must make sure salen is the
2577 * correct length for the incoming sa_family.
2580 if (salen
== sizeof(struct sockaddr_storage
)) {
2581 salen
= sizeof(struct sockaddr_in
);
2582 #if defined(HAVE_IPV6)
2583 if (psa
->sa_family
== AF_INET6
) {
2584 salen
= sizeof(struct sockaddr_in6
);
2588 return getnameinfo(psa
, salen
, host
, hostlen
, service
, servlen
, flags
);
2591 int sys_connect(int fd
, const struct sockaddr
* addr
)
2593 socklen_t salen
= -1;
2595 if (addr
->sa_family
== AF_INET
) {
2596 salen
= sizeof(struct sockaddr_in
);
2597 } else if (addr
->sa_family
== AF_UNIX
) {
2598 salen
= sizeof(struct sockaddr_un
);
2600 #if defined(HAVE_IPV6)
2601 else if (addr
->sa_family
== AF_INET6
) {
2602 salen
= sizeof(struct sockaddr_in6
);
2606 return connect(fd
, addr
, salen
);