cli/polkit: merge branch 'th/polkit-cleanup'

https://github.com/NetworkManager/NetworkManager/pull/90
This commit is contained in:
Thomas Haller 2018-04-16 16:35:20 +02:00
commit 41e0ca6824
9 changed files with 293 additions and 291 deletions

View file

@ -21,15 +21,9 @@
#define NMC_NMCLI_H
#include "nm-secret-agent-old.h"
#include "nm-meta-setting-desc.h"
#if WITH_POLKIT_AGENT
#include "nm-polkit-listener.h"
#else
/* polkit agent is not available; define fake NMPolkitListener */
typedef gpointer NMPolkitListener;
#endif
struct _NMPolkitListener;
typedef char *(*NmcCompEntryFunc) (const char *, int);
@ -135,7 +129,7 @@ typedef struct _NmCli {
NMSecretAgentOld *secret_agent; /* Secret agent */
GHashTable *pwds_hash; /* Hash table with passwords in passwd-file */
NMPolkitListener *pk_listener ; /* polkit agent listener */
struct _NMPolkitListener *pk_listener; /* polkit agent listener */
int should_wait; /* Semaphore indicating whether nmcli should not end or not yet */
gboolean nowait_flag; /* '--nowait' option; used for passing to callbacks */

View file

@ -19,8 +19,6 @@
#include "nm-default.h"
#if WITH_POLKIT_AGENT
#include "polkit-agent.h"
#include <stdio.h>
@ -29,17 +27,18 @@
#include <unistd.h>
#include "nm-polkit-listener.h"
#include "common.h"
#if WITH_POLKIT_AGENT
static char *
polkit_request (const char *request,
polkit_request (NMPolkitListener *listener,
const char *request,
const char *action_id,
const char *message,
const char *icon_name,
const char *user,
gboolean echo_on,
gpointer user_data)
gpointer user_data)
{
char *response, *tmp, *p;
@ -62,28 +61,42 @@ polkit_request (const char *request,
}
static void
polkit_show_info (const char *text)
polkit_show_info (NMPolkitListener *listener,
const char *text,
gpointer user_data)
{
g_print (_("Authentication message: %s\n"), text);
}
static void
polkit_show_error (const char *text)
polkit_show_error (NMPolkitListener *listener,
const char *text,
gpointer user_data)
{
g_print (_("Authentication error: %s\n"), text);
}
static void
polkit_completed (gboolean gained_authorization)
polkit_completed (NMPolkitListener *listener,
gboolean gained_authorization,
gpointer user_data)
{
/* We don't print anything here. The outcome will be evident from
* the operation result anyway. */
}
#endif
gboolean
nmc_polkit_agent_init (NmCli* nmc, gboolean for_session, GError **error)
{
PolkitAgentListener *listener;
#if WITH_POLKIT_AGENT
static const NMPolkitListenVtable vtable = {
.on_request = polkit_request,
.on_show_info = polkit_show_info,
.on_show_error = polkit_show_error,
.on_completed = polkit_completed,
};
NMPolkitListener *listener;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@ -91,24 +104,28 @@ nmc_polkit_agent_init (NmCli* nmc, gboolean for_session, GError **error)
if (!listener)
return FALSE;
nm_polkit_listener_set_request_callback (NM_POLKIT_LISTENER (listener), polkit_request, nmc);
nm_polkit_listener_set_show_info_callback (NM_POLKIT_LISTENER (listener), polkit_show_info);
nm_polkit_listener_set_show_error_callback (NM_POLKIT_LISTENER (listener), polkit_show_error);
nm_polkit_listener_set_completed_callback (NM_POLKIT_LISTENER (listener), polkit_completed);
nm_polkit_listener_set_vtable (listener, &vtable, nmc);
nmc->pk_listener = NM_POLKIT_LISTENER (listener);
nmc->pk_listener = listener;
#endif
return TRUE;
}
void
nmc_polkit_agent_fini (NmCli* nmc)
{
g_clear_object (&nmc->pk_listener);
#if WITH_POLKIT_AGENT
if (nmc->pk_listener) {
nm_polkit_listener_set_vtable (nmc->pk_listener, NULL, NULL);
g_clear_object (&nmc->pk_listener);
}
#endif
}
gboolean
nmc_start_polkit_agent_start_try (NmCli *nmc)
{
#if WITH_POLKIT_AGENT
GError *error = NULL;
/* We don't register polkit agent at all when running non-interactively */
@ -121,30 +138,6 @@ nmc_start_polkit_agent_start_try (NmCli *nmc)
g_error_free (error);
return FALSE;
}
#endif
return TRUE;
}
#else
/* polkit agent is not avalable; implement stub functions. */
#include "nmcli.h"
#include "polkit-agent.h"
gboolean
nmc_polkit_agent_init (NmCli* nmc, gboolean for_session, GError **error)
{
return TRUE;
}
void
nmc_polkit_agent_fini (NmCli* nmc)
{
}
gboolean
nmc_start_polkit_agent_start_try (NmCli *nmc)
{
return TRUE;
}
#endif /* #if WITH_POLKIT_AGENT */

View file

@ -33,15 +33,15 @@
#include "nm-default.h"
#include "nm-polkit-listener.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "nm-polkit-listener.h"
#if WITH_POLKIT_AGENT
G_DEFINE_TYPE (NMPolkitListener, nm_polkit_listener, POLKIT_AGENT_TYPE_LISTENER)
#define NM_POLKIT_LISTENER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_POLKIT_LISTENER, NMPolkitListenerPrivate))
/*****************************************************************************/
typedef struct {
gpointer reg_handle; /* handle of polkit agent registration */
@ -56,14 +56,28 @@ typedef struct {
char *icon_name;
char *identity;
/* callbacks */
NMPolkitListenerOnRequestFunc on_request_callback;
NMPolkitListenerOnShowInfoFunc on_show_info_callback;
NMPolkitListenerOnShowErrorFunc on_show_error_callback;
NMPolkitListenerOnCompletedFunc on_completed_callback;
gpointer request_callback_data;
const NMPolkitListenVtable *vtable;
gpointer vtable_user_data;
} NMPolkitListenerPrivate;
G_DEFINE_TYPE (NMPolkitListener, nm_polkit_listener, POLKIT_AGENT_TYPE_LISTENER)
#define NM_POLKIT_LISTENER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_POLKIT_LISTENER, NMPolkitListenerPrivate))
/*****************************************************************************/
void
nm_polkit_listener_set_vtable (NMPolkitListener *self,
const NMPolkitListenVtable *vtable,
gpointer user_data)
{
NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self);
priv->vtable = vtable;
priv->vtable_user_data = user_data;
}
/*****************************************************************************/
static void
on_request (PolkitAgentSession *session,
@ -71,20 +85,21 @@ on_request (PolkitAgentSession *session,
gboolean echo_on,
gpointer user_data)
{
NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (user_data);
char *response = NULL;
NMPolkitListener *self = NM_POLKIT_LISTENER (user_data);
NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self);
gs_free char *response = NULL;
if (priv->on_request_callback) {
response = priv->on_request_callback (request, priv->action_id,
priv->message, priv->icon_name,
priv->identity, echo_on,
priv->request_callback_data);
if (priv->vtable && priv->vtable->on_request) {
response = priv->vtable->on_request (self,
request, priv->action_id,
priv->message, priv->icon_name,
priv->identity, echo_on,
priv->vtable_user_data);
}
if (response) {
if (response)
polkit_agent_session_response (session, response);
g_free (response);
} else {
else {
//FIXME: polkit_agent_session_cancel() should emit "completed", but it doesn't work for me ???
//polkit_agent_session_cancel (session);
polkit_agent_session_response (session, "");
@ -96,10 +111,13 @@ on_show_info (PolkitAgentSession *session,
const char *text,
gpointer user_data)
{
NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (user_data);
NMPolkitListener *self = NM_POLKIT_LISTENER (user_data);
NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self);
if (priv->on_show_info_callback)
priv->on_show_info_callback (text);
if (priv->vtable && priv->vtable->on_show_info) {
priv->vtable->on_show_info (self, text,
priv->vtable_user_data);
}
}
static void
@ -107,10 +125,13 @@ on_show_error (PolkitAgentSession *session,
const char *text,
gpointer user_data)
{
NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (user_data);
NMPolkitListener *self = NM_POLKIT_LISTENER (user_data);
NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self);
if (priv->on_show_error_callback)
priv->on_show_error_callback (text);
if (priv->vtable && priv->vtable->on_show_error) {
priv->vtable->on_show_error (self, text,
priv->vtable_user_data);
}
}
static void
@ -118,10 +139,13 @@ on_completed (PolkitAgentSession *session,
gboolean gained_authorization,
gpointer user_data)
{
NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (user_data);
NMPolkitListener *self = NM_POLKIT_LISTENER (user_data);
NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self);
if (priv->on_completed_callback)
priv->on_completed_callback (gained_authorization);
if (priv->vtable->on_completed) {
priv->vtable->on_completed (self, gained_authorization,
priv->vtable_user_data);
}
g_simple_async_result_complete_in_idle (priv->simple);
@ -145,7 +169,8 @@ on_completed (PolkitAgentSession *session,
static void
on_cancelled (GCancellable *cancellable, gpointer user_data)
{
NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (user_data);
NMPolkitListener *self = NM_POLKIT_LISTENER (user_data);
NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self);
polkit_agent_session_cancel (priv->active_session);
}
@ -264,12 +289,58 @@ initiate_authentication_finish (PolkitAgentListener *listener,
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
}
/*****************************************************************************/
static void
nm_polkit_listener_init (NMPolkitListener *agent)
{
}
/**
* nm_polkit_listener_new:
* @for_session: %TRUE for registering the polkit agent for the user session,
* %FALSE for registering it for the running process
* @vtable: mandatory callbacks
* @user_data: user-data pointer for callbacks
* @error: location to store error, or %NULL
*
* Creates a new #NMPolkitListener and registers it as a polkit agent.
*
* Returns: a new #NMPolkitListener
*/
NMPolkitListener *
nm_polkit_listener_new (gboolean for_session,
GError **error)
{
NMPolkitListener *listener;
PolkitSubject* session;
NMPolkitListenerPrivate *priv;
g_return_val_if_fail (!error || !*error, NULL);
listener = g_object_new (NM_TYPE_POLKIT_LISTENER, NULL);
priv = NM_POLKIT_LISTENER_GET_PRIVATE (listener);
if (for_session) {
session = polkit_unix_session_new_for_process_sync (getpid (), NULL, error);
if (!session)
return NULL;
} else
session = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
priv->reg_handle = polkit_agent_listener_register (POLKIT_AGENT_LISTENER (listener),
POLKIT_AGENT_REGISTER_FLAGS_NONE,
session, NULL, NULL, error);
if (!priv->reg_handle) {
g_object_unref (listener);
g_object_unref (session);
return NULL;
}
return listener;
}
static void
nm_polkit_listener_finalize (GObject *object)
{
@ -300,117 +371,4 @@ nm_polkit_listener_class_init (NMPolkitListenerClass *klass)
pkal_class->initiate_authentication_finish = initiate_authentication_finish;
}
/**
* nm_polkit_listener_new:
* @for_session: %TRUE for registering the polkit agent for the user session,
* %FALSE for registering it for the running process
* @error: location to store error, or %NULL
*
* Creates a new #NMPolkitListener and registers it as a polkit agent.
*
* Returns: a new #NMPolkitListener
*/
PolkitAgentListener *
nm_polkit_listener_new (gboolean for_session, GError **error)
{
PolkitAgentListener *listener;
PolkitSubject* session;
NMPolkitListenerPrivate *priv;
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
listener = g_object_new (NM_TYPE_POLKIT_LISTENER, NULL);
priv = NM_POLKIT_LISTENER_GET_PRIVATE (listener);
if (for_session) {
session = polkit_unix_session_new_for_process_sync (getpid (), NULL, error);
if (!session)
return NULL;
} else
session = polkit_unix_process_new_for_owner (getpid (), 0, getuid ());
priv->reg_handle = polkit_agent_listener_register (listener, POLKIT_AGENT_REGISTER_FLAGS_NONE,
session, NULL, NULL, error);
if (!priv->reg_handle) {
g_object_unref (listener);
g_object_unref (session);
return NULL;
}
return listener;
}
/**
* nm_polkit_listener_set_request_callback:
* @self: a #NMPolkitListener object
* @request_callback: callback to install for polkit requests
* @request_callback_data: usaer data passed to request_callback when it is called
*
* Set a callback for "request" signal. The callback will be invoked when polkit
* requests an authorization.
*/
void
nm_polkit_listener_set_request_callback (NMPolkitListener *self,
NMPolkitListenerOnRequestFunc request_callback,
gpointer request_callback_data)
{
NMPolkitListenerPrivate *priv;
g_return_if_fail (NM_IS_POLKIT_LISTENER (self));
priv = NM_POLKIT_LISTENER_GET_PRIVATE (self);
priv->on_request_callback = request_callback;
priv->request_callback_data = request_callback_data;
}
/**
* nm_polkit_listener_set_show_info_callback:
* @self: a #NMPolkitListener object
* @show_info_callback: callback to install for polkit show info trigger
*
* Set a callback for "show-info" signal. The callback will be invoked when polkit
* has an info text to display.
*/
void
nm_polkit_listener_set_show_info_callback (NMPolkitListener *self,
NMPolkitListenerOnShowInfoFunc show_info_callback)
{
g_return_if_fail (NM_IS_POLKIT_LISTENER (self));
NM_POLKIT_LISTENER_GET_PRIVATE (self)->on_show_info_callback = show_info_callback;
}
/**
* nm_polkit_listener_set_show_error_callback:
* @self: a #NMPolkitListener object
* @show_error_callback: callback to install for polkit show error trigger
*
* Set a callback for "show-error" signal. The callback will be invoked when polkit
* has an error text to display.
*/
void
nm_polkit_listener_set_show_error_callback (NMPolkitListener *self,
NMPolkitListenerOnShowErrorFunc show_error_callback)
{
g_return_if_fail (NM_IS_POLKIT_LISTENER (self));
NM_POLKIT_LISTENER_GET_PRIVATE (self)->on_show_error_callback = show_error_callback;
}
/**
* nm_polkit_listener_set_completed_callback:
* @self: a #NMPolkitListener object
* @completed_callback: callback to install for polkit completing authorization
*
* Set a callback for "completed" signal. The callback will be invoked when polkit
* completed the request.
*/
void
nm_polkit_listener_set_completed_callback (NMPolkitListener *self,
NMPolkitListenerOnCompletedFunc completed_callback)
{
g_return_if_fail (NM_IS_POLKIT_LISTENER (self));
NM_POLKIT_LISTENER_GET_PRIVATE (self)->on_completed_callback = completed_callback;
}
#endif /* WITH_POLKIT_AGENT */

View file

@ -19,6 +19,64 @@
#ifndef __NM_POLKIT_LISTENER_H__
#define __NM_POLKIT_LISTENER_H__
#if WITH_POLKIT_AGENT
typedef struct _NMPolkitListener NMPolkitListener;
typedef struct _NMPolkitListenerClass NMPolkitListenerClass;
typedef struct {
/*
* @request: the request asked by polkit agent
* @action_id: the action_id of the polkit request
* @message: the message of the polkit request
* @icon_name: the icon name of the polkit request
* @user: user name
* @echo_on: whether the response to the request should be echoed to the screen
* @user_data: user data for the callback
*
* Called as a result of a request by polkit. The function should obtain response
* to the request from user, i.e. get the password required.
*/
char *(*on_request) (NMPolkitListener *self,
const char *request,
const char *action_id,
const char *message,
const char *icon_name,
const char *user,
gboolean echo_on,
gpointer user_data);
/*
* @text: the info text from polkit
*
* Called as a result of show-info signal by polkit.
*/
void (*on_show_info) (NMPolkitListener *self,
const char *text,
gpointer user_data);
/*
* @text: the error text from polkit
*
* Called as a result of show-error signal by polkit.
*/
void (*on_show_error) (NMPolkitListener *self,
const char *text,
gpointer user_data);
/*
* @gained_authorization: whether the autorization was successful
*
* Called as a result of completed signal by polkit.
*/
void (*on_completed) (NMPolkitListener *self,
gboolean gained_authorization,
gpointer user_data);
} NMPolkitListenVtable;
/*****************************************************************************/
#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE
#include <polkitagent/polkitagent.h>
@ -72,27 +130,23 @@ typedef void (*NMPolkitListenerOnShowErrorFunc) (const char *text);
typedef void (*NMPolkitListenerOnCompletedFunc) (gboolean gained_authorization);
typedef struct {
struct _NMPolkitListener {
PolkitAgentListener parent;
};
} NMPolkitListener;
typedef struct {
struct _NMPolkitListenerClass {
PolkitAgentListenerClass parent;
} NMPolkitListenerClass;
};
GType nm_polkit_listener_get_type (void);
PolkitAgentListener* nm_polkit_listener_new (gboolean for_session, GError **error);
void nm_polkit_listener_set_request_callback (NMPolkitListener *self,
NMPolkitListenerOnRequestFunc request_callback,
gpointer request_callback_data);
void nm_polkit_listener_set_show_info_callback (NMPolkitListener *self,
NMPolkitListenerOnShowInfoFunc show_info_callback);
void nm_polkit_listener_set_show_error_callback (NMPolkitListener *self,
NMPolkitListenerOnShowErrorFunc show_error_callback);
void nm_polkit_listener_set_completed_callback (NMPolkitListener *self,
NMPolkitListenerOnCompletedFunc completed_callback);
NMPolkitListener *nm_polkit_listener_new (gboolean for_session,
GError **error);
void nm_polkit_listener_set_vtable (NMPolkitListener *self,
const NMPolkitListenVtable *vtable,
gpointer user_data);
#endif
#endif /* __NM_POLKIT_LISTENER_H__ */

View file

@ -1195,3 +1195,82 @@ nm_utils_strv_make_deep_copied (const char **strv)
return (char **) strv;
}
/*****************************************************************************/
/**
* nm_utils_get_start_time_for_pid:
* @pid: the process identifier
* @out_state: return the state character, like R, S, Z. See `man 5 proc`.
* @out_ppid: parent process id
*
* Originally copied from polkit source (src/polkit/polkitunixprocess.c)
* and adjusted.
*
* Returns: the timestamp when the process started (by parsing /proc/$PID/stat).
* If an error occurs (e.g. the process does not exist), 0 is returned.
*
* The returned start time counts since boot, in the unit HZ (with HZ usually being (1/100) seconds)
**/
guint64
nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid)
{
guint64 start_time;
char filename[256];
gs_free gchar *contents = NULL;
size_t length;
gs_strfreev gchar **tokens = NULL;
guint num_tokens;
gchar *p;
char state = ' ';
gint64 ppid = 0;
start_time = 0;
contents = NULL;
g_return_val_if_fail (pid > 0, 0);
nm_sprintf_buf (filename, "/proc/%"G_GUINT64_FORMAT"/stat", (guint64) pid);
if (!g_file_get_contents (filename, &contents, &length, NULL))
goto fail;
/* start time is the token at index 19 after the '(process name)' entry - since only this
* field can contain the ')' character, search backwards for this to avoid malicious
* processes trying to fool us
*/
p = strrchr (contents, ')');
if (p == NULL)
goto fail;
p += 2; /* skip ') ' */
if (p - contents >= (int) length)
goto fail;
state = p[0];
tokens = g_strsplit (p, " ", 0);
num_tokens = g_strv_length (tokens);
if (num_tokens < 20)
goto fail;
if (out_ppid) {
ppid = _nm_utils_ascii_str_to_int64 (tokens[1], 10, 1, G_MAXINT, 0);
if (ppid == 0)
goto fail;
}
start_time = _nm_utils_ascii_str_to_int64 (tokens[19], 10, 1, G_MAXINT64, 0);
if (start_time == 0)
goto fail;
NM_SET_OUT (out_state, state);
NM_SET_OUT (out_ppid, ppid);
return start_time;
fail:
NM_SET_OUT (out_state, ' ');
NM_SET_OUT (out_ppid, 0);
return 0;
}

View file

@ -586,4 +586,8 @@ int nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll)
/*****************************************************************************/
guint64 nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid);
/*****************************************************************************/
#endif /* __NM_SHARED_UTILS_H__ */

