The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



"Ubuntu планирует перейти на systemd, следом за Debian"
Версия для распечатки Пред. тема | След. тема
Форум Разговоры, обсуждение новостей
Исходное сообщение [ Отслеживать ]
Присылайте удачные настройки в раздел примеров файлов конфигурации на WIKI.opennet.ru.
. "Ubuntu Linux переходит на systemd, следом за Debian" +4 +/
Сообщение от arisu (ok), 16-Фев-14, 04:51 
> ух-ты какой эпичный баттхёрт… и конечно этот балабол «написал» инит, ага -
> чем хейтер тупее, тем больше у него понтов.

прикинь, я тебе сейчас инит напишу. внемли, дитя:


/* See LICENSE file for copyright and license details. */

#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/signalfd.h>
#include <sys/types.h>
#include <sys/wait.h>


/***********************************************************************/******************************************************************************/
static char *const rcinitcmd[] = { "/etc/rc.d/rc.init", NULL };
static char *const rcrebootcmd[] = { "/etc/rc.d/rc.shutdown", "reboot", NULL };
static char *const rcpoweroffcmd[] = { "/etc/rc.d/rc.shutdown", "poweroff", NULL };


/***********************************************************************/******************************************************************************/
#define LEN(x) (sizeof (x)/sizeof *(x))


/***********************************************************************/******************************************************************************/
static __attribute__((noreturn)) void venprintf (int status, const char *fmt, va_list ap) {
  vfprintf(stderr, fmt, ap);
  if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
    fputc(' ', stderr);
    perror(NULL);
  }
  exit(status);
}


static __attribute__((noreturn,format(printf,1,2))) void eprintf (const char *fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  venprintf(EXIT_FAILURE, fmt, ap);
  va_end(ap);
}


static __attribute__((noreturn,format(printf,1,2))) void weprintf (const char *fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  vfprintf(stderr, fmt, ap);
  va_end(ap);
  if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
    fputc(' ', stderr);
    perror(NULL);
  }
  exit(EXIT_FAILURE);
}


/***********************************************************************/******************************************************************************/
typedef struct {
  int sig;
  void (*func) (void);
} sigcbinfo_t;


/***********************************************************************/******************************************************************************/
static void spawn (char *const argv[]) {
  pid_t pid = fork();
  if (pid < 0) {
    weprintf("sinit: fork:");
  } else if (pid == 0) {
    setsid();
    setpgid(0, 0);
    execvp(argv[0], argv);
    weprintf("sinit: execvp %s:", argv[0]);
    _exit(errno == ENOENT ? 127 : 126);
  }
}


/***********************************************************************/******************************************************************************/
static void sigpoweroff (void) {
  spawn(rcpoweroffcmd);
}


static void sigreap (void) {
  while (waitpid(-1, NULL, WNOHANG) > 0) ;
}


static void sigreboot (void) {
  spawn(rcrebootcmd);
}


/***********************************************************************/******************************************************************************/
static sigcbinfo_t dispatchsig[] = {
  { SIGUSR1, sigpoweroff },
  { SIGCHLD, sigreap     },
  { SIGINT,  sigreboot   },
};


/***********************************************************************/******************************************************************************/
int main (int argc, char *argv[]) {
  struct signalfd_siginfo siginfo;
  sigset_t sigset;
  int sigfd;

  if (getpid() != 1) {
    /* check for special links */
    if (argc > 0 && argv[0]) {
      const char *ee = strchr(argv[0], '/');
      if (ee == NULL) ee = argv[0];
      if (strcmp(ee, "reboot") == 0) {
        kill(1, SIGINT);
        return 0;
      }
      if (strcmp(ee, "poweroff") == 0) {
        kill(1, SIGUSR1);
        return 0;
      }
    }
    return EXIT_FAILURE;
  }
  setsid();

  if (sigemptyset(&sigset) < 0) eprintf("sinit: sigemptyset:");

  for (int i = 0; i < LEN(dispatchsig); ++i) {
    if (sigaddset(&sigset, dispatchsig[i].sig) < 0) eprintf("sinit: sigaddset:");
  }

  if (sigprocmask(SIG_BLOCK, &sigset, NULL) < 0) eprintf("sinit: sigprocmask:");

  sigfd = signalfd(-1, &sigset, SFD_CLOEXEC);
  if (sigfd < 0) eprintf("sinit: signalfd:");

  spawn(rcinitcmd);

  for (;;) {
    ssize_t n = read(sigfd, &siginfo, sizeof(siginfo));
    if (n < 0) eprintf("sinit: read:");
    if (n != sizeof(siginfo)) continue;
    for (int i = 0; i < LEN(dispatchsig); ++i) {
      if (dispatchsig[i].sig == siginfo.ssi_signo) dispatchsig[i].func();
    }
  }

  /* not reachable */
  return EXIT_SUCCESS;
}

и это ещё сложнее, чем надо, потому что вот тебе рабочий инит:


#define _XOPEN_SOURCE 700
#include <signal.h>
#include <unistd.h>

int main () {
  sigset_t set;
  int status;

  if (getpid() != 1) return 1;

  sigfillset(&set);
  sigprocmask(SIG_BLOCK, &set, 0);

  if (fork()) for (;;) wait(&status);

  sigprocmask(SIG_UNBLOCK, &set, 0);

  setsid();
  setpgid(0, 0);
  return execve("/etc/rc", (char *[]) { "rc", 0}, (char *[]) { 0});
}

но ты же совершенно не разбираешься в теме, ты умеешь только про «понты» вещать. а лучше бы ты жевал и учился.

Ответить | Правка | Наверх | Cообщить модератору

Оглавление
Ubuntu планирует перейти на systemd, следом за Debian, opennews, 14-Фев-14, 20:06  [смотреть все]
Форумы | Темы | Пред. тема | След. тема



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру