-code deduplication in rsa sign/verify code
[oweals/gnunet.git] / src / util / os_priority.c
index 173d8814a7ec3fba5d763dfb1047c0723107e359..20d54341dbea9bfc6d5c4f8681006d1ebf1e381e 100644 (file)
@@ -79,7 +79,8 @@ static struct GNUNET_OS_Process current_process;
 /**
  * Creates a named pipe/FIFO and opens it
  *
- * @param fn pointer to the name of the named pipe or to NULL
+ * @param fn pointer to the name of the named pipe or to NULL,
+ *           possibly updated to the new name (or free'd)
  * @param flags open flags
  * @param perm access permissions
  * @return pipe handle on success, NULL on error
@@ -103,12 +104,12 @@ npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags,
   if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)
     openMode |= FILE_FLAG_FIRST_PIPE_INSTANCE;
 
-  while (h == NULL)
+  while (NULL == h)
   {
     DWORD error_code;
 
     name = NULL;
-    if (*fn != NULL)
+    if (NULL != *fn)
     {
       GNUNET_asprintf (&name, "\\\\.\\pipe\\%.246s", fn);
       LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -134,25 +135,22 @@ npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags,
                            NULL);
     }
     error_code = GetLastError ();
-    if (name)
-      GNUNET_free (name);
+    GNUNET_free_non_null (name);
     /* don't re-set name to NULL yet */
-    if (h == INVALID_HANDLE_VALUE)
+    if (INVALID_HANDLE_VALUE == h)
     {
       SetErrnoFromWinError (error_code);
       LOG (GNUNET_ERROR_TYPE_DEBUG,
            "Pipe creation have failed because of %d, errno is %d\n", error_code,
            errno);
-      if (name == NULL)
+      if (NULL != *fn)
       {
         LOG (GNUNET_ERROR_TYPE_DEBUG,
              "Pipe was to be unique, considering re-creation\n");
         GNUNET_free (*fn);
         *fn = NULL;
-        if (error_code != ERROR_ACCESS_DENIED && error_code != ERROR_PIPE_BUSY)
-        {
-          return NULL;
-        }
+        if ( (ERROR_ACCESS_DENIED != error_code) && (ERROR_PIPE_BUSY != error_code) )        
+          return NULL;        
         LOG (GNUNET_ERROR_TYPE_DEBUG,
              "Pipe name was not unique, trying again\n");
         h = NULL;
@@ -161,11 +159,9 @@ npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags,
         return NULL;
     }
   }
-  errno = 0;
-
-  ret = GNUNET_malloc (sizeof (*ret));
+  ret = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle));
   ret->h = h;
-  ret->type = GNUNET_PIPE;
+  ret->type = GNUNET_DISK_HANLDE_TYPE_PIPE;
   ret->oOverlapRead = GNUNET_malloc (sizeof (OVERLAPPED));
   ret->oOverlapWrite = GNUNET_malloc (sizeof (OVERLAPPED));
   ret->oOverlapRead->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
@@ -198,15 +194,15 @@ npipe_open (const char *fn, enum GNUNET_DISK_OpenFlags flags)
 
   h = CreateFile (fn, openMode, 0, NULL, OPEN_EXISTING,
                   FILE_FLAG_OVERLAPPED | FILE_READ_ATTRIBUTES, NULL);
-  if (h == INVALID_HANDLE_VALUE)
+  if (INVALID_HANDLE_VALUE == h)
   {
     SetErrnoFromWinError (GetLastError ());
     return NULL;
   }
 
-  ret = GNUNET_malloc (sizeof (*ret));
+  ret = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle));
   ret->h = h;
-  ret->type = GNUNET_PIPE;
+  ret->type = GNUNET_DISK_HANLDE_TYPE_PIPE;
   ret->oOverlapRead = GNUNET_malloc (sizeof (OVERLAPPED));
   ret->oOverlapWrite = GNUNET_malloc (sizeof (OVERLAPPED));
   ret->oOverlapRead->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
