# Eventually support separate compilation, but we don't have it yet...
OBJROOT = $(SRCROOT)
+# Kernel trees (source and obj) - can potentially be different
+KRNLSRC = $(SRCROOT)/linux
+KRNLOBJ = $(SRCROOT)/linux
+
ARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
CROSS =
CC = $(CROSS)gcc
LD = $(CROSS)ld
KLIBSRC = $(SRCROOT)/klibc
KLIBOBJ = $(OBJROOT)/klibc
-REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include \
- -D__KLIBC__ -DBITSIZE=$(BITSIZE) \
- -I$(SRCROOT)/include/arch/$(ARCH) \
+INCLUDE = -I$(SRCROOT)/include/arch/$(ARCH) \
-I$(SRCROOT)/include/bits$(BITSIZE) \
-I$(SRCROOT)/include \
- -I$(SRCROOT)/linux/include -I$(SRCROOT)/linux/include2
-
+ -I$(KRNLOBJ)/include -I$(KRNLOBJ)/include2 -I$(KRNLSRC)/include
+REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include \
+ -D__KLIBC__ -DBITSIZE=$(BITSIZE) \
+ $(INCLUDE)
LDFLAGS =
AR = $(CROSS)ar
RANLIB = $(CROSS)ranlib
VERSION := $(shell cat version)
-SUBDIRS = klibc
+SUBDIRS = klibc ash ipconfig nfsmount utils kinit gzip
all:
--- /dev/null
+/*
+ * arch/m32r/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long __r8;
+ unsigned long __r9;
+ unsigned long __r10;
+ unsigned long __r11;
+ unsigned long __r12;
+ unsigned long __r13;
+ unsigned long __r14;
+ unsigned long __r15;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _KLIBC_ARCHSETJMP_H */
--- /dev/null
+/*
+ * arch/m32r/include/klibc/archsignal.h
+ *
+ * Architecture-specific signal definitions
+ *
+ */
+
+#ifndef _KLIBC_ARCHSIGNAL_H
+#define _KLIBC_ARCHSIGNAL_H
+
+/* No special stuff for this architecture */
+
+#endif
--- /dev/null
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#define _STATBUF_ST_NSEC
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat {
+ unsigned long long st_dev;
+ unsigned char __pad0[4];
+
+ unsigned long __st_ino;
+
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+ unsigned long long st_rdev;
+ unsigned char __pad3[4];
+
+ long long st_size;
+ unsigned long st_blksize;
+
+ unsigned long st_blocks; /* Number 512-byte blocks allocated. */
+ unsigned long __pad4; /* future possible st_blocks high bits */
+
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+
+ unsigned long long st_ino;
+};
+
+#endif
--- /dev/null
+/*
+ * arch/m32r/include/klibc/archsys.h
+ *
+ * Architecture-specific syscall definitions
+ */
+
+#ifndef _KLIBC_ARCHSYS_H
+#define _KLIBC_ARCHSYS_H
+
+/* No special syscall definitions for this architecture */
+
+#endif /* _KLIBC_ARCHSYS_H */
__extern pid_t __clone2(int, void *, void *);
static __inline__ pid_t __clone(int _f, void *_sp)
{
- return __clone2(_f, _sp, 0);
+ /* If this is used with _sp != 0 it will have the effect of the sp
+ and rsp growing away from a single point in opposite directions. */
+ return __clone2(_f, _sp, _sp);
}
#else
__extern pid_t __clone(int, void *);
}
extern __inline__ size_t
-fwrite(void *__p, size_t __s, size_t __n, FILE *__f)
+fwrite(const void *__p, size_t __s, size_t __n, FILE *__f)
{
return _fwrite(__p, __s*__n, __f)/__s;
}
__extern int vsprintf(char *, const char *, va_list);
__extern int snprintf(char *, size_t n, const char *, ...);
__extern int vsnprintf(char *, size_t n, const char *, va_list);
+__extern int asprintf(char **, const char *, ...);
+__extern int vasprintf(char **, const char *, va_list);
/* No buffering, so no flushing needed */
extern __inline__ int
static __inline__ int abs(int __n) {
return (__n < 0) ? -__n : __n;
}
+__extern int system(const char * string);
__extern int atexit(void (*)(void));
__extern int on_exit(void (*)(int, void *), void *);
__extern int atoi(const char *);
#define _SYS_MOUNT_H
#include <klibc/extern.h>
+#include <sys/ioctl.h>
/*
* These are the fs-independent mount-flags: up to 32 flags are supported
#define MS_SYNCHRONOUS 16 /* Writes are synced at once */
#define MS_REMOUNT 32 /* Alter flags of a mounted FS */
#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
-#define MS_DIRSYNC 128 /* Directory modifications are synchronous */
+#define MS_DIRSYNC 128 /* Directory modifications are synchronous */
#define MS_NOATIME 1024 /* Do not update access times. */
#define MS_NODIRATIME 2048 /* Do not update directory access times */
#define MS_BIND 4096
-#define MS_MOVE 8192
+#define MS_MOVE 8192
#define MS_REC 16384
#define MS_VERBOSE 32768
+#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */
+#define MS_ONE_SECOND (1<<17) /* fs has 1 sec a/m/ctime resolution */
+#define MS_ACTIVE (1<<30)
#define MS_NOUSER (1<<31)
/*
/*
* umount2() flags
*/
-#define MNT_FORCE 1
+#define MNT_FORCE 1 /* Forcibly unmount */
+#define MNT_DETACH 2 /* Detach from tree only */
+#define MNT_EXPIRE 4 /* Mark for expiry */
+
+/*
+ * Block device ioctls
+ */
+#define BLKROSET _IO(0x12, 93) /* Set device read-only (0 = read-write). */
+#define BLKROGET _IO(0x12, 94) /* Get read-only status (0 = read_write). */
+#define BLKRRPART _IO(0x12, 95) /* Re-read partition table. */
+#define BLKGETSIZE _IO(0x12, 96) /* Return device size. */
+#define BLKFLSBUF _IO(0x12, 97) /* Flush buffer cache. */
+#define BLKRASET _IO(0x12, 98) /* Set read ahead for block device. */
+#define BLKRAGET _IO(0x12, 99) /* Get current read ahead setting. */
/*
* Prototypes
#define LOG_FACMASK 01770
#define LOG_FAC(x) (((x) >> 3) & (LOG_FACMASK >> 3))
+/* openlog() flags; only LOG_PID and LOG_PERROR supported */
+#define LOG_PID 0x01 /* include pid with message */
+#define LOG_CONS 0x02 /* write to console on logger error */
+#define LOG_ODELAY 0x04 /* delay connection until syslog() */
+#define LOG_NDELAY 0x08 /* open connection immediately */
+#define LOG_NOWAIT 0x10 /* wait for child processes (unused on linux) */
+#define LOG_PERROR 0x20 /* additional logging to stderr */
+
+
__extern void openlog(const char *, int, int);
__extern void syslog(int, const char *, ...);
__extern void vsyslog(int, const char *, va_list);
Summary: A minimal libc subset for use with initramfs.
Name: klibc
-Version: 0.181
+Version: 0.194
Release: 1
License: BSD/GPL
Group: Development/Libraries
REQFLAGS += -DWITH_ERRLIST
endif
-CFLAGS = -Wp,-MD,$(dir $*).$(notdir $*).d $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS)
+CFLAGS = -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS)
SOFLAGS = -fPIC
strcasecmp.o strncasecmp.o strndup.o strerror.o \
strcat.o strchr.o strcmp.o strcpy.o strdup.o strlen.o strnlen.o \
strncat.o strlcpy.o strlcat.o \
- strstr.o strncmp.o strncpy.o strrchr.o strspn.o \
- strsep.o strtok.o \
+ strstr.o strncmp.o strncpy.o strrchr.o \
+ strxspn.o strspn.o strcspn.o strpbrk.o strsep.o strtok.o \
gethostname.o getdomainname.o getcwd.o \
seteuid.o setegid.o \
getenv.o setenv.o putenv.o __put_env.o unsetenv.o \
INTERP_O = interp.o
-all: $(CRT0) $(LIB) $(SOLIB) klibc.so
+all: tests $(CRT0) $(LIB) $(SOLIB) klibc.so
# Add any architecture-specific rules
include arch/$(ARCH)/Makefile.inc
cp arch/$(ARCH)/crt0.o .
errlist.c:
- $(PERL) makeerrlist.pl -errlist > $@ || rm -f $@
+ $(PERL) makeerrlist.pl -q $(INCLUDE) -errlist > $@ || rm -f $@
# We pass -ansi to keep cpp from define e.g. "i386" as well as "__i386__"
SYSCALLS.i: SYSCALLS.def
$(CC) $(CFLAGS) -D__ASSEMBLY__ -ansi -x assembler-with-cpp -E -o $@ $<
-syscalls.nrs: ../include/sys/syscall.h ../include/arch/$(ARCH)/klibc/archsys.h ../linux/include/asm/unistd.h
- $(CC) $(CFLAGS) -Wp,-dM -x c -E -o $@ ../include/sys/syscall.h
+syscalls.nrs: ../include/sys/syscall.h
+ $(CC) $(CFLAGS) -Wp,-dM -x c -E -o $@ $<
syscalls.dir: SYSCALLS.i syscalls.pl arch/$(ARCH)/sysstub.ph syscommon.h syscalls.nrs
rm -rf syscalls
arm-thumb: Untested
arm26: Not yet ported
arm: Working
- cris: Untested
+ cris: Working
h8300: Not yet ported
i386: Working
ia64: Working
+ m32r: Untested
m68k: Not yet ported
mips64: Not yet ported
mips: Working
s390: Working static, shared untested
s390x: Working
sh: Untested
- sparc64: sigaction() fails in ash for unknown reason
+ sparc64: Untested
sparc: Working
v850: Not yet ported
x86-64: Working
;
; Process-related syscalls
;
+<!i386,x86_64> void _exit,exit::_exit(int)
<?!ia64> pid_t clone::__clone(unsigned long, void *)
<?ia64> pid_t clone::__clone2(unsigned long, void *, void *)
<?!sparc> pid_t fork()
int mount(const char *, const char *, const char *, unsigned long, const void *)
<!alpha,ia64> int umount2(const char *, int)
<alpha,ia64> int umount::umount2(const char *, int)
-<!m68k> int pivot_root(const char *, const char *)
+<?> int pivot_root(const char *, const char *)
int sync()
#ifdef __NR_statfs64
int statfs64::__statfs64(const char *, size_t, struct statfs *)
int chroot(const char *)
int symlink(const char *, const char *)
int readlink(const char *, char *, size_t)
-int stat64,stat::stat(const char *, struct stat *)
-int lstat64,lstat::lstat(const char *, struct stat *)
-int fstat64,fstat::fstat(int, struct stat *)
+<!ppc64> int stat64,stat::stat(const char *, struct stat *)
+<!ppc64> int lstat64,lstat::lstat(const char *, struct stat *)
+<!ppc64> int fstat64,fstat::fstat(int, struct stat *)
+<ppc64> int stat::stat(const char *, struct stat *)
+<ppc64> int lstat::lstat(const char *, struct stat *)
+<ppc64> int fstat::fstat(int, struct stat *)
int getdents64,getdents::getdents(unsigned int, struct dirent *, unsigned int)
int chown32,chown::chown(const char *, uid_t, gid_t)
int fchown32,fchown::fchown(int, uid_t, gid_t)
int dup(int)
int dup2(int, int)
<i386> int fcntl64@varadic::fcntl(int, int, unsigned long)
-<!i386> int fcntl64,fcntl::fcntl(int, int, unsigned long)
+<ppc64> int fcntl(int, int, unsigned long)
+<!i386,ppc64> int fcntl64,fcntl::fcntl(int, int, unsigned long)
int ioctl(int, int, void *)
int flock(int, int)
int _newselect,select::select(int, fd_set *, fd_set *, fd_set *, struct timeval *)
* pipe.c
*/
-#include "syscommon.h"
+#include <sys/syscall.h>
#include <klibc/archsys.h>
#define ASM_CLOBBERS ,"out2", "out3", "out4", "out5", "out6", "out7", \
--- /dev/null
+# -*- makefile -*-
+#
+# arch/m32r/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 32
+
+# Extra linkflags when building the shared version of the library
+# This address needs to be reachable using normal inter-module
+# calls, and work on the memory models for this architecture
+# 224 MB - normal binaries start at 0 (?)
+# (lib?)gcc on cris seems to insist on producing .init and .fini sections
+SHAREDFLAGS = --section-start .init=0x0e000100
--- /dev/null
+# -*- makefile -*-
+#
+# arch/m32r/Makefile.inc
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+ARCHOBJS = \
+ arch/$(ARCH)/setjmp.o \
+ arch/$(ARCH)/syscall.o \
+ libgcc/__divdi3.o \
+ libgcc/__moddi3.o \
+ libgcc/__udivdi3.o \
+ libgcc/__umoddi3.o \
+ libgcc/__udivmoddi4.o
+
+archclean:
--- /dev/null
+#
+# arch/m32r/crt0.S
+#
+# Does arch-specific initialization and invokes __libc_init
+# with the appropriate arguments.
+#
+# See __static_init.c or __shared_init.c for the expected
+# arguments.
+#
+
+ .text
+ .balign 4
+ .type _start,@function
+ .globl _start
+_start:
+ /* Save the address of the ELF argument array */
+ mv r0, sp
+
+ /* atexit() function (assume null) */
+ xor r1, r1
+
+ bl __libc_init
+
+ .size _start, .-_start
+
--- /dev/null
+#
+# arch/m32r/setjmp.S
+#
+# setjmp/longjmp for the M32R architecture
+#
+
+#
+# The jmp_buf is assumed to contain the following, in order:
+# r8-r15
+#
+# Note that r14 is the return address register and
+# r15 is the stack pointer.
+#
+
+ .text
+ .balign 4
+ .globl setjmp
+ .type setjmp, @function
+setjmp:
+ st r8, @r0
+ st r9, @+r0
+ st r10, @+r0
+ st r11, @+r0
+ st r12, @+r0
+ st r13, @+r0
+ st r14, @+r0
+ st r15, @+r0
+ xor r0, r0
+ jmp r14
+ .size setjmp,.-setjmp
+
+ .text
+ .balign 4
+ .globl longjmp
+ .type longjmp, @function
+longjmp:
+ ld r8, @r0+
+ ld r9, @r0+
+ ld r10, @r0+
+ ld r11, @r0+
+ ld r12, @r0+
+ ld r13, @r0+
+ ld r14, @r0+
+ ld r15, @r0
+ mv r0, r1
+ jmp r14
+ .size longjmp,.-longjmp
--- /dev/null
+/*
+ * arch/m32r/syscall.S
+ *
+ * r7 contains the syscall number (set by stub);
+ * r0..r3 contains arguments 0-3 per standard calling convention;
+ * r4..r5 contains arguments 4-5, but we have to get those from
+ * the stack.
+ */
+
+ .section ".text","ax"
+ .balign 4
+ .globl __syscall_common
+ .type __syscall_common,@function
+__syscall_common:
+ ld r4,@sp
+ ld r5,@(4,sp)
+ trap #2
+ cmpi r0, #-4096
+ bnc 1f
+ jmp r14
+1:
+ seth r2,#high(errno)
+ or3 r2,r2,#low(errno)
+ neg r1,r0
+ st r1,@r7
+ ldi r0,#-1
+ jmp r14
+
+ .size __syscall_common,.-__syscall_common
--- /dev/null
+# -*- perl -*-
+#
+# arch/m32r/sysstub.ph
+#
+# Script to generate system call stubs
+#
+
+sub make_sysstub($$$$@) {
+ my($fname, $type, $sname, $stype, @args) = @_;
+
+ open(OUT, '>', "syscalls/${fname}.S");
+ print OUT "#include <asm/unistd.h>\n";
+ print OUT "\n";
+ print OUT "\t.text\n";
+ print OUT "\t.type\t${fname},\@function\n";
+ print OUT "\t.globl\t${fname}\n";
+ print OUT "\t.balign\t4\n";
+ print OUT "${fname}:\n";
+ print OUT "\tldi\tr7,#__NR_${sname}\n";
+ print OUT "\tbra\t__syscall_common\n";
+ print OUT "\t.size ${fname},.-${fname}\n";
+ close(OUT);
+}
+
+1;
blr /* return */
.size longjmp,.-longjmp
-
\ No newline at end of file
+
# accordingly.
#
-OPTFLAGS = -Os -fomit-frame-pointer
-BITSIZE = 64
+ARCHREQFLAGS = -m64 -mcall-aixdesc
+OPTFLAGS = -Os -fomit-frame-pointer
+BITSIZE = 64
+LDFLAGS = -m elf64ppc
# Extra linkflags when building the shared version of the library
# This address needs to be reachable using normal inter-module
$(LD) $(LDFLAGS) -r -o $@ interp1.o klibc.got
klibc.got: $(SOHASH)
- $(OBJCOPY) -j.got $< $@
+ $(OBJCOPY) -j .got $< $@
archclean:
rm -f klibc.got
print OUT "\t.align 3\n";
print OUT "${fname}:\n";
print OUT "\t.quad .${fname},.TOC.\@tocbase,0\n";
- print OUT "\t.size ${fname},24\n";
print OUT "\t.text\n";
print OUT "\t.type .${fname},\@function\n";
print OUT "\t.globl .${fname}\n";
print OUT ".${fname}:\n";
print OUT "\tli 0,__NR_${sname}\n";
print OUT "\tsc\n";
- print OUT "\tmfcr 0\n";
- print OUT "\trldicl. 9,0,36,63\n";
- print OUT "\tbeqlr- 0\n";
+ print OUT "\tbnslr\n";
print OUT "\tb .__syscall_error\n";
print OUT "\t.size .${fname},.-.${fname}\n";
close(OUT);
BITSIZE = 64
LDFLAGS = -m elf_x86_64
+# Extra linkflags when building the shared version of the library
+# This address needs to be reachable using normal inter-module
+# calls, and work on the memory models for this architecture
+# 2 MB - normal binaries start at 4 MB
+SHAREDFLAGS = -Ttext 0x00200200
+
va_start(ap, format);
va_copy(ap1, ap);
- bytes = vsnprintf(NULL, 0, format, ap1);
+ bytes = vsnprintf(NULL, 0, format, ap1) + 1;
va_end(ap1);
- *bufp = p = malloc(bytes+1);
+ *bufp = p = malloc(bytes);
if ( !p )
return -1;
struct atexit *next;
};
-extern struct atexit *__atexit_list;
-
#endif /* ATEXIT_H */
/*
* exit.c
*
- * Note: all programs need exit(), since it's invoked from
- * crt0.o. Therefore there is no point in breaking apart
- * exit() and _exit().
+ * Implement exit()
*/
#include <stdlib.h>
#if !defined(__i386__) && !defined(__x86_64__)
-#define __NR___exit __NR_exit
-
-/* Syscalls can't return void... */
-static inline _syscall1(int,__exit,int,rv);
-
/* This allows atexit/on_exit to install a hook */
__noreturn (*__exit_handler)(int) = _exit;
__exit_handler(rv);
}
-__noreturn _exit(int rv)
-{
- __exit(rv);
- for(;;);
-}
-
#endif
#include <sys/syscall.h>
#include <signal.h>
#include <unistd.h>
+#include <sched.h>
#ifndef __NR_fork
-extern pid_t __clone(unsigned long flags, void * newsp);
-
pid_t fork(void)
{
return __clone(SIGCHLD, 0);
uint64_t x;
/* The xsubi[] array is littleendian by spec */
- x = (uint64_t)xsubi[0] +
- ((uint64_t)xsubi[1] << 16) +
- ((uint64_t)xsubi[2] << 32);
+ x = (uint64_t)(uint16_t)xsubi[0] +
+ ((uint64_t)(uint16_t)xsubi[1] << 16) +
+ ((uint64_t)(uint16_t)xsubi[2] << 32);
x = (0x5deece66dULL * x) + 0xb;
- xsubi[0] = (unsigned short)x;
- xsubi[1] = (unsigned short)(x >> 16);
- xsubi[2] = (unsigned short)(x >> 32);
+ xsubi[0] = (unsigned short)(uint16_t)x;
+ xsubi[1] = (unsigned short)(uint16_t)(x >> 16);
+ xsubi[2] = (unsigned short)(uint16_t)(x >> 32);
return (long)(int32_t)(x >> 16);
}
%errors = ();
%errmsg = ();
$maxerr = -1;
-$rootdir = '../linux/include/'; # Must have trailing /
+@includelist = (); # Include directories
sub parse_file($) {
my($file) = @_;
my($fh) = new FileHandle;
my($line, $error, $msg);
my($kernelonly) = 0;
-
- $file = $rootdir.$file;
+ my($root);
print STDERR "opening $file\n" unless ( $quiet );
- if ( !($fh->open("< ".$file)) ) {
- die "$0: cannot open $file\n";
+ $ok = 0;
+ foreach $root ( @includelist ) {
+ if ( $fh->open($root.'//'.$file, '<') ) {
+ $ok = 1;
+ last;
+ }
+ }
+
+ if ( ! $ok ) {
+ die "$0: Cannot find file $file\n";
}
while ( defined($line = <$fh>) ) {
$quiet = 1;
} elsif ( $arg =~ /^-(errlist|errnos|maxerr)$/ ) {
$type = $arg;
+ } elsif ( $arg =~ '^\-I' ) {
+ push(@includelist, "$'");
} else {
- die "$0: Unknown option: $arg\n";
+ die "$0: Unknown option: $arg\n";
}
}
}
__current_brk = new_brk;
- return end;
+ return start;
}
--- /dev/null
+/*
+ * strcspn
+ */
+
+#include "strxspn.h"
+
+size_t
+strcspn(const char *s, const char *reject)
+{
+ return __strxspn(s, reject, 1);
+}
--- /dev/null
+/*
+ * strpbrk
+ */
+
+#include "strxspn.h"
+
+char *
+strpbrk(const char *s, const char *accept)
+{
+ const char *ss = s+__strxspn(s, accept, 1);
+
+ return *ss ? (char *)ss : NULL;
+}
+
/*
- * strspn, strcspn
+ * strspn
*/
-#include <string.h>
-#include <stddef.h>
-#include <inttypes.h>
-#include <limits.h>
-
-#ifndef LONG_BIT
-#define LONG_BIT (CHAR_BIT*sizeof(long))
-#endif
-
-static inline void
-set_bit(unsigned long *bitmap, unsigned int bit)
-{
- bitmap[bit/LONG_BIT] |= 1UL << (bit%LONG_BIT);
-}
-
-static inline int
-test_bit(unsigned long *bitmap, unsigned int bit)
-{
- return (int)(bitmap[bit/LONG_BIT] >> (bit%LONG_BIT)) & 1;
-}
-
-static size_t
-strxspn(const char *s, const char *map, int parity)
-{
- unsigned long matchmap[((1 << CHAR_BIT)+LONG_BIT-1)/LONG_BIT];
- size_t n = 0;
-
- /* Create bitmap */
- memset(matchmap, 0, sizeof matchmap);
- while ( *map )
- set_bit(matchmap, (unsigned char) *map++);
-
- /* Make sure the null character never matches */
- if ( parity )
- set_bit(matchmap, 0);
-
- /* Calculate span length */
- while ( test_bit(matchmap, (unsigned char) *s++)^parity )
- n++;
-
- return n;
-}
+#include "strxspn.h"
size_t
strspn(const char *s, const char *accept)
{
- return strxspn(s, accept, 0);
+ return __strxspn(s, accept, 0);
}
-
-size_t
-strcspn(const char *s, const char *reject)
-{
- return strxspn(s, reject, 1);
-}
-
-char *
-strpbrk(const char *s, const char *accept)
-{
- const char *ss = s+strxspn(s, accept, 1);
-
- return *ss ? (char *)ss : NULL;
-}
-
--- /dev/null
+/*
+ * strpbrk
+ */
+
+#include <string.h>
+#include <stddef.h>
+#include <inttypes.h>
+#include <limits.h>
+#include "strxspn.h"
+
+size_t
+__strxspn(const char *s, const char *map, int parity)
+{
+ char matchmap[UCHAR_MAX+1];
+ size_t n = 0;
+
+ /* Create bitmap */
+ memset(matchmap, 0, sizeof matchmap);
+ while ( *map )
+ matchmap[(unsigned char) *map++] = 1;
+
+ /* Make sure the null character never matches */
+ matchmap[0] = parity;
+
+ /* Calculate span length */
+ while ( matchmap[(unsigned char) *s++] ^ parity )
+ n++;
+
+ return n;
+}
--- /dev/null
+/*
+ * strxspn.h
+ */
+
+#ifndef STRXSPN_H
+#define STRXSPN_H
+
+#include <stddef.h>
+
+extern size_t
+__strxspn(const char *s, const char *map, int parity);
+
+#endif
#define LOGDEV "/dev/kmsg"
/* Max length of ID string */
-#define MAXID 31 /* MAXID+6 must be < BUFLEN */
+#define MAXID 31 /* MAXID+5 must be < BUFLEN */
int __syslog_fd = -1;
static char id[MAXID+1];
+static int syslog_flags = 0;
void openlog(const char *ident, int option, int facility)
{
fcntl(fd, F_SETFD, (long)FD_CLOEXEC);
}
+ syslog_flags = option;
+
strncpy(id, ident?ident:"", MAXID);
- id[MAXID] = '\0'; /* Make sure it's null-terminated */
}
void vsyslog(int prio, const char *format, va_list ap)
buf[2] = '>';
len = 3;
- if ( *id )
+ if ( syslog_flags & LOG_PID )
+ len += sprintf(buf+3, "%s[%u]: ", id, getpid());
+ else if ( *id )
len += sprintf(buf+3, "%s: ", id);
len += vsnprintf(buf+len, BUFLEN-len, format, ap);
fd = 2; /* Failed to open log, write to stderr */
write(fd, buf, len);
+
+ if ( syslog_flags & LOG_PERROR )
+ _fwrite(buf+3, len-3, stderr);
}
void syslog(int prio, const char *format, ...)
va_copy(ap1, ap);
- bytes = vsnprintf(NULL, 0, format, ap1);
+ bytes = vsnprintf(NULL, 0, format, ap1) + 1;
va_end(ap1);
- *bufp = p = malloc(bytes+1);
+ *bufp = p = malloc(bytes);
if ( !p )
return -1;