C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
detach.c
Go to the documentation of this file.
1/** @file detach.c
2 @brief Launch executable, detaching from current process
3 @author Bill Waller
4 Copyright (c) 2025
5 MIT License
6 billxwaller@gmail.com
7 @date 2026-02-09
8 */
9
10#include <errno.h>
11#include <fcntl.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <sys/types.h>
16#include <sys/wait.h>
17#include <unistd.h>
18
19#ifdef __USE_GNU_GETTEXT
20#include <libintl.h>
21#define _(String) gettext(String)
22#define gettext_noop(String) String
23#define N_(String) gettext_noop(String)
24#else
25#define _(String) (String)
26#define N_(String) String
27#define textdomain(Domain)
28#define bindtextdomain(Package, Directory)
29#endif
30
31int fork_detach_execvp(char **eargv);
32
33/** @brief Fork, set new session ID, close files, and execute detached command
34 @ingroup exec
35 @param eargv - array of arguments for the command to execute
36 @return EXIT_SUCCESS on success, EXIT_FAILURE on failure
37 @details Sets the new session ID. Redirects standard file descriptors
38 to /dev/null. Closes all open file descriptors. Executes the command using
39 execvp. Exits with failure if any step fails.
40 @note Tested 2026-06-05 on Linux - appears to be functioning properly */
41int fork_detach_execvp(char **eargv) {
42 pid_t pid = fork();
43
44 if (pid < 0) {
45 fprintf(stderr, _("First fork failed: %s\n"), strerror(errno));
46 exit(EXIT_FAILURE);
47 }
48 if (pid == 0) {
49 if (setsid() < 0) {
50 fprintf(stderr, _("Set session ID failed: %s\n"), strerror(errno));
51 exit(EXIT_FAILURE);
52 }
53 close(STDIN_FILENO);
54 close(STDOUT_FILENO);
55 close(STDERR_FILENO);
56 int dev_null = open("/dev/null", O_RDWR);
57 if (dev_null != -1) {
58 dup2(dev_null, STDIN_FILENO);
59 dup2(dev_null, STDOUT_FILENO);
60 dup2(dev_null, STDERR_FILENO);
61 if (dev_null > 2) {
62 close(dev_null);
63 }
64 }
65 long max_fd = sysconf(_SC_OPEN_MAX);
66 for (long fd = 3; fd < max_fd; fd++)
67 close(fd);
68 execvp(eargv[0], eargv);
69 perror(_("execvp failed"));
70 exit(EXIT_FAILURE);
71 }
72 return 0;
73}
74
75int main(int argc, char *argv[]) {
76 char **eargv = &argv[1];
77
78 if (argc < 2) {
79 fprintf(stderr, _("Usage: %s <command> [args...]\n"), argv[0]);
80 return EXIT_FAILURE;
81 }
82
83 if (fork_detach_execvp(eargv) != 0) {
84 fprintf(stderr, _("Failed to fork and execute command\n"));
85 return EXIT_FAILURE;
86 }
87 return EXIT_SUCCESS;
88}
#define _(String)
Definition amort.c:23
int main(int argc, char **argv)
Capture the current terminal settings for later restoration.
Definition amort.c:41
int fork_detach_execvp(char **eargv)
Fork, set new session ID, close files, and execute detached command.
Definition detach.c:41