@@ -374,7 +370,7 @@ GNUNET_OS_install_parent_control_handler (void *cls,
   struct GNUNET_DISK_FileHandle *control_pipe;
 
   env_buf = getenv (GNUNET_OS_CONTROL_PIPE);
-  if ( (env_buf == NULL) || (strlen (env_buf) <= 0) )
+  if ( (NULL == env_buf) || (strlen (env_buf) <= 0) )
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Not installing a handler because $%s is empty\n",
@@ -442,7 +438,7 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
   if (NULL != proc->control_pipe)
   {
     ret = GNUNET_DISK_file_write (proc->control_pipe, &csig, sizeof (csig));
-    if (ret == sizeof (csig))  
+    if (sizeof (csig) == ret)
       return 0;
   }
   /* pipe failed or non-existent, try other methods */
@@ -461,10 +457,31 @@ GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
       if (0 != GetExitCodeProcess (proc->handle, &exitcode))
         must_kill = (exitcode == STILL_ACTIVE) ? GNUNET_YES : GNUNET_NO;
       if (GNUNET_YES == must_kill)
-        if (0 == TerminateProcess (proc->handle, 0))
+        if (0 == SafeTerminateProcess (proc->handle, 0, 0))
         {
-          SetErrnoFromWinError (GetLastError ());
-          return -1;
+          DWORD error_code = GetLastError ();
+          if ((error_code != WAIT_TIMEOUT) && (error_code != ERROR_PROCESS_ABORTED))
+          {
+            LOG ((error_code == ERROR_ACCESS_DENIED) ?
+                GNUNET_ERROR_TYPE_INFO : GNUNET_ERROR_TYPE_WARNING,
+                "SafeTermiateProcess failed with code %lu\n", error_code);
+            /* The problem here is that a process that is already dying
+             * might cause SafeTerminateProcess to fail with
+             * ERROR_ACCESS_DENIED, but the process WILL die eventually.
+             * If we really had a permissions problem, hanging up (which
+             * is what will happen in process_wait() in that case) is
+             * a valid option.
+             */
+            if (ERROR_ACCESS_DENIED == error_code)
+            {
+              errno = 0;
+            }
+            else
+            {
+              SetErrnoFromWinError (error_code);
+              return -1;
+            }
+          }
         }
     }
     return 0;
@@ -564,7 +581,7 @@ GNUNET_OS_set_process_priority (struct GNUNET_OS_Process *proc,
   int rprio;
 
   GNUNET_assert (prio < GNUNET_SCHEDULER_PRIORITY_COUNT);
-  if (prio == GNUNET_SCHEDULER_PRIORITY_KEEP)
+  if (GNUNET_SCHEDULER_PRIORITY_KEEP == prio)
     return GNUNET_OK;
 
   /* convert to MINGW/Unix values */
@@ -676,7 +693,7 @@ CreateCustomEnvTable (char **vars)
   char *val;
 
   win32_env_table = GetEnvironmentStringsA ();
-  if (win32_env_table == NULL)
+  if (NULL == win32_env_table)
     return NULL;
   for (c = 0, var_ptr = vars; *var_ptr; var_ptr += 2, c++) ;
   n_var = c;
@@ -843,7 +860,10 @@ start_process (int pipe_control,
     return NULL; /* not executable */
   if ( (GNUNET_YES == pipe_control) &&
        (GNUNET_OK != npipe_setup (&childpipename)) )
-    return NULL;  
+  {
+    GNUNET_free (childpipename);
+    return NULL;
+  }
   if (NULL != pipe_stdout)
   {
     GNUNET_assert (GNUNET_OK ==
@@ -1050,7 +1070,7 @@ start_process (int pipe_control,
   }
 
   cmdlen = strlen (filename);
-  if (cmdlen < 5 || strcmp (&filename[cmdlen - 4], ".exe") != 0)
+  if ( (cmdlen < 5) || (0 != strcmp (&filename[cmdlen - 4], ".exe")) )
     GNUNET_asprintf (&non_const_filename, "%s.exe", filename);
   else
     GNUNET_asprintf (&non_const_filename, "%s", filename);
@@ -1314,7 +1334,7 @@ start_process (int pipe_control,
   ResumeThread (proc.hThread);
   CloseHandle (proc.hThread);
 
-  if (lsocks == NULL || lsocks[0] == INVALID_SOCKET)
+  if ( (NULL == lsocks) || (INVALID_SOCKET == lsocks[0]) )
     return gnunet_proc;
 
   GNUNET_DISK_pipe_close_end (lsocks_pipe, GNUNET_DISK_PIPE_END_READ);
@@ -1323,16 +1343,20 @@ start_process (int pipe_control,
   fail = 1;
   do
   {
-    int wrote;
-    uint64_t size, count, i;
+    ssize_t wrote;
+    uint64_t size;
+    uint64_t count;
+    unsigned int i;
 
     /* Tell the number of sockets */
     for (count = 0; lsocks && lsocks[count] != INVALID_SOCKET; count++);
 
     wrote = GNUNET_DISK_file_write (lsocks_write_fd, &count, sizeof (count));
-    if (wrote != sizeof (count))
+    if (sizeof (count) != wrote)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to write %u count bytes to the child: %u\n", sizeof (count), GetLastError ());
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
+                 "Failed to write %u count bytes to the child: %u\n",
+                 sizeof (count), GetLastError ());
       break;
     }
     for (i = 0; lsocks && lsocks[i] != INVALID_SOCKET; i++)
@@ -1341,8 +1365,9 @@ start_process (int pipe_control,
       /* Get a socket duplication info */
       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, GetLastError ());
-        LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "CreateProcess");
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
+                   "Failed to duplicate an socket[%llu]: %u\n", i, 
+                   GetLastError ());
         break;
       }
       /* Synchronous I/O is not nice, but we can't schedule this:
@@ -1355,16 +1380,20 @@ start_process (int pipe_control,
        */
       size = sizeof (pi);
       wrote = GNUNET_DISK_file_write (lsocks_write_fd, &size, sizeof (size));
-      if (wrote != sizeof (size))
+      if (sizeof (size) != wrote)
       {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to write %u size[%llu] bytes to the child: %u\n", sizeof (size), i, GetLastError ());
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
+                   "Failed to write %u size[%llu] bytes to the child: %u\n", 
+                   sizeof (size), i, GetLastError ());
         break;
       }
       /* Finally! Send the data */
       wrote = GNUNET_DISK_file_write (lsocks_write_fd, &pi, sizeof (pi));
-      if (wrote != sizeof (pi))
+      if (sizeof (pi) != wrote)
       {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to write %u socket[%llu] bytes to the child: %u\n", sizeof (pi), i, GetLastError ());
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
+                   "Failed to write %u socket[%llu] bytes to the child: %u\n", 
+                   sizeof (pi), i, GetLastError ());
         break;
       }
     }
