aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-10-10 14:52:47 +0000
committerChristian Grothoff <christian@grothoff.org>2016-10-10 14:52:47 +0000
commit2378353eab064ed06166e025a1df9d4a23efe6c4 (patch)
treef2418dbd6d50c4fe93da623e8b572fd725058450 /src/util
parent474111bf7923be9458ee84c6dcc577261aa65fea (diff)
downloadgnunet-2378353eab064ed06166e025a1df9d4a23efe6c4.tar.gz
gnunet-2378353eab064ed06166e025a1df9d4a23efe6c4.zip
extending process API to allow obtaining status code in blocking fashion
Diffstat (limited to 'src/util')
-rw-r--r--src/util/os_priority.c66
-rw-r--r--src/util/service_new.c68
2 files changed, 109 insertions, 25 deletions
diff --git a/src/util/os_priority.c b/src/util/os_priority.c
index 9b1ec0963..4b1dbd491 100644
--- a/src/util/os_priority.c
+++ b/src/util/os_priority.c
@@ -1592,19 +1592,21 @@ GNUNET_OS_start_process_s (int pipe_control,
1592 * @param proc process ID 1592 * @param proc process ID
1593 * @param type status type 1593 * @param type status type
1594 * @param code return code/signal number 1594 * @param code return code/signal number
1595 * @param options WNOHANG if non-blocking is desired
1595 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise 1596 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
1596 */ 1597 */
1597int 1598static int
1598GNUNET_OS_process_status (struct GNUNET_OS_Process *proc, 1599process_status (struct GNUNET_OS_Process *proc,
1599 enum GNUNET_OS_ProcessStatusType *type, 1600 enum GNUNET_OS_ProcessStatusType *type,
1600 unsigned long *code) 1601 unsigned long *code,
1602 int options)
1601{ 1603{
1602#ifndef MINGW 1604#ifndef MINGW
1603 int status; 1605 int status;
1604 int ret; 1606 int ret;
1605 1607
1606 GNUNET_assert (0 != proc); 1608 GNUNET_assert (0 != proc);
1607 ret = waitpid (proc->pid, &status, WNOHANG); 1609 ret = waitpid (proc->pid, &status, options);
1608 if (ret < 0) 1610 if (ret < 0)
1609 { 1611 {
1610 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, 1612 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
@@ -1650,6 +1652,10 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1650 *code = 0; 1652 *code = 0;
1651 } 1653 }
1652#else 1654#else
1655#ifndef WNOHANG
1656#define WNOHANG 42 /* just a flag for W32, purely internal at this point */
1657#endif
1658
1653 HANDLE h; 1659 HANDLE h;
1654 DWORD c, error_code, ret; 1660 DWORD c, error_code, ret;
1655 1661
@@ -1665,6 +1671,14 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1665 if (h == NULL) 1671 if (h == NULL)
1666 h = GetCurrentProcess (); 1672 h = GetCurrentProcess ();
1667 1673
1674 if (WNOHANG != options)
1675 {
1676 if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE))
1677 {
1678 SetErrnoFromWinError (GetLastError ());
1679 return GNUNET_SYSERR;
1680 }
1681 }
1668 SetLastError (0); 1682 SetLastError (0);
1669 ret = GetExitCodeProcess (h, &c); 1683 ret = GetExitCodeProcess (h, &c);
1670 error_code = GetLastError (); 1684 error_code = GetLastError ();
@@ -1689,6 +1703,48 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1689 1703
1690 1704
1691/** 1705/**
1706 * Retrieve the status of a process, waiting on him if dead.
1707 * Nonblocking version.
1708 *
1709 * @param proc process ID
1710 * @param type status type
1711 * @param code return code/signal number
1712 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
1713 */
1714int
1715GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
1716 enum GNUNET_OS_ProcessStatusType *type,
1717 unsigned long *code)
1718{
1719 return process_status (proc,
1720 type,
1721 code,
1722 WNOHANG);
1723}
1724
1725
1726/**
1727 * Retrieve the status of a process, waiting on him if dead.
1728 * Blocking version.
1729 *
1730 * @param proc pointer to process structure
1731 * @param type status type
1732 * @param code return code/signal number
1733 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
1734 */
1735int
1736GNUNET_OS_process_wait_status (struct GNUNET_OS_Process *proc,
1737 enum GNUNET_OS_ProcessStatusType *type,
1738 unsigned long *code)
1739{
1740 return process_status (proc,
1741 type,
1742 code,
1743 0);
1744}
1745
1746
1747/**
1692 * Wait for a process to terminate. The return code is discarded. 1748 * Wait for a process to terminate. The return code is discarded.
1693 * You must not use #GNUNET_OS_process_status() on the same process 1749 * You must not use #GNUNET_OS_process_status() on the same process
1694 * after calling this function! This function is blocking and should 1750 * after calling this function! This function is blocking and should
diff --git a/src/util/service_new.c b/src/util/service_new.c
index cf871eb89..9929341f4 100644
--- a/src/util/service_new.c
+++ b/src/util/service_new.c
@@ -1536,6 +1536,35 @@ detach_terminal (struct GNUNET_SERVICE_Handle *sh)
1536 1536
1537 1537
1538/** 1538/**
1539 * Tear down the service, closing the listen sockets and
1540 * freeing the ACLs.
1541 *
1542 * @param sh handle to the service to tear down.
1543 */
1544static void
1545teardown_service (struct GNUNET_SERVICE_Handle *sh)
1546{
1547 struct ServiceListenContext *slc;
1548
1549 GNUNET_free_non_null (sh->v4_denied);
1550 GNUNET_free_non_null (sh->v6_denied);
1551 GNUNET_free_non_null (sh->v4_allowed);
1552 GNUNET_free_non_null (sh->v6_allowed);
1553 while (NULL != (slc = sh->slc_head))
1554 {
1555 GNUNET_CONTAINER_DLL_remove (sh->slc_head,
1556 sh->slc_tail,
1557 slc);
1558 if (NULL != slc->listen_task)
1559 GNUNET_SCHEDULER_cancel (slc->listen_task);
1560 GNUNET_break (GNUNET_OK ==
1561 GNUNET_NETWORK_socket_close (slc->listen_socket));
1562 GNUNET_free (slc);
1563 }
1564}
1565
1566
1567/**
1539 * Low-level function to start a service if the scheduler 1568 * Low-level function to start a service if the scheduler
1540 * is already running. Should only be used directly in 1569 * is already running. Should only be used directly in
1541 * special cases. 1570 * special cases.
@@ -1579,8 +1608,21 @@ GNUNET_SERVICE_starT (const char *service_name,
1579 void *cls, 1608 void *cls,
1580 const struct GNUNET_MQ_MessageHandler *handlers) 1609 const struct GNUNET_MQ_MessageHandler *handlers)
1581{ 1610{
1582 GNUNET_break (0); // FIXME: not implemented 1611 struct GNUNET_SERVICE_Handle *sh;
1583 return NULL; 1612
1613 sh = GNUNET_new (struct GNUNET_SERVICE_Handle);
1614 sh->service_name = service_name;
1615 sh->cfg = cfg;
1616 sh->connect_cb = connect_cb;
1617 sh->disconnect_cb = disconnect_cb;
1618 sh->cb_cls = cls;
1619 sh->handlers = handlers;
1620 if (GNUNET_OK != setup_service (sh))
1621 {
1622 GNUNET_free (sh);
1623 return NULL;
1624 }
1625 return sh;
1584} 1626}
1585 1627
1586 1628
@@ -1592,7 +1634,8 @@ GNUNET_SERVICE_starT (const char *service_name,
1592void 1634void
1593GNUNET_SERVICE_stoP (struct GNUNET_SERVICE_Handle *srv) 1635GNUNET_SERVICE_stoP (struct GNUNET_SERVICE_Handle *srv)
1594{ 1636{
1595 GNUNET_assert (0); // FIXME: not implemented 1637 teardown_service (srv);
1638 GNUNET_free (srv);
1596} 1639}
1597 1640
1598 1641
@@ -1823,29 +1866,14 @@ shutdown:
1823 } 1866 }
1824 } 1867 }
1825#endif 1868#endif
1869 teardown_service (&sh);
1870
1826 GNUNET_SPEEDUP_stop_ (); 1871 GNUNET_SPEEDUP_stop_ ();
1827 GNUNET_CONFIGURATION_destroy (cfg); 1872 GNUNET_CONFIGURATION_destroy (cfg);
1828
1829 while (NULL != sh.slc_head)
1830 {
1831 struct ServiceListenContext *slc = sh.slc_head;
1832
1833 sh.slc_head = slc->next;
1834 if (NULL != slc->listen_task)
1835 GNUNET_SCHEDULER_cancel (slc->listen_task);
1836 GNUNET_break (GNUNET_OK ==
1837 GNUNET_NETWORK_socket_close (slc->listen_socket));
1838 GNUNET_free (slc);
1839 }
1840
1841 GNUNET_free_non_null (logfile); 1873 GNUNET_free_non_null (logfile);
1842 GNUNET_free_non_null (loglev); 1874 GNUNET_free_non_null (loglev);
1843 GNUNET_free (cfg_filename); 1875 GNUNET_free (cfg_filename);
1844 GNUNET_free_non_null (opt_cfg_filename); 1876 GNUNET_free_non_null (opt_cfg_filename);
1845 GNUNET_free_non_null (sh.v4_denied);
1846 GNUNET_free_non_null (sh.v6_denied);
1847 GNUNET_free_non_null (sh.v4_allowed);
1848 GNUNET_free_non_null (sh.v6_allowed);
1849 1877
1850 return err ? GNUNET_SYSERR : sh.ret; 1878 return err ? GNUNET_SYSERR : sh.ret;
1851} 1879}