MCPcopy Index your code
hub / github.com/docker/docker-agent / RunShellBackground

Method RunShellBackground

pkg/tools/builtin/shell/shell.go:330–380  ·  view source on GitHub ↗
(ctx context.Context, params RunShellBackgroundArgs)

Source from the content-addressed store, hash-verified

328}
329
330func (h *shellHandler) RunShellBackground(ctx context.Context, params RunShellBackgroundArgs) (*tools.ToolCallResult, error) {
331 if strings.TrimSpace(params.Cmd) == "" {
332 return tools.ResultError(`Error: missing or empty "cmd" parameter. Pass the shell command as {"cmd": "..."}.`), nil
333 }
334
335 counter := h.jobCounter.Add(1)
336 jobID := fmt.Sprintf("job_%d_%d", time.Now().Unix(), counter)
337
338 bgCmd, bgEnv := h.applyAskpass(ctx, params.Cmd)
339 cmd := exec.Command(h.shell, append(h.shellArgsPrefix, bgCmd)...) //nolint:noctx // RunShellBackground intentionally outlives the request context
340 cmd.Env = bgEnv
341 cmd.Dir = h.resolveWorkDir(params.Cwd)
342 cmd.SysProcAttr = platformSpecificSysProcAttr()
343
344 job := &backgroundJob{
345 id: jobID,
346 cmd: params.Cmd,
347 cwd: params.Cwd,
348 output: &bytes.Buffer{},
349 startTime: time.Now(),
350 }
351
352 // The limitedWriter shares the job's outputMu so that readers
353 // (ViewBackgroundJob, ListBackgroundJobs) and the pipe-copy
354 // goroutines spawned by exec.Cmd use the same lock.
355 lw := &limitedWriter{mu: &job.outputMu, buf: job.output, maxSize: 10 * 1024 * 1024}
356 cmd.Stdout = lw
357 cmd.Stderr = lw
358
359 if err := cmd.Start(); err != nil {
360 return tools.ResultError(fmt.Sprintf("Error starting background command: %s", err)), nil
361 }
362
363 pg, err := createProcessGroup(cmd.Process)
364 if err != nil {
365 // Successfully started the child but couldn't install it in its own
366 // process group: clean it up before bailing out.
367 reapSpawnedChild(cmd, pg)
368 return tools.ResultError(fmt.Sprintf("Error creating process group: %s", err)), nil
369 }
370
371 job.process = cmd.Process
372 job.processGroup = pg
373 job.status.Store(statusRunning)
374 h.jobs.Store(jobID, job)
375
376 go h.monitorJob(job, cmd)
377
378 return tools.ResultSuccess(fmt.Sprintf("Background job started with ID: %s\nCommand: %s\nWorking directory: %s",
379 jobID, params.Cmd, params.Cwd)), nil
380}
381
382func (h *shellHandler) monitorJob(job *backgroundJob, cmd *exec.Cmd) {
383 err := cmd.Wait()

Calls 12

applyAskpassMethod · 0.95
resolveWorkDirMethod · 0.95
monitorJobMethod · 0.95
ResultErrorFunction · 0.92
ResultSuccessFunction · 0.92
reapSpawnedChildFunction · 0.85
NowMethod · 0.80
createProcessGroupFunction · 0.70
AddMethod · 0.65
StartMethod · 0.65
StoreMethod · 0.45

Tested by 2