@@ -1386,7 +1415,7 @@ start_process (int pipe_control,
     /* If we can't pass on the socket(s), the child will block forever,
      * better put it out of its misery.
      */
-    TerminateProcess (gnunet_proc->handle, 0);
+    SafeTerminateProcess (gnunet_proc->handle, 0, 0);
     CloseHandle (gnunet_proc->handle);
     if (NULL != gnunet_proc->control_pipe)
       GNUNET_DISK_file_close (gnunet_proc->control_pipe);
@@ -1474,7 +1503,6 @@ GNUNET_OS_start_process_va (int pipe_control,
 }
 
 
-
 /**
  * Start a process.
  *
@@ -1484,9 +1512,7 @@ GNUNET_OS_start_process_va (int pipe_control,
  * @param pipe_stdout pipe to use to get output from child process (or NULL)
  * @param filename name of the binary
  * @param ... NULL-terminated list of arguments to the process
- *
  * @return pointer to process structure of the new process, NULL on error
- *
  */
 struct GNUNET_OS_Process *
 GNUNET_OS_start_process (int pipe_control,
@@ -1500,7 +1526,7 @@ GNUNET_OS_start_process (int pipe_control,
 
   va_start (ap, filename);
   ret = GNUNET_OS_start_process_va (pipe_control, std_inheritance, pipe_stdin,
-      pipe_stdout, filename, ap);
+                                   pipe_stdout, filename, ap);
   va_end (ap);
   return ret;
 }
@@ -1510,6 +1536,10 @@ GNUNET_OS_start_process (int pipe_control,
  * Start a process.
  *
  * @param pipe_control should a pipe be used to send signals to the child?
+ * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags controlling which
+ *        std handles of the parent are inherited by the child.
+ *        pipe_stdin and pipe_stdout take priority over std_inheritance
+ *        (when they are non-NULL).
  * @param lsocks array of listen sockets to dup systemd-style (or NULL);
  *         must be NULL on platforms where dup is not supported
  * @param filename name of the binary
@@ -1636,13 +1666,13 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
 
 /**
  * Wait for a process
+ *
  * @param proc pointer to process structure
  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
  */
 int
 GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc)
 {
-
 #ifndef MINGW
   pid_t pid = proc->pid;
   pid_t ret;
@@ -1657,7 +1687,6 @@ GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc)
   return GNUNET_OK;
 #else
   HANDLE h;
-  int ret;
 
   h = proc->handle;
   if (NULL == h)
@@ -1666,18 +1695,15 @@ GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc)
          proc->pid, h);
     return GNUNET_SYSERR;
   }
-  if (h == NULL)
+  if (NULL == h)
     h = GetCurrentProcess ();
 
   if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE))
   {
     SetErrnoFromWinError (GetLastError ());
-    ret = GNUNET_SYSERR;
+    return GNUNET_SYSERR;
   }
-  else
-    ret = GNUNET_OK;
-
-  return ret;
+  return GNUNET_OK;
 #endif
 }
 
@@ -1745,8 +1771,7 @@ struct GNUNET_OS_CommandHandle
 void
 GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd)
 {
-
-  if (cmd->proc != NULL)
+  if (NULL != cmd->proc)
   {
     GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != cmd->rtask);
     GNUNET_SCHEDULER_cancel (cmd->rtask);
@@ -1799,7 +1824,7 @@ cmd_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   }
   end = memchr (&cmd->buf[cmd->off], '\n', ret);
   cmd->off += ret;
-  while (end != NULL)
+  while (NULL != end)
   {
     *end = '\0';
     cmd->proc (cmd->proc_cls, cmd->buf);
@@ -1859,6 +1884,4 @@ GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, void *proc_cls,
 }
 
 
-
-
 /* end of os_priority.c */