summaryrefslogtreecommitdiff
path: root/source3/lib/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/system.c')
-rw-r--r--source3/lib/system.c197
1 files changed, 159 insertions, 38 deletions
diff --git a/source3/lib/system.c b/source3/lib/system.c
index f9de800bd3..a59f94a6a9 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -60,7 +60,7 @@ static int pollfd(int fd)
return(r);
}
-int sys_select(int maxfd, fd_set *fds, fd_set *w_fds, struct timeval *tval)
+int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
{
fd_set fds2;
int counter=0;
@@ -90,7 +90,7 @@ int sys_select(int maxfd, fd_set *fds, fd_set *w_fds, struct timeval *tval)
}
#else /* !NO_SELECT */
-int sys_select(int maxfd, fd_set *r_fds, fd_set *w_fds, struct timeval *tval)
+int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
{
#ifdef USE_POLL
struct pollfd pfd[256];
@@ -131,8 +131,7 @@ int sys_select(int maxfd, fd_set *r_fds, fd_set *w_fds, struct timeval *tval)
do {
if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
errno = 0;
- selrtn = select(maxfd,SELECT_CAST r_fds,SELECT_CAST w_fds,
- NULL,tval?&t2:NULL);
+ selrtn = select(maxfd,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
} while (selrtn<0 && errno == EINTR);
return(selrtn);
@@ -141,16 +140,54 @@ int sys_select(int maxfd, fd_set *r_fds, fd_set *w_fds, struct timeval *tval)
#endif /* NO_SELECT */
/*******************************************************************
+ A wrapper for usleep in case we don't have one.
+********************************************************************/
+
+int sys_usleep(long usecs)
+{
+#ifndef HAVE_USLEEP
+ struct timeval tval;
+#endif
+
+ /*
+ * We need this braindamage as the glibc usleep
+ * is not SPEC1170 complient... grumble... JRA.
+ */
+
+ if(usecs < 0 || usecs > 1000000) {
+ errno = EINVAL;
+ return -1;
+ }
+
+#if HAVE_USLEEP
+ usleep(usecs);
+ return 0;
+#else /* HAVE_USLEEP */
+ /*
+ * Fake it with select...
+ */
+ tval.tv_sec = 0;
+ tval.tv_usec = usecs/1000;
+ select(0,NULL,NULL,NULL,&tval);
+ return 0;
+#endif /* HAVE_USLEEP */
+}
+
+/*******************************************************************
A stat() wrapper that will deal with 64 bit filesizes.
********************************************************************/
int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
{
-#if defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
- return stat64(fname, sbuf);
+ int ret;
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
+ ret = stat64(fname, sbuf);
#else
- return stat(fname, sbuf);
+ ret = stat(fname, sbuf);
#endif
+ /* we always want directories to appear zero size */
+ if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+ return ret;
}
/*******************************************************************
@@ -159,11 +196,15 @@ int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
{
-#if defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
- return fstat64(fd, sbuf);
+ int ret;
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
+ ret = fstat64(fd, sbuf);
#else
- return fstat(fd, sbuf);
+ ret = fstat(fd, sbuf);
#endif
+ /* we always want directories to appear zero size */
+ if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+ return ret;
}
/*******************************************************************
@@ -172,11 +213,15 @@ int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
{
-#if defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
- return lstat64(fname, sbuf);
+ int ret;
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
+ ret = lstat64(fname, sbuf);
#else
- return lstat(fname, sbuf);
+ ret = lstat(fname, sbuf);
#endif
+ /* we always want directories to appear zero size */
+ if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+ return ret;
}
/*******************************************************************
@@ -185,7 +230,7 @@ int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
int sys_ftruncate(int fd, SMB_OFF_T offset)
{
-#if defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
return ftruncate64(fd, offset);
#else
return ftruncate(fd, offset);
@@ -198,7 +243,7 @@ int sys_ftruncate(int fd, SMB_OFF_T offset)
SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
{
-#if defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
return lseek64(fd, offset, whence);
#else
return lseek(fd, offset, whence);
@@ -211,8 +256,10 @@ SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
{
-#if defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
return fseek64(fp, offset, whence);
+#elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
+ return fseeko64(fp, offset, whence);
#else
return fseek(fp, offset, whence);
#endif
@@ -224,8 +271,10 @@ int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
SMB_OFF_T sys_ftell(FILE *fp)
{
-#if defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
return (SMB_OFF_T)ftell64(fp);
+#elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
+ return (SMB_OFF_T)ftello64(fp);
#else
return (SMB_OFF_T)ftell(fp);
#endif
@@ -237,7 +286,7 @@ SMB_OFF_T sys_ftell(FILE *fp)
int sys_creat(const char *path, mode_t mode)
{
-#if defined(HAVE_CREAT64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
return creat64(path, mode);
#else
/*
@@ -254,7 +303,7 @@ int sys_creat(const char *path, mode_t mode)
int sys_open(const char *path, int oflag, mode_t mode)
{
-#if defined(HAVE_OPEN64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
return open64(path, oflag, mode);
#else
return open(path, oflag, mode);
@@ -267,26 +316,43 @@ int sys_open(const char *path, int oflag, mode_t mode)
FILE *sys_fopen(const char *path, const char *type)
{
-#if defined(HAVE_FOPEN64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
return fopen64(path, type);
#else
return fopen(path, type);
#endif
}
+#if defined(HAVE_MMAP)
+
/*******************************************************************
An mmap() wrapper that will deal with 64 bit filesizes.
********************************************************************/
void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, SMB_OFF_T offset)
{
-#if defined(LARGE_SMB_OFF_T) && defined(HAVE_MMAP64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_MMAP64)
return mmap64(addr, len, prot, flags, fd, offset);
#else
return mmap(addr, len, prot, flags, fd, offset);
#endif
}
+#endif /* HAVE_MMAP */
+
+/*******************************************************************
+ A readdir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
+ return readdir64(dirp);
+#else
+ return readdir(dirp);
+#endif
+}
+
/*******************************************************************
The wait() calls vary between systems
********************************************************************/
@@ -305,18 +371,19 @@ system wrapper for getwd
********************************************************************/
char *sys_getwd(char *s)
{
- char *wd;
+ char *wd;
#ifdef HAVE_GETCWD
- wd = (char *)getcwd(s, sizeof (pstring));
+ wd = (char *)getcwd(s, sizeof (pstring));
#else
- wd = (char *)getwd(s);
+ wd = (char *)getwd(s);
#endif
- return wd;
+ return wd;
}
/*******************************************************************
chown isn't used much but OS/2 doesn't have it
********************************************************************/
+
int sys_chown(const char *fname,uid_t uid,gid_t gid)
{
#ifndef HAVE_CHOWN
@@ -413,9 +480,12 @@ BOOL set_process_capability( uint32 cap_flag, BOOL enable )
if (cap_set_proc(cap) == -1) {
DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
strerror(errno)));
+ cap_free(cap);
return False;
}
+ cap_free(cap);
+
DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
}
#endif
@@ -447,9 +517,12 @@ BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable )
if (cap_set_proc(cap) == -1) {
DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
strerror(errno)));
+ cap_free(cap);
return False;
}
+ cap_free(cap);
+
DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
}
#endif
@@ -516,7 +589,8 @@ int sys_getgroups(int setlen, gid_t *gidset)
return -1;
}
- if (setlen == 0) setlen = 1;
+ if (setlen == 0)
+ setlen = 1;
if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
DEBUG(0,("sys_getgroups: Malloc fail.\n"));
@@ -538,6 +612,62 @@ int sys_getgroups(int setlen, gid_t *gidset)
#endif /* HAVE_BROKEN_GETGROUPS */
}
+#ifdef HAVE_SETGROUPS
+
+/**************************************************************************
+ Wrapper for setgroups. Deals with broken (int) case. Automatically used
+ if we have broken getgroups.
+****************************************************************************/
+
+int sys_setgroups(int setlen, gid_t *gidset)
+{
+#if !defined(HAVE_BROKEN_GETGROUPS)
+ return setgroups(setlen, gidset);
+#else
+
+ GID_T *group_list;
+ int i ;
+
+ if (setlen == 0)
+ return 0 ;
+
+#ifdef NGROUPS_MAX
+ if (setlen > NGROUPS_MAX) {
+ errno = EINVAL;
+ return -1;
+ }
+#endif
+
+ /*
+ * Broken case. We need to allocate a
+ * GID_T array of size setlen.
+ */
+
+ if (setlen == 0)
+ setlen = 1;
+
+ if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
+ DEBUG(0,("sys_setgroups: Malloc fail.\n"));
+ return -1;
+ }
+
+ for(i = 0; i < setlen; i++)
+ group_list[i] = (GID_T) gidset[i];
+
+ if(setgroups(setlen, group_list) != 0) {
+ int saved_errno = errno;
+ free((char *)group_list);
+ errno = saved_errno;
+ return -1;
+ }
+
+ free((char *)group_list);
+ return 0 ;
+#endif /* HAVE_BROKEN_GETGROUPS */
+}
+
+#endif /* HAVE_SETGROUPS */
+
/*
* We only wrap pw_name and pw_passwd for now as these
* are the only potentially modified fields.
@@ -547,7 +677,7 @@ int sys_getgroups(int setlen, gid_t *gidset)
Helper function for getpwnam/getpwuid wrappers.
****************************************************************************/
-struct passwd *copy_passwd_struct(struct passwd *pass)
+static struct passwd *setup_pwret(struct passwd *pass)
{
static pstring pw_name;
static pstring pw_passwd;
@@ -558,25 +688,16 @@ struct passwd *copy_passwd_struct(struct passwd *pass)
return NULL;
}
- if (pass == &pw_ret)
- {
- /* catch silly error where buffer was already copied */
- DEBUG(0,("copy_passwd_struct: can't copy internal buffer!\n"));
- return NULL;
- }
-
memcpy((char *)&pw_ret, pass, sizeof(struct passwd));
if (pass->pw_name)
{
- pw_name[0] = '\0';
pw_ret.pw_name = pw_name;
pstrcpy(pw_ret.pw_name, pass->pw_name);
}
if (pass->pw_passwd)
{
- pw_passwd[0] = '\0';
pw_ret.pw_passwd = pw_passwd;
pstrcpy(pw_ret.pw_passwd, pass->pw_passwd);
}
@@ -590,7 +711,7 @@ struct passwd *copy_passwd_struct(struct passwd *pass)
struct passwd *sys_getpwnam(const char *name)
{
- return copy_passwd_struct(getpwnam(name));
+ return setup_pwret(getpwnam(name));
}
/**************************************************************************
@@ -599,5 +720,5 @@ struct passwd *sys_getpwnam(const char *name)
struct passwd *sys_getpwuid(uid_t uid)
{
- return copy_passwd_struct(getpwuid(uid));
+ return setup_pwret(getpwuid(uid));
}