--- Makefile +++ Makefile 2007-06-18 16:40:20.300899000 +0200 @@ -53,6 +53,7 @@ UBINPRG = ifeq ($(DISTRO),SuSE) UBINPRG += usleep + UBINPRG += fsync endif all: $(SBINPRG) $(UBINPRG) @@ -72,8 +73,11 @@ checkproc: checkproc.c libinit.o usleep: usleep.c $(CC) $(CFLAGS) -o $@ $^ +fsync: fsync.c + $(CC) $(CFLAGS) -o $@ $^ + clean: - $(RM) *.o *~ killproc startproc checkproc pidofproc start_daemon usleep + $(RM) *.o *~ killproc startproc checkproc pidofproc start_daemon usleep fsync install: $(TODO) if test -n "$(SBINPRG)" ; then \ @@ -116,6 +120,8 @@ FILES = README \ libinit.h \ usleep.c \ usleep.1 \ + fsync.c \ + fsync.1 \ killproc-$(VERSION).lsm dest: --- checkproc.c +++ checkproc.c 2007-03-09 14:05:44.000000000 +0100 @@ -162,8 +162,8 @@ int main(int argc, char **argv) if (remember_pids(pid_file,fullname,root,flags) < 0) exit(LSB_PROOFX); - if (!remember && (flags & KILL)) - exit(LSB_NOPROC); /* New LSB: no pid file is no job */ + if (!remember) + exit(LSB_STATUS_NOPROC); /* New LSB: no pid file is no job */ } /* No pid file means that we have to search in /proc/ */ free(pid_file); --- fsync.1 +++ fsync.1 2007-06-18 16:45:14.768333000 +0200 @@ -0,0 +1,39 @@ +.\" +.\" Copyright 2007 Werner Fink, 2007 SuSE GmbH Nuernberg, Germany. +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.TH FSYNC 1 "Jun 18, 2007" "Version 1.16" "The SuSE boot concept" +.UC 1 +.SH NAME +fsync \- synchronize the specified file with storage device +.\" +.SH SYNOPSIS +.\" +.B fsync +.I file +.\" +.SH DESCRIPTION +.B fsync +synchronize the in-core state of the specified file with the storage device +.\" +.SH BUGS +The +.B fsync +program uses the +.BR fsync (2) +function and therefore shows the same weaknesses +by any system activity. +\." +.SH SEE ALSO +.BR fsync (2), +.BR fdatasync (2). +\." +.SH COPYRIGHT +2007 Werner Fink, +2007 SuSE GmbH Nuernberg, Germany. +.SH AUTHOR +Werner Fink --- fsync.c +++ fsync.c 2007-06-18 16:37:20.393692000 +0200 @@ -0,0 +1,89 @@ +/* + * fsync.c File data sync for the specified file + * + * Usage: fsync file + * + * Copyright 2007 Werner Fink, 2007 SUSE LINUX Products GmbH, Germany. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Author: Werner Fink + */ + +#ifndef __USE_STRING_INLINES +# define __USE_STRING_INLINES +#endif +#ifdef __NO_STRING_INLINES +# undef __NO_STRING_INLINES +#endif +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USAGE "Usage:\t%s file\n", we_are + +static char *we_are; +int main(int argc, char **argv) +{ + int ret, fd, flags; + char *path, *dir = NULL; + + if (argc != 2) + goto err; + + if ((path = strdup(argv[1])) == (char*)0) + goto err; + + dir = dirname(path); + flags = O_RDONLY|O_NOCTTY|O_NONBLOCK; + + if (getuid() == 0) + flags |= O_NOATIME; + + if ((fd = open(argv[1], flags)) < 0) { + if (errno != ENOENT) + goto err; + if ((fd = open(dir, flags|O_DIRECTORY)) < 0) + goto err; + ret = fsync(fd); + close(fd); + if (ret < 0) + goto err; + if ((fd = open(argv[1], flags)) < 0) + goto err; + } + ret = fsync(fd); + close(fd); + if (ret < 0) + goto err; + + return 0; + /* Do this at the end for speed */ +err: + we_are = basename(argv[0]); + fprintf(stderr, USAGE); + + if (argc > 1 && *(argv[1]) == '-') { + argv[1]++; + if (!strcmp(argv[1], "-help") || *(argv[1]) == 'h' || *(argv[1]) == '?') { + fprintf(stderr, "Do a fsync(2) on the specified file.\n\n"); + fprintf(stderr, "Help options:\n"); + fprintf(stderr, " -h, -?, --help display this help and exit.\n"); + exit (0); + } + } else if (errno != 0) + fprintf(stderr, "%s: %s\n", argv[1], strerror(errno)); + exit (1); +} --- killproc.c +++ killproc.c 2007-10-31 17:09:10.502940783 +0100 @@ -26,8 +26,9 @@ #define OTHERSIG "HUP" #define USAGE "Usage:\n"\ - "\t%s [-v] [-t] [-g|-G] [-SIG] /full/path/to/program\n" \ - "\t%s -l\n", we_are, we_are + " %s [-v] [-q] [-L] [-g|-G] [-N] [-p pid_file] [-i ingnore_file] \\\n"\ + " [-c root] [-t] [-SIG] /full/path/to/executable\n"\ + " %s -l\n", we_are, we_are static int do_kill(const char *name, const pid_t proc, const int sig, const int group_leader, const int process_group); --- startproc.8 +++ startproc.8 2007-10-31 16:53:55.193901107 +0100 @@ -15,30 +15,32 @@ Start_daemon \- Start processes identifi .SH SYNOPSIS .\" .B startproc -.RB [ -f ] -.RB [ -L ] -.RB [[ "-n "] +/- ] -.RB [ -s ] -.RB [ "-t +.RB [ \-f ] +.RB [ \-L ] +.RB [[ "\-n "] +/\- ] +.RB [ \-s ] +.RB [ \-t +.I sec +.RB | \-T .IR sec ] -.RB [ "-u" +.RB [ \-u .IR user ] -.RB [ "-g" +.RB [ \-g .IR group ] -.RB [ "-v" "] [" "-e" "] [" -l +.RB [ \-v "] [" \-e "] [" \-l .I log_file -.RB | -q | -d ] -.RB [ -p +.RB | \-q | \-d ] +.RB [ \-p .IR pid_file ] -.RB [ -i +.RB [ \-i .IR ignore_file ] -.RB [ -c +.RB [ \-c .IR root ] .IR /path/to/executable " [" "arguments for executable" ] .PP .B start_daemon -.RB [ -f ] -.RB [ "-n " +/- ] +.RB [ \-f ] +.RB [ "\-n " +/\- ] .IR /path/to/executable " [" "arguments for executable" ] .\" .SH DESCRIPTION @@ -192,6 +194,12 @@ for minutes, and .B h for hours to wait. .TP +.BI \-T " sec" +The same as for option +.B \-t +but wait only on the started process not on childs forked by +the process. +.TP .BI \-u " user" Sets the user ID of the process to .IR user . --- startproc.c +++ startproc.c 2007-10-31 17:09:20.172175763 +0100 @@ -26,14 +26,15 @@ #include #define USAGE "Usage:\n"\ - "\t%s [-f] [+/-] [-s] [-u uid] [-g gid] [-v] [-l log_file|-q] /full/path/to/program\n" + " %s [-f] [-L] [[-n ]+/-] [-s] [-t sec|-T sec] [-u uid] [-g gid] [-v] [-e] \\\n"\ + " [-l log|-q|-d] [-p pid_file] [-i ignore_file] [-c root] /path/to/executable [args]\n" #define USAGE_SD "Usage:\n"\ "\t%s [-f] [-n +/-] /full/path/to/program\n" static int do_fork(const char *name, char *argv[], const char* log_file, const int nicelvl, const int env, const char* root, unsigned short flags); -static int quiet = 1, supprmsg = 0, sess = 0, seconds = 0, force = 0, dialog = 0; +static int quiet = 1, supprmsg = 0, sess = 0, seconds = 0, sigchld = 0, force = 0, dialog = 0; static struct passwd *user = NULL; struct group *grp = NULL; static int syslogd = 0; @@ -46,6 +47,14 @@ static void sig_quit(int nsig) signaled = 1; } +static void sig_chld(int nsig) +{ + if (nsig != SIGCHLD) + return; + (void)signal(nsig, SIG_DFL); + seconds = 0; +} + int main(int argc, char **argv) { extern char * we_are; @@ -81,7 +90,7 @@ int main(int argc, char **argv) } opterr = 0; - while ((c = getopt(argc, argv, "+c:edp:l:hqvsu:g:t:n:fLi:")) != -1) { /* `+' is POSIX correct */ + while ((c = getopt(argc, argv, "+c:edp:l:hqvsu:g:t:n:fLi:T:")) != -1) { /* `+' is POSIX correct */ switch (c) { case 'v': quiet = 0; @@ -169,6 +178,8 @@ int main(int argc, char **argv) } else error(LSB_WRGSYN,"Option -g requires group id or group name\n"); break; + case 'T': + sigchld++; case 't': if (optarg && optarg[0] != '/' && optarg[0] != '-') { char *endptr; @@ -370,8 +381,11 @@ static int do_fork(const char *inname, c error(LSB_PROOF," cannot open %s: %s\n", log_file, strerror(errno)); } - (void)signal(SIGQUIT, sig_quit); - (void)signal(SIGCHLD, SIG_DFL); + save_sigquit = signal(SIGQUIT, sig_quit); + if (sigchld) + (void)signal(SIGCHLD, sig_chld); + else + (void)signal(SIGCHLD, SIG_DFL); fflush(stdout); fflush(stderr); /* flush stdout and especially stderr */