2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1998-2002
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 The idea is that this file will eventually have wrappers around all
26 important system calls in samba. The aims are:
28 - to enable easier porting by putting OS dependent stuff in here
30 - to allow for hooks into other "pseudo-filesystems"
32 - to allow easier integration of things like the japanese extensions
34 - to support the philosophy of Samba to expose the features of
35 the OS within the SMB model. In general whatever file/printer/variable
36 expansions/etc make sense to the OS should be acceptable to Samba.
41 /*******************************************************************
42 A wrapper for usleep in case we don't have one.
43 ********************************************************************/
45 int sys_usleep(long usecs)
52 * We need this braindamage as the glibc usleep
53 * is not SPEC1170 complient... grumble... JRA.
56 if(usecs < 0 || usecs > 1000000) {
64 #else /* HAVE_USLEEP */
66 * Fake it with select...
69 tval.tv_usec = usecs/1000;
70 select(0,NULL,NULL,NULL,&tval);
72 #endif /* HAVE_USLEEP */
75 /*******************************************************************
76 A read wrapper that will deal with EINTR.
77 ********************************************************************/
79 ssize_t sys_read(int fd, void *buf, size_t count)
84 ret = read(fd, buf, count);
85 } while (ret == -1 && errno == EINTR);
89 /*******************************************************************
90 A write wrapper that will deal with EINTR.
91 ********************************************************************/
93 ssize_t sys_write(int fd, const void *buf, size_t count)
98 ret = write(fd, buf, count);
99 } while (ret == -1 && errno == EINTR);
103 /*******************************************************************
104 A send wrapper that will deal with EINTR.
105 ********************************************************************/
107 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
112 ret = send(s, msg, len, flags);
113 } while (ret == -1 && errno == EINTR);
117 /*******************************************************************
118 A sendto wrapper that will deal with EINTR.
119 ********************************************************************/
121 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
126 ret = sendto(s, msg, len, flags, to, tolen);
127 } while (ret == -1 && errno == EINTR);
131 /*******************************************************************
132 A recvfrom wrapper that will deal with EINTR.
133 ********************************************************************/
135 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
140 ret = recvfrom(s, buf, len, flags, from, fromlen);
141 } while (ret == -1 && errno == EINTR);
145 /*******************************************************************
146 A fcntl wrapper that will deal with EINTR.
147 ********************************************************************/
149 int sys_fcntl_ptr(int fd, int cmd, void *arg)
154 ret = fcntl(fd, cmd, arg);
155 } while (ret == -1 && errno == EINTR);
159 /*******************************************************************
160 A fcntl wrapper that will deal with EINTR.
161 ********************************************************************/
163 int sys_fcntl_long(int fd, int cmd, long arg)
168 ret = fcntl(fd, cmd, arg);
169 } while (ret == -1 && errno == EINTR);
173 /*******************************************************************
174 A stat() wrapper that will deal with 64 bit filesizes.
175 ********************************************************************/
177 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
180 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
181 ret = stat64(fname, sbuf);
183 ret = stat(fname, sbuf);
185 /* we always want directories to appear zero size */
186 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
190 /*******************************************************************
191 An fstat() wrapper that will deal with 64 bit filesizes.
192 ********************************************************************/
194 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
197 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
198 ret = fstat64(fd, sbuf);
200 ret = fstat(fd, sbuf);
202 /* we always want directories to appear zero size */
203 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
207 /*******************************************************************
208 An lstat() wrapper that will deal with 64 bit filesizes.
209 ********************************************************************/
211 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
214 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
215 ret = lstat64(fname, sbuf);
217 ret = lstat(fname, sbuf);
219 /* we always want directories to appear zero size */
220 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
224 /*******************************************************************
225 An ftruncate() wrapper that will deal with 64 bit filesizes.
226 ********************************************************************/
228 int sys_ftruncate(int fd, SMB_OFF_T offset)
230 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
231 return ftruncate64(fd, offset);
233 return ftruncate(fd, offset);
237 /*******************************************************************
238 An lseek() wrapper that will deal with 64 bit filesizes.
239 ********************************************************************/
241 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
243 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
244 return lseek64(fd, offset, whence);
246 return lseek(fd, offset, whence);
250 /*******************************************************************
251 An fseek() wrapper that will deal with 64 bit filesizes.
252 ********************************************************************/
254 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
256 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
257 return fseek64(fp, offset, whence);
258 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
259 return fseeko64(fp, offset, whence);
261 return fseek(fp, offset, whence);
265 /*******************************************************************
266 An ftell() wrapper that will deal with 64 bit filesizes.
267 ********************************************************************/
269 SMB_OFF_T sys_ftell(FILE *fp)
271 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
272 return (SMB_OFF_T)ftell64(fp);
273 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
274 return (SMB_OFF_T)ftello64(fp);
276 return (SMB_OFF_T)ftell(fp);
280 /*******************************************************************
281 A creat() wrapper that will deal with 64 bit filesizes.
282 ********************************************************************/
284 int sys_creat(const char *path, mode_t mode)
286 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
287 return creat64(path, mode);
290 * If creat64 isn't defined then ensure we call a potential open64.
293 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
297 /*******************************************************************
298 An open() wrapper that will deal with 64 bit filesizes.
299 ********************************************************************/
301 int sys_open(const char *path, int oflag, mode_t mode)
303 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
304 return open64(path, oflag, mode);
306 return open(path, oflag, mode);
310 /*******************************************************************
311 An fopen() wrapper that will deal with 64 bit filesizes.
312 ********************************************************************/
314 FILE *sys_fopen(const char *path, const char *type)
316 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
317 return fopen64(path, type);
319 return fopen(path, type);
323 /*******************************************************************
324 A readdir wrapper that will deal with 64 bit filesizes.
325 ********************************************************************/
327 SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
329 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
330 return readdir64(dirp);
332 return readdir(dirp);
336 /*******************************************************************
337 The wait() calls vary between systems
338 ********************************************************************/
340 int sys_waitpid(pid_t pid,int *status,int options)
343 return waitpid(pid,status,options);
344 #else /* HAVE_WAITPID */
345 return wait4(pid, status, options, NULL);
346 #endif /* HAVE_WAITPID */
349 /*******************************************************************
350 System wrapper for getwd
351 ********************************************************************/
353 char *sys_getwd(char *s)
357 wd = (char *)getcwd(s, sizeof (pstring));
359 wd = (char *)getwd(s);
364 /*******************************************************************
365 system wrapper for link
366 ********************************************************************/
368 int sys_link(const char *oldpath, const char *newpath)
374 return link(oldpath, newpath);
378 /*******************************************************************
379 os/2 also doesn't have chroot
380 ********************************************************************/
381 int sys_chroot(const char *dname)
386 DEBUG(1,("WARNING: no chroot!\n"));
392 return(chroot(dname));
396 /**************************************************************************
397 A wrapper for gethostbyname() that tries avoids looking up hostnames
398 in the root domain, which can cause dial-on-demand links to come up for no
400 ****************************************************************************/
402 struct hostent *sys_gethostbyname(const char *name)
404 #ifdef REDUCE_ROOT_DNS_LOOKUPS
405 char query[256], hostname[256];
408 /* Does this name have any dots in it? If so, make no change */
410 if (strchr_m(name, '.'))
411 return(gethostbyname(name));
413 /* Get my hostname, which should have domain name
414 attached. If not, just do the gethostname on the
418 gethostname(hostname, sizeof(hostname) - 1);
419 hostname[sizeof(hostname) - 1] = 0;
420 if ((domain = strchr_m(hostname, '.')) == NULL)
421 return(gethostbyname(name));
423 /* Attach domain name to query and do modified query.
424 If names too large, just do gethostname on the
428 if((strlen(name) + strlen(domain)) >= sizeof(query))
429 return(gethostbyname(name));
431 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
432 return(gethostbyname(query));
433 #else /* REDUCE_ROOT_DNS_LOOKUPS */
434 return(gethostbyname(name));
435 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
439 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
440 /**************************************************************************
441 Try and abstract process capabilities (for systems that have them).
442 ****************************************************************************/
443 static BOOL set_process_capability( uint32 cap_flag, BOOL enable )
445 if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
446 cap_t cap = cap_get_proc();
449 DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n",
455 cap->cap_effective |= CAP_NETWORK_MGT;
457 cap->cap_effective &= ~CAP_NETWORK_MGT;
459 if (cap_set_proc(cap) == -1) {
460 DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
468 DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
473 /**************************************************************************
474 Try and abstract inherited process capabilities (for systems that have them).
475 ****************************************************************************/
477 static BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable )
479 if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
480 cap_t cap = cap_get_proc();
483 DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
489 cap->cap_inheritable |= CAP_NETWORK_MGT;
491 cap->cap_inheritable &= ~CAP_NETWORK_MGT;
493 if (cap_set_proc(cap) == -1) {
494 DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
502 DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
508 /****************************************************************************
509 Gain the oplock capability from the kernel if possible.
510 ****************************************************************************/
512 void oplock_set_capability(BOOL this_process, BOOL inherit)
514 #if HAVE_KERNEL_OPLOCKS_IRIX
515 set_process_capability(KERNEL_OPLOCK_CAPABILITY,this_process);
516 set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,inherit);
520 /**************************************************************************
521 Wrapper for random().
522 ****************************************************************************/
524 long sys_random(void)
526 #if defined(HAVE_RANDOM)
527 return (long)random();
528 #elif defined(HAVE_RAND)
531 DEBUG(0,("Error - no random function available !\n"));
536 /**************************************************************************
537 Wrapper for srandom().
538 ****************************************************************************/
540 void sys_srandom(unsigned int seed)
542 #if defined(HAVE_SRANDOM)
544 #elif defined(HAVE_SRAND)
547 DEBUG(0,("Error - no srandom function available !\n"));
552 /**************************************************************************
553 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
554 ****************************************************************************/
558 #if defined(SYSCONF_SC_NGROUPS_MAX)
559 int ret = sysconf(_SC_NGROUPS_MAX);
560 return (ret == -1) ? NGROUPS_MAX : ret;
566 /**************************************************************************
567 Wrapper for getgroups. Deals with broken (int) case.
568 ****************************************************************************/
570 int sys_getgroups(int setlen, gid_t *gidset)
572 #if !defined(HAVE_BROKEN_GETGROUPS)
573 return getgroups(setlen, gidset);
581 return getgroups(setlen, &gid);
585 * Broken case. We need to allocate a
586 * GID_T array of size setlen.
595 setlen = groups_max();
597 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
598 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
602 if((ngroups = getgroups(setlen, group_list)) < 0) {
603 int saved_errno = errno;
604 SAFE_FREE(group_list);
609 for(i = 0; i < ngroups; i++)
610 gidset[i] = (gid_t)group_list[i];
612 SAFE_FREE(group_list);
614 #endif /* HAVE_BROKEN_GETGROUPS */
617 #ifdef HAVE_SETGROUPS
619 /**************************************************************************
620 Wrapper for setgroups. Deals with broken (int) case. Automatically used
621 if we have broken getgroups.
622 ****************************************************************************/
624 int sys_setgroups(int setlen, gid_t *gidset)
626 #if !defined(HAVE_BROKEN_GETGROUPS)
627 return setgroups(setlen, gidset);
636 if (setlen < 0 || setlen > groups_max()) {
642 * Broken case. We need to allocate a
643 * GID_T array of size setlen.
646 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
647 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
651 for(i = 0; i < setlen; i++)
652 group_list[i] = (GID_T) gidset[i];
654 if(setgroups(setlen, group_list) != 0) {
655 int saved_errno = errno;
656 SAFE_FREE(group_list);
661 SAFE_FREE(group_list);
663 #endif /* HAVE_BROKEN_GETGROUPS */
666 #endif /* HAVE_SETGROUPS */
668 struct passwd *sys_getpwent(void)
673 void sys_endpwent(void)
678 /**************************************************************************
679 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
680 ****************************************************************************/
682 struct passwd *sys_getpwnam(const char *name)
684 return getpwnam(name);
687 struct passwd *sys_getpwuid(uid_t uid)
689 return getpwuid(uid);
692 struct group *sys_getgrnam(const char *name)
694 return getgrnam(name);
697 struct group *sys_getgrgid(gid_t gid)
699 return getgrgid(gid);
702 #if 0 /* NOT CURRENTLY USED - JRA */
703 /**************************************************************************
704 The following are the UNICODE versions of *all* system interface functions
705 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
706 which currently are left as ascii as they are not used other than in name
708 ****************************************************************************/
710 /**************************************************************************
711 Wide stat. Just narrow and call sys_xxx.
712 ****************************************************************************/
714 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
717 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
720 /**************************************************************************
721 Wide lstat. Just narrow and call sys_xxx.
722 ****************************************************************************/
724 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
727 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
730 /**************************************************************************
731 Wide creat. Just narrow and call sys_xxx.
732 ****************************************************************************/
734 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
737 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
740 /**************************************************************************
741 Wide open. Just narrow and call sys_xxx.
742 ****************************************************************************/
744 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
747 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
750 /**************************************************************************
751 Wide fopen. Just narrow and call sys_xxx.
752 ****************************************************************************/
754 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
757 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
760 /**************************************************************************
761 Wide opendir. Just narrow and call sys_xxx.
762 ****************************************************************************/
764 DIR *wsys_opendir(const smb_ucs2_t *wfname)
767 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
770 /**************************************************************************
771 Wide readdir. Return a structure pointer containing a wide filename.
772 ****************************************************************************/
774 SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
776 static SMB_STRUCT_WDIRENT retval;
777 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
783 * The only POSIX defined member of this struct is d_name.
786 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
791 /**************************************************************************
792 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
793 ****************************************************************************/
795 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
798 char *p = sys_getwd(fname);
803 return unix_to_unicode(s, p, sizeof(wpstring));
806 /**************************************************************************
807 Wide chown. Just narrow and call sys_xxx.
808 ****************************************************************************/
810 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
813 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
816 /**************************************************************************
817 Wide chroot. Just narrow and call sys_xxx.
818 ****************************************************************************/
820 int wsys_chroot(const smb_ucs2_t *wfname)
823 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
826 /**************************************************************************
827 Wide getpwnam. Return a structure pointer containing wide names.
828 ****************************************************************************/
830 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
832 static SMB_STRUCT_WPASSWD retval;
834 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
839 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
840 retval.pw_passwd = pwret->pw_passwd;
841 retval.pw_uid = pwret->pw_uid;
842 retval.pw_gid = pwret->pw_gid;
843 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
844 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
845 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
850 /**************************************************************************
851 Wide getpwuid. Return a structure pointer containing wide names.
852 ****************************************************************************/
854 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
856 static SMB_STRUCT_WPASSWD retval;
857 struct passwd *pwret = sys_getpwuid(uid);
862 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
863 retval.pw_passwd = pwret->pw_passwd;
864 retval.pw_uid = pwret->pw_uid;
865 retval.pw_gid = pwret->pw_gid;
866 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
867 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
868 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
872 #endif /* NOT CURRENTLY USED - JRA */
874 /**************************************************************************
875 Extract a command into an arg list. Uses a static pstring for storage.
876 Caller frees returned arg list (which contains pointers into the static pstring).
877 ****************************************************************************/
879 static char **extract_args(const char *command)
881 static pstring trunc_cmd;
887 pstrcpy(trunc_cmd, command);
889 if(!(ptr = strtok(trunc_cmd, " \t"))) {
898 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
901 if((argl = (char **)malloc((argcl + 1) * sizeof(char *))) == NULL)
905 * Now do the extraction.
908 pstrcpy(trunc_cmd, command);
910 ptr = strtok(trunc_cmd, " \t");
914 while((ptr = strtok(NULL, " \t")) != NULL)
921 /**************************************************************************
922 Wrapper for popen. Safer as it doesn't search a path.
923 Modified from the glibc sources.
924 modified by tridge to return a file descriptor. We must kick our FILE* habit
925 ****************************************************************************/
927 typedef struct _popen_list
931 struct _popen_list *next;
934 static popen_list *popen_chain;
936 int sys_popen(const char *command)
938 int parent_end, child_end;
940 popen_list *entry = NULL;
943 if (pipe(pipe_fds) < 0)
946 parent_end = pipe_fds[0];
947 child_end = pipe_fds[1];
954 if((entry = (popen_list *)malloc(sizeof(popen_list))) == NULL)
960 * Extract the command and args into a NULL terminated array.
963 if(!(argl = extract_args(command)))
966 entry->child_pid = fork();
968 if (entry->child_pid == -1) {
972 if (entry->child_pid == 0) {
978 int child_std_end = STDOUT_FILENO;
982 if (child_end != child_std_end) {
983 dup2 (child_end, child_std_end);
988 * POSIX.2: "popen() shall ensure that any streams from previous
989 * popen() calls that remain open in the parent process are closed
990 * in the new child process."
993 for (p = popen_chain; p; p = p->next)
996 execv(argl[0], argl);
1007 /* Link into popen_chain. */
1008 entry->next = popen_chain;
1009 popen_chain = entry;
1010 entry->fd = parent_end;
1023 /**************************************************************************
1024 Wrapper for pclose. Modified from the glibc sources.
1025 ****************************************************************************/
1027 int sys_pclose(int fd)
1030 popen_list **ptr = &popen_chain;
1031 popen_list *entry = NULL;
1035 /* Unlink from popen_chain. */
1036 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1037 if ((*ptr)->fd == fd) {
1039 *ptr = (*ptr)->next;
1045 if (status < 0 || close(entry->fd) < 0)
1049 * As Samba is catching and eating child process
1050 * exits we don't really care about the child exit
1051 * code, a -1 with errno = ECHILD will do fine for us.
1055 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1056 } while (wait_pid == -1 && errno == EINTR);
1065 /**************************************************************************
1066 Wrappers for dlopen, dlsym, dlclose.
1067 ****************************************************************************/
1069 void *sys_dlopen(const char *name, int flags)
1071 #if defined(HAVE_DLOPEN)
1072 return dlopen(name, flags);
1078 void *sys_dlsym(void *handle, const char *symbol)
1080 #if defined(HAVE_DLSYM)
1081 return dlsym(handle, symbol);
1087 int sys_dlclose (void *handle)
1089 #if defined(HAVE_DLCLOSE)
1090 return dlclose(handle);
1096 const char *sys_dlerror(void)
1098 #if defined(HAVE_DLERROR)
1105 int sys_dup2(int oldfd, int newfd)
1107 #if defined(HAVE_DUP2)
1108 return dup2(oldfd, newfd);