@@ -37,6 +37,7 @@ impl LaunchdManager {
3737 if uid. is_empty ( ) {
3838 return Err ( "empty uid from `id -u`" . into ( ) ) ;
3939 }
40+ validate_service_uid ( & uid) ?;
4041 Ok ( uid)
4142 }
4243
@@ -215,6 +216,7 @@ impl ServiceManager for LaunchdManager {
215216 }
216217
217218 fn install ( & self , spec : & ServiceSpec ) -> Result < InstallReport , Box < dyn std:: error:: Error > > {
219+ self . uid ( ) ?;
218220 let plist_path = self . write_plist ( spec) ?;
219221 self . ensure_bootstrapped ( & plist_path) ?;
220222 self . kickstart ( false ) ?;
@@ -226,6 +228,7 @@ impl ServiceManager for LaunchdManager {
226228 }
227229
228230 fn uninstall ( & self ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
231+ self . uid ( ) ?;
229232 // bootout first so launchd stops tracking the job, then rm the plist.
230233 self . bootout ( ) ?;
231234 let plist_path = self . plist_path ( ) ?;
@@ -236,6 +239,7 @@ impl ServiceManager for LaunchdManager {
236239 }
237240
238241 fn start ( & self ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
242+ self . uid ( ) ?;
239243 let plist_path = self . plist_path ( ) ?;
240244 if !plist_path. exists ( ) {
241245 return Err ( format ! (
@@ -250,10 +254,12 @@ impl ServiceManager for LaunchdManager {
250254 }
251255
252256 fn stop ( & self ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
257+ self . uid ( ) ?;
253258 self . bootout ( )
254259 }
255260
256261 fn restart ( & self , spec : & ServiceSpec ) -> Result < InstallReport , Box < dyn std:: error:: Error > > {
262+ self . uid ( ) ?;
257263 let plist_path = self . write_plist ( spec) ?;
258264 self . ensure_bootstrapped ( & plist_path) ?;
259265 self . kickstart ( true ) ?;
@@ -269,6 +275,16 @@ impl ServiceManager for LaunchdManager {
269275 }
270276}
271277
278+ fn validate_service_uid ( uid : & str ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
279+ if uid == "0" {
280+ return Err (
281+ "`garyx gateway` service commands install a per-user macOS LaunchAgent; do not run them with sudo. Re-run as your normal login user, for example: `garyx gateway install`"
282+ . into ( ) ,
283+ ) ;
284+ }
285+ Ok ( ( ) )
286+ }
287+
272288fn candidate_install_domains_for (
273289 uid : & str ,
274290 is_aqua_session : bool ,
0 commit comments