diff --git a/ChangeLog b/ChangeLog index a857249f..39603706 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2009-09-19 Tatsuhiro Tsujikawa + + Added our own daemon() function for systems which desn't have + daemon(3). + * configure.ac + * src/Makefile.am + * src/daemon.cc + * src/daemon.h + * src/option_processing.cc + 2009-09-19 Tatsuhiro Tsujikawa Simplified File::getCurrentDir() diff --git a/configure b/configure index 03653176..201b3f39 100755 --- a/configure +++ b/configure @@ -641,6 +641,8 @@ gt_needs= ac_header_list= ac_func_list= ac_subst_vars='LTLIBOBJS +HAVE_DAEMON_FALSE +HAVE_DAEMON_TRUE HAVE_TIMEGM_FALSE HAVE_TIMEGM_TRUE HAVE_STRPTIME_FALSE @@ -21591,14 +21593,12 @@ done - for ac_func in __argz_count \ __argz_next \ __argz_stringify \ atexit \ - daemon \ ftruncate \ getcwd \ gethostbyaddr \ @@ -23016,6 +23016,115 @@ fi done +for ac_func in daemon +do +as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 +$as_echo_n "checking for $ac_func... " >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + eval "$as_ac_var=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + have_daemon=yes +fi +done + + if test "x$have_daemon" = "xyes"; then + HAVE_DAEMON_TRUE= + HAVE_DAEMON_FALSE='#' +else + HAVE_DAEMON_TRUE='#' + HAVE_DAEMON_FALSE= +fi + + case "$target" in *mingw*) if true; then @@ -23601,6 +23710,13 @@ $as_echo "$as_me: error: conditional \"HAVE_TIMEGM\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${HAVE_DAEMON_TRUE}" && test -z "${HAVE_DAEMON_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"HAVE_DAEMON\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"HAVE_DAEMON\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi if test -z "${HAVE_GETADDRINFO_TRUE}" && test -z "${HAVE_GETADDRINFO_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"HAVE_GETADDRINFO\" was never defined. Usually this means the macro was only invoked conditionally." >&5 diff --git a/configure.ac b/configure.ac index f6e3345f..86a06763 100644 --- a/configure.ac +++ b/configure.ac @@ -259,7 +259,6 @@ AC_CHECK_FUNCS([__argz_count \ __argz_next \ __argz_stringify \ atexit \ - daemon \ ftruncate \ getcwd \ gethostbyaddr \ @@ -333,6 +332,8 @@ AC_CHECK_FUNCS([strptime], AC_CHECK_FUNCS([timegm], [AM_CONDITIONAL([HAVE_TIMEGM], true)], [AM_CONDITIONAL([HAVE_TIMEGM], false)]) +AC_CHECK_FUNCS([daemon], [have_daemon=yes]) +AM_CONDITIONAL([HAVE_DAEMON], [test "x$have_daemon" = "xyes"]) case "$target" in *mingw*) diff --git a/src/Makefile.am b/src/Makefile.am index b84623ac..52317171 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -511,6 +511,10 @@ if !HAVE_TIMEGM SRCS += timegm.c timegm.h endif # !HAVE_TIMEGM +if !HAVE_DAEMON +SRCS += daemon.cc daemon.h +endif # !HAVE_DAEMON + noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ diff --git a/src/Makefile.in b/src/Makefile.in index af944299..5890c150 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -272,6 +272,7 @@ bin_PROGRAMS = aria2c$(EXEEXT) @HAVE_LOCALTIME_R_FALSE@am__append_23 = localtime_r.c localtime_r.h @HAVE_STRPTIME_FALSE@am__append_24 = strptime.c strptime.h @HAVE_TIMEGM_FALSE@am__append_25 = timegm.c timegm.h +@HAVE_DAEMON_FALSE@am__append_26 = daemon.cc daemon.h subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in alloca.c ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -594,7 +595,7 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ libgen.h getaddrinfo.c getaddrinfo.h gai_strerror.c \ gai_strerror.h gettimeofday.c gettimeofday.h inet_aton.c \ inet_aton.h localtime_r.c localtime_r.h strptime.c strptime.h \ - timegm.c timegm.h + timegm.c timegm.h daemon.cc daemon.h @ENABLE_XML_RPC_TRUE@am__objects_1 = \ @ENABLE_XML_RPC_TRUE@ XmlRpcRequestParserController.$(OBJEXT) \ @ENABLE_XML_RPC_TRUE@ XmlRpcRequestParserStateMachine.$(OBJEXT) \ @@ -771,7 +772,8 @@ am__objects_6 = @HAVE_LOCALTIME_R_FALSE@am__objects_23 = localtime_r.$(OBJEXT) @HAVE_STRPTIME_FALSE@am__objects_24 = strptime.$(OBJEXT) @HAVE_TIMEGM_FALSE@am__objects_25 = timegm.$(OBJEXT) -am__objects_26 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \ +@HAVE_DAEMON_FALSE@am__objects_26 = daemon.$(OBJEXT) +am__objects_27 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \ AbstractCommand.$(OBJEXT) \ InitiateConnectionCommandFactory.$(OBJEXT) \ DownloadCommand.$(OBJEXT) \ @@ -854,8 +856,9 @@ am__objects_26 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \ $(am__objects_14) $(am__objects_15) $(am__objects_16) \ $(am__objects_17) $(am__objects_18) $(am__objects_19) \ $(am__objects_20) $(am__objects_21) $(am__objects_22) \ - $(am__objects_23) $(am__objects_24) $(am__objects_25) -am_libaria2c_a_OBJECTS = $(am__objects_26) + $(am__objects_23) $(am__objects_24) $(am__objects_25) \ + $(am__objects_26) +am_libaria2c_a_OBJECTS = $(am__objects_27) libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS) am__installdirs = "$(DESTDIR)$(bindir)" binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) @@ -1188,7 +1191,8 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \ $(am__append_14) $(am__append_15) $(am__append_16) \ $(am__append_17) $(am__append_18) $(am__append_19) \ $(am__append_20) $(am__append_21) $(am__append_22) \ - $(am__append_23) $(am__append_24) $(am__append_25) + $(am__append_23) $(am__append_24) $(am__append_25) \ + $(am__append_26) noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ @@ -1575,6 +1579,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asctime_r.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bencode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bittorrent_helper.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/daemon.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/download_helper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gai_strerror.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getaddrinfo.Po@am__quote@ diff --git a/src/daemon.cc b/src/daemon.cc new file mode 100644 index 00000000..04b37e00 --- /dev/null +++ b/src/daemon.cc @@ -0,0 +1,80 @@ +/* */ +#include "daemon.h" + +#include +#include +#include + +namespace aria2 { + +int daemon(int nochdir, int noclose) +{ + pid_t pid; + pid = fork(); + if(pid == -1) { + return -1; + } else if(pid > 0) { + exit(EXIT_SUCCESS); + } + if(setsid() == -1) { + return -1; + } + pid = fork(); + if(pid == -1) { + return -1; + } else if(pid > 0) { + exit(EXIT_SUCCESS); + } + if(nochdir == 0) { + if(chdir("/") == -1) { + return -1; + } + } + if(noclose == 0) { + if(freopen("/dev/null", "r", stdin) == 0) { + return -1; + } + if(freopen("/dev/null", "w", stdout) == 0) { + return -1; + } + if(freopen("/dev/null", "w", stderr) == 0) { + return -1; + } + } + return 0; +} + +} // namespace aria2 diff --git a/src/daemon.h b/src/daemon.h new file mode 100644 index 00000000..d3be03aa --- /dev/null +++ b/src/daemon.h @@ -0,0 +1,50 @@ +/* */ +#ifndef _D_DAEMON_H_ +#define _D_DAEMON_H_ + +#include "common.h" + +namespace aria2 { + +// Detach the current process from terminal session and run in the +// background. This function acts like daemon(3) standard function. +// On success, this function returns 0. If an error occurs, it returns +// -1. +int daemon(int nochdir, int noclose); + +} // namespace aria2 + +#endif // _D_DAEMON_H_ diff --git a/src/option_processing.cc b/src/option_processing.cc index 965a55a8..3f37ad53 100644 --- a/src/option_processing.cc +++ b/src/option_processing.cc @@ -56,6 +56,9 @@ #include "DownloadResultCode.h" #include "SimpleRandomizer.h" #include "bittorrent_helper.h" +#ifndef HAVE_DAEMON +#include "daemon.h" +#endif // !HAVE_DAEMON namespace aria2 { @@ -191,19 +194,12 @@ void option_processing(Option& op, std::deque& uris, exit(downloadresultcode::UNKNOWN_ERROR); } } -#ifdef HAVE_DAEMON if(op.getAsBool(PREF_DAEMON)) { - if(File::getCurrentDir() == ".") { - std::cerr << "Failed to get the current working directory." - << " With -D option engaged," - << " the default value of --dir option is /." << std::endl; - } if(daemon(0, 0) < 0) { perror(MSG_DAEMON_FAILED); exit(downloadresultcode::UNKNOWN_ERROR); } } -#endif // HAVE_DAEMON } } // namespace aria2