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/>.
24 #include "system/syslog.h"
26 #ifdef HAVE_SYS_PRCTL_H
27 #include <sys/prctl.h>
31 The idea is that this file will eventually have wrappers around all
32 important system calls in samba. The aims are:
34 - to enable easier porting by putting OS dependent stuff in here
36 - to allow for hooks into other "pseudo-filesystems"
38 - to allow easier integration of things like the japanese extensions
40 - to support the philosophy of Samba to expose the features of
41 the OS within the SMB model. In general whatever file/printer/variable
42 expansions/etc make sense to the OS should be acceptable to Samba.
47 /*******************************************************************
48 A wrapper for memalign
49 ********************************************************************/
51 void *sys_memalign( size_t align, size_t size )
53 #if defined(HAVE_POSIX_MEMALIGN)
55 int ret = posix_memalign( &p, align, size );
60 #elif defined(HAVE_MEMALIGN)
61 return memalign( align, size );
63 /* On *BSD systems memaligns doesn't exist, but memory will
64 * be aligned on allocations of > pagesize. */
65 #if defined(SYSCONF_SC_PAGESIZE)
66 size_t pagesize = (size_t)sysconf(_SC_PAGESIZE);
67 #elif defined(HAVE_GETPAGESIZE)
68 size_t pagesize = (size_t)getpagesize();
70 size_t pagesize = (size_t)-1;
72 if (pagesize == (size_t)-1) {
73 DEBUG(0,("memalign functionalaity not available on this platform!\n"));
76 if (size < pagesize) {
79 return SMB_MALLOC(size);
83 /*******************************************************************
84 A wrapper for usleep in case we don't have one.
85 ********************************************************************/
87 int sys_usleep(long usecs)
94 * We need this braindamage as the glibc usleep
95 * is not SPEC1170 complient... grumble... JRA.
98 if(usecs < 0 || usecs > 999999) {
106 #else /* HAVE_USLEEP */
108 * Fake it with select...
111 tval.tv_usec = usecs/1000;
112 select(0,NULL,NULL,NULL,&tval);
114 #endif /* HAVE_USLEEP */
117 /*******************************************************************
118 A read wrapper that will deal with EINTR.
119 ********************************************************************/
121 ssize_t sys_read(int fd, void *buf, size_t count)
126 ret = read(fd, buf, count);
127 #if defined(EWOULDBLOCK)
128 } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
130 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
135 /*******************************************************************
136 A write wrapper that will deal with EINTR.
137 ********************************************************************/
139 ssize_t sys_write(int fd, const void *buf, size_t count)
144 ret = write(fd, buf, count);
145 #if defined(EWOULDBLOCK)
146 } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
148 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
153 /*******************************************************************
154 A writev wrapper that will deal with EINTR.
155 ********************************************************************/
157 ssize_t sys_writev(int fd, const struct iovec *iov, int iovcnt)
162 /* Try to confuse write_data_iov a bit */
163 if ((random() % 5) == 0) {
164 return sys_write(fd, iov[0].iov_base, iov[0].iov_len);
166 if (iov[0].iov_len > 1) {
167 return sys_write(fd, iov[0].iov_base,
168 (random() % (iov[0].iov_len-1)) + 1);
173 ret = writev(fd, iov, iovcnt);
174 #if defined(EWOULDBLOCK)
175 } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
177 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
182 /*******************************************************************
183 A pread wrapper that will deal with EINTR and 64-bit file offsets.
184 ********************************************************************/
186 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
187 ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
192 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
193 ret = pread64(fd, buf, count, off);
195 ret = pread(fd, buf, count, off);
197 } while (ret == -1 && errno == EINTR);
202 /*******************************************************************
203 A write wrapper that will deal with EINTR and 64-bit file offsets.
204 ********************************************************************/
206 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
207 ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
212 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
213 ret = pwrite64(fd, buf, count, off);
215 ret = pwrite(fd, buf, count, off);
217 } while (ret == -1 && errno == EINTR);
222 /*******************************************************************
223 A send wrapper that will deal with EINTR or EAGAIN or EWOULDBLOCK.
224 ********************************************************************/
226 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
231 ret = send(s, msg, len, flags);
232 #if defined(EWOULDBLOCK)
233 } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
235 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
240 /*******************************************************************
241 A sendto wrapper that will deal with EINTR or EAGAIN or EWOULDBLOCK.
242 ********************************************************************/
244 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
249 ret = sendto(s, msg, len, flags, to, tolen);
250 #if defined(EWOULDBLOCK)
251 } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
253 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
258 /*******************************************************************
259 A recv wrapper that will deal with EINTR or EAGAIN or EWOULDBLOCK.
260 ********************************************************************/
262 ssize_t sys_recv(int fd, void *buf, size_t count, int flags)
267 ret = recv(fd, buf, count, flags);
268 #if defined(EWOULDBLOCK)
269 } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
271 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
276 /*******************************************************************
277 A recvfrom wrapper that will deal with EINTR.
278 ********************************************************************/
280 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
285 ret = recvfrom(s, buf, len, flags, from, fromlen);
286 #if defined(EWOULDBLOCK)
287 } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
289 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
294 /*******************************************************************
295 A fcntl wrapper that will deal with EINTR.
296 ********************************************************************/
298 int sys_fcntl_ptr(int fd, int cmd, void *arg)
303 ret = fcntl(fd, cmd, arg);
304 } while (ret == -1 && errno == EINTR);
308 /*******************************************************************
309 A fcntl wrapper that will deal with EINTR.
310 ********************************************************************/
312 int sys_fcntl_long(int fd, int cmd, long arg)
317 ret = fcntl(fd, cmd, arg);
318 } while (ret == -1 && errno == EINTR);
322 /****************************************************************************
323 Get/Set all the possible time fields from a stat struct as a timespec.
324 ****************************************************************************/
326 static struct timespec get_atimespec(const struct stat *pst)
328 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
331 /* Old system - no ns timestamp. */
332 ret.tv_sec = pst->st_atime;
336 #if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
338 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
340 ret.tv_sec = pst->st_atime;
341 ret.tv_nsec = pst->st_atimensec;
343 #elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
345 ret.tv_sec = pst->st_atime;
346 ret.tv_nsec = pst->st_atime_n;
348 #elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
350 ret.tv_sec = pst->st_atime;
351 ret.tv_nsec = pst->st_uatime * 1000;
353 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
354 return pst->st_atimespec;
356 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
361 static struct timespec get_mtimespec(const struct stat *pst)
363 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
366 /* Old system - no ns timestamp. */
367 ret.tv_sec = pst->st_mtime;
371 #if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
373 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
375 ret.tv_sec = pst->st_mtime;
376 ret.tv_nsec = pst->st_mtimensec;
378 #elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
380 ret.tv_sec = pst->st_mtime;
381 ret.tv_nsec = pst->st_mtime_n;
383 #elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
385 ret.tv_sec = pst->st_mtime;
386 ret.tv_nsec = pst->st_umtime * 1000;
388 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
389 return pst->st_mtimespec;
391 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
396 static struct timespec get_ctimespec(const struct stat *pst)
398 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
401 /* Old system - no ns timestamp. */
402 ret.tv_sec = pst->st_ctime;
406 #if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
408 #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
410 ret.tv_sec = pst->st_ctime;
411 ret.tv_nsec = pst->st_ctimensec;
413 #elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
415 ret.tv_sec = pst->st_ctime;
416 ret.tv_nsec = pst->st_ctime_n;
418 #elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
420 ret.tv_sec = pst->st_ctime;
421 ret.tv_nsec = pst->st_uctime * 1000;
423 #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
424 return pst->st_ctimespec;
426 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
431 /****************************************************************************
432 Return the best approximation to a 'create time' under UNIX from a stat
434 ****************************************************************************/
436 static struct timespec calc_create_time_stat(const struct stat *st)
438 struct timespec ret, ret1;
439 struct timespec c_time = get_ctimespec(st);
440 struct timespec m_time = get_mtimespec(st);
441 struct timespec a_time = get_atimespec(st);
443 ret = timespec_compare(&c_time, &m_time) < 0 ? c_time : m_time;
444 ret1 = timespec_compare(&ret, &a_time) < 0 ? ret : a_time;
446 if(!null_timespec(ret1)) {
451 * One of ctime, mtime or atime was zero (probably atime).
452 * Just return MIN(ctime, mtime).
457 /****************************************************************************
458 Return the best approximation to a 'create time' under UNIX from a stat_ex
460 ****************************************************************************/
462 static struct timespec calc_create_time_stat_ex(const struct stat_ex *st)
464 struct timespec ret, ret1;
465 struct timespec c_time = st->st_ex_ctime;
466 struct timespec m_time = st->st_ex_mtime;
467 struct timespec a_time = st->st_ex_atime;
469 ret = timespec_compare(&c_time, &m_time) < 0 ? c_time : m_time;
470 ret1 = timespec_compare(&ret, &a_time) < 0 ? ret : a_time;
472 if(!null_timespec(ret1)) {
477 * One of ctime, mtime or atime was zero (probably atime).
478 * Just return MIN(ctime, mtime).
483 /****************************************************************************
484 Return the 'create time' from a stat struct if it exists (birthtime) or else
485 use the best approximation.
486 ****************************************************************************/
488 static void make_create_timespec(const struct stat *pst, struct stat_ex *dst,
489 bool fake_dir_create_times)
491 if (S_ISDIR(pst->st_mode) && fake_dir_create_times) {
492 dst->st_ex_btime.tv_sec = 315493200L; /* 1/1/1980 */
493 dst->st_ex_btime.tv_nsec = 0;
496 dst->st_ex_calculated_birthtime = false;
498 #if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC)
499 dst->st_ex_btime = pst->st_birthtimespec;
500 #elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
501 dst->st_ex_btime.tv_sec = pst->st_birthtime;
502 dst->st_ex_btime.tv_nsec = pst->st_birthtimenspec;
503 #elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
504 dst->st_ex_btime.tv_sec = pst->st_birthtime;
505 dst->st_ex_btime.tv_nsec = 0;
507 dst->st_ex_btime = calc_create_time_stat(pst);
508 dst->st_ex_calculated_birthtime = true;
511 /* Deal with systems that don't initialize birthtime correctly.
512 * Pointed out by SATOH Fumiyasu <fumiyas@osstech.jp>.
514 if (null_timespec(dst->st_ex_btime)) {
515 dst->st_ex_btime = calc_create_time_stat(pst);
516 dst->st_ex_calculated_birthtime = true;
520 /****************************************************************************
521 If we update a timestamp in a stat_ex struct we may have to recalculate
522 the birthtime. For now only implement this for write time, but we may
523 also need to do it for atime and ctime. JRA.
524 ****************************************************************************/
526 void update_stat_ex_mtime(struct stat_ex *dst,
527 struct timespec write_ts)
529 dst->st_ex_mtime = write_ts;
531 /* We may have to recalculate btime. */
532 if (dst->st_ex_calculated_birthtime) {
533 dst->st_ex_btime = calc_create_time_stat_ex(dst);
537 void update_stat_ex_create_time(struct stat_ex *dst,
538 struct timespec create_time)
540 dst->st_ex_btime = create_time;
541 dst->st_ex_calculated_birthtime = false;
544 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
545 static void init_stat_ex_from_stat (struct stat_ex *dst,
546 const struct stat64 *src,
547 bool fake_dir_create_times)
549 static void init_stat_ex_from_stat (struct stat_ex *dst,
550 const struct stat *src,
551 bool fake_dir_create_times)
554 dst->st_ex_dev = src->st_dev;
555 dst->st_ex_ino = src->st_ino;
556 dst->st_ex_mode = src->st_mode;
557 dst->st_ex_nlink = src->st_nlink;
558 dst->st_ex_uid = src->st_uid;
559 dst->st_ex_gid = src->st_gid;
560 dst->st_ex_rdev = src->st_rdev;
561 dst->st_ex_size = src->st_size;
562 dst->st_ex_atime = get_atimespec(src);
563 dst->st_ex_mtime = get_mtimespec(src);
564 dst->st_ex_ctime = get_ctimespec(src);
565 make_create_timespec(src, dst, fake_dir_create_times);
566 #ifdef HAVE_STAT_ST_BLKSIZE
567 dst->st_ex_blksize = src->st_blksize;
569 dst->st_ex_blksize = STAT_ST_BLOCKSIZE;
572 #ifdef HAVE_STAT_ST_BLOCKS
573 dst->st_ex_blocks = src->st_blocks;
575 dst->st_ex_blocks = src->st_size / dst->st_ex_blksize + 1;
578 #ifdef HAVE_STAT_ST_FLAGS
579 dst->st_ex_flags = src->st_flags;
581 dst->st_ex_flags = 0;
585 /*******************************************************************
586 A stat() wrapper that will deal with 64 bit filesizes.
587 ********************************************************************/
589 int sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf,
590 bool fake_dir_create_times)
593 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
594 struct stat64 statbuf;
595 ret = stat64(fname, &statbuf);
598 ret = stat(fname, &statbuf);
601 /* we always want directories to appear zero size */
602 if (S_ISDIR(statbuf.st_mode)) {
605 init_stat_ex_from_stat(sbuf, &statbuf, fake_dir_create_times);
610 /*******************************************************************
611 An fstat() wrapper that will deal with 64 bit filesizes.
612 ********************************************************************/
614 int sys_fstat(int fd, SMB_STRUCT_STAT *sbuf, bool fake_dir_create_times)
617 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
618 struct stat64 statbuf;
619 ret = fstat64(fd, &statbuf);
622 ret = fstat(fd, &statbuf);
625 /* we always want directories to appear zero size */
626 if (S_ISDIR(statbuf.st_mode)) {
629 init_stat_ex_from_stat(sbuf, &statbuf, fake_dir_create_times);
634 /*******************************************************************
635 An lstat() wrapper that will deal with 64 bit filesizes.
636 ********************************************************************/
638 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf,
639 bool fake_dir_create_times)
642 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
643 struct stat64 statbuf;
644 ret = lstat64(fname, &statbuf);
647 ret = lstat(fname, &statbuf);
650 /* we always want directories to appear zero size */
651 if (S_ISDIR(statbuf.st_mode)) {
654 init_stat_ex_from_stat(sbuf, &statbuf, fake_dir_create_times);
659 /*******************************************************************
660 An posix_fallocate() wrapper that will deal with 64 bit filesizes.
661 ********************************************************************/
662 int sys_posix_fallocate(int fd, SMB_OFF_T offset, SMB_OFF_T len)
664 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_POSIX_FALLOCATE64) && !defined(HAVE_BROKEN_POSIX_FALLOCATE)
665 return posix_fallocate64(fd, offset, len);
666 #elif defined(HAVE_POSIX_FALLOCATE) && !defined(HAVE_BROKEN_POSIX_FALLOCATE)
667 return posix_fallocate(fd, offset, len);
668 #elif defined(F_RESVSP64)
669 /* this handles XFS on IRIX */
671 SMB_OFF_T new_len = offset + len;
675 /* unlikely to get a too large file on a 64bit system but ... */
679 fl.l_whence = SEEK_SET;
683 ret=fcntl(fd, F_RESVSP64, &fl);
688 /* Make sure the file gets enlarged after we allocated space: */
690 if (new_len > sbuf.st_size)
691 ftruncate64(fd, new_len);
698 /*******************************************************************
699 An fallocate() function that matches the semantics of the Linux one.
700 ********************************************************************/
702 #ifdef HAVE_LINUX_FALLOC_H
703 #include <linux/falloc.h>
706 int sys_fallocate(int fd, enum vfs_fallocate_mode mode, SMB_OFF_T offset, SMB_OFF_T len)
708 #if defined(HAVE_LINUX_FALLOCATE64) || defined(HAVE_LINUX_FALLOCATE)
711 case VFS_FALLOCATE_EXTEND_SIZE:
714 case VFS_FALLOCATE_KEEP_SIZE:
715 lmode = FALLOC_FL_KEEP_SIZE;
721 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LINUX_FALLOCATE64)
722 return fallocate64(fd, lmode, offset, len);
723 #elif defined(HAVE_LINUX_FALLOCATE)
724 return fallocate(fd, lmode, offset, len);
727 /* TODO - plumb in fallocate from other filesysetms like VXFS etc. JRA. */
733 /*******************************************************************
734 An ftruncate() wrapper that will deal with 64 bit filesizes.
735 ********************************************************************/
737 int sys_ftruncate(int fd, SMB_OFF_T offset)
739 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
740 return ftruncate64(fd, offset);
742 return ftruncate(fd, offset);
746 /*******************************************************************
747 An lseek() wrapper that will deal with 64 bit filesizes.
748 ********************************************************************/
750 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
752 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
753 return lseek64(fd, offset, whence);
755 return lseek(fd, offset, whence);
759 /*******************************************************************
760 An fseek() wrapper that will deal with 64 bit filesizes.
761 ********************************************************************/
763 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
765 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
766 return fseek64(fp, offset, whence);
767 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
768 return fseeko64(fp, offset, whence);
770 return fseek(fp, offset, whence);
774 /*******************************************************************
775 An ftell() wrapper that will deal with 64 bit filesizes.
776 ********************************************************************/
778 SMB_OFF_T sys_ftell(FILE *fp)
780 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
781 return (SMB_OFF_T)ftell64(fp);
782 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
783 return (SMB_OFF_T)ftello64(fp);
785 return (SMB_OFF_T)ftell(fp);
789 /*******************************************************************
790 A creat() wrapper that will deal with 64 bit filesizes.
791 ********************************************************************/
793 int sys_creat(const char *path, mode_t mode)
795 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
796 return creat64(path, mode);
799 * If creat64 isn't defined then ensure we call a potential open64.
802 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
806 /*******************************************************************
807 An open() wrapper that will deal with 64 bit filesizes.
808 ********************************************************************/
810 int sys_open(const char *path, int oflag, mode_t mode)
812 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
813 return open64(path, oflag, mode);
815 return open(path, oflag, mode);
819 /*******************************************************************
820 An fopen() wrapper that will deal with 64 bit filesizes.
821 ********************************************************************/
823 FILE *sys_fopen(const char *path, const char *type)
825 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
826 return fopen64(path, type);
828 return fopen(path, type);
833 /*******************************************************************
834 A flock() wrapper that will perform the kernel flock.
835 ********************************************************************/
837 void kernel_flock(int fd, uint32 share_mode, uint32 access_mask)
839 #if HAVE_KERNEL_SHARE_MODES
841 if (share_mode == FILE_SHARE_WRITE) {
842 kernel_mode = LOCK_MAND|LOCK_WRITE;
843 } else if (share_mode == FILE_SHARE_READ) {
844 kernel_mode = LOCK_MAND|LOCK_READ;
845 } else if (share_mode == FILE_SHARE_NONE) {
846 kernel_mode = LOCK_MAND;
849 flock(fd, kernel_mode);
857 /*******************************************************************
858 An opendir wrapper that will deal with 64 bit filesizes.
859 ********************************************************************/
861 SMB_STRUCT_DIR *sys_opendir(const char *name)
863 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
864 return opendir64(name);
866 return opendir(name);
870 /*******************************************************************
871 An fdopendir wrapper that will deal with 64 bit filesizes.
872 Ugly hack - we need dirfd for this to work correctly in the
874 ********************************************************************/
876 SMB_STRUCT_DIR *sys_fdopendir(int fd)
878 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FDOPENDIR64) && defined(HAVE_DIRFD)
879 return fdopendir64(fd);
880 #elif defined(HAVE_FDOPENDIR) && defined(HAVE_DIRFD)
881 return fdopendir(fd);
888 /*******************************************************************
889 A readdir wrapper that will deal with 64 bit filesizes.
890 ********************************************************************/
892 SMB_STRUCT_DIRENT *sys_readdir(SMB_STRUCT_DIR *dirp)
894 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
895 return readdir64(dirp);
897 return readdir(dirp);
901 /*******************************************************************
902 A seekdir wrapper that will deal with 64 bit filesizes.
903 ********************************************************************/
905 void sys_seekdir(SMB_STRUCT_DIR *dirp, long offset)
907 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
908 seekdir64(dirp, offset);
910 seekdir(dirp, offset);
914 /*******************************************************************
915 A telldir wrapper that will deal with 64 bit filesizes.
916 ********************************************************************/
918 long sys_telldir(SMB_STRUCT_DIR *dirp)
920 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
921 return (long)telldir64(dirp);
923 return (long)telldir(dirp);
927 /*******************************************************************
928 A rewinddir wrapper that will deal with 64 bit filesizes.
929 ********************************************************************/
931 void sys_rewinddir(SMB_STRUCT_DIR *dirp)
933 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
940 /*******************************************************************
941 A close wrapper that will deal with 64 bit filesizes.
942 ********************************************************************/
944 int sys_closedir(SMB_STRUCT_DIR *dirp)
946 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
947 return closedir64(dirp);
949 return closedir(dirp);
953 /*******************************************************************
954 An mknod() wrapper that will deal with 64 bit filesizes.
955 ********************************************************************/
957 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
959 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
960 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
961 return mknod64(path, mode, dev);
963 return mknod(path, mode, dev);
966 /* No mknod system call. */
972 /*******************************************************************
973 The wait() calls vary between systems
974 ********************************************************************/
976 int sys_waitpid(pid_t pid,int *status,int options)
979 return waitpid(pid,status,options);
980 #else /* HAVE_WAITPID */
981 return wait4(pid, status, options, NULL);
982 #endif /* HAVE_WAITPID */
985 /*******************************************************************
986 System wrapper for getwd
987 ********************************************************************/
989 char *sys_getwd(char *s)
993 wd = (char *)getcwd(s, PATH_MAX);
995 wd = (char *)getwd(s);
1000 #if defined(HAVE_POSIX_CAPABILITIES)
1002 /**************************************************************************
1003 Try and abstract process capabilities (for systems that have them).
1004 ****************************************************************************/
1006 /* Set the POSIX capabilities needed for the given purpose into the effective
1007 * capability set of the current process. Make sure they are always removed
1008 * from the inheritable set, because there is no circumstance in which our
1009 * children should inherit our elevated privileges.
1011 static bool set_process_capability(enum smbd_capability capability,
1014 cap_value_t cap_vals[2] = {0};
1015 int num_cap_vals = 0;
1019 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
1020 /* On Linux, make sure that any capabilities we grab are sticky
1021 * across UID changes. We expect that this would allow us to keep both
1022 * the effective and permitted capability sets, but as of circa 2.6.16,
1023 * only the permitted set is kept. It is a bug (which we work around)
1024 * that the effective set is lost, but we still require the effective
1027 if (!prctl(PR_GET_KEEPCAPS)) {
1028 prctl(PR_SET_KEEPCAPS, 1);
1032 cap = cap_get_proc();
1034 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
1039 switch (capability) {
1040 case KERNEL_OPLOCK_CAPABILITY:
1041 #ifdef CAP_NETWORK_MGT
1042 /* IRIX has CAP_NETWORK_MGT for oplocks. */
1043 cap_vals[num_cap_vals++] = CAP_NETWORK_MGT;
1046 case DMAPI_ACCESS_CAPABILITY:
1047 #ifdef CAP_DEVICE_MGT
1048 /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
1049 cap_vals[num_cap_vals++] = CAP_DEVICE_MGT;
1051 /* Linux has CAP_MKNOD for DMAPI access. */
1052 cap_vals[num_cap_vals++] = CAP_MKNOD;
1055 case LEASE_CAPABILITY:
1057 cap_vals[num_cap_vals++] = CAP_LEASE;
1062 SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals));
1064 if (num_cap_vals == 0) {
1069 cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
1070 enable ? CAP_SET : CAP_CLEAR);
1072 /* We never want to pass capabilities down to our children, so make
1073 * sure they are not inherited.
1075 cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
1077 if (cap_set_proc(cap) == -1) {
1078 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
1088 #endif /* HAVE_POSIX_CAPABILITIES */
1090 /****************************************************************************
1091 Gain the oplock capability from the kernel if possible.
1092 ****************************************************************************/
1094 void set_effective_capability(enum smbd_capability capability)
1096 #if defined(HAVE_POSIX_CAPABILITIES)
1097 set_process_capability(capability, True);
1098 #endif /* HAVE_POSIX_CAPABILITIES */
1101 void drop_effective_capability(enum smbd_capability capability)
1103 #if defined(HAVE_POSIX_CAPABILITIES)
1104 set_process_capability(capability, False);
1105 #endif /* HAVE_POSIX_CAPABILITIES */
1108 /**************************************************************************
1109 Wrapper for random().
1110 ****************************************************************************/
1112 long sys_random(void)
1114 #if defined(HAVE_RANDOM)
1115 return (long)random();
1116 #elif defined(HAVE_RAND)
1117 return (long)rand();
1119 DEBUG(0,("Error - no random function available !\n"));
1124 /**************************************************************************
1125 Wrapper for srandom().
1126 ****************************************************************************/
1128 void sys_srandom(unsigned int seed)
1130 #if defined(HAVE_SRANDOM)
1132 #elif defined(HAVE_SRAND)
1135 DEBUG(0,("Error - no srandom function available !\n"));
1141 #define NGROUPS_MAX 32 /* Guess... */
1144 /**************************************************************************
1145 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
1146 ****************************************************************************/
1148 int groups_max(void)
1150 #if defined(SYSCONF_SC_NGROUPS_MAX)
1151 int ret = sysconf(_SC_NGROUPS_MAX);
1152 return (ret == -1) ? NGROUPS_MAX : ret;
1158 /**************************************************************************
1159 Wrap setgroups and getgroups for systems that declare getgroups() as
1160 returning an array of gid_t, but actuall return an array of int.
1161 ****************************************************************************/
1163 #if defined(HAVE_BROKEN_GETGROUPS)
1165 #ifdef HAVE_BROKEN_GETGROUPS
1171 static int sys_broken_getgroups(int setlen, gid_t *gidset)
1178 return getgroups(setlen, &gid);
1182 * Broken case. We need to allocate a
1183 * GID_T array of size setlen.
1192 setlen = groups_max();
1194 if((group_list = SMB_MALLOC_ARRAY(GID_T, setlen)) == NULL) {
1195 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
1199 if((ngroups = getgroups(setlen, group_list)) < 0) {
1200 int saved_errno = errno;
1201 SAFE_FREE(group_list);
1202 errno = saved_errno;
1206 for(i = 0; i < ngroups; i++)
1207 gidset[i] = (gid_t)group_list[i];
1209 SAFE_FREE(group_list);
1213 static int sys_broken_setgroups(int setlen, gid_t *gidset)
1221 if (setlen < 0 || setlen > groups_max()) {
1227 * Broken case. We need to allocate a
1228 * GID_T array of size setlen.
1231 if((group_list = SMB_MALLOC_ARRAY(GID_T, setlen)) == NULL) {
1232 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
1236 for(i = 0; i < setlen; i++)
1237 group_list[i] = (GID_T) gidset[i];
1239 if(setgroups(setlen, group_list) != 0) {
1240 int saved_errno = errno;
1241 SAFE_FREE(group_list);
1242 errno = saved_errno;
1246 SAFE_FREE(group_list);
1250 #endif /* HAVE_BROKEN_GETGROUPS */
1252 /* This is a list of systems that require the first GID passed to setgroups(2)
1253 * to be the effective GID. If your system is one of these, add it here.
1255 #if defined (FREEBSD) || defined (DARWINOS)
1256 #define USE_BSD_SETGROUPS
1259 #if defined(USE_BSD_SETGROUPS)
1260 /* Depending on the particular BSD implementation, the first GID that is
1261 * passed to setgroups(2) will either be ignored or will set the credential's
1262 * effective GID. In either case, the right thing to do is to guarantee that
1263 * gidset[0] is the effective GID.
1265 static int sys_bsd_setgroups(gid_t primary_gid, int setlen, const gid_t *gidset)
1267 gid_t *new_gidset = NULL;
1271 /* setgroups(2) will fail with EINVAL if we pass too many groups. */
1274 /* No group list, just make sure we are setting the efective GID. */
1276 return setgroups(1, &primary_gid);
1279 /* If the primary gid is not the first array element, grow the array
1280 * and insert it at the front.
1282 if (gidset[0] != primary_gid) {
1283 new_gidset = SMB_MALLOC_ARRAY(gid_t, setlen + 1);
1284 if (new_gidset == NULL) {
1288 memcpy(new_gidset + 1, gidset, (setlen * sizeof(gid_t)));
1289 new_gidset[0] = primary_gid;
1294 DEBUG(3, ("forced to truncate group list from %d to %d\n",
1299 #if defined(HAVE_BROKEN_GETGROUPS)
1300 ret = sys_broken_setgroups(setlen, new_gidset ? new_gidset : gidset);
1302 ret = setgroups(setlen, new_gidset ? new_gidset : gidset);
1307 SAFE_FREE(new_gidset);
1314 #endif /* USE_BSD_SETGROUPS */
1316 /**************************************************************************
1317 Wrapper for getgroups. Deals with broken (int) case.
1318 ****************************************************************************/
1320 int sys_getgroups(int setlen, gid_t *gidset)
1322 #if defined(HAVE_BROKEN_GETGROUPS)
1323 return sys_broken_getgroups(setlen, gidset);
1325 return getgroups(setlen, gidset);
1329 /**************************************************************************
1330 Wrapper for setgroups. Deals with broken (int) case and BSD case.
1331 ****************************************************************************/
1333 int sys_setgroups(gid_t UNUSED(primary_gid), int setlen, gid_t *gidset)
1335 #if !defined(HAVE_SETGROUPS)
1338 #endif /* HAVE_SETGROUPS */
1340 #if defined(USE_BSD_SETGROUPS)
1341 return sys_bsd_setgroups(primary_gid, setlen, gidset);
1342 #elif defined(HAVE_BROKEN_GETGROUPS)
1343 return sys_broken_setgroups(setlen, gidset);
1345 return setgroups(setlen, gidset);
1349 /**************************************************************************
1350 Extract a command into an arg list.
1351 ****************************************************************************/
1353 static char **extract_args(TALLOC_CTX *mem_ctx, const char *command)
1362 if (!(trunc_cmd = talloc_strdup(mem_ctx, command))) {
1363 DEBUG(0, ("talloc failed\n"));
1367 if(!(ptr = strtok_r(trunc_cmd, " \t", &saveptr))) {
1368 TALLOC_FREE(trunc_cmd);
1377 for( argcl = 1; ptr; ptr = strtok_r(NULL, " \t", &saveptr))
1380 TALLOC_FREE(trunc_cmd);
1382 if (!(argl = TALLOC_ARRAY(mem_ctx, char *, argcl + 1))) {
1387 * Now do the extraction.
1390 if (!(trunc_cmd = talloc_strdup(mem_ctx, command))) {
1394 ptr = strtok_r(trunc_cmd, " \t", &saveptr);
1397 if (!(argl[i++] = talloc_strdup(argl, ptr))) {
1401 while((ptr = strtok_r(NULL, " \t", &saveptr)) != NULL) {
1403 if (!(argl[i++] = talloc_strdup(argl, ptr))) {
1409 TALLOC_FREE(trunc_cmd);
1413 DEBUG(0, ("talloc failed\n"));
1414 TALLOC_FREE(trunc_cmd);
1420 /**************************************************************************
1421 Wrapper for popen. Safer as it doesn't search a path.
1422 Modified from the glibc sources.
1423 modified by tridge to return a file descriptor. We must kick our FILE* habit
1424 ****************************************************************************/
1426 typedef struct _popen_list
1430 struct _popen_list *next;
1433 static popen_list *popen_chain;
1435 int sys_popen(const char *command)
1437 int parent_end, child_end;
1439 popen_list *entry = NULL;
1442 if (pipe(pipe_fds) < 0)
1445 parent_end = pipe_fds[0];
1446 child_end = pipe_fds[1];
1453 if((entry = SMB_MALLOC_P(popen_list)) == NULL)
1456 ZERO_STRUCTP(entry);
1459 * Extract the command and args into a NULL terminated array.
1462 if(!(argl = extract_args(NULL, command)))
1465 entry->child_pid = sys_fork();
1467 if (entry->child_pid == -1) {
1471 if (entry->child_pid == 0) {
1477 int child_std_end = STDOUT_FILENO;
1481 if (child_end != child_std_end) {
1482 dup2 (child_end, child_std_end);
1487 * POSIX.2: "popen() shall ensure that any streams from previous
1488 * popen() calls that remain open in the parent process are closed
1489 * in the new child process."
1492 for (p = popen_chain; p; p = p->next)
1495 execv(argl[0], argl);
1506 /* Link into popen_chain. */
1507 entry->next = popen_chain;
1508 popen_chain = entry;
1509 entry->fd = parent_end;
1522 /**************************************************************************
1523 Wrapper for pclose. Modified from the glibc sources.
1524 ****************************************************************************/
1526 int sys_pclose(int fd)
1529 popen_list **ptr = &popen_chain;
1530 popen_list *entry = NULL;
1534 /* Unlink from popen_chain. */
1535 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1536 if ((*ptr)->fd == fd) {
1538 *ptr = (*ptr)->next;
1544 if (status < 0 || close(entry->fd) < 0)
1548 * As Samba is catching and eating child process
1549 * exits we don't really care about the child exit
1550 * code, a -1 with errno = ECHILD will do fine for us.
1554 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1555 } while (wait_pid == -1 && errno == EINTR);
1564 /**************************************************************************
1565 Wrapper for Admin Logs.
1566 ****************************************************************************/
1568 void sys_adminlog(int priority, const char *format_str, ...)
1572 char *msgbuf = NULL;
1574 va_start( ap, format_str );
1575 ret = vasprintf( &msgbuf, format_str, ap );
1581 #if defined(HAVE_SYSLOG)
1582 syslog( priority, "%s", msgbuf );
1584 DEBUG(0,("%s", msgbuf ));
1589 /******** Solaris EA helper function prototypes ********/
1590 #ifdef HAVE_ATTROPEN
1591 #define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
1592 static int solaris_write_xattr(int attrfd, const char *value, size_t size);
1593 static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size);
1594 static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size);
1595 static int solaris_unlinkat(int attrdirfd, const char *name);
1596 static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode);
1597 static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode);
1600 /**************************************************************************
1601 Wrappers for extented attribute calls. Based on the Linux package with
1602 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1603 ****************************************************************************/
1605 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
1607 #if defined(HAVE_GETXATTR)
1608 #ifndef XATTR_ADD_OPT
1609 return getxattr(path, name, value, size);
1612 return getxattr(path, name, value, size, 0, options);
1614 #elif defined(HAVE_GETEA)
1615 return getea(path, name, value, size);
1616 #elif defined(HAVE_EXTATTR_GET_FILE)
1619 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1620 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1621 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1623 * The BSD implementation has a nasty habit of silently truncating
1624 * the returned value to the size of the buffer, so we have to check
1625 * that the buffer is large enough to fit the returned value.
1627 if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1632 if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0)
1636 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno)));
1638 #elif defined(HAVE_ATTR_GET)
1639 int retval, flags = 0;
1640 int valuelength = (int)size;
1641 char *attrname = strchr(name,'.') + 1;
1643 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1645 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1647 return retval ? retval : valuelength;
1648 #elif defined(HAVE_ATTROPEN)
1650 int attrfd = solaris_attropen(path, name, O_RDONLY, 0);
1652 ret = solaris_read_xattr(attrfd, value, size);
1662 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
1664 #if defined(HAVE_LGETXATTR)
1665 return lgetxattr(path, name, value, size);
1666 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
1667 int options = XATTR_NOFOLLOW;
1668 return getxattr(path, name, value, size, 0, options);
1669 #elif defined(HAVE_LGETEA)
1670 return lgetea(path, name, value, size);
1671 #elif defined(HAVE_EXTATTR_GET_LINK)
1674 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1675 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1676 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1678 if((retval=extattr_get_link(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1683 if((retval=extattr_get_link(path, attrnamespace, attrname, value, size)) >= 0)
1687 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno)));
1689 #elif defined(HAVE_ATTR_GET)
1690 int retval, flags = ATTR_DONTFOLLOW;
1691 int valuelength = (int)size;
1692 char *attrname = strchr(name,'.') + 1;
1694 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1696 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1698 return retval ? retval : valuelength;
1699 #elif defined(HAVE_ATTROPEN)
1701 int attrfd = solaris_attropen(path, name, O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
1703 ret = solaris_read_xattr(attrfd, value, size);
1713 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
1715 #if defined(HAVE_FGETXATTR)
1716 #ifndef XATTR_ADD_OPT
1717 return fgetxattr(filedes, name, value, size);
1720 return fgetxattr(filedes, name, value, size, 0, options);
1722 #elif defined(HAVE_FGETEA)
1723 return fgetea(filedes, name, value, size);
1724 #elif defined(HAVE_EXTATTR_GET_FD)
1727 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1728 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1729 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1731 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
1736 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0)
1740 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno)));
1742 #elif defined(HAVE_ATTR_GETF)
1743 int retval, flags = 0;
1744 int valuelength = (int)size;
1745 char *attrname = strchr(name,'.') + 1;
1747 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1749 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
1751 return retval ? retval : valuelength;
1752 #elif defined(HAVE_ATTROPEN)
1754 int attrfd = solaris_openat(filedes, name, O_RDONLY|O_XATTR, 0);
1756 ret = solaris_read_xattr(attrfd, value, size);
1766 #if defined(HAVE_EXTATTR_LIST_FILE)
1768 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1776 { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
1777 { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
1785 static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
1787 ssize_t list_size, total_size = 0;
1790 /* Iterate through extattr(2) namespaces */
1791 for(t = 0; t < (sizeof(extattr)/sizeof(extattr[0])); t++) {
1793 #if defined(HAVE_EXTATTR_LIST_FILE)
1795 list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
1798 #if defined(HAVE_EXTATTR_LIST_LINK)
1800 list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
1803 #if defined(HAVE_EXTATTR_LIST_FD)
1805 list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
1812 /* Some error happend. Errno should be set by the previous call */
1818 /* XXX: Call with an empty buffer may be used to calculate
1819 necessary buffer size. Unfortunately, we can't say, how
1820 many attributes were returned, so here is the potential
1821 problem with the emulation.
1824 /* Take the worse case of one char attribute names -
1825 two bytes per name plus one more for sanity.
1827 total_size += list_size + (list_size/2 + 1)*extattr[t].len;
1830 /* Count necessary offset to fit namespace prefixes */
1832 for(i = 0; i < list_size; i += list[i] + 1)
1833 len += extattr[t].len;
1835 total_size += list_size + len;
1836 /* Buffer is too small to fit the results */
1837 if(total_size > size) {
1841 /* Shift results back, so we can prepend prefixes */
1842 buf = (char *)memmove(list + len, list, list_size);
1844 for(i = 0; i < list_size; i += len + 1) {
1846 strncpy(list, extattr[t].name, extattr[t].len + 1);
1847 list += extattr[t].len;
1848 strncpy(list, buf + i + 1, len);
1859 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1860 static char attr_buffer[ATTR_MAX_VALUELEN];
1862 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
1864 int retval = 0, index;
1865 attrlist_cursor_t *cursor = 0;
1867 attrlist_t * al = (attrlist_t *)attr_buffer;
1869 size_t ent_size, left = size;
1874 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1876 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1878 for (index = 0; index < al->al_count; index++) {
1879 ae = ATTR_ENTRY(attr_buffer, index);
1880 ent_size = strlen(ae->a_name) + sizeof("user.");
1881 if (left >= ent_size) {
1882 strncpy(bp, "user.", sizeof("user."));
1883 strncat(bp, ae->a_name, ent_size - sizeof("user."));
1891 total_size += ent_size;
1893 if (al->al_more == 0) break;
1900 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1902 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1904 for (index = 0; index < al->al_count; index++) {
1905 ae = ATTR_ENTRY(attr_buffer, index);
1906 ent_size = strlen(ae->a_name) + sizeof("system.");
1907 if (left >= ent_size) {
1908 strncpy(bp, "system.", sizeof("system."));
1909 strncat(bp, ae->a_name, ent_size - sizeof("system."));
1917 total_size += ent_size;
1919 if (al->al_more == 0) break;
1922 return (ssize_t)(retval ? retval : total_size);
1927 ssize_t sys_listxattr (const char *path, char *list, size_t size)
1929 #if defined(HAVE_LISTXATTR)
1930 #ifndef XATTR_ADD_OPT
1931 return listxattr(path, list, size);
1934 return listxattr(path, list, size, options);
1936 #elif defined(HAVE_LISTEA)
1937 return listea(path, list, size);
1938 #elif defined(HAVE_EXTATTR_LIST_FILE)
1941 return bsd_attr_list(0, arg, list, size);
1942 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1943 return irix_attr_list(path, 0, list, size, 0);
1944 #elif defined(HAVE_ATTROPEN)
1946 int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0);
1947 if (attrdirfd >= 0) {
1948 ret = solaris_list_xattr(attrdirfd, list, size);
1958 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
1960 #if defined(HAVE_LLISTXATTR)
1961 return llistxattr(path, list, size);
1962 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
1963 int options = XATTR_NOFOLLOW;
1964 return listxattr(path, list, size, options);
1965 #elif defined(HAVE_LLISTEA)
1966 return llistea(path, list, size);
1967 #elif defined(HAVE_EXTATTR_LIST_LINK)
1970 return bsd_attr_list(1, arg, list, size);
1971 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1972 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
1973 #elif defined(HAVE_ATTROPEN)
1975 int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
1976 if (attrdirfd >= 0) {
1977 ret = solaris_list_xattr(attrdirfd, list, size);
1987 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
1989 #if defined(HAVE_FLISTXATTR)
1990 #ifndef XATTR_ADD_OPT
1991 return flistxattr(filedes, list, size);
1994 return flistxattr(filedes, list, size, options);
1996 #elif defined(HAVE_FLISTEA)
1997 return flistea(filedes, list, size);
1998 #elif defined(HAVE_EXTATTR_LIST_FD)
2000 arg.filedes = filedes;
2001 return bsd_attr_list(2, arg, list, size);
2002 #elif defined(HAVE_ATTR_LISTF)
2003 return irix_attr_list(NULL, filedes, list, size, 0);
2004 #elif defined(HAVE_ATTROPEN)
2006 int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0);
2007 if (attrdirfd >= 0) {
2008 ret = solaris_list_xattr(attrdirfd, list, size);
2018 int sys_removexattr (const char *path, const char *name)
2020 #if defined(HAVE_REMOVEXATTR)
2021 #ifndef XATTR_ADD_OPT
2022 return removexattr(path, name);
2025 return removexattr(path, name, options);
2027 #elif defined(HAVE_REMOVEEA)
2028 return removeea(path, name);
2029 #elif defined(HAVE_EXTATTR_DELETE_FILE)
2031 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2032 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2033 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2035 return extattr_delete_file(path, attrnamespace, attrname);
2036 #elif defined(HAVE_ATTR_REMOVE)
2038 char *attrname = strchr(name,'.') + 1;
2040 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
2042 return attr_remove(path, attrname, flags);
2043 #elif defined(HAVE_ATTROPEN)
2045 int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0);
2046 if (attrdirfd >= 0) {
2047 ret = solaris_unlinkat(attrdirfd, name);
2057 int sys_lremovexattr (const char *path, const char *name)
2059 #if defined(HAVE_LREMOVEXATTR)
2060 return lremovexattr(path, name);
2061 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
2062 int options = XATTR_NOFOLLOW;
2063 return removexattr(path, name, options);
2064 #elif defined(HAVE_LREMOVEEA)
2065 return lremoveea(path, name);
2066 #elif defined(HAVE_EXTATTR_DELETE_LINK)
2068 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2069 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2070 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2072 return extattr_delete_link(path, attrnamespace, attrname);
2073 #elif defined(HAVE_ATTR_REMOVE)
2074 int flags = ATTR_DONTFOLLOW;
2075 char *attrname = strchr(name,'.') + 1;
2077 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
2079 return attr_remove(path, attrname, flags);
2080 #elif defined(HAVE_ATTROPEN)
2082 int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
2083 if (attrdirfd >= 0) {
2084 ret = solaris_unlinkat(attrdirfd, name);
2094 int sys_fremovexattr (int filedes, const char *name)
2096 #if defined(HAVE_FREMOVEXATTR)
2097 #ifndef XATTR_ADD_OPT
2098 return fremovexattr(filedes, name);
2101 return fremovexattr(filedes, name, options);
2103 #elif defined(HAVE_FREMOVEEA)
2104 return fremoveea(filedes, name);
2105 #elif defined(HAVE_EXTATTR_DELETE_FD)
2107 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2108 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2109 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2111 return extattr_delete_fd(filedes, attrnamespace, attrname);
2112 #elif defined(HAVE_ATTR_REMOVEF)
2114 char *attrname = strchr(name,'.') + 1;
2116 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
2118 return attr_removef(filedes, attrname, flags);
2119 #elif defined(HAVE_ATTROPEN)
2121 int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0);
2122 if (attrdirfd >= 0) {
2123 ret = solaris_unlinkat(attrdirfd, name);
2133 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
2135 #if defined(HAVE_SETXATTR)
2136 #ifndef XATTR_ADD_OPT
2137 return setxattr(path, name, value, size, flags);
2140 return setxattr(path, name, value, size, 0, options);
2142 #elif defined(HAVE_SETEA)
2143 return setea(path, name, value, size, flags);
2144 #elif defined(HAVE_EXTATTR_SET_FILE)
2147 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2148 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2149 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2151 /* Check attribute existence */
2152 retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0);
2154 /* REPLACE attribute, that doesn't exist */
2155 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2159 /* Ignore other errors */
2162 /* CREATE attribute, that already exists */
2163 if (flags & XATTR_CREATE) {
2169 retval = extattr_set_file(path, attrnamespace, attrname, value, size);
2170 return (retval < 0) ? -1 : 0;
2171 #elif defined(HAVE_ATTR_SET)
2173 char *attrname = strchr(name,'.') + 1;
2175 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2176 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2177 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2179 return attr_set(path, attrname, (const char *)value, size, myflags);
2180 #elif defined(HAVE_ATTROPEN)
2182 int myflags = O_RDWR;
2184 if (flags & XATTR_CREATE) myflags |= O_EXCL;
2185 if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
2186 attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
2188 ret = solaris_write_xattr(attrfd, value, size);
2198 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
2200 #if defined(HAVE_LSETXATTR)
2201 return lsetxattr(path, name, value, size, flags);
2202 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
2203 int options = XATTR_NOFOLLOW;
2204 return setxattr(path, name, value, size, 0, options);
2205 #elif defined(LSETEA)
2206 return lsetea(path, name, value, size, flags);
2207 #elif defined(HAVE_EXTATTR_SET_LINK)
2210 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2211 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2212 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2214 /* Check attribute existence */
2215 retval = extattr_get_link(path, attrnamespace, attrname, NULL, 0);
2217 /* REPLACE attribute, that doesn't exist */
2218 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2222 /* Ignore other errors */
2225 /* CREATE attribute, that already exists */
2226 if (flags & XATTR_CREATE) {
2233 retval = extattr_set_link(path, attrnamespace, attrname, value, size);
2234 return (retval < 0) ? -1 : 0;
2235 #elif defined(HAVE_ATTR_SET)
2236 int myflags = ATTR_DONTFOLLOW;
2237 char *attrname = strchr(name,'.') + 1;
2239 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2240 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2241 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2243 return attr_set(path, attrname, (const char *)value, size, myflags);
2244 #elif defined(HAVE_ATTROPEN)
2246 int myflags = O_RDWR | AT_SYMLINK_NOFOLLOW;
2248 if (flags & XATTR_CREATE) myflags |= O_EXCL;
2249 if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
2250 attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
2252 ret = solaris_write_xattr(attrfd, value, size);
2262 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
2264 #if defined(HAVE_FSETXATTR)
2265 #ifndef XATTR_ADD_OPT
2266 return fsetxattr(filedes, name, value, size, flags);
2269 return fsetxattr(filedes, name, value, size, 0, options);
2271 #elif defined(HAVE_FSETEA)
2272 return fsetea(filedes, name, value, size, flags);
2273 #elif defined(HAVE_EXTATTR_SET_FD)
2276 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2277 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2278 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2280 /* Check attribute existence */
2281 retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0);
2283 /* REPLACE attribute, that doesn't exist */
2284 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2288 /* Ignore other errors */
2291 /* CREATE attribute, that already exists */
2292 if (flags & XATTR_CREATE) {
2298 retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
2299 return (retval < 0) ? -1 : 0;
2300 #elif defined(HAVE_ATTR_SETF)
2302 char *attrname = strchr(name,'.') + 1;
2304 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2305 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2306 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2308 return attr_setf(filedes, attrname, (const char *)value, size, myflags);
2309 #elif defined(HAVE_ATTROPEN)
2311 int myflags = O_RDWR | O_XATTR;
2313 if (flags & XATTR_CREATE) myflags |= O_EXCL;
2314 if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
2315 attrfd = solaris_openat(filedes, name, myflags, (mode_t) SOLARIS_ATTRMODE);
2317 ret = solaris_write_xattr(attrfd, value, size);
2327 /**************************************************************************
2328 helper functions for Solaris' EA support
2329 ****************************************************************************/
2330 #ifdef HAVE_ATTROPEN
2331 static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size)
2335 if (fstat(attrfd, &sbuf) == -1) {
2340 /* This is to return the current size of the named extended attribute */
2342 return sbuf.st_size;
2345 /* check size and read xattr */
2346 if (sbuf.st_size > size) {
2351 return read(attrfd, value, sbuf.st_size);
2354 static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size)
2359 int newfd = dup(attrdirfd);
2360 /* CAUTION: The originating file descriptor should not be
2361 used again following the call to fdopendir().
2362 For that reason we dup() the file descriptor
2363 here to make things more clear. */
2364 dirp = fdopendir(newfd);
2366 while ((de = readdir(dirp))) {
2367 size_t listlen = strlen(de->d_name);
2368 if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
2369 /* we don't want "." and ".." here: */
2370 DEBUG(10,("skipped EA %s\n",de->d_name));
2375 /* return the current size of the list of extended attribute names*/
2378 /* check size and copy entrieѕ + nul into list. */
2379 if ((len + listlen + 1) > size) {
2384 safe_strcpy(list + len, de->d_name, listlen);
2392 if (closedir(dirp) == -1) {
2393 DEBUG(0,("closedir dirp failed: %s\n",strerror(errno)));
2399 static int solaris_unlinkat(int attrdirfd, const char *name)
2401 if (unlinkat(attrdirfd, name, 0) == -1) {
2402 if (errno == ENOENT) {
2410 static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode)
2412 int filedes = attropen(path, attrpath, oflag, mode);
2413 if (filedes == -1) {
2414 DEBUG(10,("attropen FAILED: path: %s, name: %s, errno: %s\n",path,attrpath,strerror(errno)));
2415 if (errno == EINVAL) {
2424 static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode)
2426 int filedes = openat(fildes, path, oflag, mode);
2427 if (filedes == -1) {
2428 DEBUG(10,("openat FAILED: fd: %d, path: %s, errno: %s\n",filedes,path,strerror(errno)));
2429 if (errno == EINVAL) {
2438 static int solaris_write_xattr(int attrfd, const char *value, size_t size)
2440 if ((ftruncate(attrfd, 0) == 0) && (write(attrfd, value, size) == size)) {
2443 DEBUG(10,("solaris_write_xattr FAILED!\n"));
2447 #endif /*HAVE_ATTROPEN*/
2450 /****************************************************************************
2451 Return the major devicenumber for UNIX extensions.
2452 ****************************************************************************/
2454 uint32 unix_dev_major(SMB_DEV_T dev)
2456 #if defined(HAVE_DEVICE_MAJOR_FN)
2457 return (uint32)major(dev);
2459 return (uint32)(dev >> 8);
2463 /****************************************************************************
2464 Return the minor devicenumber for UNIX extensions.
2465 ****************************************************************************/
2467 uint32 unix_dev_minor(SMB_DEV_T dev)
2469 #if defined(HAVE_DEVICE_MINOR_FN)
2470 return (uint32)minor(dev);
2472 return (uint32)(dev & 0xff);
2476 #if defined(WITH_AIO)
2478 /*******************************************************************
2479 An aio_read wrapper that will deal with 64-bit sizes.
2480 ********************************************************************/
2482 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2484 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2485 return aio_read64(aiocb);
2486 #elif defined(HAVE_AIO_READ)
2487 return aio_read(aiocb);
2494 /*******************************************************************
2495 An aio_write wrapper that will deal with 64-bit sizes.
2496 ********************************************************************/
2498 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2500 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2501 return aio_write64(aiocb);
2502 #elif defined(HAVE_AIO_WRITE)
2503 return aio_write(aiocb);
2510 /*******************************************************************
2511 An aio_return wrapper that will deal with 64-bit sizes.
2512 ********************************************************************/
2514 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2516 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2517 return aio_return64(aiocb);
2518 #elif defined(HAVE_AIO_RETURN)
2519 return aio_return(aiocb);
2526 /*******************************************************************
2527 An aio_cancel wrapper that will deal with 64-bit sizes.
2528 ********************************************************************/
2530 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2532 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2533 return aio_cancel64(fd, aiocb);
2534 #elif defined(HAVE_AIO_CANCEL)
2535 return aio_cancel(fd, aiocb);
2542 /*******************************************************************
2543 An aio_error wrapper that will deal with 64-bit sizes.
2544 ********************************************************************/
2546 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2548 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2549 return aio_error64(aiocb);
2550 #elif defined(HAVE_AIO_ERROR)
2551 return aio_error(aiocb);
2558 /*******************************************************************
2559 An aio_fsync wrapper that will deal with 64-bit sizes.
2560 ********************************************************************/
2562 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2564 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2565 return aio_fsync64(op, aiocb);
2566 #elif defined(HAVE_AIO_FSYNC)
2567 return aio_fsync(op, aiocb);
2574 /*******************************************************************
2575 An aio_fsync wrapper that will deal with 64-bit sizes.
2576 ********************************************************************/
2578 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2580 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2581 return aio_suspend64(cblist, n, timeout);
2582 #elif defined(HAVE_AIO_FSYNC)
2583 return aio_suspend(cblist, n, timeout);
2589 #else /* !WITH_AIO */
2591 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2597 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2603 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2609 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2615 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2621 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2627 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2632 #endif /* WITH_AIO */
2634 int sys_getpeereid( int s, uid_t *uid)
2636 #if defined(HAVE_PEERCRED)
2638 socklen_t cred_len = sizeof(struct ucred);
2641 ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
2646 if (cred_len != sizeof(struct ucred)) {
2654 #if defined(HAVE_GETPEEREID)
2656 return getpeereid(s, uid, &gid);
2663 int sys_getnameinfo(const struct sockaddr *psa,
2672 * For Solaris we must make sure salen is the
2673 * correct length for the incoming sa_family.
2676 if (salen == sizeof(struct sockaddr_storage)) {
2677 salen = sizeof(struct sockaddr_in);
2678 #if defined(HAVE_IPV6)
2679 if (psa->sa_family == AF_INET6) {
2680 salen = sizeof(struct sockaddr_in6);
2684 return getnameinfo(psa, salen, host, hostlen, service, servlen, flags);
2687 int sys_connect(int fd, const struct sockaddr * addr)
2689 socklen_t salen = (socklen_t)-1;
2691 if (addr->sa_family == AF_INET) {
2692 salen = sizeof(struct sockaddr_in);
2693 } else if (addr->sa_family == AF_UNIX) {
2694 salen = sizeof(struct sockaddr_un);
2696 #if defined(HAVE_IPV6)
2697 else if (addr->sa_family == AF_INET6) {
2698 salen = sizeof(struct sockaddr_in6);
2702 return connect(fd, addr, salen);