gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r1046 - in GNUnet: contrib src/include src/util


From: grothoff
Subject: [GNUnet-SVN] r1046 - in GNUnet: contrib src/include src/util
Date: Sun, 26 Jun 2005 03:34:34 -0700 (PDT)

Author: grothoff
Date: 2005-06-26 03:34:27 -0700 (Sun, 26 Jun 2005)
New Revision: 1046

Added:
   GNUnet/src/util/daemon.c
Modified:
   GNUnet/contrib/gnunet.user
   GNUnet/src/include/gnunet_util.h
   GNUnet/src/util/Makefile.am
Log:
daemon

Modified: GNUnet/contrib/gnunet.user
===================================================================
--- GNUnet/contrib/gnunet.user  2005-06-26 09:59:28 UTC (rev 1045)
+++ GNUnet/contrib/gnunet.user  2005-06-26 10:34:27 UTC (rev 1046)
@@ -25,6 +25,11 @@
 # is any problems.
 LOGLEVEL        = WARNING
 
+# For clients that want to fork a gnunetd process, which config
+# file should be used? (option -c will not be used if this option
+# is not set, this is the default).
+# EXAMPLE: GNUNETD-CONFIG = "~/.gnunet/gnunetd.conf"
+
 # Where to write the messages? Leave the entry unspecified (as
 # default) to make the clients print their messages to stderr.
 # Default is unspecified (stderr).

Modified: GNUnet/src/include/gnunet_util.h
===================================================================
--- GNUnet/src/include/gnunet_util.h    2005-06-26 09:59:28 UTC (rev 1045)
+++ GNUnet/src/include/gnunet_util.h    2005-06-26 10:34:27 UTC (rev 1046)
@@ -2335,6 +2335,73 @@
 int CreateServiceAccount(char *pszName, char *pszDesc);
 #endif
 
+
+
+/** 
+ * Checks if gnunetd is running
+ * 
+ * Uses CS_PROTO_CLIENT_COUNT query to determine if gnunetd is
+ * running.
+ *
+ * @return OK if gnunetd is running, SYSERR if not
+ */
+int checkGNUnetDaemonRunning(void);
+
+/**
+ * Start gnunetd process
+ * 
+ * @param daemonize YES if gnunetd should be daemonized
+ * @return pid_t of gnunetd if NOT daemonized, 0 if
+ *  daemonized sucessfully, -1 on error
+ */
+int startGNUnetDaemon(int daemonize);
+
+
+/** 
+ * Stop gnunetd
+ *
+ * Note that returning an error does NOT mean that
+ * gnunetd will continue to run (it may have been
+ * shutdown by something else in the meantime or
+ * crashed).  Call checkDaemonRunning() frequently
+ * to check the status of gnunetd.
+ *
+ * Furthermore, note that this WILL potentially kill
+ * gnunetd processes on remote machines that cannot
+ * be restarted with startGNUnetDaemon!
+ *
+ * This function does NOT need the PID and will also
+ * kill daemonized gnunetd's.
+ *
+ * @return OK successfully stopped, SYSERR: error
+ */
+int stopGNUnetDaemon(void);
+
+
+/**
+ * Wait until the gnunet daemon is
+ * running.
+ * 
+ * @param timeout how long to wait at most
+ * @return OK if gnunetd is now running
+ */
+int waitForGNUnetDaemonRunning(cron_t timeout);
+
+
+/**
+ * Wait until the gnunet daemon (or any other CHILD process for that
+ * matter) with the given PID has terminated.  Assumes that
+ * the daemon was started with startGNUnetDaemon in no-daemonize mode.
+ * On arbitrary PIDs, this function may fail unexpectedly.
+ * 
+ * @return YES if gnunetd shutdown with
+ *  return value 0, SYSERR if waitpid
+ *  failed, NO if gnunetd shutdown with
+ *  some error 
+ */
+int waitForGNUnetDaemonTermination(int pid);
+
+
 /* ifndef GNUNET_UTIL_H */
 #endif
 /* end of gnunet_util.h */

Modified: GNUnet/src/util/Makefile.am
===================================================================
--- GNUnet/src/util/Makefile.am 2005-06-26 09:59:28 UTC (rev 1045)
+++ GNUnet/src/util/Makefile.am 2005-06-26 10:34:27 UTC (rev 1046)
@@ -56,6 +56,7 @@
  checksum.c \
  configuration.c \
  cron.c \
+ daemon.c \
  dso.c \
  getopt.c \
  generate_gnunetd_conf.c \

