added qse_get_highest_fd(), qse_close_open_fds_using_proc()
added QSE::AppRoot::daemonize()
This commit is contained in:
parent
4e097466ae
commit
3478885962
56
qse/include/qse/si/AppRoot.hpp
Normal file
56
qse/include/qse/si/AppRoot.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _QSE_SI_APPROOT_H_
|
||||
#define _QSE_SI_APPROOT_H_
|
||||
|
||||
#include <qse/Types.hpp>
|
||||
#include <qse/Uncopyable.hpp>
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
||||
|
||||
class AppRoot: QSE::Uncopyable
|
||||
{
|
||||
public:
|
||||
AppRoot (): _root_only (false) {}
|
||||
virtual ~AppRoot () {}
|
||||
|
||||
int daemonize (bool chdir_to_root = true, int fork_count = 1) QSE_CPP_NOEXCEPT;
|
||||
|
||||
protected:
|
||||
bool _root_only;
|
||||
|
||||
|
||||
void on_signal () QSE_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_END_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
||||
|
||||
#endif
|
@ -19,6 +19,7 @@ pkginclude_HEADERS = \
|
||||
pio.h \
|
||||
rwl.h \
|
||||
sck.h \
|
||||
sinfo.h \
|
||||
sio.h \
|
||||
task.h \
|
||||
thr.h \
|
||||
@ -26,6 +27,7 @@ pkginclude_HEADERS = \
|
||||
|
||||
if ENABLE_CXX
|
||||
pkginclude_HEADERS += \
|
||||
AppRoot.hpp \
|
||||
SocketAddress.hpp \
|
||||
Socket.hpp
|
||||
endif
|
||||
|
@ -88,6 +88,7 @@ POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
@ENABLE_CXX_TRUE@am__append_1 = \
|
||||
@ENABLE_CXX_TRUE@ AppRoot.hpp \
|
||||
@ENABLE_CXX_TRUE@ SocketAddress.hpp \
|
||||
@ENABLE_CXX_TRUE@ Socket.hpp
|
||||
|
||||
@ -130,8 +131,8 @@ am__can_run_installinfo = \
|
||||
esac
|
||||
am__pkginclude_HEADERS_DIST = aio.h aio-pro.h aio-sck.h cnd.h dir.h \
|
||||
fio.h fs.h glob.h intr.h log.h mtx.h mux.h nwad.h nwif.h \
|
||||
nwio.h pio.h rwl.h sck.h sio.h task.h thr.h tio.h \
|
||||
SocketAddress.hpp Socket.hpp
|
||||
nwio.h pio.h rwl.h sck.h sinfo.h sio.h task.h thr.h tio.h \
|
||||
AppRoot.hpp SocketAddress.hpp Socket.hpp
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
@ -366,7 +367,7 @@ top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
pkginclude_HEADERS = aio.h aio-pro.h aio-sck.h cnd.h dir.h fio.h fs.h \
|
||||
glob.h intr.h log.h mtx.h mux.h nwad.h nwif.h nwio.h pio.h \
|
||||
rwl.h sck.h sio.h task.h thr.h tio.h $(am__append_1)
|
||||
rwl.h sck.h sinfo.h sio.h task.h thr.h tio.h $(am__append_1)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
|
49
qse/include/qse/si/sinfo.h
Normal file
49
qse/include/qse/si/sinfo.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _QSE_SI_SINFO_H_
|
||||
#define _QSE_SI_SINFO_H_
|
||||
|
||||
#include <qse/types.h>
|
||||
#include <qse/macros.h>
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
QSE_EXPORT int qse_get_highest_fd (void);
|
||||
|
||||
QSE_EXPORT int qse_close_open_fds_using_proc (
|
||||
int* excepts,
|
||||
qse_size_t count
|
||||
);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -69,6 +69,9 @@
|
||||
#if defined(HAVE_DIRENT_H)
|
||||
# include <dirent.h>
|
||||
#endif
|
||||
#if defined(HAVE_SYS_IOCTL_H)
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(QSE_USE_SYSCALL) && defined(HAVE_SYS_SYSCALL_H)
|
||||
# include <sys/syscall.h>
|
||||
@ -214,6 +217,24 @@
|
||||
# define QSE_GETEGID() getegid()
|
||||
#endif
|
||||
|
||||
#if defined(SYS_getsid) && defined(QSE_USE_SYSCALL)
|
||||
# define QSE_GETSID(pid) syscall(SYS_getsid,pid)
|
||||
#else
|
||||
# define QSE_GETSID(pid) getsid(pid)
|
||||
#endif
|
||||
|
||||
#if defined(SYS_setsid) && defined(QSE_USE_SYSCALL)
|
||||
# define QSE_SETSID() syscall(SYS_setsid)
|
||||
#else
|
||||
# define QSE_SETSID() setsid()
|
||||
#endif
|
||||
|
||||
#if defined(SYS_signal) && defined(QSE_USE_SYSCALL)
|
||||
# define QSE_SIGNAL(signum,handler) syscall(SYS_signal,signum,handler)
|
||||
#else
|
||||
# define QSE_SIGNAL(signum,handler) signal(signum,handler)
|
||||
#endif
|
||||
|
||||
#if defined(SYS_gettimeofday) && defined(QSE_USE_SYSCALL)
|
||||
# define QSE_GETTIMEOFDAY(tv,tz) syscall(SYS_gettimeofday,tv,tz)
|
||||
#else
|
||||
@ -250,6 +271,12 @@
|
||||
# define QSE_SETRLIMIT(res,lim) setrlimit(res,lim)
|
||||
#endif
|
||||
|
||||
#if defined(SYS_ioctl) && defined(QSE_USE_SYSCALL)
|
||||
# define QSE_IOCTL(fd,req,arg) syscall(SYS_ioctl,fd,req,arg)
|
||||
#else
|
||||
# define QSE_IOCTL(fd,req,arg) ioctl(fd,req,arg)
|
||||
#endif
|
||||
|
||||
|
||||
/* ===== FILE SYSTEM CALLS ===== */
|
||||
|
||||
@ -378,6 +405,12 @@
|
||||
# define QSE_RENAME(oldpath,newpath) rename(oldpath,newpath)
|
||||
#endif
|
||||
|
||||
#if defined(SYS_umask) && defined(QSE_USE_SYSCALL)
|
||||
# define QSE_UMASK(mode) syscall(SYS_umask,mode)
|
||||
#else
|
||||
# define QSE_UMASK(mode) umask(mode)
|
||||
#endif
|
||||
|
||||
#if defined(SYS_mkdir) && defined(QSE_USE_SYSCALL)
|
||||
# define QSE_MKDIR(path,mode) syscall(SYS_mkdir,path,mode)
|
||||
#else
|
||||
@ -390,6 +423,12 @@
|
||||
# define QSE_RMDIR(path) rmdir(path)
|
||||
#endif
|
||||
|
||||
#if defined(SYS_chdir) && defined(QSE_USE_SYSCALL)
|
||||
# define QSE_CHDIR(path) syscall(SYS_chdir,path)
|
||||
#else
|
||||
# define QSE_CHDIR(path) chdir(path)
|
||||
#endif
|
||||
|
||||
#if defined(SYS_symlink) && defined(QSE_USE_SYSCALL)
|
||||
# define QSE_SYMLINK(oldpath,newpath) syscall(SYS_symlink,oldpath,newpath)
|
||||
#else
|
||||
|
153
qse/lib/si/AppRoot.cpp
Normal file
153
qse/lib/si/AppRoot.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/si/AppRoot.hpp>
|
||||
#include <qse/si/sinfo.h>
|
||||
#include "../cmn/syscall.h"
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
||||
|
||||
int AppRoot::daemonize (bool chdir_to_root, int fork_count) QSE_CPP_NOEXCEPT
|
||||
{
|
||||
if (this->_root_only && QSE_GETEUID() != 0) return -1;
|
||||
|
||||
if (fork_count >= 1)
|
||||
{
|
||||
if (fork_count >= 2)
|
||||
{
|
||||
struct sigaction sa;
|
||||
int n = QSE_FORK();
|
||||
if (n == -1) return -1;
|
||||
if (n != 0) QSE_EXIT(0);
|
||||
|
||||
QSE_SETSID ();
|
||||
}
|
||||
|
||||
int n = QSE_FORK();
|
||||
if (n == -1)
|
||||
{
|
||||
//throw DaemonError ("can't xp_fork");
|
||||
//if (err_code) *err_code = ERR_FORK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// the parent exits
|
||||
if (n != 0) QSE_EXIT(0); // TODO: should i call exit() in stdlib.h?
|
||||
}
|
||||
|
||||
QSE_UMASK (0);
|
||||
if (chdir_to_root) QSE_CHDIR("/"); // don't care about failure
|
||||
|
||||
if (true)
|
||||
{
|
||||
int keep[] = { 0, 1, 2};
|
||||
|
||||
if (qse_close_open_fds_using_proc (keep, QSE_COUNTOF(keep)) <= -1)
|
||||
{
|
||||
for (int i = qse_get_highest_fd(); i >= 3; i--) QSE_CLOSE (i);
|
||||
}
|
||||
|
||||
int fd = QSE_OPEN ("/dev/null", O_RDWR, 0);
|
||||
if (fd >= 0)
|
||||
{
|
||||
if (fd != 0) QSE_DUP2 (fd, 0);
|
||||
if (fd != 1) QSE_DUP2 (fd, 1);
|
||||
if (fd != 2) QSE_DUP2 (fd, 2);
|
||||
if (fd > 2) QSE_CLOSE (fd);
|
||||
}
|
||||
}
|
||||
|
||||
if (fork_count <= 1)
|
||||
{
|
||||
if (fork_count <= 0)
|
||||
{
|
||||
// detach from the controlling terminal manually
|
||||
// when no fork() is requested though setsid() is supposed to
|
||||
// do this as well.
|
||||
int fd = QSE_OPEN ("/dev/tty", O_RDWR, 0);
|
||||
if (fd >= 0)
|
||||
{
|
||||
QSE_IOCTL(fd, TIOCNOTTY, NULL);
|
||||
QSE_CLOSE (fd);
|
||||
}
|
||||
|
||||
// since no fork() has been executed, the process that has
|
||||
// executed this process will remain as the parent. there
|
||||
// will happen no orphaning of this process and take-over
|
||||
// by init happen
|
||||
}
|
||||
|
||||
QSE_SETSID (); // don't care about failure
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int AppRoot::switchUser () QSE_CPP_NOEXCEPT
|
||||
{
|
||||
struct passwd* pw;
|
||||
|
||||
pw = getpwnam (username);
|
||||
if (!pw)
|
||||
|
||||
|
||||
if (QSE_SETGID(pw->pw_gid) == -1)
|
||||
{
|
||||
}
|
||||
|
||||
QSE_SETEGID(gid);
|
||||
QSE_SETUID(uid);
|
||||
QSE_SETEUID(uid);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void AppRoot::on_signal () QSE_CPP_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
int main ()
|
||||
{
|
||||
AppRoot app;
|
||||
|
||||
app.daemonize();
|
||||
app.switchUser ("nobody", "nobody");
|
||||
app.switchUser (10, 20);
|
||||
app.catchSignal (SIGINT, xxxxx);
|
||||
app.catchSignal (SIGTERM, xxx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_END_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
@ -38,6 +38,7 @@ libqsesi_la_SOURCES = \
|
||||
pio.c \
|
||||
rwl.c \
|
||||
sck.c \
|
||||
sinfo.c \
|
||||
sio.c \
|
||||
task.c \
|
||||
thr.c \
|
||||
@ -51,6 +52,7 @@ libqsesi_la_LIBADD = -lqsecmn $(PTHREAD_LIBS) $(SSL_LIBS)
|
||||
if ENABLE_CXX
|
||||
lib_LTLIBRARIES += libqsesixx.la
|
||||
libqsesixx_la_SOURCES = \
|
||||
AppRoot.cpp \
|
||||
SocketAddress.cpp \
|
||||
Socket.cpp
|
||||
libqsesixx_la_LDFLAGS = -L. -L../cmn -version-info 1:0:0 -no-undefined
|
||||
|
@ -150,8 +150,8 @@ am_libqsesi_la_OBJECTS = libqsesi_la-aio.lo libqsesi_la-aio-pro.lo \
|
||||
libqsesi_la-nwad.lo libqsesi_la-nwad-skad.lo \
|
||||
libqsesi_la-nwif.lo libqsesi_la-nwif-cfg.lo \
|
||||
libqsesi_la-nwio.lo libqsesi_la-pio.lo libqsesi_la-rwl.lo \
|
||||
libqsesi_la-sck.lo libqsesi_la-sio.lo libqsesi_la-task.lo \
|
||||
libqsesi_la-thr.lo libqsesi_la-tio.lo
|
||||
libqsesi_la-sck.lo libqsesi_la-sinfo.lo libqsesi_la-sio.lo \
|
||||
libqsesi_la-task.lo libqsesi_la-thr.lo libqsesi_la-tio.lo
|
||||
libqsesi_la_OBJECTS = $(am_libqsesi_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
@ -161,8 +161,10 @@ libqsesi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libqsesi_la_CFLAGS) \
|
||||
$(CFLAGS) $(libqsesi_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
libqsesixx_la_DEPENDENCIES =
|
||||
am__libqsesixx_la_SOURCES_DIST = SocketAddress.cpp Socket.cpp
|
||||
@ENABLE_CXX_TRUE@am_libqsesixx_la_OBJECTS = SocketAddress.lo Socket.lo
|
||||
am__libqsesixx_la_SOURCES_DIST = AppRoot.cpp SocketAddress.cpp \
|
||||
Socket.cpp
|
||||
@ENABLE_CXX_TRUE@am_libqsesixx_la_OBJECTS = AppRoot.lo \
|
||||
@ENABLE_CXX_TRUE@ SocketAddress.lo Socket.lo
|
||||
libqsesixx_la_OBJECTS = $(am_libqsesixx_la_OBJECTS)
|
||||
libqsesixx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
|
||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
|
||||
@ -471,6 +473,7 @@ libqsesi_la_SOURCES = \
|
||||
pio.c \
|
||||
rwl.c \
|
||||
sck.c \
|
||||
sinfo.c \
|
||||
sio.c \
|
||||
task.c \
|
||||
thr.c \
|
||||
@ -481,6 +484,7 @@ libqsesi_la_CFLAGS = $(PTHREAD_CFLAGS)
|
||||
libqsesi_la_LDFLAGS = -L../cmn -version-info 1:0:0 -no-undefined
|
||||
libqsesi_la_LIBADD = -lqsecmn $(PTHREAD_LIBS) $(SSL_LIBS)
|
||||
@ENABLE_CXX_TRUE@libqsesixx_la_SOURCES = \
|
||||
@ENABLE_CXX_TRUE@ AppRoot.cpp \
|
||||
@ENABLE_CXX_TRUE@ SocketAddress.cpp \
|
||||
@ENABLE_CXX_TRUE@ Socket.cpp
|
||||
|
||||
@ -567,6 +571,7 @@ mostlyclean-compile:
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AppRoot.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Socket.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SocketAddress.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-aio-pro.Plo@am__quote@
|
||||
@ -596,6 +601,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-pio.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-rwl.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-sck.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-sinfo.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-sio.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-task.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libqsesi_la-thr.Plo@am__quote@
|
||||
@ -811,6 +817,13 @@ libqsesi_la-sck.lo: sck.c
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libqsesi_la_CFLAGS) $(CFLAGS) -c -o libqsesi_la-sck.lo `test -f 'sck.c' || echo '$(srcdir)/'`sck.c
|
||||
|
||||
libqsesi_la-sinfo.lo: sinfo.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libqsesi_la_CFLAGS) $(CFLAGS) -MT libqsesi_la-sinfo.lo -MD -MP -MF $(DEPDIR)/libqsesi_la-sinfo.Tpo -c -o libqsesi_la-sinfo.lo `test -f 'sinfo.c' || echo '$(srcdir)/'`sinfo.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libqsesi_la-sinfo.Tpo $(DEPDIR)/libqsesi_la-sinfo.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sinfo.c' object='libqsesi_la-sinfo.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libqsesi_la_CFLAGS) $(CFLAGS) -c -o libqsesi_la-sinfo.lo `test -f 'sinfo.c' || echo '$(srcdir)/'`sinfo.c
|
||||
|
||||
libqsesi_la-sio.lo: sio.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libqsesi_la_CFLAGS) $(CFLAGS) -MT libqsesi_la-sio.lo -MD -MP -MF $(DEPDIR)/libqsesi_la-sio.Tpo -c -o libqsesi_la-sio.lo `test -f 'sio.c' || echo '$(srcdir)/'`sio.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libqsesi_la-sio.Tpo $(DEPDIR)/libqsesi_la-sio.Plo
|
||||
|
154
qse/lib/si/pio.c
154
qse/lib/si/pio.c
@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <qse/si/pio.h>
|
||||
#include <qse/si/sinfo.h>
|
||||
#include <qse/cmn/mbwc.h>
|
||||
#include "../cmn/mem-prv.h"
|
||||
|
||||
@ -374,145 +375,6 @@ static QSE_INLINE int is_fd_valid_and_nocloexec (int fd)
|
||||
return !(flags & FD_CLOEXEC)? 1: 0;
|
||||
}
|
||||
|
||||
static int close_unneeded_fds_using_proc (int* excepts, qse_size_t count)
|
||||
{
|
||||
QSE_DIR* d;
|
||||
|
||||
/* will getting the highest file descriptor be faster than
|
||||
* attempting to close any files descriptors less than the
|
||||
* system limit? */
|
||||
|
||||
d = QSE_OPENDIR (QSE_MT("/proc/self/fd"));
|
||||
if (!d)
|
||||
{
|
||||
qse_mchar_t buf[64];
|
||||
qse_mbsxfmt (buf, QSE_COUNTOF(buf), QSE_MT("/proc/%d/fd"), QSE_GETPID());
|
||||
d = QSE_OPENDIR (buf);
|
||||
#if !defined(_SCO_DS)
|
||||
/* on SCO OpenServer, a range of file descriptors starting from 0 are
|
||||
* listed under /dev/fd regardless of opening state. And some high
|
||||
* numbered descriptors are not listed all. not reliable */
|
||||
|
||||
if (!d) d = QSE_OPENDIR (QSE_MT("/dev/fd")); /* Darwin, FreeBSD */
|
||||
#endif
|
||||
}
|
||||
|
||||
if (d)
|
||||
{
|
||||
qse_dirent_t* de;
|
||||
while ((de = QSE_READDIR (d)))
|
||||
{
|
||||
qse_long_t l;
|
||||
const qse_mchar_t* endptr;
|
||||
|
||||
if (de->d_name[0] == QSE_MT('.')) continue;
|
||||
|
||||
QSE_MBSTONUM (l, de->d_name, &endptr, 10);
|
||||
if (*endptr == QSE_MT('\0'))
|
||||
{
|
||||
int fd = (int)l;
|
||||
if ((qse_long_t)fd == l && fd != QSE_DIRFD(d) && fd > 2)
|
||||
{
|
||||
qse_size_t i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (fd == excepts[i]) goto skip_close;
|
||||
}
|
||||
|
||||
QSE_CLOSE (fd);
|
||||
|
||||
skip_close:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSE_CLOSEDIR (d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int get_highest_fd (void)
|
||||
{
|
||||
#if defined(HAVE_GETRLIMIT)
|
||||
struct rlimit rlim;
|
||||
#endif
|
||||
int fd = -1;
|
||||
QSE_DIR* d;
|
||||
|
||||
#if defined(F_MAXFD)
|
||||
fd = QSE_FCNTL (0, F_MAXFD, 0);
|
||||
if (fd >= 0) return fd;
|
||||
#endif
|
||||
|
||||
/* will getting the highest file descriptor be faster than
|
||||
* attempting to close any files descriptors less than the
|
||||
* system limit? */
|
||||
|
||||
d = QSE_OPENDIR (QSE_MT("/proc/self/fd"));
|
||||
if (!d)
|
||||
{
|
||||
qse_mchar_t buf[64];
|
||||
qse_mbsxfmt (buf, QSE_COUNTOF(buf), QSE_MT("/proc/%d/fd"), QSE_GETPID());
|
||||
d = QSE_OPENDIR (buf);
|
||||
if (!d) d = QSE_OPENDIR (QSE_MT("/dev/fd")); /* Darwin, FreeBSD */
|
||||
}
|
||||
|
||||
if (d)
|
||||
{
|
||||
int maxfd = -1;
|
||||
qse_dirent_t* de;
|
||||
while ((de = QSE_READDIR (d)))
|
||||
{
|
||||
qse_long_t l;
|
||||
const qse_mchar_t* endptr;
|
||||
|
||||
if (de->d_name[0] == QSE_MT('.')) continue;
|
||||
|
||||
QSE_MBSTONUM (l, de->d_name, &endptr, 10);
|
||||
if (*endptr == QSE_MT('\0'))
|
||||
{
|
||||
fd = (int)l;
|
||||
if ((qse_long_t)fd == l && fd != QSE_DIRFD(d))
|
||||
{
|
||||
if (fd > maxfd) maxfd = fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSE_CLOSEDIR (d);
|
||||
return maxfd;
|
||||
}
|
||||
|
||||
/* TODO: should i also use getdtablesize() if available? */
|
||||
|
||||
#if defined(HAVE_GETRLIMIT)
|
||||
if (QSE_GETRLIMIT (RLIMIT_NOFILE, &rlim) <= -1 ||
|
||||
rlim.rlim_max == RLIM_INFINITY)
|
||||
{
|
||||
#if defined(HAVE_SYSCONF)
|
||||
fd = sysconf (_SC_OPEN_MAX);
|
||||
#endif
|
||||
}
|
||||
else fd = rlim.rlim_max;
|
||||
#elif defined(HAVE_SYSCONF)
|
||||
fd = sysconf (_SC_OPEN_MAX);
|
||||
#endif
|
||||
if (fd <= -1) fd = 1024; /* fallback */
|
||||
|
||||
/* F_MAXFD is the highest fd. but RLIMIT_NOFILE and
|
||||
* _SC_OPEN_MAX returnes the maximum number of file
|
||||
* descriptors. make adjustment */
|
||||
if (fd > 0) fd--;
|
||||
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
static qse_pio_pid_t standard_fork_and_exec (qse_pio_t* pio, int pipes[], param_t* param, qse_env_t* env)
|
||||
{
|
||||
qse_pio_pid_t pid;
|
||||
@ -537,17 +399,17 @@ static qse_pio_pid_t standard_fork_and_exec (qse_pio_t* pio, int pipes[], param_
|
||||
|
||||
if (!(pio->flags & QSE_PIO_NOCLOEXEC))
|
||||
{
|
||||
if (close_unneeded_fds_using_proc (pipes, 6) <= -1)
|
||||
if (qse_close_open_fds_using_proc (pipes, 6) <= -1)
|
||||
{
|
||||
int fd = get_highest_fd ();
|
||||
int fd = qse_get_highest_fd ();
|
||||
|
||||
/* close all other unknown open handles except
|
||||
* stdin/out/err and the pipes. */
|
||||
while (fd > 2)
|
||||
{
|
||||
if (fd != pipes[0] && fd != pipes[1] &&
|
||||
fd != pipes[2] && fd != pipes[3] &&
|
||||
fd != pipes[4] && fd != pipes[5])
|
||||
fd != pipes[2] && fd != pipes[3] &&
|
||||
fd != pipes[4] && fd != pipes[5])
|
||||
{
|
||||
QSE_CLOSE (fd);
|
||||
}
|
||||
@ -1571,7 +1433,7 @@ create_process:
|
||||
|
||||
if (!(flags & QSE_PIO_NOCLOEXEC))
|
||||
{
|
||||
int fd = get_highest_fd ();
|
||||
int fd = qse_get_highest_fd ();
|
||||
while (fd > 2)
|
||||
{
|
||||
if (fd != handle[0] && fd != handle[1] &&
|
||||
@ -1651,7 +1513,7 @@ create_process:
|
||||
/* prepare some data before vforking for vfork limitation.
|
||||
* the child in vfork should not make function calls or
|
||||
* change data shared with the parent. */
|
||||
if (!(flags & QSE_PIO_NOCLOEXEC)) highest_fd = get_highest_fd ();
|
||||
if (!(flags & QSE_PIO_NOCLOEXEC)) highest_fd = qse_get_highest_fd ();
|
||||
envarr = env? qse_env_getarr(env): environ;
|
||||
|
||||
QSE_SYSCALL0 (pid, SYS_vfork);
|
||||
@ -1673,7 +1535,7 @@ create_process:
|
||||
|
||||
if (!(flags & QSE_PIO_NOCLOEXEC))
|
||||
{
|
||||
/* cannot call close_unneeded_fds_using_proc() in the vfork() context */
|
||||
/* cannot call qse_close_open_fds_using_proc() in the vfork() context */
|
||||
|
||||
int fd = highest_fd;
|
||||
|
||||
|
166
qse/lib/si/sinfo.c
Normal file
166
qse/lib/si/sinfo.c
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/si/sinfo.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include "../cmn/syscall.h"
|
||||
|
||||
int qse_get_highest_fd (void)
|
||||
{
|
||||
#if defined(HAVE_GETRLIMIT)
|
||||
struct rlimit rlim;
|
||||
#endif
|
||||
int fd = -1;
|
||||
QSE_DIR* d;
|
||||
|
||||
#if defined(F_MAXFD)
|
||||
fd = QSE_FCNTL (0, F_MAXFD, 0);
|
||||
if (fd >= 0) return fd;
|
||||
#endif
|
||||
|
||||
/* will getting the highest file descriptor be faster than
|
||||
* attempting to close any files descriptors less than the
|
||||
* system limit? */
|
||||
|
||||
d = QSE_OPENDIR (QSE_MT("/proc/self/fd"));
|
||||
if (!d)
|
||||
{
|
||||
qse_mchar_t buf[64];
|
||||
qse_mbsxfmt (buf, QSE_COUNTOF(buf), QSE_MT("/proc/%d/fd"), QSE_GETPID());
|
||||
d = QSE_OPENDIR (buf);
|
||||
if (!d) d = QSE_OPENDIR (QSE_MT("/dev/fd")); /* Darwin, FreeBSD */
|
||||
}
|
||||
|
||||
if (d)
|
||||
{
|
||||
int maxfd = -1;
|
||||
qse_dirent_t* de;
|
||||
while ((de = QSE_READDIR (d)))
|
||||
{
|
||||
qse_long_t l;
|
||||
const qse_mchar_t* endptr;
|
||||
|
||||
if (de->d_name[0] == QSE_MT('.')) continue;
|
||||
|
||||
QSE_MBSTONUM (l, de->d_name, &endptr, 10);
|
||||
if (*endptr == QSE_MT('\0'))
|
||||
{
|
||||
fd = (int)l;
|
||||
if ((qse_long_t)fd == l && fd != QSE_DIRFD(d))
|
||||
{
|
||||
if (fd > maxfd) maxfd = fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSE_CLOSEDIR (d);
|
||||
return maxfd;
|
||||
}
|
||||
|
||||
/* TODO: should i also use getdtablesize() if available? */
|
||||
|
||||
#if defined(HAVE_GETRLIMIT)
|
||||
if (QSE_GETRLIMIT (RLIMIT_NOFILE, &rlim) <= -1 ||
|
||||
rlim.rlim_max == RLIM_INFINITY)
|
||||
{
|
||||
#if defined(HAVE_SYSCONF)
|
||||
fd = sysconf (_SC_OPEN_MAX);
|
||||
#endif
|
||||
}
|
||||
else fd = rlim.rlim_max;
|
||||
#elif defined(HAVE_SYSCONF)
|
||||
fd = sysconf (_SC_OPEN_MAX);
|
||||
#endif
|
||||
if (fd <= -1) fd = 1024; /* fallback */
|
||||
|
||||
/* F_MAXFD is the highest fd. but RLIMIT_NOFILE and
|
||||
* _SC_OPEN_MAX returnes the maximum number of file
|
||||
* descriptors. make adjustment */
|
||||
if (fd > 0) fd--;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int qse_close_open_fds_using_proc (int* excepts, qse_size_t count)
|
||||
{
|
||||
QSE_DIR* d;
|
||||
|
||||
/* will getting the highest file descriptor be faster than
|
||||
* attempting to close any files descriptors less than the
|
||||
* system limit? */
|
||||
|
||||
d = QSE_OPENDIR (QSE_MT("/proc/self/fd"));
|
||||
if (!d)
|
||||
{
|
||||
qse_mchar_t buf[64];
|
||||
qse_mbsxfmt (buf, QSE_COUNTOF(buf), QSE_MT("/proc/%d/fd"), QSE_GETPID());
|
||||
d = QSE_OPENDIR (buf);
|
||||
#if !defined(_SCO_DS)
|
||||
/* on SCO OpenServer, a range of file descriptors starting from 0 are
|
||||
* listed under /dev/fd regardless of opening state. And some high
|
||||
* numbered descriptors are not listed. not reliable */
|
||||
|
||||
if (!d) d = QSE_OPENDIR (QSE_MT("/dev/fd")); /* Darwin, FreeBSD */
|
||||
#endif
|
||||
}
|
||||
|
||||
if (d)
|
||||
{
|
||||
qse_dirent_t* de;
|
||||
while ((de = QSE_READDIR (d)))
|
||||
{
|
||||
qse_long_t l;
|
||||
const qse_mchar_t* endptr;
|
||||
|
||||
if (de->d_name[0] == QSE_MT('.')) continue;
|
||||
|
||||
QSE_MBSTONUM (l, de->d_name, &endptr, 10);
|
||||
if (*endptr == QSE_MT('\0'))
|
||||
{
|
||||
int fd = (int)l;
|
||||
if ((qse_long_t)fd == l && fd != QSE_DIRFD(d) && fd > 2)
|
||||
{
|
||||
qse_size_t i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (fd == excepts[i]) goto skip_close;
|
||||
}
|
||||
|
||||
QSE_CLOSE (fd);
|
||||
|
||||
skip_close:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSE_CLOSEDIR (d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user