minit

A small yet feature-complete init (http://fefe.de/minit/)
Log | Files | Refs | README | LICENSE

commit 06aa26ce6594e8072c300fe94c0867019d289ea5
parent 39c137709c9e29341b2c01717b44358fddbbe65d
Author: leitner <leitner>
Date:   Thu, 30 Aug 2001 19:59:44 +0000

add buffering and formatting from libowfat

Diffstat:
MMakefile | 34+++++++++++++++-------------------
Abuffer.h | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abuffer_1.c | 7+++++++
Abuffer_2.c | 7+++++++
Abuffer_flush.c | 10++++++++++
Abuffer_put.c | 17+++++++++++++++++
Abuffer_putflush.c | 7+++++++
Abuffer_puts.c | 5+++++
Abuffer_putsflush.c | 5+++++
Abuffer_putulong.c | 8++++++++
Abuffer_stubborn.c | 15+++++++++++++++
Abyte.h | 41+++++++++++++++++++++++++++++++++++++++++
Abyte_copy.c | 30++++++++++++++++++++++++++++++
Afmt.h | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afmt_ulong.c | 11+++++++++++
Mminit.c | 34++++++++++++++++++++++++++--------
Mmsvc.c | 68+++++++++++++++++++++++++++++++++++---------------------------------
17 files changed, 379 insertions(+), 60 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,27 +1,23 @@ all: minit msvc pidfilehack #CFLAGS=-pipe -march=i386 -fomit-frame-pointer -Os -I../dietlibc/include -CFLAGS=-pipe -fomit-frame-pointer -Os -I../dietlibc/include -CROSS=arm-linux- -LDFLAGS=../dietlibc/start.o ../dietlibc/dietlibc.a -lgcc-sf +DIET=diet +CC=gcc +CFLAGS=-pipe -fomit-frame-pointer -Os +CROSS= +#CROSS=arm-linux- +LDFLAGS=-s -minit: minit.o split.o openreadclose.o - gcc -g $(LDFLAGS) -o minit $^ +minit: minit.o split.o openreadclose.o fmt_ulong.o + $(DIET) $(CROSS)$(CC) $(LDFLAGS) -o minit $^ -msvc: msvc.o - gcc -g $(LDFLAGS) -o msvc msvc.o +msvc: msvc.o fmt_ulong.o buffer_1.o buffer_2.o buffer_puts.o \ +buffer_putsflush.o buffer_putulong.o buffer_put.o byte_copy.o \ +buffer_flush.o buffer_stubborn.o buffer_putflush.o + $(DIET) $(CROSS)$(CC) $(LDFLAGS) -o msvc $^ %.o: %.c - gcc $(CFLAGS) -c $^ - -diet: minit.c split.o openreadclose.o - $(CROSS)gcc -nostdlib -o minit $(CFLAGS) minit.c split.c openreadclose.c $(LDFLAGS) - $(CROSS)gcc -nostdlib -o msvc $(CFLAGS) msvc.c $(LDFLAGS) - $(CROSS)gcc -nostdlib -o pidfilehack $(CFLAGS) pidfilehack.c $(LDFLAGS) - strip -R .note -R .comment minit msvc pidfilehack - -diet2: minit.c split.o openreadclose.o - gcc -nostdlib -g -o minit -pipe minit.c split.c openreadclose.c ../dietlibc/start.o ../dietlibc/dietlibc.a + $(DIET) $(CROSS)$(CC) $(CFLAGS) -c $^ clean: rm -f *.o minit msvc pidfilehack @@ -30,12 +26,12 @@ test: test.c gcc -nostdlib -o $@ $^ -I../dietlibc/include ../dietlibc/start.o ../dietlibc/dietlibc.a pidfilehack: pidfilehack.c - gcc -nostdlib -pipe -g -o $@ $^ ../dietlibc/start.o ../dietlibc/dietlibc.a + $(DIET) $(CROSS)$(CC) $(CFLAGS) -o $@ $^ install: install minit msvc pidfilehack /usr/sbin test -d /etc/minit || mkdir /etc/minit - mkfifo -m 600 /etc/minit/in /etc/minit/out + -mkfifo -m 600 /etc/minit/in /etc/minit/out tar: clean cd .. && tar cvvf minit.tar.bz2 minit --use=bzip2 --exclude CVS diff --git a/buffer.h b/buffer.h @@ -0,0 +1,69 @@ +#ifndef BUFFER_H +#define BUFFER_H + +typedef struct buffer { + char *x; + unsigned int p; + unsigned int n; + unsigned int a; + int fd; + int (*op)(); +} buffer; + +#define BUFFER_INIT(op,fd,buf,len) { (buf), 0, (len), 0, (fd), (op) } +#define BUFFER_INIT_READ(op,fd,buf,len) { (buf), 0, 0, (len), (fd), (op) } +#define BUFFER_INSIZE 8192 +#define BUFFER_OUTSIZE 8192 + +extern void buffer_init(buffer* b,int (*op)(),int fd,char* y,unsigned int ylen); + +extern int buffer_flush(buffer* b); +extern int buffer_put(buffer* b,const char* x,unsigned int len); +extern int buffer_putalign(buffer* b,const char* x,unsigned int len); +extern int buffer_putflush(buffer* b,const char* x,unsigned int len); +extern int buffer_puts(buffer* b,const char* x); +extern int buffer_putsalign(buffer* b,const char* x); +extern int buffer_putsflush(buffer* b,const char* x); + +extern int buffer_putspace(buffer* b); + +#define buffer_PUTC(s,c) \ + ( ((s)->n != (s)->p) \ + ? ( (s)->x[(s)->p++] = (c), 0 ) \ + : buffer_put((s),&(c),1) \ + ) + +extern int buffer_get(buffer* b,char* x,unsigned int len); +extern int buffer_bget(buffer* b,char* x,unsigned int len); +extern int buffer_feed(buffer* b); +extern int buffer_getc(buffer* b,char* x); +extern int buffer_getn(buffer* b,char* x,unsigned int len); +extern int buffer_get_token(buffer* b,char* x,unsigned int len,const char* charset,unsigned int setlen); +#define buffer_getline(b,x,len) buffer_get_token((b),(x),(len),"\n",1) + +extern char *buffer_peek(buffer* b); +extern void buffer_seek(buffer* b,unsigned int len); + +#define buffer_PEEK(s) ( (s)->x + (s)->n ) +#define buffer_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) ) + +#define buffer_GETC(s,c) \ + ( ((s)->p > 0) \ + ? ( *(c) = (s)->x[(s)->n], buffer_SEEK((s),1), 1 ) \ + : buffer_get((s),(c),1) \ + ) + +extern int buffer_copy(buffer* out,buffer* in); + +extern int buffer_putulong(buffer *b,unsigned long l); +extern int buffer_put8long(buffer *b,unsigned long l); +extern int buffer_putxlong(buffer *b,unsigned long l); +extern int buffer_putlong(buffer *b,unsigned long l); + +extern buffer *buffer_0; +extern buffer *buffer_0small; +extern buffer *buffer_1; +extern buffer *buffer_1small; +extern buffer *buffer_2; + +#endif diff --git a/buffer_1.c b/buffer_1.c @@ -0,0 +1,7 @@ +#include <unistd.h> +#include "buffer.h" + +char buffer_1_space[BUFFER_INSIZE]; +static buffer it = BUFFER_INIT(write,1,buffer_1_space,sizeof buffer_1_space); +buffer *buffer_1 = &it; + diff --git a/buffer_2.c b/buffer_2.c @@ -0,0 +1,7 @@ +#include <unistd.h> +#include "buffer.h" + +char buffer_2_space[BUFFER_INSIZE]; +static buffer it = BUFFER_INIT(write,2,buffer_2_space,sizeof buffer_2_space); +buffer *buffer_2 = &it; + diff --git a/buffer_flush.c b/buffer_flush.c @@ -0,0 +1,10 @@ +#include "buffer.h" + +extern int buffer_stubborn(int (*op)(),int fd,const char* buf, unsigned int len); + +extern int buffer_flush(buffer* b) { + register int p; + if (!(p=b->p)) return 0; /* buffer already empty */ + b->p=0; + return buffer_stubborn(b->op,b->fd,b->x,p); +} diff --git a/buffer_put.c b/buffer_put.c @@ -0,0 +1,17 @@ +#include "byte.h" +#include "buffer.h" + +extern int buffer_stubborn(int (*op)(),int fd,const char* buf, unsigned int len); + +int buffer_put(buffer* b,const char* buf,unsigned int len) { + if (len>b->n-b->p) { /* doesn't fit */ + if (buffer_flush(b)==-1) return -1; + if (len>b->n) { + if (buffer_stubborn(b->op,b->fd,buf,len)<0) return -1; + return 0; + } + } + byte_copy(b->x+b->p, len, buf); + b->p+=len; + return 0; +} diff --git a/buffer_putflush.c b/buffer_putflush.c @@ -0,0 +1,7 @@ +#include "buffer.h" + +int buffer_putflush(buffer* b,const char* x,unsigned int len) { + if (buffer_put(b,x,len)<0) return -1; + if (buffer_flush(b)<0) return -1; + return 0; +} diff --git a/buffer_puts.c b/buffer_puts.c @@ -0,0 +1,5 @@ +#include "buffer.h" + +int buffer_puts(buffer* b,const char* x) { + return buffer_put(b,x,strlen(x)); +} diff --git a/buffer_putsflush.c b/buffer_putsflush.c @@ -0,0 +1,5 @@ +#include "buffer.h" + +int buffer_putsflush(buffer* b,const char* x) { + return buffer_putflush(b,x,strlen(x)); +} diff --git a/buffer_putulong.c b/buffer_putulong.c @@ -0,0 +1,8 @@ +#include "buffer.h" +#include "fmt.h" + +int buffer_putulong(buffer *b,unsigned long l) { + char buf[FMT_ULONG]; + return buffer_put(b,buf,fmt_ulong(buf,l)); +} + diff --git a/buffer_stubborn.c b/buffer_stubborn.c @@ -0,0 +1,15 @@ +#include <errno.h> +#include "buffer.h" + +int buffer_stubborn(int (*op)(),int fd,const char* buf, unsigned int len) { + int w; + while (len) { + if ((w=op(fd,buf,len))<0) { + if (errno == EINTR) continue; + return -1; + }; + buf+=w; + len-=w; + } + return 0; +} diff --git a/byte.h b/byte.h @@ -0,0 +1,41 @@ +#ifndef BYTE_H +#define BYTE_H + +#include <sys/cdefs.h> + +#ifndef __pure__ +#define __pure__ +#endif +#ifndef __THROW +#define __THROW +#endif + +/* byte_chr returns the smallest integer i between 0 and len-1 + * inclusive such that one[i] equals needle, or len it not found. */ +unsigned int byte_chr(const void* haystack, unsigned int len, char needle) __THROW __pure__; + +/* byte_rchr returns the largest integer i between 0 and len-1 inclusive + * such that one[i] equals needle, or len if not found. */ +unsigned int byte_rchr(const void* haystack,unsigned int len,char needle) __THROW __pure__; + +/* byte_copy copies in[0] to out[0], in[1] to out[1], ... and in[len-1] + * to out[len-1]. */ +void byte_copy(void* out, unsigned int len, const void* in) __THROW; + +/* byte_copyr copies in[len-1] to out[len-1], in[len-2] to out[len-2], + * ... and in[0] to out[0] */ +void byte_copyr(void* out, unsigned int len, const void* in) __THROW; + +/* byte_diff returns negative, 0, or positive, depending on whether the + * string a[0], a[1], ..., a[len-1] is lexicographically smaller + * than, equal to, or greater than the string b[0], b[1], ..., + * b[len-1]. When the strings are different, byte_diff does not read + * bytes past the first difference. */ +int byte_diff(const void* a, unsigned int len, const void* b) __THROW __pure__; + +/* byte_zero sets the bytes out[0], out[1], ..., out[len-1] to 0 */ +void byte_zero(void* out, unsigned len) __THROW; + +#define byte_equal(s,n,t) (!byte_diff((s),(n),(t))) + +#endif diff --git a/byte_copy.c b/byte_copy.c @@ -0,0 +1,30 @@ +#include "byte.h" + +/* byte_copy copies in[0] to out[0], in[1] to out[1], ... and in[len-1] + * to out[len-1]. */ +void byte_copy(void* out, unsigned int len, const void* in) { + register char* s=out; + register const char* t=in; + register const char* u=in+len; + if (len>127) { + if (sizeof(unsigned long)>4) { /* a good compiler should optimize this check away */ + for (;(unsigned long)t&7;) { + if (t==u) break; *s=*t; ++s; ++t; + } + } else { + for (;(unsigned long)t&3;) { + if (t==u) break; *s=*t; ++s; ++t; + } + } + while (t+sizeof(long)<=u) { + *(unsigned long*)s=*(unsigned long*)t; + s+=sizeof(long); t+=sizeof(long); + } + } + for (;;) { + if (t==u) break; *s=*t; ++s; ++t; + if (t==u) break; *s=*t; ++s; ++t; + if (t==u) break; *s=*t; ++s; ++t; + if (t==u) break; *s=*t; ++s; ++t; + } +} diff --git a/fmt.h b/fmt.h @@ -0,0 +1,71 @@ +#ifndef FMT_H +#define FMT_H + +#define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */ +#define FMT_8LONG 44 /* enough space to hold 2^128 - 1 in octal, plus \0 */ +#define FMT_XLONG 33 /* enough space to hold 2^128 - 1 in hexadecimal, plus \0 */ +#define FMT_LEN ((char *) 0) /* convenient abbreviation */ + +/* The formatting routines do not append \0! + * Use them like this: buf[fmt_ulong(buf,number)]=0; */ + +/* convert signed src integer -23 to ASCII '-','2','3', return length. + * If dest is not NULL, write result to dest */ +unsigned int fmt_long(char *dest,signed long src) ; + +/* convert unsigned src integer 23 to ASCII '2','3', return length. + * If dest is not NULL, write result to dest */ +unsigned int fmt_ulong(char *dest,unsigned long src) ; + +/* convert unsigned src integer 0x23 to ASCII '2','3', return length. + * If dest is not NULL, write result to dest */ +unsigned int fmt_xlong(char *dest,unsigned long src) ; + +/* convert unsigned src integer 023 to ASCII '2','3', return length. + * If dest is not NULL, write result to dest */ +unsigned int fmt_8long(char *dest,unsigned long src) ; + +#define fmt_uint(dest,src) fmt_ulong(dest,src) +#define fmt_int(dest,src) fmt_long(dest,src) +#define fmt_xint(dest,src) fmt_xlong(dest,src) +#define fmt_8int(dest,src) fmt_8long(dest,src) + +/* Like fmt_ulong, but prepend '0' while length is smaller than padto. + * Does not truncate! */ +unsigned int fmt_ulong0(char *,unsigned long src,unsigned int padto) ; + +#define fmt_uint0(buf,src,padto) fmt_ulong0(buf,src,padto) + +/* convert src double 1.7 to ASCII '1','.','7', return length. + * If dest is not NULL, write result to dest */ +unsigned int fmt_double(char *dest, double d,int max,int prec) ; + +/* if src is negative, write '-' and return 1. + * if src is positive, write '+' and return 1. + * otherwise return 0 */ +unsigned int fmt_plusminus(char *dest,int src) ; + +/* if src is negative, write '-' and return 1. + * otherwise return 0. */ +unsigned int fmt_minus(char *dest,int src) ; + +/* copy str to dest until \0 byte, return number of copied bytes. */ +unsigned int fmt_str(char *dest,const char *src) ; + +/* copy str to dest until \0 byte or limit bytes copied. + * return number of copied bytes. */ +unsigned int fmt_strn(char *dest,const char *src,unsigned int limit) ; + +/* "foo" -> " foo" + * write padlen-srclen spaces, if that is >= 0. Then copy srclen + * characters from src. Truncate only if total length is larger than + * maxlen. Return number of characters written. */ +unsigned int fmt_pad(char* dest,const char* src,unsigned int srclen,unsigned int padlen,unsigned int maxlen) ; + +/* "foo" -> "foo " + * append padlen-srclen spaces after dest, if that is >= 0. Truncate + * only if total length is larger than maxlen. Return number of + * characters written. */ +unsigned int fmt_fill(char* dest,unsigned int srclen,unsigned int padlen,unsigned int maxlen) ; + +#endif diff --git a/fmt_ulong.c b/fmt_ulong.c @@ -0,0 +1,11 @@ +#include "fmt.h" + +unsigned int fmt_ulong(char *dest,unsigned long i) { + register unsigned long len,tmp,len2; + /* first count the number of bytes needed */ + for (len=1, tmp=i; tmp>9; ++len) tmp/=10; + if (dest) + for (tmp=i, dest+=len, len2=len+1; --len2; tmp/=10) + *--dest = (tmp%10)+'0'; + return len; +} diff --git a/minit.c b/minit.c @@ -12,6 +12,7 @@ #include <sys/wait.h> #include <stdio.h> #include <linux/kd.h> +#include "fmt.h" #define MINITROOT "/etc/minit" @@ -30,6 +31,8 @@ static struct process { char respawn; char circular; time_t startedat; + int __stdin,__stdout; + int logservice; } *root; static int maxprocess=-1; @@ -80,7 +83,7 @@ int addprocess(struct process *p) { int loadservice(char *service) { struct process tmp; int fd; - if (*service==0) return 0; + if (*service==0) return -1; fd=findservice(service); if (fd>=0) return fd; if (chdir(MINITROOT) || chdir(service)) return -1; @@ -94,6 +97,19 @@ int loadservice(char *service) { tmp.respawn=0; tmp.startedat=0; tmp.circular=0; + tmp.__stdin=0; tmp.__stdout=1; + { + char *logservice=alloca(strlen(service)+5); + strcpy(logservice,service); + strcat(logservice,"/log"); + tmp.logservice=loadservice(logservice); + if (tmp.logservice>=0) { + int pipefd[2]; + if (pipe(pipefd)) return -1; + root[tmp.logservice].__stdin=pipefd[0]; + tmp.__stdout=pipefd[1]; + } + } addprocess(&tmp); } @@ -105,7 +121,7 @@ int isup(int service) { } /* called from inside the service directory, return the PID or 0 on error */ -pid_t forkandexec(int pause) { +pid_t forkandexec(int pause,int __stdin,int __stdout) { char **argv=0; int count=0; pid_t p; @@ -148,6 +164,8 @@ again: argv[0]++; else argv[0]=argv0; + if (__stdin != 0) dup2(__stdin,0); + if (__stdout != 1) dup2(__stdout,1); execve("run",argv,environ); _exit(0); abort: @@ -175,7 +193,7 @@ int startnodep(int service,int pause) { /* step 2: fork and exec service, put PID in data structure */ if (chdir(MINITROOT) || chdir(root[service].name)) return -1; root[service].startedat=time(0); - root[service].pid=forkandexec(pause); + root[service].pid=forkandexec(pause,root[service].__stdin,root[service].__stdout); return root[service].pid; } @@ -190,10 +208,12 @@ int startservice(int service,int pause) { write(1,root[service].name,strlen(root[service].name)); write(1,"\n",1); #endif - if (chdir(MINITROOT) || chdir(root[service].name)) return -1; if (root[service].circular) return 0; root[service].circular=1; + if (root[service].logservice>=0) + startservice(root[service].logservice,pause); + if (chdir(MINITROOT) || chdir(root[service].name)) return -1; if ((dir=open(".",O_RDONLY))>=0) { if (!openreadclose("depends",&s,&len)) { char **argv; @@ -351,8 +371,7 @@ error: else { switch (buf[0]) { case 'p': - i=snprintf(buf,10,"%d",root[idx].pid); - write(outfd,buf,strlen(buf)); + write(outfd,buf,fmt_ulong(buf,root[idx].pid)); break; case 'r': root[idx].respawn=0; @@ -381,8 +400,7 @@ ok: write(outfd,"1",1); break; case 'u': - snprintf(buf,10,"%d",time(0)-root[idx].startedat); - write(outfd,buf,strlen(buf)); + write(outfd,buf,fmt_ulong(buf,time(0)-root[idx].startedat)); } } } diff --git a/msvc.c b/msvc.c @@ -3,23 +3,13 @@ #include <signal.h> #include <stdio.h> #include <string.h> +#include "fmt.h" +#include "buffer.h" static int infd,outfd; static char buf[1500]; -unsigned int fmt_ulong(register char *s,register unsigned long u) -{ - register unsigned int len; register unsigned long q; - len = 1; q = u; - while (q > 9) { ++len; q /= 10; } - if (s) { - s += len; - do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */ - } - return len; -} - /* return PID, 0 if error */ pid_t __readpid(char *service) { int len; @@ -80,7 +70,8 @@ unsigned long uptime(char *service) { main(int argc,char *argv[]) { int len; if (argc<2) { - puts("usage: msvc -[uodpchaitko] service\n" + buffer_putsflush(buffer_1, + "usage: msvc -[uodpchaitko] service\n" " msvc -Ppid service\n" " -u up; start service with respawn\n" " -o once; start service without respawn\n" @@ -91,32 +82,32 @@ main(int argc,char *argv[]) { " -a alarm; send SIGALRM\n" " -i intr; send SIGINT\n" " -t terminate; send SIGTERM\n" - " -k kill; send SIGKILL\n"); + " -k kill; send SIGKILL\n\n"); + return 0; } infd=open("/etc/minit/in",O_WRONLY); outfd=open("/etc/minit/out",O_RDONLY); if (infd>=0) { while (lockf(infd,F_LOCK,1)) { - puts("could not aquire lock!"); + buffer_putsflush(buffer_2,"could not aquire lock!\n"); sleep(1); } if (argc==2) { pid_t pid=__readpid(argv[1]); if (buf[0]!='0') { unsigned long len; - write(1,argv[1],strlen(argv[1])); - write(1,": ",2); - if (pid==0) write(1,"down ",5); - else if (pid==1) write(1,"finished ",9); + buffer_puts(buffer_1,argv[1]); + buffer_puts(buffer_1,": "); + if (pid==0) buffer_puts(buffer_1,"down "); + else if (pid==1) buffer_puts(buffer_1,"finished "); else { - write(1,"up (pid ",8); - snprintf(buf,30,"%d) ",pid); - write(1,buf,strlen(buf)); + buffer_puts(buffer_1,"up (pid "); + buffer_putulong(buffer_1,pid); + buffer_puts(buffer_1,") "); } len=uptime(argv[1]); - snprintf(buf,30,"%d seconds\n",len); - write(1,buf,strlen(buf)); -/* puts(buf); */ + buffer_putulong(buffer_1,len); + buffer_putsflush(buffer_1," seconds\n"); } } else { int i; @@ -132,27 +123,36 @@ main(int argc,char *argv[]) { case 't': sig=SIGTERM; goto dokill; break; case 'k': sig=SIGKILL; goto dokill; break; case 'o': /* TODO: start but don't restart */ - if (startservice(argv[2]) || respawn(argv[2],0)) - fprintf(stderr,"Could not start %s\n",argv[2]); + if (startservice(argv[2]) || respawn(argv[2],0)) { + buffer_puts(buffer_2,"Could not start "); + buffer_puts(buffer_2,argv[2]); + buffer_putsflush(buffer_2,"\n"); + } break; case 'd': /* TODO: down */ pid=__readpid(argv[2]); if (pid==0) { - puts("service not found"); + buffer_putsflush(buffer_2,"service not found"); return 1; } else if (pid==1) return 0; if (respawn(argv[2],0) || kill(pid,SIGTERM)); break; case 'u': /* TODO: up */ - if (startservice(argv[2]) || respawn(argv[2],1)) - fprintf(stderr,"Could not start %s\n",argv[2]); + if (startservice(argv[2]) || respawn(argv[2],1)) { + buffer_puts(buffer_2,"Could not start "); + buffer_puts(buffer_2,argv[2]); + buffer_putsflush(buffer_2,"\n"); + } break; case 'P': pid=atoi(argv[1]+2); if (pid>1) - if (setpid(argv[2],pid)) - fprintf(stderr,"Could not set pid of service %s\n",argv[2]); + if (setpid(argv[2],pid)) { + buffer_puts(buffer_2,"Could not set pid of service "); + buffer_puts(buffer_2,argv[2]); + buffer_putsflush(buffer_2,"\n"); + } } } return 0; @@ -160,7 +160,9 @@ dokill: for (i=2; i<=argc; i++) { pid=__readpid(argv[2]); if (kill(pid,sig)) { - fprintf(stderr,"Could not send signal to PID %d\n",pid); + buffer_puts(buffer_2,"Could not send signal to PID "); + buffer_putulong(buffer_2,pid); + buffer_putsflush(buffer_2,"\n"); } } }