(name string)
| 502 | } |
| 503 | |
| 504 | func (sm *ServiceManager) StopService(name string) error { |
| 505 | sm.Mu.RLock() |
| 506 | service, exists := sm.Services[name] |
| 507 | sm.Mu.RUnlock() |
| 508 | |
| 509 | if !exists { |
| 510 | return fmt.Errorf("can't find service: %s", name) |
| 511 | } |
| 512 | |
| 513 | service.mu.Lock() |
| 514 | defer service.mu.Unlock() |
| 515 | |
| 516 | if service.Status != "running" { |
| 517 | return fmt.Errorf("service not working: %s", name) |
| 518 | } |
| 519 | |
| 520 | service.Status = "stopped" |
| 521 | pidToKill := service.PID |
| 522 | |
| 523 | log.Printf("Stopping service %s (PID: %d)...", name, pidToKill) |
| 524 | |
| 525 | if err := killProcessTree(pidToKill); err != nil { |
| 526 | log.Printf("Process tree kill error for %s: %v", name, err) |
| 527 | } |
| 528 | |
| 529 | deadline := time.Now().Add(10 * time.Second) |
| 530 | for time.Now().Before(deadline) { |
| 531 | process, err := os.FindProcess(pidToKill) |
| 532 | if err != nil || process.Signal(syscall.Signal(0)) != nil { |
| 533 | log.Printf("Service %s stopped successfully.", name) |
| 534 | service.CMD = nil |
| 535 | service.PID = 0 |
| 536 | return nil |
| 537 | } |
| 538 | time.Sleep(200 * time.Millisecond) |
| 539 | } |
| 540 | |
| 541 | log.Printf("Timeout reached, forcefully killing service %s (PID: %d)", name, pidToKill) |
| 542 | if process, err := os.FindProcess(pidToKill); err == nil { |
| 543 | if err := process.Kill(); err != nil { |
| 544 | log.Printf("Force kill failed for %s: %v", name, err) |
| 545 | } |
| 546 | } |
| 547 | |
| 548 | time.Sleep(100 * time.Millisecond) |
| 549 | |
| 550 | service.CMD = nil |
| 551 | service.PID = 0 |
| 552 | log.Printf("Service %s forcefully stopped.", name) |
| 553 | return nil |
| 554 | } |
| 555 | |
| 556 | func (sm *ServiceManager) GetUserServicePermissions(serviceName string, username string) (ServiceUserPermissions, error) { |
| 557 | sm.Mu.RLock() |
no test coverage detected