X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fos_priority.c;h=a758f24f1da7678eb006f315a464e24e9458b550;hb=6ede545d597509fefcc3d4fd2ef865bc5f57603f;hp=2a6ea8321005ae00df08b3dd0a5a7a7cd13d79a1;hpb=95f9076a2139f5fb042b944a0658b6cda2fa35db;p=oweals%2Fgnunet.git diff --git a/src/util/os_priority.c b/src/util/os_priority.c index 2a6ea8321..a758f24f1 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c @@ -2,20 +2,18 @@ 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. - - 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. + 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 . */ /** @@ -29,11 +27,11 @@ #include "disk.h" #include -#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" @@ -70,6 +68,11 @@ static struct GNUNET_OS_Process current_process; */ static struct GNUNET_SCHEDULER_Task *pch; +/** + * Handle for the #shutdown_pch() Task. + */ +static struct GNUNET_SCHEDULER_Task *spch; + /** * This handler is called on shutdown to remove the #pch. @@ -80,7 +83,7 @@ static void shutdown_pch (void *cls) { struct GNUNET_DISK_FileHandle *control_pipe = cls; - + GNUNET_SCHEDULER_cancel (pch); pch = NULL; GNUNET_DISK_file_close (control_pipe); @@ -114,6 +117,8 @@ parent_control_handler (void *cls) "Closing control pipe\n"); GNUNET_DISK_file_close (control_pipe); control_pipe = NULL; + GNUNET_SCHEDULER_cancel (spch); + spch = NULL; return; } pipe_fd = getenv (GNUNET_OS_CONTROL_PIPE); @@ -147,6 +152,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... */ @@ -205,8 +211,8 @@ GNUNET_OS_install_parent_control_handler (void *cls) control_pipe, &parent_control_handler, control_pipe); - GNUNET_SCHEDULER_add_shutdown (&shutdown_pch, - control_pipe); + spch = GNUNET_SCHEDULER_add_shutdown (&shutdown_pch, + control_pipe); putenv (GNUNET_OS_CONTROL_PIPE "="); } @@ -1084,7 +1090,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) @@ -1222,7 +1231,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; } @@ -1233,7 +1242,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; } @@ -1250,7 +1259,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; } @@ -1259,7 +1268,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; } @@ -1579,25 +1588,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, @@ -1643,6 +1654,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; @@ -1658,6 +1673,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 (); @@ -1681,6 +1704,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 @@ -1858,7 +1923,7 @@ cmd_read (void *cls) cmd->off -= (end + 1 - cmd->buf); end = memchr (cmd->buf, '\n', cmd->off); } - cmd->rtask + cmd->rtask = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining (cmd->timeout), cmd->r,