src: for every AGPL3.0 file, add SPDX identifier.
[oweals/gnunet.git] / src / util / os_priority.c
index 9b1ec09639639036a1445a4ce5cb541c5c698345..03d4bde9e12956e51079d96ea6f34d3f426e2882 100644 (file)
@@ -2,20 +2,20 @@
      This file is part of GNUnet
      Copyright (C) 2002, 2003, 2004, 2005, 2006, 2011 GNUnet e.V.
 
-     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 3, or (at your
-     option) any later version.
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     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.
+     Affero General Public License for more details.
+    
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-     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., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
+     SPDX-License-Identifier: AGPL3.0-or-later
 */
 
 /**
 #include "disk.h"
 #include <unistr.h>
 
-#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
+#define LOG(kind,...) GNUNET_log_from (kind, "util-os-priority", __VA_ARGS__)
 
-#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
+#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-os-priority", syscall)
 
-#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
+#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-os-priority", syscall, filename)
 
 #define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE"
 
@@ -154,6 +154,7 @@ GNUNET_OS_install_parent_control_handler (void *cls)
   struct GNUNET_DISK_FileHandle *control_pipe;
   uint64_t pipe_fd;
 
+  (void) cls;
   if (NULL != pch)
   {
     /* already done, we've been called twice... */
@@ -1091,7 +1092,10 @@ start_process (int pipe_control,
                                        &lsocks_read, sizeof (HANDLE));
   }
   else
+  {
     lsocks_pipe = NULL;
+    lsocks_write_fd = NULL;
+  }
 
   env_off = 0;
   if (GNUNET_YES == pipe_control)
@@ -1229,7 +1233,7 @@ start_process (int pipe_control,
     if (sizeof (count) != wrote)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 "Failed to write %u count bytes to the child: %u\n",
+                 "Failed to write %u count bytes to the child: %lu\n",
                  sizeof (count), GetLastError ());
       break;
     }
@@ -1240,7 +1244,7 @@ start_process (int pipe_control,
       if (SOCKET_ERROR == WSADuplicateSocketA (lsocks[i], gnunet_proc->pid, &pi))
       {
         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                   "Failed to duplicate an socket[%llu]: %u\n", i,
+                   "Failed to duplicate an socket[%u]: %lu\n", i,
                    GetLastError ());
         break;
       }
@@ -1257,7 +1261,7 @@ start_process (int pipe_control,
       if (sizeof (size) != wrote)
       {
         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                   "Failed to write %u size[%llu] bytes to the child: %u\n",
+                   "Failed to write %u size[%u] bytes to the child: %lu\n",
                    sizeof (size), i, GetLastError ());
         break;
       }
@@ -1266,7 +1270,7 @@ start_process (int pipe_control,
       if (sizeof (pi) != wrote)
       {
         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                   "Failed to write %u socket[%llu] bytes to the child: %u\n",
+                   "Failed to write %u socket[%u] bytes to the child: %lu\n",
                    sizeof (pi), i, GetLastError ());
         break;
       }
@@ -1586,25 +1590,27 @@ GNUNET_OS_start_process_s (int pipe_control,
 
 
 /**
- * Retrieve the status of a process, waiting on him if dead.
+ * Retrieve the status of a process, waiting on it if dead.
  * Nonblocking version.
  *
  * @param proc process ID
  * @param type status type
  * @param code return code/signal number
+ * @param options WNOHANG if non-blocking is desired
  * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
  */
-int
-GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
-                          enum GNUNET_OS_ProcessStatusType *type,
-                          unsigned long *code)
+static int
+process_status (struct GNUNET_OS_Process *proc,
+                enum GNUNET_OS_ProcessStatusType *type,
+                unsigned long *code,
+                int options)
 {
 #ifndef MINGW
   int status;
   int ret;
 
   GNUNET_assert (0 != proc);
-  ret = waitpid (proc->pid, &status, WNOHANG);
+  ret = waitpid (proc->pid, &status, options);
   if (ret < 0)
   {
     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
@@ -1650,6 +1656,10 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
     *code = 0;
   }
 #else
+#ifndef WNOHANG
+#define WNOHANG  42 /* just a flag for W32, purely internal at this point */
+#endif
+
   HANDLE h;
   DWORD c, error_code, ret;
 
@@ -1665,6 +1675,14 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
   if (h == NULL)
     h = GetCurrentProcess ();
 
+  if (WNOHANG != options)
+  {
+    if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE))
+    {
+      SetErrnoFromWinError (GetLastError ());
+      return GNUNET_SYSERR;
+    }
+  }
   SetLastError (0);
   ret = GetExitCodeProcess (h, &c);
   error_code = GetLastError ();
@@ -1688,6 +1706,48 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
 }
 
 
+/**
+ * Retrieve the status of a process, waiting on it if dead.
+ * Nonblocking version.
+ *
+ * @param proc process ID
+ * @param type status type
+ * @param code return code/signal number
+ * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
+                          enum GNUNET_OS_ProcessStatusType *type,
+                          unsigned long *code)
+{
+  return process_status (proc,
+                         type,
+                         code,
+                         WNOHANG);
+}
+
+
+/**
+ * Retrieve the status of a process, waiting on it if dead.
+ * Blocking version.
+ *
+ * @param proc pointer to process structure
+ * @param type status type
+ * @param code return code/signal number
+ * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_OS_process_wait_status (struct GNUNET_OS_Process *proc,
+                               enum GNUNET_OS_ProcessStatusType *type,
+                               unsigned long *code)
+{
+  return process_status (proc,
+                         type,
+                         code,
+                         0);
+}
+
+
 /**
  * Wait for a process to terminate. The return code is discarded.
  * You must not use #GNUNET_OS_process_status() on the same process