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
)
461 if (S_ISDIR(pst
->st_mode
) && lp_fake_dir_create_times()) {
462 dst
->st_ex_btime
.tv_sec
= 315493200L; /* 1/1/1980 */
463 dst
->st_ex_btime
.tv_nsec
= 0;
466 dst
->st_ex_calculated_birthtime
= false;
468 #if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC)
469 dst
->st_ex_btime
= pst
->st_birthtimespec
;
470 #elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
471 dst
->st_ex_btime
.tv_sec
= pst
->st_birthtime
;
472 dst
->st_ex_btime
.tv_nsec
= pst
->st_birthtimenspec
;
473 #elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
474 dst
->st_ex_btime
.tv_sec
= pst
->st_birthtime
;
475 dst
->st_ex_btime
.tv_nsec
= 0;
477 dst
->st_ex_btime
= calc_create_time_stat(pst
);
478 dst
->st_ex_calculated_birthtime
= true;
481 /* Deal with systems that don't initialize birthtime correctly.
482 * Pointed out by SATOH Fumiyasu <fumiyas@osstech.jp>.
484 if (null_timespec(dst
->st_ex_btime
)) {
485 dst
->st_ex_btime
= calc_create_time_stat(pst
);
486 dst
->st_ex_calculated_birthtime
= true;
490 /****************************************************************************
491 If we update a timestamp in a stat_ex struct we may have to recalculate
492 the birthtime. For now only implement this for write time, but we may
493 also need to do it for atime and ctime. JRA.
494 ****************************************************************************/
496 void update_stat_ex_mtime(struct stat_ex
*dst
,
497 struct timespec write_ts
)
499 dst
->st_ex_mtime
= write_ts
;
501 /* We may have to recalculate btime. */
502 if (dst
->st_ex_calculated_birthtime
) {
503 dst
->st_ex_btime
= calc_create_time_stat_ex(dst
);
507 static void init_stat_ex_from_stat (struct stat_ex
*dst
,
508 const struct stat
*src
)
510 dst
->st_ex_dev
= src
->st_dev
;
511 dst
->st_ex_ino
= src
->st_ino
;
512 dst
->st_ex_mode
= src
->st_mode
;
513 dst
->st_ex_nlink
= src
->st_nlink
;
514 dst
->st_ex_uid
= src
->st_uid
;
515 dst
->st_ex_gid
= src
->st_gid
;
516 dst
->st_ex_rdev
= src
->st_rdev
;
517 dst
->st_ex_size
= src
->st_size
;
518 dst
->st_ex_atime
= get_atimespec(src
);
519 dst
->st_ex_mtime
= get_mtimespec(src
);
520 dst
->st_ex_ctime
= get_ctimespec(src
);
521 make_create_timespec(src
, dst
);
522 dst
->st_ex_blksize
= src
->st_blksize
;
523 dst
->st_ex_blocks
= src
->st_blocks
;
525 #ifdef HAVE_STAT_ST_FLAGS
526 dst
->st_ex_flags
= src
->st_flags
;
528 dst
->st_ex_flags
= 0;
532 /*******************************************************************
533 A stat() wrapper that will deal with 64 bit filesizes.
534 ********************************************************************/
536 int sys_stat(const char *fname
,SMB_STRUCT_STAT
*sbuf
)
539 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
540 ret
= stat64(fname
, sbuf
);
543 ret
= stat(fname
, &statbuf
);
546 /* we always want directories to appear zero size */
547 if (S_ISDIR(statbuf
.st_mode
)) {
550 init_stat_ex_from_stat(sbuf
, &statbuf
);
555 /*******************************************************************
556 An fstat() wrapper that will deal with 64 bit filesizes.
557 ********************************************************************/
559 int sys_fstat(int fd
,SMB_STRUCT_STAT
*sbuf
)
562 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
563 ret
= fstat64(fd
, sbuf
);
566 ret
= fstat(fd
, &statbuf
);
569 /* we always want directories to appear zero size */
570 if (S_ISDIR(statbuf
.st_mode
)) {
573 init_stat_ex_from_stat(sbuf
, &statbuf
);
578 /*******************************************************************
579 An lstat() wrapper that will deal with 64 bit filesizes.
580 ********************************************************************/
582 int sys_lstat(const char *fname
,SMB_STRUCT_STAT
*sbuf
)
585 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
586 ret
= lstat64(fname
, sbuf
);
589 ret
= lstat(fname
, &statbuf
);
592 /* we always want directories to appear zero size */
593 if (S_ISDIR(statbuf
.st_mode
)) {
596 init_stat_ex_from_stat(sbuf
, &statbuf
);
601 /*******************************************************************
602 An ftruncate() wrapper that will deal with 64 bit filesizes.
603 ********************************************************************/
605 int sys_ftruncate(int fd
, SMB_OFF_T offset
)
607 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
608 return ftruncate64(fd
, offset
);
610 return ftruncate(fd
, offset
);
614 /*******************************************************************
615 An lseek() wrapper that will deal with 64 bit filesizes.
616 ********************************************************************/
618 SMB_OFF_T
sys_lseek(int fd
, SMB_OFF_T offset
, int whence
)
620 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
621 return lseek64(fd
, offset
, whence
);
623 return lseek(fd
, offset
, whence
);
627 /*******************************************************************
628 An fseek() wrapper that will deal with 64 bit filesizes.
629 ********************************************************************/
631 int sys_fseek(FILE *fp
, SMB_OFF_T offset
, int whence
)
633 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
634 return fseek64(fp
, offset
, whence
);
635 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
636 return fseeko64(fp
, offset
, whence
);
638 return fseek(fp
, offset
, whence
);
642 /*******************************************************************
643 An ftell() wrapper that will deal with 64 bit filesizes.
644 ********************************************************************/
646 SMB_OFF_T
sys_ftell(FILE *fp
)
648 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
649 return (SMB_OFF_T
)ftell64(fp
);
650 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
651 return (SMB_OFF_T
)ftello64(fp
);
653 return (SMB_OFF_T
)ftell(fp
);
657 /*******************************************************************
658 A creat() wrapper that will deal with 64 bit filesizes.
659 ********************************************************************/
661 int sys_creat(const char *path
, mode_t mode
)
663 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
664 return creat64(path
, mode
);
667 * If creat64 isn't defined then ensure we call a potential open64.
670 return sys_open(path
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
674 /*******************************************************************
675 An open() wrapper that will deal with 64 bit filesizes.
676 ********************************************************************/
678 int sys_open(const char *path
, int oflag
, mode_t mode
)
680 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
681 return open64(path
, oflag
, mode
);
683 return open(path
, oflag
, mode
);
687 /*******************************************************************
688 An fopen() wrapper that will deal with 64 bit filesizes.
689 ********************************************************************/
691 FILE *sys_fopen(const char *path
, const char *type
)
693 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
694 return fopen64(path
, type
);
696 return fopen(path
, type
);
701 /*******************************************************************
702 A flock() wrapper that will perform the kernel flock.
703 ********************************************************************/
705 void kernel_flock(int fd
, uint32 share_mode
, uint32 access_mask
)
707 #if HAVE_KERNEL_SHARE_MODES
709 if (share_mode
== FILE_SHARE_WRITE
) {
710 kernel_mode
= LOCK_MAND
|LOCK_WRITE
;
711 } else if (share_mode
== FILE_SHARE_READ
) {
712 kernel_mode
= LOCK_MAND
|LOCK_READ
;
713 } else if (share_mode
== FILE_SHARE_NONE
) {
714 kernel_mode
= LOCK_MAND
;
717 flock(fd
, kernel_mode
);
725 /*******************************************************************
726 An opendir wrapper that will deal with 64 bit filesizes.
727 ********************************************************************/
729 SMB_STRUCT_DIR
*sys_opendir(const char *name
)
731 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
732 return opendir64(name
);
734 return opendir(name
);
738 /*******************************************************************
739 A readdir wrapper that will deal with 64 bit filesizes.
740 ********************************************************************/
742 SMB_STRUCT_DIRENT
*sys_readdir(SMB_STRUCT_DIR
*dirp
)
744 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
745 return readdir64(dirp
);
747 return readdir(dirp
);
751 /*******************************************************************
752 A seekdir wrapper that will deal with 64 bit filesizes.
753 ********************************************************************/
755 void sys_seekdir(SMB_STRUCT_DIR
*dirp
, long offset
)
757 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
758 seekdir64(dirp
, offset
);
760 seekdir(dirp
, offset
);
764 /*******************************************************************
765 A telldir wrapper that will deal with 64 bit filesizes.
766 ********************************************************************/
768 long sys_telldir(SMB_STRUCT_DIR
*dirp
)
770 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
771 return (long)telldir64(dirp
);
773 return (long)telldir(dirp
);
777 /*******************************************************************
778 A rewinddir wrapper that will deal with 64 bit filesizes.
779 ********************************************************************/
781 void sys_rewinddir(SMB_STRUCT_DIR
*dirp
)
783 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
790 /*******************************************************************
791 A close wrapper that will deal with 64 bit filesizes.
792 ********************************************************************/
794 int sys_closedir(SMB_STRUCT_DIR
*dirp
)
796 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
797 return closedir64(dirp
);
799 return closedir(dirp
);
803 /*******************************************************************
804 An mknod() wrapper that will deal with 64 bit filesizes.
805 ********************************************************************/
807 int sys_mknod(const char *path
, mode_t mode
, SMB_DEV_T dev
)
809 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
810 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
811 return mknod64(path
, mode
, dev
);
813 return mknod(path
, mode
, dev
);
816 /* No mknod system call. */
822 /*******************************************************************
823 The wait() calls vary between systems
824 ********************************************************************/
826 int sys_waitpid(pid_t pid
,int *status
,int options
)
829 return waitpid(pid
,status
,options
);
830 #else /* HAVE_WAITPID */
831 return wait4(pid
, status
, options
, NULL
);
832 #endif /* HAVE_WAITPID */
835 /*******************************************************************
836 System wrapper for getwd
837 ********************************************************************/
839 char *sys_getwd(char *s
)
843 wd
= (char *)getcwd(s
, PATH_MAX
);
845 wd
= (char *)getwd(s
);
850 #if defined(HAVE_POSIX_CAPABILITIES)
852 /**************************************************************************
853 Try and abstract process capabilities (for systems that have them).
854 ****************************************************************************/
856 /* Set the POSIX capabilities needed for the given purpose into the effective
857 * capability set of the current process. Make sure they are always removed
858 * from the inheritable set, because there is no circumstance in which our
859 * children should inherit our elevated privileges.
861 static bool set_process_capability(enum smbd_capability capability
,
864 cap_value_t cap_vals
[2] = {0};
865 int num_cap_vals
= 0;
869 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
870 /* On Linux, make sure that any capabilities we grab are sticky
871 * across UID changes. We expect that this would allow us to keep both
872 * the effective and permitted capability sets, but as of circa 2.6.16,
873 * only the permitted set is kept. It is a bug (which we work around)
874 * that the effective set is lost, but we still require the effective
877 if (!prctl(PR_GET_KEEPCAPS
)) {
878 prctl(PR_SET_KEEPCAPS
, 1);
882 cap
= cap_get_proc();
884 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
889 switch (capability
) {
890 case KERNEL_OPLOCK_CAPABILITY
:
891 #ifdef CAP_NETWORK_MGT
892 /* IRIX has CAP_NETWORK_MGT for oplocks. */
893 cap_vals
[num_cap_vals
++] = CAP_NETWORK_MGT
;
896 case DMAPI_ACCESS_CAPABILITY
:
897 #ifdef CAP_DEVICE_MGT
898 /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
899 cap_vals
[num_cap_vals
++] = CAP_DEVICE_MGT
;
901 /* Linux has CAP_MKNOD for DMAPI access. */
902 cap_vals
[num_cap_vals
++] = CAP_MKNOD
;
905 case LEASE_CAPABILITY
:
907 cap_vals
[num_cap_vals
++] = CAP_LEASE
;
912 SMB_ASSERT(num_cap_vals
<= ARRAY_SIZE(cap_vals
));
914 if (num_cap_vals
== 0) {
919 cap_set_flag(cap
, CAP_EFFECTIVE
, num_cap_vals
, cap_vals
,
920 enable
? CAP_SET
: CAP_CLEAR
);
922 /* We never want to pass capabilities down to our children, so make
923 * sure they are not inherited.
925 cap_set_flag(cap
, CAP_INHERITABLE
, num_cap_vals
, cap_vals
, CAP_CLEAR
);
927 if (cap_set_proc(cap
) == -1) {
928 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
938 #endif /* HAVE_POSIX_CAPABILITIES */
940 /****************************************************************************
941 Gain the oplock capability from the kernel if possible.
942 ****************************************************************************/
944 void set_effective_capability(enum smbd_capability capability
)
946 #if defined(HAVE_POSIX_CAPABILITIES)
947 set_process_capability(capability
, True
);
948 #endif /* HAVE_POSIX_CAPABILITIES */
951 void drop_effective_capability(enum smbd_capability capability
)
953 #if defined(HAVE_POSIX_CAPABILITIES)
954 set_process_capability(capability
, False
);
955 #endif /* HAVE_POSIX_CAPABILITIES */
958 /**************************************************************************
959 Wrapper for random().
960 ****************************************************************************/
962 long sys_random(void)
964 #if defined(HAVE_RANDOM)
965 return (long)random();
966 #elif defined(HAVE_RAND)
969 DEBUG(0,("Error - no random function available !\n"));
974 /**************************************************************************
975 Wrapper for srandom().
976 ****************************************************************************/
978 void sys_srandom(unsigned int seed
)
980 #if defined(HAVE_SRANDOM)
982 #elif defined(HAVE_SRAND)
985 DEBUG(0,("Error - no srandom function available !\n"));
990 /**************************************************************************
991 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
992 ****************************************************************************/
996 #if defined(SYSCONF_SC_NGROUPS_MAX)
997 int ret
= sysconf(_SC_NGROUPS_MAX
);
998 return (ret
== -1) ? NGROUPS_MAX
: ret
;
1004 /**************************************************************************
1005 Wrap setgroups and getgroups for systems that declare getgroups() as
1006 returning an array of gid_t, but actuall return an array of int.
1007 ****************************************************************************/
1009 #if defined(HAVE_BROKEN_GETGROUPS)
1010 static int sys_broken_getgroups(int setlen
, gid_t
*gidset
)
1017 return getgroups(setlen
, &gid
);
1021 * Broken case. We need to allocate a
1022 * GID_T array of size setlen.
1031 setlen
= groups_max();
1033 if((group_list
= SMB_MALLOC_ARRAY(GID_T
, setlen
)) == NULL
) {
1034 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
1038 if((ngroups
= getgroups(setlen
, group_list
)) < 0) {
1039 int saved_errno
= errno
;
1040 SAFE_FREE(group_list
);
1041 errno
= saved_errno
;
1045 for(i
= 0; i
< ngroups
; i
++)
1046 gidset
[i
] = (gid_t
)group_list
[i
];
1048 SAFE_FREE(group_list
);
1052 static int sys_broken_setgroups(int setlen
, gid_t
*gidset
)
1060 if (setlen
< 0 || setlen
> groups_max()) {
1066 * Broken case. We need to allocate a
1067 * GID_T array of size setlen.
1070 if((group_list
= SMB_MALLOC_ARRAY(GID_T
, setlen
)) == NULL
) {
1071 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
1075 for(i
= 0; i
< setlen
; i
++)
1076 group_list
[i
] = (GID_T
) gidset
[i
];
1078 if(setgroups(setlen
, group_list
) != 0) {
1079 int saved_errno
= errno
;
1080 SAFE_FREE(group_list
);
1081 errno
= saved_errno
;
1085 SAFE_FREE(group_list
);
1089 #endif /* HAVE_BROKEN_GETGROUPS */
1091 /* This is a list of systems that require the first GID passed to setgroups(2)
1092 * to be the effective GID. If your system is one of these, add it here.
1094 #if defined (FREEBSD) || defined (DARWINOS)
1095 #define USE_BSD_SETGROUPS
1098 #if defined(USE_BSD_SETGROUPS)
1099 /* Depending on the particular BSD implementation, the first GID that is
1100 * passed to setgroups(2) will either be ignored or will set the credential's
1101 * effective GID. In either case, the right thing to do is to guarantee that
1102 * gidset[0] is the effective GID.
1104 static int sys_bsd_setgroups(gid_t primary_gid
, int setlen
, const gid_t
*gidset
)
1106 gid_t
*new_gidset
= NULL
;
1110 /* setgroups(2) will fail with EINVAL if we pass too many groups. */
1113 /* No group list, just make sure we are setting the efective GID. */
1115 return setgroups(1, &primary_gid
);
1118 /* If the primary gid is not the first array element, grow the array
1119 * and insert it at the front.
1121 if (gidset
[0] != primary_gid
) {
1122 new_gidset
= SMB_MALLOC_ARRAY(gid_t
, setlen
+ 1);
1123 if (new_gidset
== NULL
) {
1127 memcpy(new_gidset
+ 1, gidset
, (setlen
* sizeof(gid_t
)));
1128 new_gidset
[0] = primary_gid
;
1133 DEBUG(3, ("forced to truncate group list from %d to %d\n",
1138 #if defined(HAVE_BROKEN_GETGROUPS)
1139 ret
= sys_broken_setgroups(setlen
, new_gidset
? new_gidset
: gidset
);
1141 ret
= setgroups(setlen
, new_gidset
? new_gidset
: gidset
);
1146 SAFE_FREE(new_gidset
);
1153 #endif /* USE_BSD_SETGROUPS */
1155 /**************************************************************************
1156 Wrapper for getgroups. Deals with broken (int) case.
1157 ****************************************************************************/
1159 int sys_getgroups(int setlen
, gid_t
*gidset
)
1161 #if defined(HAVE_BROKEN_GETGROUPS)
1162 return sys_broken_getgroups(setlen
, gidset
);
1164 return getgroups(setlen
, gidset
);
1168 /**************************************************************************
1169 Wrapper for setgroups. Deals with broken (int) case and BSD case.
1170 ****************************************************************************/
1172 int sys_setgroups(gid_t
UNUSED(primary_gid
), int setlen
, gid_t
*gidset
)
1174 #if !defined(HAVE_SETGROUPS)
1177 #endif /* HAVE_SETGROUPS */
1179 #if defined(USE_BSD_SETGROUPS)
1180 return sys_bsd_setgroups(primary_gid
, setlen
, gidset
);
1181 #elif defined(HAVE_BROKEN_GETGROUPS)
1182 return sys_broken_setgroups(setlen
, gidset
);
1184 return setgroups(setlen
, gidset
);
1188 /**************************************************************************
1189 Wrappers for setpwent(), getpwent() and endpwent()
1190 ****************************************************************************/
1192 void sys_setpwent(void)
1197 struct passwd
*sys_getpwent(void)
1202 void sys_endpwent(void)
1207 /**************************************************************************
1208 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
1209 ****************************************************************************/
1212 struct passwd
*sys_getpwnam(const char *name
)
1214 return getpwnam(name
);
1217 struct passwd
*sys_getpwuid(uid_t uid
)
1219 return getpwuid(uid
);
1222 struct group
*sys_getgrnam(const char *name
)
1224 return getgrnam(name
);
1227 struct group
*sys_getgrgid(gid_t gid
)
1229 return getgrgid(gid
);
1232 /**************************************************************************
1233 Extract a command into an arg list.
1234 ****************************************************************************/
1236 static char **extract_args(TALLOC_CTX
*mem_ctx
, const char *command
)
1245 if (!(trunc_cmd
= talloc_strdup(mem_ctx
, command
))) {
1246 DEBUG(0, ("talloc failed\n"));
1250 if(!(ptr
= strtok_r(trunc_cmd
, " \t", &saveptr
))) {
1251 TALLOC_FREE(trunc_cmd
);
1260 for( argcl
= 1; ptr
; ptr
= strtok_r(NULL
, " \t", &saveptr
))
1263 TALLOC_FREE(trunc_cmd
);
1265 if (!(argl
= TALLOC_ARRAY(mem_ctx
, char *, argcl
+ 1))) {
1270 * Now do the extraction.
1273 if (!(trunc_cmd
= talloc_strdup(mem_ctx
, command
))) {
1277 ptr
= strtok_r(trunc_cmd
, " \t", &saveptr
);
1280 if (!(argl
[i
++] = talloc_strdup(argl
, ptr
))) {
1284 while((ptr
= strtok_r(NULL
, " \t", &saveptr
)) != NULL
) {
1286 if (!(argl
[i
++] = talloc_strdup(argl
, ptr
))) {
1295 DEBUG(0, ("talloc failed\n"));
1296 TALLOC_FREE(trunc_cmd
);
1302 /**************************************************************************
1303 Wrapper for popen. Safer as it doesn't search a path.
1304 Modified from the glibc sources.
1305 modified by tridge to return a file descriptor. We must kick our FILE* habit
1306 ****************************************************************************/
1308 typedef struct _popen_list
1312 struct _popen_list
*next
;
1315 static popen_list
*popen_chain
;
1317 int sys_popen(const char *command
)
1319 int parent_end
, child_end
;
1321 popen_list
*entry
= NULL
;
1324 if (pipe(pipe_fds
) < 0)
1327 parent_end
= pipe_fds
[0];
1328 child_end
= pipe_fds
[1];
1335 if((entry
= SMB_MALLOC_P(popen_list
)) == NULL
)
1338 ZERO_STRUCTP(entry
);
1341 * Extract the command and args into a NULL terminated array.
1344 if(!(argl
= extract_args(NULL
, command
)))
1347 entry
->child_pid
= sys_fork();
1349 if (entry
->child_pid
== -1) {
1353 if (entry
->child_pid
== 0) {
1359 int child_std_end
= STDOUT_FILENO
;
1363 if (child_end
!= child_std_end
) {
1364 dup2 (child_end
, child_std_end
);
1369 * POSIX.2: "popen() shall ensure that any streams from previous
1370 * popen() calls that remain open in the parent process are closed
1371 * in the new child process."
1374 for (p
= popen_chain
; p
; p
= p
->next
)
1377 execv(argl
[0], argl
);
1388 /* Link into popen_chain. */
1389 entry
->next
= popen_chain
;
1390 popen_chain
= entry
;
1391 entry
->fd
= parent_end
;
1404 /**************************************************************************
1405 Wrapper for pclose. Modified from the glibc sources.
1406 ****************************************************************************/
1408 int sys_pclose(int fd
)
1411 popen_list
**ptr
= &popen_chain
;
1412 popen_list
*entry
= NULL
;
1416 /* Unlink from popen_chain. */
1417 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
) {
1418 if ((*ptr
)->fd
== fd
) {
1420 *ptr
= (*ptr
)->next
;
1426 if (status
< 0 || close(entry
->fd
) < 0)
1430 * As Samba is catching and eating child process
1431 * exits we don't really care about the child exit
1432 * code, a -1 with errno = ECHILD will do fine for us.
1436 wait_pid
= sys_waitpid (entry
->child_pid
, &wstatus
, 0);
1437 } while (wait_pid
== -1 && errno
== EINTR
);
1446 /**************************************************************************
1447 Wrapper for Admin Logs.
1448 ****************************************************************************/
1450 void sys_adminlog(int priority
, const char *format_str
, ...)
1454 char *msgbuf
= NULL
;
1456 va_start( ap
, format_str
);
1457 ret
= vasprintf( &msgbuf
, format_str
, ap
);
1463 #if defined(HAVE_SYSLOG)
1464 syslog( priority
, "%s", msgbuf
);
1466 DEBUG(0,("%s", msgbuf
));
1471 /******** Solaris EA helper function prototypes ********/
1472 #ifdef HAVE_ATTROPEN
1473 #define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
1474 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
);
1475 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
);
1476 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
);
1477 static int solaris_unlinkat(int attrdirfd
, const char *name
);
1478 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
);
1479 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
);
1482 /**************************************************************************
1483 Wrappers for extented attribute calls. Based on the Linux package with
1484 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1485 ****************************************************************************/
1487 ssize_t
sys_getxattr (const char *path
, const char *name
, void *value
, size_t size
)
1489 #if defined(HAVE_GETXATTR)
1490 #ifndef XATTR_ADD_OPT
1491 return getxattr(path
, name
, value
, size
);
1494 return getxattr(path
, name
, value
, size
, 0, options
);
1496 #elif defined(HAVE_GETEA)
1497 return getea(path
, name
, value
, size
);
1498 #elif defined(HAVE_EXTATTR_GET_FILE)
1501 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1502 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1503 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1505 * The BSD implementation has a nasty habit of silently truncating
1506 * the returned value to the size of the buffer, so we have to check
1507 * that the buffer is large enough to fit the returned value.
1509 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1514 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1518 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno
)));
1520 #elif defined(HAVE_ATTR_GET)
1521 int retval
, flags
= 0;
1522 int valuelength
= (int)size
;
1523 char *attrname
= strchr(name
,'.') + 1;
1525 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1527 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1529 return retval
? retval
: valuelength
;
1530 #elif defined(HAVE_ATTROPEN)
1532 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
, 0);
1534 ret
= solaris_read_xattr(attrfd
, value
, size
);
1544 ssize_t
sys_lgetxattr (const char *path
, const char *name
, void *value
, size_t size
)
1546 #if defined(HAVE_LGETXATTR)
1547 return lgetxattr(path
, name
, value
, size
);
1548 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
1549 int options
= XATTR_NOFOLLOW
;
1550 return getxattr(path
, name
, value
, size
, 0, options
);
1551 #elif defined(HAVE_LGETEA)
1552 return lgetea(path
, name
, value
, size
);
1553 #elif defined(HAVE_EXTATTR_GET_LINK)
1556 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1557 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1558 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1560 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1565 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1569 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno
)));
1571 #elif defined(HAVE_ATTR_GET)
1572 int retval
, flags
= ATTR_DONTFOLLOW
;
1573 int valuelength
= (int)size
;
1574 char *attrname
= strchr(name
,'.') + 1;
1576 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1578 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1580 return retval
? retval
: valuelength
;
1581 #elif defined(HAVE_ATTROPEN)
1583 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1585 ret
= solaris_read_xattr(attrfd
, value
, size
);
1595 ssize_t
sys_fgetxattr (int filedes
, const char *name
, void *value
, size_t size
)
1597 #if defined(HAVE_FGETXATTR)
1598 #ifndef XATTR_ADD_OPT
1599 return fgetxattr(filedes
, name
, value
, size
);
1602 return fgetxattr(filedes
, name
, value
, size
, 0, options
);
1604 #elif defined(HAVE_FGETEA)
1605 return fgetea(filedes
, name
, value
, size
);
1606 #elif defined(HAVE_EXTATTR_GET_FD)
1609 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1610 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1611 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1613 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1618 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, value
, size
)) >= 0)
1622 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno
)));
1624 #elif defined(HAVE_ATTR_GETF)
1625 int retval
, flags
= 0;
1626 int valuelength
= (int)size
;
1627 char *attrname
= strchr(name
,'.') + 1;
1629 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1631 retval
= attr_getf(filedes
, attrname
, (char *)value
, &valuelength
, flags
);
1633 return retval
? retval
: valuelength
;
1634 #elif defined(HAVE_ATTROPEN)
1636 int attrfd
= solaris_openat(filedes
, name
, O_RDONLY
|O_XATTR
, 0);
1638 ret
= solaris_read_xattr(attrfd
, value
, size
);
1648 #if defined(HAVE_EXTATTR_LIST_FILE)
1650 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1658 { EXTATTR_NAMESPACE_SYSTEM
, EXTATTR_PREFIX("system.") },
1659 { EXTATTR_NAMESPACE_USER
, EXTATTR_PREFIX("user.") },
1667 static ssize_t
bsd_attr_list (int type
, extattr_arg arg
, char *list
, size_t size
)
1669 ssize_t list_size
, total_size
= 0;
1672 /* Iterate through extattr(2) namespaces */
1673 for(t
= 0; t
< (sizeof(extattr
)/sizeof(extattr
[0])); t
++) {
1675 #if defined(HAVE_EXTATTR_LIST_FILE)
1677 list_size
= extattr_list_file(arg
.path
, extattr
[t
].space
, list
, size
);
1680 #if defined(HAVE_EXTATTR_LIST_LINK)
1682 list_size
= extattr_list_link(arg
.path
, extattr
[t
].space
, list
, size
);
1685 #if defined(HAVE_EXTATTR_LIST_FD)
1687 list_size
= extattr_list_fd(arg
.filedes
, extattr
[t
].space
, list
, size
);
1694 /* Some error happend. Errno should be set by the previous call */
1700 /* XXX: Call with an empty buffer may be used to calculate
1701 necessary buffer size. Unfortunately, we can't say, how
1702 many attributes were returned, so here is the potential
1703 problem with the emulation.
1706 /* Take the worse case of one char attribute names -
1707 two bytes per name plus one more for sanity.
1709 total_size
+= list_size
+ (list_size
/2 + 1)*extattr
[t
].len
;
1712 /* Count necessary offset to fit namespace prefixes */
1714 for(i
= 0; i
< list_size
; i
+= list
[i
] + 1)
1715 len
+= extattr
[t
].len
;
1717 total_size
+= list_size
+ len
;
1718 /* Buffer is too small to fit the results */
1719 if(total_size
> size
) {
1723 /* Shift results back, so we can prepend prefixes */
1724 buf
= memmove(list
+ len
, list
, list_size
);
1726 for(i
= 0; i
< list_size
; i
+= len
+ 1) {
1728 strncpy(list
, extattr
[t
].name
, extattr
[t
].len
+ 1);
1729 list
+= extattr
[t
].len
;
1730 strncpy(list
, buf
+ i
+ 1, len
);
1741 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1742 static char attr_buffer
[ATTR_MAX_VALUELEN
];
1744 static ssize_t
irix_attr_list(const char *path
, int filedes
, char *list
, size_t size
, int flags
)
1746 int retval
= 0, index
;
1747 attrlist_cursor_t
*cursor
= 0;
1749 attrlist_t
* al
= (attrlist_t
*)attr_buffer
;
1751 size_t ent_size
, left
= size
;
1756 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1758 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1760 for (index
= 0; index
< al
->al_count
; index
++) {
1761 ae
= ATTR_ENTRY(attr_buffer
, index
);
1762 ent_size
= strlen(ae
->a_name
) + sizeof("user.");
1763 if (left
>= ent_size
) {
1764 strncpy(bp
, "user.", sizeof("user."));
1765 strncat(bp
, ae
->a_name
, ent_size
- sizeof("user."));
1773 total_size
+= ent_size
;
1775 if (al
->al_more
== 0) break;
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("system.");
1789 if (left
>= ent_size
) {
1790 strncpy(bp
, "system.", sizeof("system."));
1791 strncat(bp
, ae
->a_name
, ent_size
- sizeof("system."));
1799 total_size
+= ent_size
;
1801 if (al
->al_more
== 0) break;
1804 return (ssize_t
)(retval
? retval
: total_size
);
1809 ssize_t
sys_listxattr (const char *path
, char *list
, size_t size
)
1811 #if defined(HAVE_LISTXATTR)
1812 #ifndef XATTR_ADD_OPT
1813 return listxattr(path
, list
, size
);
1816 return listxattr(path
, list
, size
, options
);
1818 #elif defined(HAVE_LISTEA)
1819 return listea(path
, list
, size
);
1820 #elif defined(HAVE_EXTATTR_LIST_FILE)
1823 return bsd_attr_list(0, arg
, list
, size
);
1824 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1825 return irix_attr_list(path
, 0, list
, size
, 0);
1826 #elif defined(HAVE_ATTROPEN)
1828 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
1829 if (attrdirfd
>= 0) {
1830 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1840 ssize_t
sys_llistxattr (const char *path
, char *list
, size_t size
)
1842 #if defined(HAVE_LLISTXATTR)
1843 return llistxattr(path
, list
, size
);
1844 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
1845 int options
= XATTR_NOFOLLOW
;
1846 return listxattr(path
, list
, size
, options
);
1847 #elif defined(HAVE_LLISTEA)
1848 return llistea(path
, list
, size
);
1849 #elif defined(HAVE_EXTATTR_LIST_LINK)
1852 return bsd_attr_list(1, arg
, list
, size
);
1853 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1854 return irix_attr_list(path
, 0, list
, size
, ATTR_DONTFOLLOW
);
1855 #elif defined(HAVE_ATTROPEN)
1857 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1858 if (attrdirfd
>= 0) {
1859 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1869 ssize_t
sys_flistxattr (int filedes
, char *list
, size_t size
)
1871 #if defined(HAVE_FLISTXATTR)
1872 #ifndef XATTR_ADD_OPT
1873 return flistxattr(filedes
, list
, size
);
1876 return flistxattr(filedes
, list
, size
, options
);
1878 #elif defined(HAVE_FLISTEA)
1879 return flistea(filedes
, list
, size
);
1880 #elif defined(HAVE_EXTATTR_LIST_FD)
1882 arg
.filedes
= filedes
;
1883 return bsd_attr_list(2, arg
, list
, size
);
1884 #elif defined(HAVE_ATTR_LISTF)
1885 return irix_attr_list(NULL
, filedes
, list
, size
, 0);
1886 #elif defined(HAVE_ATTROPEN)
1888 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
1889 if (attrdirfd
>= 0) {
1890 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1900 int sys_removexattr (const char *path
, const char *name
)
1902 #if defined(HAVE_REMOVEXATTR)
1903 #ifndef XATTR_ADD_OPT
1904 return removexattr(path
, name
);
1907 return removexattr(path
, name
, options
);
1909 #elif defined(HAVE_REMOVEEA)
1910 return removeea(path
, name
);
1911 #elif defined(HAVE_EXTATTR_DELETE_FILE)
1913 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1914 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1915 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1917 return extattr_delete_file(path
, attrnamespace
, attrname
);
1918 #elif defined(HAVE_ATTR_REMOVE)
1920 char *attrname
= strchr(name
,'.') + 1;
1922 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1924 return attr_remove(path
, attrname
, flags
);
1925 #elif defined(HAVE_ATTROPEN)
1927 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
1928 if (attrdirfd
>= 0) {
1929 ret
= solaris_unlinkat(attrdirfd
, name
);
1939 int sys_lremovexattr (const char *path
, const char *name
)
1941 #if defined(HAVE_LREMOVEXATTR)
1942 return lremovexattr(path
, name
);
1943 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
1944 int options
= XATTR_NOFOLLOW
;
1945 return removexattr(path
, name
, options
);
1946 #elif defined(HAVE_LREMOVEEA)
1947 return lremoveea(path
, name
);
1948 #elif defined(HAVE_EXTATTR_DELETE_LINK)
1950 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1951 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1952 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1954 return extattr_delete_link(path
, attrnamespace
, attrname
);
1955 #elif defined(HAVE_ATTR_REMOVE)
1956 int flags
= ATTR_DONTFOLLOW
;
1957 char *attrname
= strchr(name
,'.') + 1;
1959 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1961 return attr_remove(path
, attrname
, flags
);
1962 #elif defined(HAVE_ATTROPEN)
1964 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1965 if (attrdirfd
>= 0) {
1966 ret
= solaris_unlinkat(attrdirfd
, name
);
1976 int sys_fremovexattr (int filedes
, const char *name
)
1978 #if defined(HAVE_FREMOVEXATTR)
1979 #ifndef XATTR_ADD_OPT
1980 return fremovexattr(filedes
, name
);
1983 return fremovexattr(filedes
, name
, options
);
1985 #elif defined(HAVE_FREMOVEEA)
1986 return fremoveea(filedes
, name
);
1987 #elif defined(HAVE_EXTATTR_DELETE_FD)
1989 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1990 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1991 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1993 return extattr_delete_fd(filedes
, attrnamespace
, attrname
);
1994 #elif defined(HAVE_ATTR_REMOVEF)
1996 char *attrname
= strchr(name
,'.') + 1;
1998 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2000 return attr_removef(filedes
, attrname
, flags
);
2001 #elif defined(HAVE_ATTROPEN)
2003 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
2004 if (attrdirfd
>= 0) {
2005 ret
= solaris_unlinkat(attrdirfd
, name
);
2015 int sys_setxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2017 #if defined(HAVE_SETXATTR)
2018 #ifndef XATTR_ADD_OPT
2019 return setxattr(path
, name
, value
, size
, flags
);
2022 return setxattr(path
, name
, value
, size
, 0, options
);
2024 #elif defined(HAVE_SETEA)
2025 return setea(path
, name
, value
, size
, flags
);
2026 #elif defined(HAVE_EXTATTR_SET_FILE)
2029 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2030 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2031 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2033 /* Check attribute existence */
2034 retval
= extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0);
2036 /* REPLACE attribute, that doesn't exist */
2037 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2041 /* Ignore other errors */
2044 /* CREATE attribute, that already exists */
2045 if (flags
& XATTR_CREATE
) {
2051 retval
= extattr_set_file(path
, attrnamespace
, attrname
, value
, size
);
2052 return (retval
< 0) ? -1 : 0;
2053 #elif defined(HAVE_ATTR_SET)
2055 char *attrname
= strchr(name
,'.') + 1;
2057 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2058 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2059 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2061 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2062 #elif defined(HAVE_ATTROPEN)
2064 int myflags
= O_RDWR
;
2066 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2067 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2068 attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2070 ret
= solaris_write_xattr(attrfd
, value
, size
);
2080 int sys_lsetxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2082 #if defined(HAVE_LSETXATTR)
2083 return lsetxattr(path
, name
, value
, size
, flags
);
2084 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
2085 int options
= XATTR_NOFOLLOW
;
2086 return setxattr(path
, name
, value
, size
, 0, options
);
2087 #elif defined(LSETEA)
2088 return lsetea(path
, name
, value
, size
, flags
);
2089 #elif defined(HAVE_EXTATTR_SET_LINK)
2092 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2093 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2094 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2096 /* Check attribute existence */
2097 retval
= extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0);
2099 /* REPLACE attribute, that doesn't exist */
2100 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2104 /* Ignore other errors */
2107 /* CREATE attribute, that already exists */
2108 if (flags
& XATTR_CREATE
) {
2115 retval
= extattr_set_link(path
, attrnamespace
, attrname
, value
, size
);
2116 return (retval
< 0) ? -1 : 0;
2117 #elif defined(HAVE_ATTR_SET)
2118 int myflags
= ATTR_DONTFOLLOW
;
2119 char *attrname
= strchr(name
,'.') + 1;
2121 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2122 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2123 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2125 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2126 #elif defined(HAVE_ATTROPEN)
2128 int myflags
= O_RDWR
| AT_SYMLINK_NOFOLLOW
;
2130 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2131 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2132 attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2134 ret
= solaris_write_xattr(attrfd
, value
, size
);
2144 int sys_fsetxattr (int filedes
, const char *name
, const void *value
, size_t size
, int flags
)
2146 #if defined(HAVE_FSETXATTR)
2147 #ifndef XATTR_ADD_OPT
2148 return fsetxattr(filedes
, name
, value
, size
, flags
);
2151 return fsetxattr(filedes
, name
, value
, size
, 0, options
);
2153 #elif defined(HAVE_FSETEA)
2154 return fsetea(filedes
, name
, value
, size
, flags
);
2155 #elif defined(HAVE_EXTATTR_SET_FD)
2158 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2159 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2160 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2162 /* Check attribute existence */
2163 retval
= extattr_get_fd(filedes
, attrnamespace
, attrname
, NULL
, 0);
2165 /* REPLACE attribute, that doesn't exist */
2166 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2170 /* Ignore other errors */
2173 /* CREATE attribute, that already exists */
2174 if (flags
& XATTR_CREATE
) {
2180 retval
= extattr_set_fd(filedes
, attrnamespace
, attrname
, value
, size
);
2181 return (retval
< 0) ? -1 : 0;
2182 #elif defined(HAVE_ATTR_SETF)
2184 char *attrname
= strchr(name
,'.') + 1;
2186 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2187 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2188 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2190 return attr_setf(filedes
, attrname
, (const char *)value
, size
, myflags
);
2191 #elif defined(HAVE_ATTROPEN)
2193 int myflags
= O_RDWR
| O_XATTR
;
2195 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2196 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2197 attrfd
= solaris_openat(filedes
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2199 ret
= solaris_write_xattr(attrfd
, value
, size
);
2209 /**************************************************************************
2210 helper functions for Solaris' EA support
2211 ****************************************************************************/
2212 #ifdef HAVE_ATTROPEN
2213 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
)
2217 if (fstat(attrfd
, &sbuf
) == -1) {
2222 /* This is to return the current size of the named extended attribute */
2224 return sbuf
.st_size
;
2227 /* check size and read xattr */
2228 if (sbuf
.st_size
> size
) {
2233 return read(attrfd
, value
, sbuf
.st_size
);
2236 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
)
2241 int newfd
= dup(attrdirfd
);
2242 /* CAUTION: The originating file descriptor should not be
2243 used again following the call to fdopendir().
2244 For that reason we dup() the file descriptor
2245 here to make things more clear. */
2246 dirp
= fdopendir(newfd
);
2248 while ((de
= readdir(dirp
))) {
2249 size_t listlen
= strlen(de
->d_name
);
2250 if (!strcmp(de
->d_name
, ".") || !strcmp(de
->d_name
, "..")) {
2251 /* we don't want "." and ".." here: */
2252 DEBUG(10,("skipped EA %s\n",de
->d_name
));
2257 /* return the current size of the list of extended attribute names*/
2260 /* check size and copy entrieѕ + nul into list. */
2261 if ((len
+ listlen
+ 1) > size
) {
2266 safe_strcpy(list
+ len
, de
->d_name
, listlen
);
2274 if (closedir(dirp
) == -1) {
2275 DEBUG(0,("closedir dirp failed: %s\n",strerror(errno
)));
2281 static int solaris_unlinkat(int attrdirfd
, const char *name
)
2283 if (unlinkat(attrdirfd
, name
, 0) == -1) {
2284 if (errno
== ENOENT
) {
2292 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
)
2294 int filedes
= attropen(path
, attrpath
, oflag
, mode
);
2295 if (filedes
== -1) {
2296 DEBUG(10,("attropen FAILED: path: %s, name: %s, errno: %s\n",path
,attrpath
,strerror(errno
)));
2297 if (errno
== EINVAL
) {
2306 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
)
2308 int filedes
= openat(fildes
, path
, oflag
, mode
);
2309 if (filedes
== -1) {
2310 DEBUG(10,("openat FAILED: fd: %d, path: %s, errno: %s\n",filedes
,path
,strerror(errno
)));
2311 if (errno
== EINVAL
) {
2320 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
)
2322 if ((ftruncate(attrfd
, 0) == 0) && (write(attrfd
, value
, size
) == size
)) {
2325 DEBUG(10,("solaris_write_xattr FAILED!\n"));
2329 #endif /*HAVE_ATTROPEN*/
2332 /****************************************************************************
2333 Return the major devicenumber for UNIX extensions.
2334 ****************************************************************************/
2336 uint32
unix_dev_major(SMB_DEV_T dev
)
2338 #if defined(HAVE_DEVICE_MAJOR_FN)
2339 return (uint32
)major(dev
);
2341 return (uint32
)(dev
>> 8);
2345 /****************************************************************************
2346 Return the minor devicenumber for UNIX extensions.
2347 ****************************************************************************/
2349 uint32
unix_dev_minor(SMB_DEV_T dev
)
2351 #if defined(HAVE_DEVICE_MINOR_FN)
2352 return (uint32
)minor(dev
);
2354 return (uint32
)(dev
& 0xff);
2358 #if defined(WITH_AIO)
2360 /*******************************************************************
2361 An aio_read wrapper that will deal with 64-bit sizes.
2362 ********************************************************************/
2364 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2366 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2367 return aio_read64(aiocb
);
2368 #elif defined(HAVE_AIO_READ)
2369 return aio_read(aiocb
);
2376 /*******************************************************************
2377 An aio_write wrapper that will deal with 64-bit sizes.
2378 ********************************************************************/
2380 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2382 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2383 return aio_write64(aiocb
);
2384 #elif defined(HAVE_AIO_WRITE)
2385 return aio_write(aiocb
);
2392 /*******************************************************************
2393 An aio_return wrapper that will deal with 64-bit sizes.
2394 ********************************************************************/
2396 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2398 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2399 return aio_return64(aiocb
);
2400 #elif defined(HAVE_AIO_RETURN)
2401 return aio_return(aiocb
);
2408 /*******************************************************************
2409 An aio_cancel wrapper that will deal with 64-bit sizes.
2410 ********************************************************************/
2412 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2414 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2415 return aio_cancel64(fd
, aiocb
);
2416 #elif defined(HAVE_AIO_CANCEL)
2417 return aio_cancel(fd
, aiocb
);
2424 /*******************************************************************
2425 An aio_error wrapper that will deal with 64-bit sizes.
2426 ********************************************************************/
2428 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2430 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2431 return aio_error64(aiocb
);
2432 #elif defined(HAVE_AIO_ERROR)
2433 return aio_error(aiocb
);
2440 /*******************************************************************
2441 An aio_fsync wrapper that will deal with 64-bit sizes.
2442 ********************************************************************/
2444 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2446 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2447 return aio_fsync64(op
, aiocb
);
2448 #elif defined(HAVE_AIO_FSYNC)
2449 return aio_fsync(op
, aiocb
);
2456 /*******************************************************************
2457 An aio_fsync wrapper that will deal with 64-bit sizes.
2458 ********************************************************************/
2460 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2462 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2463 return aio_suspend64(cblist
, n
, timeout
);
2464 #elif defined(HAVE_AIO_FSYNC)
2465 return aio_suspend(cblist
, n
, timeout
);
2471 #else /* !WITH_AIO */
2473 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2479 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2485 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2491 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2497 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2503 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2509 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2514 #endif /* WITH_AIO */
2516 int sys_getpeereid( int s
, uid_t
*uid
)
2518 #if defined(HAVE_PEERCRED)
2520 socklen_t cred_len
= sizeof(struct ucred
);
2523 ret
= getsockopt(s
, SOL_SOCKET
, SO_PEERCRED
, (void *)&cred
, &cred_len
);
2528 if (cred_len
!= sizeof(struct ucred
)) {
2541 int sys_getnameinfo(const struct sockaddr
*psa
,
2550 * For Solaris we must make sure salen is the
2551 * correct length for the incoming sa_family.
2554 if (salen
== sizeof(struct sockaddr_storage
)) {
2555 salen
= sizeof(struct sockaddr_in
);
2556 #if defined(HAVE_IPV6)
2557 if (psa
->sa_family
== AF_INET6
) {
2558 salen
= sizeof(struct sockaddr_in6
);
2562 return getnameinfo(psa
, salen
, host
, hostlen
, service
, servlen
, flags
);
2565 int sys_connect(int fd
, const struct sockaddr
* addr
)
2567 socklen_t salen
= -1;
2569 if (addr
->sa_family
== AF_INET
) {
2570 salen
= sizeof(struct sockaddr_in
);
2571 } else if (addr
->sa_family
== AF_UNIX
) {
2572 salen
= sizeof(struct sockaddr_un
);
2574 #if defined(HAVE_IPV6)
2575 else if (addr
->sa_family
== AF_INET6
) {
2576 salen
= sizeof(struct sockaddr_in6
);
2580 return connect(fd
, addr
, salen
);