aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_os_lib.h25
-rw-r--r--src/include/gnunet_testbed_service.h1
-rw-r--r--src/util/os_priority.c66
-rw-r--r--src/util/service_new.c68
4 files changed, 132 insertions, 28 deletions
diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h
index 39c70c8bd..ce3e05f13 100644
--- a/src/include/gnunet_os_lib.h
+++ b/src/include/gnunet_os_lib.h
@@ -524,7 +524,8 @@ struct GNUNET_OS_CommandHandle;
524 * @param cls closure 524 * @param cls closure
525 * @param line line of output from a command, NULL for the end 525 * @param line line of output from a command, NULL for the end
526 */ 526 */
527typedef void (*GNUNET_OS_LineProcessor) (void *cls, const char *line); 527typedef void
528(*GNUNET_OS_LineProcessor) (void *cls, const char *line);
528 529
529 530
530/** 531/**
@@ -548,8 +549,10 @@ GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd);
548 * @return NULL on error 549 * @return NULL on error
549 */ 550 */
550struct GNUNET_OS_CommandHandle * 551struct GNUNET_OS_CommandHandle *
551GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, void *proc_cls, 552GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc,
552 struct GNUNET_TIME_Relative timeout, const char *binary, 553 void *proc_cls,
554 struct GNUNET_TIME_Relative timeout,
555 const char *binary,
553 ...); 556 ...);
554 557
555 558
@@ -582,6 +585,22 @@ int
582GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc); 585GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc);
583 586
584 587
588
589/**
590 * Retrieve the status of a process, waiting on him if dead.
591 * Blocking version.
592 *
593 * @param proc pointer to process structure
594 * @param type status type
595 * @param code return code/signal number
596 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
597 */
598int
599GNUNET_OS_process_wait_status (struct GNUNET_OS_Process *proc,
600 enum GNUNET_OS_ProcessStatusType *type,
601 unsigned long *code);
602
603
585/** 604/**
586 * Connects this process to its parent via pipe; 605 * Connects this process to its parent via pipe;
587 * essentially, the parent control handler will read signal numbers 606 * essentially, the parent control handler will read signal numbers
diff --git a/src/include/gnunet_testbed_service.h b/src/include/gnunet_testbed_service.h
index 7d9abbe49..f8a8ef38d 100644
--- a/src/include/gnunet_testbed_service.h
+++ b/src/include/gnunet_testbed_service.h
@@ -1493,6 +1493,7 @@ GNUNET_TESTBED_test_run (const char *testname,
1493struct GNUNET_TESTBED_Controller * 1493struct GNUNET_TESTBED_Controller *
1494GNUNET_TESTBED_run_get_controller_handle (struct GNUNET_TESTBED_RunHandle *h); 1494GNUNET_TESTBED_run_get_controller_handle (struct GNUNET_TESTBED_RunHandle *h);
1495 1495
1496
1496/** 1497/**
1497 * Opaque handle for barrier 1498 * Opaque handle for barrier
1498 */ 1499 */
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}