Added: GNUnet/src/util/daemon.c
===================================================================
--- GNUnet/src/util/daemon.c    2005-06-26 09:59:28 UTC (rev 1045)
+++ GNUnet/src/util/daemon.c    2005-06-26 10:34:27 UTC (rev 1046)
@@ -0,0 +1,296 @@
+/*
+     This file is part of GNUnet.
+     (C) 2005 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file src/util/daemon.c
+ * @brief code for client-gnunetd interaction (start, stop, waitpid, check 
running)
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_util.h"
+#include "gnunet_protocols.h"
+#ifndef MINGW
+ #include <sys/wait.h>
+#endif
+
+
+/** 
+ * Checks if gnunetd is running
+ * 
+ * Uses CS_PROTO_CLIENT_COUNT query to determine if gnunetd is
+ * running.
+ *
+ * @return OK if gnunetd is running, SYSERR if not
+ */
+int checkGNUnetDaemonRunning() {
+  GNUNET_TCP_SOCKET * sock;
+  CS_HEADER csHdr;
+  int ret;
+
+  sock = getClientSocket();
+  if(sock == NULL) {
+    BREAK();
+    return SYSERR;  
+  }    
+
+  csHdr.size
+    = htons(sizeof(CS_HEADER));
+  csHdr.type
+    = htons(CS_PROTO_CLIENT_COUNT);
+  if (SYSERR == writeToSocket(sock,
+                              &csHdr)) {
+    releaseClientSocket(sock);
+    return SYSERR;
+  } 
+  if (SYSERR == readTCPResult(sock, 
+                             &ret)) {
+    releaseClientSocket(sock);
+    return SYSERR;
+  }
+  releaseClientSocket(sock);
+  
+  return OK;
+}
+
+
+#if LINUX || OSX || SOLARIS || SOMEBSD
+/**
+ * Fork a gnunetd process
+ * 
+ * @param daemonize YES if gnunetd should be daemonized
+ * @return pid_t of gnunetd if NOT daemonized, 0 if
+ *  daemonized sucessfully, -1 on error
+ */
+static pid_t launchWithExec(int daemonize) {
+  pid_t pid;
+
+  pid = fork();
+  if (pid == 0) {
+    char * args[5];
+    char * path;
+    char * cp;
+
+    path = NULL;
+    cp = getConfigurationString("MAIN", 
+                               "ARGV[0]");
+    if (cp != NULL) {
+      int i = strlen(cp);
+      while ( (i >= 0) && 
+             (cp[i] != DIR_SEPARATOR) )
+       i--;
+      if ( i != -1 ) {
+       cp[i+1] = '\0';
+       path = MALLOC(i+1+strlen("gnunetd"));
+       strcpy(path, cp);
+       strcat(path, "gnunetd");      
+       args[0] = path;
+       FREE(cp);
+      } else {
+       args[0] = "gnunetd";
+      }
+    }
+    cp = getConfigurationString("GNUNET",
+                               "GNUNETD-CONFIG");
+    if (cp != NULL) {
+      args[1] = "-c";
+      args[2] = cp;
+      if (NO == daemonize) {
+       args[3] = "-d";
+       args[4] = NULL;
+      } else
+       args[3] = NULL;
+    } else {
+      if (NO == daemonize) {
+       args[1] = "-d";
+       args[2] = NULL;
+      } else
+       args[1] = NULL;
+    }
+    errno = 0;
+    nice(10); /* return value is not well-defined */
+    if (errno != 0) 
+      LOG_STRERROR(LOG_WARNING, "nice");    
+    if (path != NULL)
+      execv(path,
+           args);
+    else
+      execvp("gnunetd",
+            args);
+    LOG_STRERROR(LOG_FAILURE, "exec");
+    LOG(LOG_FAILURE,
+       _("Attempted path to '%s' was '%s'.\n"),
+       "gnunetd",
+       (path == NULL) ? "gnunetd" : path);
+    FREENONNULL(path); /* yeah, right, like we're likely to get
+                         here... */
+    FREENONNULL(args[1]);
+    _exit(-1);
+  } else if (daemonize) {
+    pid_t ret;
+    int status;
+
+    ret = waitpid(pid, &status, 0);
+    if (ret == -1) {
+      LOG_STRERROR(LOG_ERROR, "waitpid");
+      return SYSERR;
+    }
+    if ( (WIFEXITED(status) &&
+         (0 != WEXITSTATUS(status)) ) ) {
+      return SYSERR;
+    }
+#ifdef WCOREDUMP
+    if (WCOREDUMP(status)) {
+      return SYSERR;
+    }
+#endif
+    if (WIFSIGNALED(status) ||
+       WTERMSIG(status) ) {
+      return SYSERR;
+    }
+    return 0;
+  }
+  return pid;
+}
+#endif
+
+/**
+ * Start gnunetd process
+ * 
+ * @param daemonize YES if gnunetd should be daemonized
+ * @return pid_t of gnunetd if NOT daemonized, 0 if
+ *  daemonized sucessfully, -1 on error
+ */
+int startGNUnetDaemon(int daemonize) {
+#if LINUX || OSX || SOLARIS || SOMEBSD
+  return launchWithExec(daemonize);
+#elif MINGW
+  char szCall[_MAX_PATH + 1], szWd[_MAX_PATH + 1], szCWd[_MAX_PATH + 1];
+  char *args[1];
+
+  plibc_conv_to_win_path("/bin/gnunetd.exe", szCall);
+  plibc_conv_to_win_path("/bin", szWd);
+  _getcwd(szCWd, _MAX_PATH);
+
+  chdir(szWd);
+  args[0] = NULL;
+  spawnvp(_P_NOWAIT, szCall, (const char *const *) args);
+  chdir(szCWd);
+  
+  return 0; /* FIXME NILS: return PID if NO == daemonize, also
+              pass option -d in that case.  And what about
+              -c CONFIG? */
+#else
+  /* any system out there that does not support THIS!? */
+  system("gnunetd"); /* we may not have nice,
+                       so let's be minimalistic here. */
+  return 0;
+#endif  
+}
+
+
+/** 
+ * Stop gnunetd
+ *
+ * Note that returning an error does NOT mean that
+ * gnunetd will continue to run (it may have been
+ * shutdown by something else in the meantime or
+ * crashed).  Call checkDaemonRunning() frequently
+ * to check the status of gnunetd.
+ *
+ * Furthermore, note that this WILL potentially kill
+ * gnunetd processes on remote machines that cannot
+ * be restarted with startGNUnetDaemon!
+ *
+ * This function does NOT need the PID and will also
+ * kill daemonized gnunetd's.
+ *
+ * @return OK successfully stopped, SYSERR: error
+ */
+int stopGNUnetDaemon() {
+  GNUNET_TCP_SOCKET * sock;
+  CS_HEADER csHdr;
+  int ret;
+  
+  sock = getClientSocket();
+  if (sock == NULL) 
+    return SYSERR;  
+  csHdr.size 
+    = htons(sizeof(CS_HEADER));
+  csHdr.type
+    = htons(CS_PROTO_SHUTDOWN_REQUEST);
+  if (SYSERR == writeToSocket(sock,
+                             &csHdr)) {
+    releaseClientSocket(sock);
+    return SYSERR;
+  }
+  if (SYSERR == readTCPResult(sock,
+                             &ret)) {
+    releaseClientSocket(sock);
+    return SYSERR;
+  }
+  releaseClientSocket(sock);
+  return ret;
+}
+
+/**
+ * Wait until the gnunet daemon is
+ * running.
+ * 
+ * @param timeout how long to wait at most
+ * @return OK if gnunetd is now running
+ */
+int waitForGNUnetDaemonRunning(cron_t timeout) {
+  timeout += cronTime(NULL);
+  while (OK != checkGNUnetDaemonRunning()) {
+    gnunet_util_sleep(50 * cronMILLIS);
+    if (timeout < cronTime(NULL))
+      return checkGNUnetDaemonRunning();
+  }
+  return OK;
+}
+
+/**
+ * Wait until the gnunet daemon (or any other CHILD process for that
+ * matter) with the given PID has terminated.  Assumes that
+ * the daemon was started with startGNUnetDaemon in no-daemonize mode.
+ * On arbitrary PIDs, this function may fail unexpectedly.
+ * 
+ * @return YES if gnunetd shutdown with
+ *  return value 0, SYSERR if waitpid
+ *  failed, NO if gnunetd shutdown with
+ *  some error 
+ */
+int waitForGNUnetDaemonTermination(int pid) {
+  pid_t p;
+  int status;
+
+  p = pid;
+  if (p != waitpid(p, &status, 0)) {
+    LOG_STRERROR(LOG_ERROR, "waitpid");
+    return SYSERR;
+  }
+  if (WEXITSTATUS(status) == 0)
+    return YES;
+  else
+    return NO;
+}
+
+/* end of daemon.c */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]