View file

@ -34,7 +34,6 @@
#include <stdlib.h>
#include "nm-dbus-manager.h"
#include "NetworkManagerUtils.h"
enum {
PROP_0,
@ -187,15 +186,15 @@ _new_unix_process (GDBusMethodInvocation *context,
&dbus_sender,
&uid,
&pid);
} else if (message) {
} else {
nm_assert (message);
success = nm_dbus_manager_get_caller_info_from_message (nm_dbus_manager_get (),
connection,
message,
&dbus_sender,
&uid,
&pid);
} else
g_assert_not_reached ();
}
if (!success)
return NULL;

View file

@ -452,83 +452,6 @@ nm_utils_modprobe (GError **error, gboolean suppress_error_logging, const char *
return exit_status;
}
/**
* nm_utils_get_start_time_for_pid:
* @pid: the process identifier
* @out_state: return the state character, like R, S, Z. See `man 5 proc`.
* @out_ppid: parent process id
*
* Originally copied from polkit source (src/polkit/polkitunixprocess.c)
* and adjusted.
*
* Returns: the timestamp when the process started (by parsing /proc/$PID/stat).
* If an error occurs (e.g. the process does not exist), 0 is returned.
*
* The returned start time counts since boot, in the unit HZ (with HZ usually being (1/100) seconds)
**/
guint64
nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid)
{
guint64 start_time;
char filename[256];
gs_free gchar *contents = NULL;
size_t length;
gs_strfreev gchar **tokens = NULL;
guint num_tokens;
gchar *p;
char state = ' ';
gint64 ppid = 0;
start_time = 0;
contents = NULL;
g_return_val_if_fail (pid > 0, 0);
nm_sprintf_buf (filename, "/proc/%"G_GUINT64_FORMAT"/stat", (guint64) pid);
if (!g_file_get_contents (filename, &contents, &length, NULL))
goto fail;
/* start time is the token at index 19 after the '(process name)' entry - since only this
* field can contain the ')' character, search backwards for this to avoid malicious
* processes trying to fool us
*/
p = strrchr (contents, ')');
if (p == NULL)
goto fail;
p += 2; /* skip ') ' */
if (p - contents >= (int) length)
goto fail;
state = p[0];
tokens = g_strsplit (p, " ", 0);
num_tokens = g_strv_length (tokens);
if (num_tokens < 20)
goto fail;
if (out_ppid) {
ppid = _nm_utils_ascii_str_to_int64 (tokens[1], 10, 1, G_MAXINT, 0);
if (ppid == 0)
goto fail;
}
start_time = _nm_utils_ascii_str_to_int64 (tokens[19], 10, 1, G_MAXINT64, 0);
if (start_time == 0)
goto fail;
NM_SET_OUT (out_state, state);
NM_SET_OUT (out_ppid, ppid);
return start_time;
fail:
NM_SET_OUT (out_state, ' ');
NM_SET_OUT (out_ppid, 0);
return 0;
}
/*****************************************************************************/
typedef struct {

View file

@ -178,8 +178,6 @@ nm_utils_ip_route_metric_penalize (int addr_family, guint32 metric, guint32 pena
int nm_utils_modprobe (GError **error, gboolean suppress_error_loggin, const char *arg1, ...) G_GNUC_NULL_TERMINATED;
guint64 nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid);
void nm_utils_kill_process_sync (pid_t pid, guint64 start_time, int sig, guint64 log_domain,
const char *log_name, guint32 wait_before_kill_msec,
guint32 sleep_duration_msec, guint32 max_wait_msec);