@@ -18,6 +18,8 @@ package dbus
1818
1919import (
2020 "errors"
21+ "path"
22+ "strconv"
2123
2224 "github.com/godbus/dbus"
2325)
@@ -37,26 +39,26 @@ func (c *Conn) jobComplete(signal *dbus.Signal) {
3739 c .jobListener .Unlock ()
3840}
3941
40- func (c * Conn ) startJob (job string , args ... interface {}) (<- chan string , error ) {
41- c .jobListener .Lock ()
42- defer c .jobListener .Unlock ()
42+ func (c * Conn ) startJob (ch chan <- string , job string , args ... interface {}) (int , error ) {
43+ if ch != nil {
44+ c .jobListener .Lock ()
45+ defer c .jobListener .Unlock ()
46+ }
4347
44- ch := make (chan string , 1 )
45- var path dbus.ObjectPath
46- err := c .sysobj .Call (job , 0 , args ... ).Store (& path )
48+ var p dbus.ObjectPath
49+ err := c .sysobj .Call (job , 0 , args ... ).Store (& p )
4750 if err != nil {
48- return nil , err
51+ return 0 , err
4952 }
50- c .jobListener .jobs [path ] = ch
51- return ch , nil
52- }
5353
54- func (c * Conn ) runJob (job string , args ... interface {}) (string , error ) {
55- respCh , err := c .startJob (job , args ... )
56- if err != nil {
57- return "" , err
54+ if ch != nil {
55+ c .jobListener .jobs [p ] = ch
5856 }
59- return <- respCh , nil
57+
58+ // ignore error since 0 is fine if conversion fails
59+ jobID , _ := strconv .Atoi (path .Base (string (p )))
60+
61+ return jobID , nil
6062}
6163
6264// StartUnit enqueues a start job and depending jobs, if any (unless otherwise
@@ -74,59 +76,67 @@ func (c *Conn) runJob(job string, args ...interface{}) (string, error) {
7476// requirement dependencies. It is not recommended to make use of the latter
7577// two options.
7678//
77- // Result string: one of done, canceled, timeout, failed, dependency, skipped.
79+ // If the provided channel is non-nil, a result string will be sent to it upon
80+ // job completion: one of done, canceled, timeout, failed, dependency, skipped.
7881// done indicates successful execution of a job. canceled indicates that a job
7982// has been canceled before it finished execution. timeout indicates that the
8083// job timeout was reached. failed indicates that the job failed. dependency
8184// indicates that a job this job has been depending on failed and the job hence
8285// has been removed too. skipped indicates that a job was skipped because it
8386// didn't apply to the units current state.
84- func (c * Conn ) StartUnit (name string , mode string ) (string , error ) {
85- return c .runJob ("org.freedesktop.systemd1.Manager.StartUnit" , name , mode )
87+ //
88+ // If no error occurs, the ID of the underlying systemd job will be returned. There
89+ // does exist the possibility for no error to be returned, but for the returned job
90+ // ID to be 0. In this case, the actual underlying ID is not 0 and this datapoint
91+ // should not be considered authoritative.
92+ //
93+ // If an error does occur, it will be returned to the user alongside a job ID of 0.
94+ func (c * Conn ) StartUnit (name string , mode string , ch chan <- string ) (int , error ) {
95+ return c .startJob (ch , "org.freedesktop.systemd1.Manager.StartUnit" , name , mode )
8696}
8797
8898// StopUnit is similar to StartUnit but stops the specified unit rather
8999// than starting it.
90- func (c * Conn ) StopUnit (name string , mode string ) (string , error ) {
91- return c .runJob ( "org.freedesktop.systemd1.Manager.StopUnit" , name , mode )
100+ func (c * Conn ) StopUnit (name string , mode string , ch chan <- string ) (int , error ) {
101+ return c .startJob ( ch , "org.freedesktop.systemd1.Manager.StopUnit" , name , mode )
92102}
93103
94104// ReloadUnit reloads a unit. Reloading is done only if the unit is already running and fails otherwise.
95- func (c * Conn ) ReloadUnit (name string , mode string ) (string , error ) {
96- return c .runJob ( "org.freedesktop.systemd1.Manager.ReloadUnit" , name , mode )
105+ func (c * Conn ) ReloadUnit (name string , mode string , ch chan <- string ) (int , error ) {
106+ return c .startJob ( ch , "org.freedesktop.systemd1.Manager.ReloadUnit" , name , mode )
97107}
98108
99109// RestartUnit restarts a service. If a service is restarted that isn't
100110// running it will be started.
101- func (c * Conn ) RestartUnit (name string , mode string ) (string , error ) {
102- return c .runJob ( "org.freedesktop.systemd1.Manager.RestartUnit" , name , mode )
111+ func (c * Conn ) RestartUnit (name string , mode string , ch chan <- string ) (int , error ) {
112+ return c .startJob ( ch , "org.freedesktop.systemd1.Manager.RestartUnit" , name , mode )
103113}
104114
105115// TryRestartUnit is like RestartUnit, except that a service that isn't running
106116// is not affected by the restart.
107- func (c * Conn ) TryRestartUnit (name string , mode string ) (string , error ) {
108- return c .runJob ( "org.freedesktop.systemd1.Manager.TryRestartUnit" , name , mode )
117+ func (c * Conn ) TryRestartUnit (name string , mode string , ch chan <- string ) (int , error ) {
118+ return c .startJob ( ch , "org.freedesktop.systemd1.Manager.TryRestartUnit" , name , mode )
109119}
110120
111121// ReloadOrRestart attempts a reload if the unit supports it and use a restart
112122// otherwise.
113- func (c * Conn ) ReloadOrRestartUnit (name string , mode string ) (string , error ) {
114- return c .runJob ( "org.freedesktop.systemd1.Manager.ReloadOrRestartUnit" , name , mode )
123+ func (c * Conn ) ReloadOrRestartUnit (name string , mode string , ch chan <- string ) (int , error ) {
124+ return c .startJob ( ch , "org.freedesktop.systemd1.Manager.ReloadOrRestartUnit" , name , mode )
115125}
116126
117127// ReloadOrTryRestart attempts a reload if the unit supports it and use a "Try"
118128// flavored restart otherwise.
119- func (c * Conn ) ReloadOrTryRestartUnit (name string , mode string ) (string , error ) {
120- return c .runJob ( "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit" , name , mode )
129+ func (c * Conn ) ReloadOrTryRestartUnit (name string , mode string , ch chan <- string ) (int , error ) {
130+ return c .startJob ( ch , "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit" , name , mode )
121131}
122132
123133// StartTransientUnit() may be used to create and start a transient unit, which
124134// will be released as soon as it is not running or referenced anymore or the
125135// system is rebooted. name is the unit name including suffix, and must be
126136// unique. mode is the same as in StartUnit(), properties contains properties
127137// of the unit.
128- func (c * Conn ) StartTransientUnit (name string , mode string , properties ... Property ) (string , error ) {
129- return c .runJob ( "org.freedesktop.systemd1.Manager.StartTransientUnit" , name , mode , properties , make ([]PropertyCollection , 0 ))
138+ func (c * Conn ) StartTransientUnit (name string , mode string , properties [] Property , ch chan <- string ) (int , error ) {
139+ return c .startJob ( ch , "org.freedesktop.systemd1.Manager.StartTransientUnit" , name , mode , properties , make ([]PropertyCollection , 0 ))
130140}
131141
132142// KillUnit takes the unit name and a UNIX signal number to send. All of the unit's
0 commit comments