2 * --- T2-COPYRIGHT-NOTE-BEGIN ---
3 * T2 SDE: package/.../sysvinit/rc.c
4 * Copyright (C) 2004 - 2022 The T2 SDE Project
5 * Copyright (C) 1998 - 2003 ROCK Linux Project
7 * This Copyright note is generated by scripts/Create-CopyPatch,
8 * more information can be found in the files COPYING and README.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2.
12 * --- T2-COPYRIGHT-NOTE-END ---
22 #include <sys/resource.h>
25 #include <sys/types.h>
28 char env_PREVLEVEL
[100]="PREVLEVEL=N";
29 char env_RUNLEVEL
[100]="RUNLEVEL=N";
30 char env_TERM
[100]="TERM=linux";
32 char * clean_env
[] = {
33 "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
40 /* See bits/resource.h and asm/resource.h */
41 struct rlimit rlim_cpu
= { RLIM_INFINITY
, RLIM_INFINITY
};
42 struct rlimit rlim_fsize
= { RLIM_INFINITY
, RLIM_INFINITY
};
43 struct rlimit rlim_data
= { RLIM_INFINITY
, RLIM_INFINITY
};
44 struct rlimit rlim_stack
= { RLIM_INFINITY
, RLIM_INFINITY
};
45 struct rlimit rlim_core
= { RLIM_INFINITY
, RLIM_INFINITY
};
46 struct rlimit rlim_rss
= { RLIM_INFINITY
, RLIM_INFINITY
};
47 struct rlimit rlim_nofile
= { 1024, 1024 };
48 struct rlimit rlim_as
= { RLIM_INFINITY
, RLIM_INFINITY
};
49 struct rlimit rlim_nproc
= { 2048, 2048 };
50 struct rlimit rlim_memlock
= { RLIM_INFINITY
, RLIM_INFINITY
};
51 struct rlimit rlim_locks
= { RLIM_INFINITY
, RLIM_INFINITY
};
53 #define GROUP_LIST_SIZE 1
54 gid_t group_list
[GROUP_LIST_SIZE
] = { 0 };
56 /* This prototypes are missing in unistd.h */
57 int setresuid(uid_t ruid
, uid_t euid
, uid_t suid
);
58 int setresgid(gid_t rgid
, gid_t egid
, gid_t sgid
);
60 /* The first (and only) field in sched_param is sched_priority */
61 struct sched_param sp
= { 0 };
63 #define handle_error(a) if ( a == -1 ) { perror("rc: " #a); return 1; }
65 int main(int argc
, char ** argv
) {
71 /* Copy some environment variables to the new environment if set */
72 if ( getenv("PREVLEVEL") )
73 sprintf(env_PREVLEVEL
, "PREVLEVEL=%.50s", getenv("PREVLEVEL"));
74 if ( getenv("RUNLEVEL") )
75 sprintf(env_RUNLEVEL
, "RUNLEVEL=%.50s", getenv("RUNLEVEL"));
77 sprintf(env_TERM
, "TERM=%.50s", getenv("TERM"));
79 /* we never need argv[0] - skipt it */
82 /* Handle --nobtee option */
83 if ( argc
> 0 && !strcmp(*argv
, "--nobtee") ) {
88 /* Display help message */
92 " Run SystemV Init-Scripts with a clean environment and detached from\n"
95 " Usage: rc [ --nobtee ] <service> { start | stop | ... | help } [ script options ]\n");
99 " <service> might be one of:\n"
102 system("ls /etc/rc.d/init.d >&2");
105 fprintf(stderr
, "\n");
109 /* No btee when viewing the help screen for this service */
110 if ( !strcmp(argv
[1], "help") ) use_btee
= 0;
112 /* Forward output to a 'btee' process */
114 if ( pipe(btee_pipe
) ) {
115 perror("rc: Can't create pipe for btee");
119 dup2(btee_pipe
[0], 0);
122 execl("/sbin/btee", "btee", "a",
123 "/var/log/init.msg", NULL
);
124 perror("rc: Can't exec btee command");
127 dup2(btee_pipe
[1], 1);
133 /* Set umask, process-group, nice-value and current directory */
134 handle_error( umask(022) );
135 handle_error( setpgid(0,0) );
136 handle_error( setpriority(PRIO_PROCESS
, 0, 0) );
137 handle_error( chdir("/") );
139 /* Set all ulimits */
140 handle_error( setrlimit(RLIMIT_CPU
, &rlim_cpu
) );
141 handle_error( setrlimit(RLIMIT_FSIZE
, &rlim_fsize
) );
142 handle_error( setrlimit(RLIMIT_DATA
, &rlim_data
) );
143 handle_error( setrlimit(RLIMIT_STACK
, &rlim_stack
) );
144 handle_error( setrlimit(RLIMIT_CORE
, &rlim_core
) );
145 handle_error( setrlimit(RLIMIT_RSS
, &rlim_rss
) );
146 handle_error( setrlimit(RLIMIT_NOFILE
, &rlim_nofile
) );
147 handle_error( setrlimit(RLIMIT_AS
, &rlim_as
) );
148 handle_error( setrlimit(RLIMIT_NPROC
, &rlim_nproc
) );
149 handle_error( setrlimit(RLIMIT_MEMLOCK
, &rlim_memlock
) );
150 handle_error( setrlimit(RLIMIT_LOCKS
, &rlim_locks
) );
152 /* Reset all signal handlers */
153 for (i
=1; i
<NSIG
; i
++) {
154 if ( i
== SIGKILL
) continue;
155 if ( i
== SIGSTOP
) continue;
157 if ( i
>= __SIGRTMIN
) continue;
160 if ( i
> SIGUNUSED
) continue;
162 if( signal(i
, SIG_DFL
) == SIG_ERR
) {
163 fprintf(stderr
, "rc: Can't reset signal #%d: "
164 "%s\n", i
, strerror(errno
) );
169 /* Close all file-descriptors > 2 (1024 seams to be a good value -
170 * linux/fs.h defines NR_OPEN to 1024*1024, which is too big ;-) */
171 for (i
=3; i
<=1024; i
++) close(i
);
173 /* Set user and group ids */
174 handle_error( setgroups(GROUP_LIST_SIZE
, group_list
) );
175 handle_error( setresuid(0, 0, 0) );
176 handle_error( setresgid(0, 0, 0) );
178 /* clear rt scheduling */
179 #ifdef __GNU_LIBRARY__
180 handle_error( sched_setscheduler(0, SCHED_OTHER
, &sp
) );
183 /* Run the command in a (non-interactive) login shell (i.e. read
184 * /etc/profile) and send \004 after running the script if we are
186 i
= snprintf(command
, sizeof(command
), "%s%s",
187 strchr(*argv
, '/') ? "" : "/etc/rc.d/init.d/", *argv
);
189 while (*argv
) /* copy args */
190 i
+= snprintf(command
+i
, sizeof(command
)-i
, " %s", *argv
++);
191 i
+=snprintf(command
+i
, sizeof(command
)-i
, " </dev/null 2>&1%s",
192 use_btee
? "; /bin/echo -ne '\004'" : "");
193 execle("/bin/bash", "-bash", "-l", "-c", command
, NULL
, clean_env
);
195 /* Oups! Can't exec the shell. */
196 if ( use_btee
) write(1, "\004", 1);
197 perror("rc: Can't execute shell for spawning init script");