1
0
Files
MSE-CSEL/solutions/01_environment/process/process.c

134 lines
3.7 KiB
C

/**
* Copyright 2015 University of Applied Sciences Western Switzerland / Fribourg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Module: MA-CSEL1 - Building Embedded Systems under Linux
*
* Abstract: Introduction to the Embedded Linux Development Environment
*
* Purpose: This module implements a simple application to be launched from
* /etc/inttab.
* -->> tracing with syslog
*
* Autĥor: Daniel Gachet
* Date: 28.08.2015
*/
#define _XOPEN_SOURCE 600
#define _DEFAULT_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <grp.h>
#include <pwd.h>
#include <signal.h>
#include <syslog.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define UNUSED(x) (void)(x)
static int signal_catched = 0;
static void catch_signal (int signal)
{
syslog (LOG_INFO, "signal=%d catched\n", signal);
signal_catched++;
}
int main(int argc, char* argv[])
{
UNUSED(argc); UNUSED(argv);
// daemon's steps 1 to 3 skipt
// 4. capture all required signals
struct sigaction act = {.sa_handler = catch_signal,};
sigaction (SIGHUP, &act, NULL); // 1 - hangup
sigaction (SIGINT, &act, NULL); // 2 - terminal interrupt
sigaction (SIGQUIT, &act, NULL); // 3 - terminal quit
sigaction (SIGABRT, &act, NULL); // 6 - abort
sigaction (SIGTERM, &act, NULL); // 15 - termination
sigaction (SIGTSTP, &act, NULL); // 19 - terminal stop signal
// 5. update file mode creation mask
umask(0027);
// 6. change working directory to appropriate place
if (chdir ("/") == -1) {
syslog (LOG_ERR, "ERROR while changing to working directory");
exit (1);
}
// 7. close all open file descriptors
for (int fd = sysconf(_SC_OPEN_MAX); fd >= 0; fd--) {
close (fd);
}
// 8. redirect stdin, stdout and stderr to /dev/null
if (open ("/dev/null", O_RDWR) != STDIN_FILENO) {
syslog (LOG_ERR, "ERROR while opening '/dev/null' for stdin");
exit (1);
}
if (dup2 (STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO) {
syslog (LOG_ERR, "ERROR while opening '/dev/null' for stdout");
exit (1);
}
if (dup2 (STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) {
syslog (LOG_ERR, "ERROR while opening '/dev/null' for stderr");
exit (1);
}
// 9. option: open syslog for message logging
openlog (NULL, LOG_NDELAY | LOG_PID, LOG_DAEMON);
syslog (LOG_INFO, "Daemon has started...");
// 10. option: get effective user and group id for appropriate's one
struct passwd* pwd = getpwnam ("daemon");
if (pwd == 0) {
syslog (LOG_ERR, "ERROR while reading daemon password file entry");
exit (1);
}
// 11. option: change root directory
if (chroot (".") == -1) {
syslog (LOG_ERR, "ERROR while changing to new root directory");
exit (1);
}
// 12. option: change effective user and group id for appropriate's one
if (setegid (pwd->pw_gid) == -1) {
syslog (LOG_ERR, "ERROR while setting new effective group id");
exit (1);
}
if (seteuid (pwd->pw_uid) == -1) {
syslog (LOG_ERR, "ERROR while setting new effective user id");
exit (1);
}
// 13. implement daemon body...
int t = 30;
do {
t = sleep(t);
} while (t > 0);
syslog (LOG_INFO, "daemon stopped. Number of signals catched=%d\n", signal_catched);
closelog();
return 0;
}