newlib: update

git-svn-id: svn://kolibrios.org@3065 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2012-11-26 10:18:42 +00:00
parent 16ef653fe4
commit a1006b9202
51 changed files with 1196 additions and 542 deletions

View File

@ -2,250 +2,256 @@
CC = gcc CC = gcc
CFLAGS = -c -O2 -fomit-frame-pointer CFLAGS = -c -O2 -fomit-frame-pointer
LDFLAGS = -nostdlib -shared -s -T libcdll.lds --out-implib libcimp.a --image-base 0 LDFLAGS = -nostdlib -shared -s -T libcdll.lds --out-implib libcimp.a --image-base 0
LIBC_TOPDIR = . LIBC_TOPDIR = .
LIBC_INCLUDES = $(LIBC_TOPDIR)/include LIBC_INCLUDES = $(LIBC_TOPDIR)/include
NAME:= libc NAME:= libc
DEFINES:= DEFINES:=
INCLUDES:= -I $(LIBC_INCLUDES) INCLUDES:= -I $(LIBC_INCLUDES)
AMZ_SRCS:= \ AMZ_SRCS:= \
crt/crt_amz.S \ crt/crt_amz.S \
crt/chkstk.S \ crt/chkstk.S \
crt/exit.S \ crt/exit.S \
crt/pseudo-reloc.c \ crt/pseudo-reloc.c \
crt/dllstart.c \ crt/dllstart.c \
crt/setjmp.S crt/setjmp.S
STATIC_SRCS:= \
crt/start.S \
crt/crt1.c \
crt/chkstk.S \
crt/exit.S \
crt/setjmp.S
DLL_SRCS:= \ STATIC_SRCS:= \
crt/crtdll.c \ crt/start.S \
crt/chkstk.S \ crt/crt1.c \
crt/exit.S \ crt/chkstk.S \
crt/setjmp.S \ crt/exit.S \
pe/loader.c crt/setjmp.S
CORE_SRCS:= \ DLL_SRCS:= \
crt/crtdll.c \
crt/chkstk.S \
crt/exit.S \
crt/setjmp.S \
pe/loader.c
CORE_SRCS:= \
argz/buf_findstr.c \ argz/buf_findstr.c \
argz/envz_get.c \ argz/envz_get.c \
crt/emutls.c \ crt/emutls.c \
crt/thread.S \ crt/thread.S \
crt/tls.S \ crt/tls.S \
crt/assert.c \ crt/assert.c \
crt/cpu_features.c \ crt/cpu_features.c \
ctype/ctype_.c \ ctype/ctype_.c \
ctype/isascii.c \ ctype/isascii.c \
ctype/isblank.c \ ctype/isblank.c \
ctype/isalnum.c \ ctype/isalnum.c \
ctype/isalpha.c \ ctype/isalpha.c \
ctype/iscntrl.c \ ctype/iscntrl.c \
ctype/isdigit.c \ ctype/isdigit.c \
ctype/islower.c \ ctype/islower.c \
ctype/isupper.c \ ctype/isupper.c \
ctype/isprint.c \ ctype/isprint.c \
ctype/ispunct.c \ ctype/ispunct.c \
ctype/isspace.c \ ctype/isspace.c \
ctype/iswctype.c \ ctype/iswctype.c \
ctype/iswalnum.c \ ctype/iswalnum.c \
ctype/iswalpha.c \ ctype/iswalpha.c \
ctype/iswblank.c \ ctype/iswblank.c \
ctype/iswcntrl.c \ ctype/iswcntrl.c \
ctype/iswdigit.c \ ctype/iswdigit.c \
ctype/iswgraph.c \ ctype/iswgraph.c \
ctype/iswlower.c \ ctype/iswlower.c \
ctype/iswprint.c \ ctype/iswprint.c \
ctype/iswpunct.c \ ctype/iswpunct.c \
ctype/iswspace.c \ ctype/iswspace.c \
ctype/iswupper.c \ ctype/iswupper.c \
ctype/iswxdigit.c \ ctype/iswxdigit.c \
ctype/isxdigit.c \ ctype/isxdigit.c \
ctype/toascii.c \ ctype/toascii.c \
ctype/tolower.c \ ctype/tolower.c \
ctype/toupper.c \ ctype/toupper.c \
ctype/towctrans.c \ ctype/towctrans.c \
ctype/towlower.c \ ctype/towlower.c \
ctype/towupper.c \ ctype/towupper.c \
ctype/wctrans.c \ ctype/wctrans.c \
ctype/wctype.c \ ctype/wctype.c \
errno/errno.c \ errno/errno.c \
locale/locale.c \ locale/locale.c \
locale/lctype.c \ locale/lctype.c \
reent/impure.c \ reent/impure.c \
reent/getreent.c \ reent/getreent.c \
reent/gettimeofdayr.c \ reent/gettimeofdayr.c \
reent/hdlman.c \ reent/hdlman.c \
reent/isattyr.c \ reent/isattyr.c \
reent/openr.c \ reent/openr.c \
reent/closer.c \ reent/closer.c \
reent/readr.c \ reent/readr.c \
reent/lseekr.c \ reent/lseekr.c \
reent/fstatr.c \ reent/fstatr.c \
reent/writer.c \ reent/writer.c \
search/qsort.c \ search/qsort.c \
search/bsearch.c \ search/bsearch.c \
signal/signal.c \ signal/signal.c \
sys/create.c \ sys/create.c \
sys/delete.c \ sys/delete.c \
sys/finfo.c \ sys/finfo.c \
sys/read.c \ sys/read.c \
sys/write.c \ sys/write.c \
sys/fsize.c \ sys/fsize.c \
sys/fload.c \ sys/fload.c \
time/asctime.c \ time/asctime.c \
time/asctime_r.c \ time/asctime_r.c \
time/clock.c \ time/clock.c \
time/ctime.c \ time/ctime.c \
time/ctime_r.c \ time/ctime_r.c \
time/difftime.c \ time/difftime.c \
time/gettzinfo.c \ time/gettzinfo.c \
time/gmtime.c \ time/gmtime.c \
time/gmtime_r.c \ time/gmtime_r.c \
time/mktime.c \ time/mktime.c \
time/mktm_r.c \ time/mktm_r.c \
time/lcltime.c \ time/lcltime.c \
time/lcltime_r.c \ time/lcltime_r.c \
time/strftime.c \ time/strftime.c \
time/time.c \ time/time.c \
time/tzlock.c \ time/tzlock.c \
time/tzvars.c \ time/tzvars.c \
unpack/unpacker.asm unpack/unpacker.asm
STDLIB_SRCS= \ STDLIB_SRCS= \
__atexit.c \ __atexit.c \
__call_atexit.c \ __call_atexit.c \
abort.c \ abort.c \
abs.c \ abs.c \
atof.c \ atof.c \
atoi.c \ atoi.c \
div.c \ atol.c \
dtoa.c \ div.c \
dtoastub.c \ dtoa.c \
exit.c \ dtoastub.c \
gdtoa-gethex.c \ exit.c \
gdtoa-hexnan.c \ gdtoa-gethex.c \
getenv.c \ gdtoa-hexnan.c \
mprec.c \ getenv.c \
mbtowc.c \ mprec.c \
mbtowc_r.c \ mbtowc.c \
mbrtowc.c \ mbtowc_r.c \
mlock.c \ mbrtowc.c \
calloc.c \ mlock.c \
malloc.c \ calloc.c \
mallocr.c \ malloc.c \
rand.c \ mallocr.c \
rand_r.c \ rand.c \
rand48.c \ rand_r.c \
realloc.c \ rand48.c \
seed48.c \ realloc.c \
srand48.c \ seed48.c \
strtod.c \ srand48.c \
strtol.c \ strtod.c \
strtold.c \ strtol.c \
strtoll.c \ strtold.c \
strtoll_r.c \ strtoll.c \
strtoul.c \ strtoll_r.c \
strtoull.c \ strtoul.c \
strtoull_r.c \ strtoull.c \
system.c \ strtoull_r.c \
wcrtomb.c \ system.c \
wctomb_r.c wcrtomb.c \
wctomb_r.c
STRING_SRCS= memcpy.c \ STRING_SRCS= memcpy.c \
memcmp.c \ memcmp.c \
memmove.c \ memmove.c \
memset.c \ memset.c \
memchr.c \ memchr.c \
strcat.c \ strcat.c \
strchr.c \ strchr.c \
strcmp.c \ strcmp.c \
strcoll.c \ strcoll.c \
strcasecmp.c \ strcasecmp.c \
strncasecmp.c \ strncasecmp.c \
strncat.c \ strncat.c \
strncmp.c \ strncmp.c \
strncpy.c \ strncpy.c \
strndup.c \ strndup.c \
strndup_r.c \ strndup_r.c \
strnlen.c \ strnlen.c \
strcasestr.c \ strcasestr.c \
strdup.c \ strdup.c \
strdup_r.c \ strdup_r.c \
strerror.c \ strerror.c \
strlen.c \ strlen.c \
strrchr.c \ strrchr.c \
strpbrk.c \ strpbrk.c \
strsep.c \ strsep.c \
strstr.c \ strstr.c \
strtok.c \ strtok.c \
strtok_r.c \ strtok_r.c \
strupr.c \ strupr.c \
strcspn.c \ strcspn.c \
strspn.c \ strspn.c \
strcpy.c \ strcpy.c \
u_strerr.c u_strerr.c
STDIO_SRCS= \ STDIO_SRCS= \
printf.c \ clearerr.c \
putchar.c \ diprintf.c \
dprintf.c \
printf.c \
putchar.c \
fgetc.c \
fgets.c \ fgets.c \
fopen.c \ fopen.c \
fclose.c \ fclose.c \
fdopen.c \ fdopen.c \
fflush.c \ fflush.c \
flags.c \ flags.c \
fileno.c \ fileno.c \
findfp.c \ findfp.c \
fiprintf.c \ fiprintf.c \
fiscanf.c \ fiscanf.c \
fprintf.c \ fprintf.c \
fputc.c \ fputc.c \
fputs.c \ fputs.c \
fputwc.c \ fputwc.c \
fread.c \ fread.c \
freopen.c \ freopen.c \
fscanf.c \ fscanf.c \
fseek.c \ fseek.c \
fseeko.c \ fseeko.c \
ftell.c \ ftell.c \
ftello.c \ ftello.c \
fwrite.c \ fwrite.c \
fvwrite.c \ fvwrite.c \
fwalk.c \ fwalk.c \
putc.c \ putc.c \
puts.c \ puts.c \
refill.c \ refill.c \
rget.c \ rget.c \
remove.c \ remove.c \
rename.c \ rename.c \
setvbuf.c \ setvbuf.c \
stdio.c \ stdio.c \
tmpfile.c \ tmpfile.c \
tmpnam.c \ tmpnam.c \
ungetc.c \ ungetc.c \
vscanf.c \ vscanf.c \
vsprintf.c \ vsprintf.c \
vsnprintf.c \ vsnprintf.c \
vsscanf.c \ vsscanf.c \
makebuf.c \ makebuf.c \
wsetup.c \ wsetup.c \
wbuf.c \ wbuf.c \
sccl.c \ sccl.c \
snprintf.c \ sniprintf.c \
sprintf.c \ snprintf.c \
sprintf.c \
sscanf.c sscanf.c
MATH_SRCS = acosf.c acosh.c acoshf.c acoshl.c acosl.c asinf.c asinh.c asinhf.c asinhl.c \ MATH_SRCS = acosf.c acosh.c acoshf.c acoshl.c acosl.c asinf.c asinh.c asinhf.c asinhl.c \
asinl.c atan2f.c atan2l.c atanf.c atanh.c atanhf.c atanhl.c atanl.c cbrt.c \ asinl.c atan2f.c atan2l.c atanf.c atanh.c atanhf.c atanhl.c atanl.c cbrt.c \
@ -385,7 +391,7 @@ stdio/svfiscanf.o: stdio/vfscanf.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $< $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
clean: clean:
-rm -f */*.o -rm -f */*.o

View File

@ -94,7 +94,7 @@ __crt_startup (void)
struct app_hdr *header; struct app_hdr *header;
init_reent(); init_global_reent();
/* /*
* Initialize floating point unit. * Initialize floating point unit.

View File

@ -1,122 +1,100 @@
#ifndef _MACHFASTMATH_H #ifdef __sysvnecv70_target
#define _MACHFASTMATH_H double EXFUN(fast_sin,(double));
double EXFUN(fast_cos,(double));
double EXFUN(fast_tan,(double));
#if defined(__GNUC__) && __STDC__ - 0 > 0 double EXFUN(fast_asin,(double));
double EXFUN(fast_acos,(double));
double EXFUN(fast_atan,(double));
#define __str1__(__x) #__x double EXFUN(fast_sinh,(double));
#define __str2__(__x) __str1__(__x) double EXFUN(fast_cosh,(double));
#define __U_L_PREFIX__ __str2__(__USER_LABEL_PREFIX__) double EXFUN(fast_tanh,(double));
__extension__ double atan2(double, double) double EXFUN(fast_asinh,(double));
__asm__(__U_L_PREFIX__ "_f_atan2"); double EXFUN(fast_acosh,(double));
__extension__ double exp(double) double EXFUN(fast_atanh,(double));
__asm__(__U_L_PREFIX__ "_f_exp");
__extension__ double frexp(double, int*)
__asm__(__U_L_PREFIX__ "_f_frexp");
__extension__ double ldexp(double, int)
__asm__(__U_L_PREFIX__ "_f_ldexp");
__extension__ double log(double)
__asm__(__U_L_PREFIX__ "_f_log");
__extension__ double log10(double)
__asm__(__U_L_PREFIX__ "_f_log10");
__extension__ double pow(double, double)
__asm__(__U_L_PREFIX__ "_f_pow");
__extension__ double tan(double)
__asm__(__U_L_PREFIX__ "_f_tan");
#if !defined(__STRICT_ANSI__) || defined(__cplusplus) || __STDC_VERSION__ >= 199901L double EXFUN(fast_abs,(double));
double EXFUN(fast_sqrt,(double));
double EXFUN(fast_exp2,(double));
double EXFUN(fast_exp10,(double));
double EXFUN(fast_expe,(double));
double EXFUN(fast_log10,(double));
double EXFUN(fast_log2,(double));
double EXFUN(fast_loge,(double));
__extension__ float atan2f(float, float) #define sin(x) fast_sin(x)
__asm__(__U_L_PREFIX__ "_f_atan2f"); #define cos(x) fast_cos(x)
__extension__ float expf(float) #define tan(x) fast_tan(x)
__asm__(__U_L_PREFIX__ "_f_expf"); #define asin(x) fast_asin(x)
__extension__ float frexpf(float, int*) #define acos(x) fast_acos(x)
__asm__(__U_L_PREFIX__ "_f_frexpf"); #define atan(x) fast_atan(x)
__extension__ float ldexpf(float, int) #define sinh(x) fast_sinh(x)
__asm__(__U_L_PREFIX__ "_f_ldexpf"); #define cosh(x) fast_cosh(x)
__extension__ long long llrint(double) #define tanh(x) fast_tanh(x)
__asm__(__U_L_PREFIX__ "_f_llrint"); #define asinh(x) fast_asinh(x)
__extension__ long long llrintf(float) #define acosh(x) fast_acosh(x)
__asm__(__U_L_PREFIX__ "_f_llrintf"); #define atanh(x) fast_atanh(x)
__extension__ long long llrintl(long double) #define abs(x) fast_abs(x)
__asm__(__U_L_PREFIX__ "_f_llrintl"); #define sqrt(x) fast_sqrt(x)
__extension__ float logf(float) #define exp2(x) fast_exp2(x)
__asm__(__U_L_PREFIX__ "_f_logf"); #define exp10(x) fast_exp10(x)
__extension__ float log10f(float) #define expe(x) fast_expe(x)
__asm__(__U_L_PREFIX__ "_f_log10f"); #define log10(x) fast_log10(x)
__extension__ long lrint(double) #define log2(x) fast_log2(x)
__asm__(__U_L_PREFIX__ "_f_lrint"); #define loge(x) fast_loge(x)
__extension__ long lrintf(float)
__asm__(__U_L_PREFIX__ "_f_lrintf"); #ifdef _HAVE_STDC
__extension__ long lrintl(long double) /* These functions are in assembler, they really do take floats. This
__asm__(__U_L_PREFIX__ "_f_lrintl"); can only be used with a real ANSI compiler */
__extension__ float powf(float, float)
__asm__(__U_L_PREFIX__ "_f_powf"); float EXFUN(fast_sinf,(float));
__extension__ double rint(double) float EXFUN(fast_cosf,(float));
__asm__(__U_L_PREFIX__ "_f_rint"); float EXFUN(fast_tanf,(float));
__extension__ float rintf(float)
__asm__(__U_L_PREFIX__ "_f_rintf"); float EXFUN(fast_asinf,(float));
__extension__ long double rintl(long double) float EXFUN(fast_acosf,(float));
__asm__(__U_L_PREFIX__ "_f_rintl"); float EXFUN(fast_atanf,(float));
__extension__ float tanf(float)
__asm__(__U_L_PREFIX__ "_f_tanf"); float EXFUN(fast_sinhf,(float));
float EXFUN(fast_coshf,(float));
float EXFUN(fast_tanhf,(float));
float EXFUN(fast_asinhf,(float));
float EXFUN(fast_acoshf,(float));
float EXFUN(fast_atanhf,(float));
float EXFUN(fast_absf,(float));
float EXFUN(fast_sqrtf,(float));
float EXFUN(fast_exp2f,(float));
float EXFUN(fast_exp10f,(float));
float EXFUN(fast_expef,(float));
float EXFUN(fast_log10f,(float));
float EXFUN(fast_log2f,(float));
float EXFUN(fast_logef,(float));
#define sinf(x) fast_sinf(x)
#define cosf(x) fast_cosf(x)
#define tanf(x) fast_tanf(x)
#define asinf(x) fast_asinf(x)
#define acosf(x) fast_acosf(x)
#define atanf(x) fast_atanf(x)
#define sinhf(x) fast_sinhf(x)
#define coshf(x) fast_coshf(x)
#define tanhf(x) fast_tanhf(x)
#define asinhf(x) fast_asinhf(x)
#define acoshf(x) fast_acoshf(x)
#define atanhf(x) fast_atanhf(x)
#define absf(x) fast_absf(x)
#define sqrtf(x) fast_sqrtf(x)
#define exp2f(x) fast_exp2f(x)
#define exp10f(x) fast_exp10f(x)
#define expef(x) fast_expef(x)
#define log10f(x) fast_log10f(x)
#define log2f(x) fast_log2f(x)
#define logef(x) fast_logef(x)
#endif #endif
/* Override the functions defined in math.h */
#endif /* __sysvnecv70_target */
#else
double EXFUN(_f_atan2,(double, double));
double EXFUN(_f_exp,(double));
double EXFUN(_f_frexp,(double, int*));
double EXFUN(_f_ldexp,(double, int));
double EXFUN(_f_log,(double));
double EXFUN(_f_log10,(double));
double EXFUN(_f_pow,(double, double));
#define atan2(__y,__x) _f_atan2((__y),(__x))
#define exp(__x) _f_exp(__x)
#define frexp(__x,__p) _f_frexp((__x),(__p))
#define ldexp(__x,__e) _f_ldexp((__x),(__e))
#define log(__x) _f_log(__x)
#define log10(__x) _f_log10(__x)
#define pow(__x,__y) _f_pow((__x),(__y))
#ifndef __STRICT_ANSI__
float EXFUN(_f_atan2f,(float, float));
float EXFUN(_f_expf,(float));
float EXFUN(_f_frexpf,(float, int*));
float EXFUN(_f_ldexpf,(float, int));
long long EXFUN(_f_llrint,(double));
long long EXFUN(_f_llrintf,(float));
long long EXFUN(_f_llrintl,(long double));
float EXFUN(_f_logf,(float));
float EXFUN(_f_log10f,(float));
long EXFUN(_f_lrint,(double));
long EXFUN(_f_lrintf,(float));
long EXFUN(_f_lrintl,(long double));
float EXFUN(_f_powf,(float, float));
float EXFUN(_f_rint,(double));
double EXFUN(_f_rintf,(float));
long double EXFUN(_f_rintl,(long double));
#define atan2f(__y,__x) _f_atan2f((__y),(__x))
#define expf(__x) _f_expf(__x)
#define frexpf(__x,__p) _f_frexpf((__x),(__p))
#define ldexpf(__x,__e) _f_ldexpf((__x),(__e))
#define llrint(__x) _f_llrint((__x))
#define llrintf(__x) _f_llrintf((__x))
#define llrintl(__x) _f_llrintl((__x))
#define logf(__x) _f_logf(__x)
#define log10f(__x) _f_log10f(__x)
#define lrint(__x) _f_lrint((__x))
#define lrintf(__x) _f_lrintf((__x))
#define lrintl(__x) _f_lrintl((__x))
#define powf(__x,y) _f_powf((__x),(__y))
#define rint(__x) _f_rint((__x))
#define rintf(__x) _f_rintf((__x))
#define rintl(__x) _f_rintl((__x))
#endif
#endif /* GCC */
#endif /* _MACHFASTMATH_H */

View File

@ -342,6 +342,12 @@
#define __IEEE_BIG_ENDIAN #define __IEEE_BIG_ENDIAN
#endif #endif
#ifdef __RL78__
#define __IEEE_LITTLE_ENDIAN
#define __SMALL_BITFIELDS /* 16 Bit INT */
#define _DOUBLE_IS_32BITS
#endif
#ifdef __RX__ #ifdef __RX__
#ifdef __RX_BIG_ENDIAN__ #ifdef __RX_BIG_ENDIAN__

View File

@ -265,6 +265,12 @@ _BEGIN_STD_C
#define _JBTYPE unsigned short #define _JBTYPE unsigned short
#endif /* __m32c__ */ #endif /* __m32c__ */
#ifdef __RL78__
/* Three banks of registers, SP, CS, ES, PC */
#define _JBLEN (8*3+8)
#define _JBTYPE unsigned char
#endif
#ifdef __RX__ #ifdef __RX__
#define _JBLEN 0x44 #define _JBLEN 0x44
#endif #endif

View File

@ -8,6 +8,7 @@ _BEGIN_STD_C
typedef int sig_atomic_t; /* Atomic entity type (ANSI) */ typedef int sig_atomic_t; /* Atomic entity type (ANSI) */
#ifndef _POSIX_SOURCE #ifndef _POSIX_SOURCE
typedef _sig_func_ptr sig_t; /* BSD naming */
typedef _sig_func_ptr sighandler_t; /* glibc naming */ typedef _sig_func_ptr sighandler_t; /* glibc naming */
#endif /* !_POSIX_SOURCE */ #endif /* !_POSIX_SOURCE */
@ -23,6 +24,7 @@ int _EXFUN(_raise_r, (struct _reent *, int));
#ifndef _REENT_ONLY #ifndef _REENT_ONLY
_sig_func_ptr _EXFUN(signal, (int, _sig_func_ptr)); _sig_func_ptr _EXFUN(signal, (int, _sig_func_ptr));
int _EXFUN(raise, (int)); int _EXFUN(raise, (int));
void _EXFUN(psignal, (int, const char *));
#endif #endif
_END_STD_C _END_STD_C

View File

@ -9,6 +9,7 @@
#include "_ansi.h" #include "_ansi.h"
#include <sys/reent.h> #include <sys/reent.h>
#include <sys/cdefs.h>
#define __need_size_t #define __need_size_t
#include <stddef.h> #include <stddef.h>
@ -62,11 +63,25 @@ char *_EXFUN(stpcpy,(char *, const char *));
char *_EXFUN(stpncpy,(char *, const char *, size_t)); char *_EXFUN(stpncpy,(char *, const char *, size_t));
int _EXFUN(strcasecmp,(const char *, const char *)); int _EXFUN(strcasecmp,(const char *, const char *));
char *_EXFUN(strcasestr,(const char *, const char *)); char *_EXFUN(strcasestr,(const char *, const char *));
char *_EXFUN(strchrnul,(const char *, int));
char *_EXFUN(strdup,(const char *)); char *_EXFUN(strdup,(const char *));
char *_EXFUN(_strdup_r,(struct _reent *, const char *)); char *_EXFUN(_strdup_r,(struct _reent *, const char *));
char *_EXFUN(strndup,(const char *, size_t)); char *_EXFUN(strndup,(const char *, size_t));
char *_EXFUN(_strndup_r,(struct _reent *, const char *, size_t)); char *_EXFUN(_strndup_r,(struct _reent *, const char *, size_t));
/* There are two common strerror_r variants. If you request
_GNU_SOURCE, you get the GNU version; otherwise you get the POSIX
version. POSIX requires that #undef strerror_r will still let you
invoke the underlying function, but that requires gcc support. */
#ifdef _GNU_SOURCE
char *_EXFUN(strerror_r,(int, char *, size_t)); char *_EXFUN(strerror_r,(int, char *, size_t));
#else
# ifdef __GNUC__
int _EXFUN(strerror_r,(int, char *, size_t)) __asm__ (__ASMNAME ("__xpg_strerror_r"));
# else
int _EXFUN(__xpg_strerror_r,(int, char *, size_t));
# define strerror_r __xpg_strerror_r
# endif
#endif
size_t _EXFUN(strlcat,(char *, const char *, size_t)); size_t _EXFUN(strlcat,(char *, const char *, size_t));
size_t _EXFUN(strlcpy,(char *, const char *, size_t)); size_t _EXFUN(strlcpy,(char *, const char *, size_t));
int _EXFUN(strncasecmp,(const char *, const char *, size_t)); int _EXFUN(strncasecmp,(const char *, const char *, size_t));
@ -74,13 +89,30 @@ size_t _EXFUN(strnlen,(const char *, size_t));
char *_EXFUN(strsep,(char **, const char *)); char *_EXFUN(strsep,(char **, const char *));
char *_EXFUN(strlwr,(char *)); char *_EXFUN(strlwr,(char *));
char *_EXFUN(strupr,(char *)); char *_EXFUN(strupr,(char *));
#ifdef __CYGWIN__
#ifndef DEFS_H /* Kludge to work around problem compiling in gdb */ #ifndef DEFS_H /* Kludge to work around problem compiling in gdb */
char *_EXFUN(strsignal, (int __signo)); char *_EXFUN(strsignal, (int __signo));
#endif #endif
#ifdef __CYGWIN__
int _EXFUN(strtosigno, (const char *__name)); int _EXFUN(strtosigno, (const char *__name));
#endif #endif
/* Recursive version of strerror. */
char * _EXFUN(_strerror_r, (struct _reent *, int, int, int *));
#if defined _GNU_SOURCE && defined __GNUC__
#define strdupa(__s) \
(__extension__ ({const char *__in = (__s); \
size_t __len = strlen (__in) + 1; \
char * __out = (char *) __builtin_alloca (__len); \
(char *) memcpy (__out, __in, __len);}))
#define strndupa(__s, __n) \
(__extension__ ({const char *__in = (__s); \
size_t __len = strnlen (__in, (__n)) + 1; \
char *__out = (char *) __builtin_alloca (__len); \
__out[__len-1] = '\0'; \
(char *) memcpy (__out, __in, __len-1);}))
#endif /* _GNU_SOURCE && __GNUC__ */
/* These function names are used on Windows and perhaps other systems. */ /* These function names are used on Windows and perhaps other systems. */
#ifndef strcmpi #ifndef strcmpi
#define strcmpi strcasecmp #define strcmpi strcasecmp

View File

@ -58,6 +58,27 @@
#define __DOTS , ... #define __DOTS , ...
#define __THROW #define __THROW
/*
* The __CONCAT macro is used to concatenate parts of symbol names, e.g.
* with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
* The __CONCAT macro is a bit tricky to use if it must work in non-ANSI
* mode -- there must be no spaces between its arguments, and for nested
* __CONCAT's, all the __CONCAT's must be at the left. __CONCAT can also
* concatenate double-quoted strings produced by the __STRING macro, but
* this only works with ANSI C.
*
* __XSTRING is like __STRING, but it expands any macros in its argument
* first. It is only available with ANSI C.
*/
#define __CONCAT1(x,y) x ## y
#define __CONCAT(x,y) __CONCAT1(x,y)
#define __STRING(x) #x /* stringify without expanding x */
#define __XSTRING(x) __STRING(x) /* expand x, then stringify */
#ifdef __GNUC__
# define __ASMNAME(cname) __XSTRING (__USER_LABEL_PREFIX__) cname
#endif
#define __ptr_t void * #define __ptr_t void *
#define __long_double_t long double #define __long_double_t long double

View File

@ -22,6 +22,8 @@ extern __IMPORT int _sys_nerr;
#ifdef __CYGWIN__ #ifdef __CYGWIN__
extern __IMPORT const char * const sys_errlist[]; extern __IMPORT const char * const sys_errlist[];
extern __IMPORT int sys_nerr; extern __IMPORT int sys_nerr;
extern __IMPORT char *program_invocation_name;
extern __IMPORT char *program_invocation_short_name;
#endif #endif
#define __errno_r(ptr) ((ptr)->_errno) #define __errno_r(ptr) ((ptr)->_errno)

View File

@ -15,7 +15,7 @@
* OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
* SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
* *
* $Id: features.h,v 1.22 2010/08/09 08:29:22 corinna Exp $ * $Id: features.h,v 1.27 2011/07/20 19:41:15 yselkowitz Exp $
*/ */
#ifndef _SYS_FEATURES_H #ifndef _SYS_FEATURES_H
@ -102,8 +102,8 @@ extern "C" {
/* #define _POSIX_ASYNCHRONOUS_IO -1 */ /* #define _POSIX_ASYNCHRONOUS_IO -1 */
/* #define _POSIX_BARRIERS -1 */ /* #define _POSIX_BARRIERS -1 */
#define _POSIX_CHOWN_RESTRICTED 1 #define _POSIX_CHOWN_RESTRICTED 1
/* #define _POSIX_CLOCK_SELECTION -1 */ #define _POSIX_CLOCK_SELECTION 200112L
/* #define _POSIX_CPUTIME -1 */ #define _POSIX_CPUTIME 200112L
#define _POSIX_FSYNC 200112L #define _POSIX_FSYNC 200112L
#define _POSIX_IPV6 200112L #define _POSIX_IPV6 200112L
#define _POSIX_JOB_CONTROL 1 #define _POSIX_JOB_CONTROL 1
@ -125,12 +125,12 @@ extern "C" {
#define _POSIX_SHARED_MEMORY_OBJECTS 200112L #define _POSIX_SHARED_MEMORY_OBJECTS 200112L
#define _POSIX_SHELL 1 #define _POSIX_SHELL 1
/* #define _POSIX_SPAWN -1 */ /* #define _POSIX_SPAWN -1 */
/* #define _POSIX_SPIN_LOCKS -1 */ #define _POSIX_SPIN_LOCKS 200112L
/* #define _POSIX_SPORADIC_SERVER -1 */ /* #define _POSIX_SPORADIC_SERVER -1 */
#define _POSIX_SYNCHRONIZED_IO 200112L #define _POSIX_SYNCHRONIZED_IO 200112L
/* #define _POSIX_THREAD_ATTR_STACKADDR -1 */ #define _POSIX_THREAD_ATTR_STACKADDR 200112L
#define _POSIX_THREAD_ATTR_STACKSIZE 200112L #define _POSIX_THREAD_ATTR_STACKSIZE 200112L
/* #define _POSIX_THREAD_CPUTIME -1 */ #define _POSIX_THREAD_CPUTIME 200112L
/* #define _POSIX_THREAD_PRIO_INHERIT -1 */ /* #define _POSIX_THREAD_PRIO_INHERIT -1 */
/* #define _POSIX_THREAD_PRIO_PROTECT -1 */ /* #define _POSIX_THREAD_PRIO_PROTECT -1 */
#define _POSIX_THREAD_PRIORITY_SCHEDULING 200112L #define _POSIX_THREAD_PRIORITY_SCHEDULING 200112L
@ -178,6 +178,12 @@ extern "C" {
/* #define _XOPEN_UNIX -1 */ /* #define _XOPEN_UNIX -1 */
#endif /* !__STRICT_ANSI__ || __cplusplus || __STDC_VERSION__ >= 199901L */ #endif /* !__STRICT_ANSI__ || __cplusplus || __STDC_VERSION__ >= 199901L */
/* The value corresponds to UNICODE version 4.0, which is the version
supported by XP. Newlib supports 5.2 (2011) but so far Cygwin needs
the MS conversions for double-byte charsets. */
#define __STDC_ISO_10646__ 200305L
#endif /* __CYGWIN__ */ #endif /* __CYGWIN__ */
/* Per the permission given in POSIX.1-2008 section 2.2.1, define /* Per the permission given in POSIX.1-2008 section 2.2.1, define

View File

@ -76,11 +76,12 @@ typedef struct {
* *
* (1) Routines stored in sa_handler should take a single int as * (1) Routines stored in sa_handler should take a single int as
* their argument although the POSIX standard does not require this. * their argument although the POSIX standard does not require this.
* This is not longer true since at least POSIX.1-2008
* (2) The fields sa_handler and sa_sigaction may overlap, and a conforming * (2) The fields sa_handler and sa_sigaction may overlap, and a conforming
* application should not use both simultaneously. * application should not use both simultaneously.
*/ */
typedef void (*_sig_func_ptr)(); typedef void (*_sig_func_ptr)(int);
struct sigaction { struct sigaction {
int sa_flags; /* Special flags to affect behavior of signal */ int sa_flags; /* Special flags to affect behavior of signal */

View File

@ -98,6 +98,7 @@ typedef unsigned long u_long;
typedef unsigned short ushort; /* System V compatibility */ typedef unsigned short ushort; /* System V compatibility */
typedef unsigned int uint; /* System V compatibility */ typedef unsigned int uint; /* System V compatibility */
typedef unsigned long ulong; /* System V compatibility */
# endif /*!_POSIX_SOURCE */ # endif /*!_POSIX_SOURCE */
#ifndef __clock_t_defined #ifndef __clock_t_defined

View File

@ -46,6 +46,9 @@ int _EXFUN(euidaccess, (const char *__path, int __mode));
int _EXFUN(execl, (const char *__path, const char *, ... )); int _EXFUN(execl, (const char *__path, const char *, ... ));
int _EXFUN(execle, (const char *__path, const char *, ... )); int _EXFUN(execle, (const char *__path, const char *, ... ));
int _EXFUN(execlp, (const char *__file, const char *, ... )); int _EXFUN(execlp, (const char *__file, const char *, ... ));
#if defined(__CYGWIN__)
int _EXFUN(execlpe, (const char *__file, const char *, ... ));
#endif
int _EXFUN(execv, (const char *__path, char * const __argv[] )); int _EXFUN(execv, (const char *__path, char * const __argv[] ));
int _EXFUN(execve, (const char *__path, char * const __argv[], char * const __envp[] )); int _EXFUN(execve, (const char *__path, char * const __argv[], char * const __envp[] ));
int _EXFUN(execvp, (const char *__file, char * const __argv[] )); int _EXFUN(execvp, (const char *__file, char * const __argv[] ));
@ -487,10 +490,11 @@ int _EXFUN(unlinkat, (int, const char *, int));
#define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 16 #define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 16
#define _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS 17 #define _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS 17
#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS #define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS
#define _CS_XBS5_WIDTH_RESTRICTED_ENVS _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS
#define _CS_POSIX_V7_THREADS_CFLAGS 18 #define _CS_POSIX_V7_THREADS_CFLAGS 18
#define _CS_POSIX_V7_THREADS_LDFLAGS 19 #define _CS_POSIX_V7_THREADS_LDFLAGS 19
#define _CS_V7_ENV 20 #define _CS_V7_ENV 20
#define _CS_V6_ENV _CS_V6_ENV #define _CS_V6_ENV _CS_V7_ENV
#endif #endif
#ifndef __CYGWIN__ #ifndef __CYGWIN__

View File

@ -175,6 +175,22 @@ int _EXFUN(nanosleep, (const struct timespec *rqtp, struct timespec *rmtp));
#endif #endif
#endif /* _POSIX_TIMERS */ #endif /* _POSIX_TIMERS */
#if defined(_POSIX_CLOCK_SELECTION)
#ifdef __cplusplus
extern "C" {
#endif
int _EXFUN(clock_nanosleep,
(clockid_t clock_id, int flags, const struct timespec *rqtp,
struct timespec *rmtp));
#ifdef __cplusplus
}
#endif
#endif /* _POSIX_CLOCK_SELECTION */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -212,7 +228,7 @@ extern "C" {
the identifier of the CPU_time clock associated with the PROCESS the identifier of the CPU_time clock associated with the PROCESS
making the function call. */ making the function call. */
#define CLOCK_PROCESS_CPUTIME (clockid_t)2 #define CLOCK_PROCESS_CPUTIME_ID (clockid_t)2
#endif #endif
@ -222,7 +238,7 @@ extern "C" {
the identifier of the CPU_time clock associated with the THREAD the identifier of the CPU_time clock associated with the THREAD
making the function call. */ making the function call. */
#define CLOCK_THREAD_CPUTIME (clockid_t)3 #define CLOCK_THREAD_CPUTIME_ID (clockid_t)3
#endif #endif

View File

@ -16,6 +16,9 @@
/* For _mbstate_t definition. */ /* For _mbstate_t definition. */
#include <sys/_types.h> #include <sys/_types.h>
/* For __STDC_ISO_10646__ */
#include <sys/features.h>
#ifndef NULL #ifndef NULL
#define NULL 0 #define NULL 0
#endif #endif

View File

@ -50,7 +50,7 @@ struct lc_messages_T {
}; };
struct lc_messages_T *__get_current_messages_locale(void); struct lc_messages_T *__get_current_messages_locale(void);
int __numeric_load_locale(const char *, void *, const char *); int __messages_load_locale(const char *, void *, const char *);
__END_DECLS __END_DECLS

View File

@ -90,16 +90,15 @@ Cygwin additionally supports locales from the file
(<<"">> is also accepted; if given, the settings are read from the (<<"">> is also accepted; if given, the settings are read from the
corresponding LC_* environment variables and $LANG according to POSIX rules. corresponding LC_* environment variables and $LANG according to POSIX rules.
This implementation also supports a single modifier, <<"cjknarrow">>. This implementation also supports the modifier <<"cjknarrow">>, which
Any other modifier is ignored. <<"cjknarrow">>, in conjunction with one affects how the functions <<wcwidth>> and <<wcswidth>> handle characters
of the language specifiers <<"ja">>, <<"ko">>, and <<"zh">> specifies from the "CJK Ambiguous Width" category of characters described at
how the functions <<wcwidth>> and <<wcswidth>> handle characters from http://www.unicode.org/reports/tr11/#Ambiguous. These characters have a width
the "CJK Ambiguous Width" character class described in of 1 for singlebyte charsets and a width of 2 for multibyte charsets
http://www.unicode.org/unicode/reports/tr11/. Usually these characters other than UTF-8. For UTF-8, their width depends on the language specifier:
have a width of 1, unless you specify one of the aforementioned it is 2 for <<"zh">> (Chinese), <<"ja">> (Japanese), and <<"ko">> (Korean),
languages, in which case these characters have a width of 2. By and 1 for everything else. Specifying <<"cjknarrow">> forces a width of 1,
specifying the <<"cjknarrow">> modifier, these characters will have a independent of charset and language.
width of one in the languages <<"ja">>, <<"ko">>, and <<"zh">> as well.
If you use <<NULL>> as the <[locale]> argument, <<setlocale>> returns a If you use <<NULL>> as the <[locale]> argument, <<setlocale>> returns a
pointer to the string representing the current locale. The acceptable pointer to the string representing the current locale. The acceptable
@ -183,6 +182,7 @@ No supporting OS subroutines are required.
#include "lmonetary.h" #include "lmonetary.h"
#include "lnumeric.h" #include "lnumeric.h"
#include "lctype.h" #include "lctype.h"
#include "timelocal.h"
#include "../stdlib/local.h" #include "../stdlib/local.h"
#define _LC_LAST 7 #define _LC_LAST 7
@ -236,7 +236,11 @@ char __default_locale[ENCODING_LEN + 1] = DEFAULT_LOCALE;
static char current_categories[_LC_LAST][ENCODING_LEN + 1] = { static char current_categories[_LC_LAST][ENCODING_LEN + 1] = {
"C", "C",
"C", "C",
#ifdef __CYGWIN__ /* Cygwin starts with LC_CTYPE set to "C.UTF-8". */
"C.UTF-8",
#else
"C", "C",
#endif
"C", "C",
"C", "C",
"C", "C",
@ -256,13 +260,12 @@ static const char *__get_locale_env(struct _reent *, int);
#endif /* _MB_CAPABLE */ #endif /* _MB_CAPABLE */
#if 0 /*def __CYGWIN__ TODO: temporarily(?) disable C == UTF-8 */ #ifdef __CYGWIN__
static char lc_ctype_charset[ENCODING_LEN + 1] = "UTF-8"; static char lc_ctype_charset[ENCODING_LEN + 1] = "UTF-8";
static char lc_message_charset[ENCODING_LEN + 1] = "UTF-8";
#else #else
static char lc_ctype_charset[ENCODING_LEN + 1] = "ASCII"; static char lc_ctype_charset[ENCODING_LEN + 1] = "ASCII";
static char lc_message_charset[ENCODING_LEN + 1] = "ASCII";
#endif #endif
static char lc_message_charset[ENCODING_LEN + 1] = "ASCII";
static int lc_ctype_cjk_lang = 0; static int lc_ctype_cjk_lang = 0;
char * char *
@ -433,7 +436,7 @@ currentlocale()
#ifdef _MB_CAPABLE #ifdef _MB_CAPABLE
#ifdef __CYGWIN__ #ifdef __CYGWIN__
extern void __set_charset_from_locale (const char *locale, char *charset); extern void __set_charset_from_locale (const char *locale, char *charset);
extern int __set_locale_from_locale_alias (const char *, char *); extern char *__set_locale_from_locale_alias (const char *, char *);
extern int __collate_load_locale (const char *, void *, const char *); extern int __collate_load_locale (const char *, void *, const char *);
#endif /* __CYGWIN__ */ #endif /* __CYGWIN__ */
@ -453,7 +456,7 @@ loadlocale(struct _reent *p, int category)
char *locale = NULL; char *locale = NULL;
char charset[ENCODING_LEN + 1]; char charset[ENCODING_LEN + 1];
unsigned long val; unsigned long val;
char *end, *c; char *end, *c = NULL;
int mbc_max; int mbc_max;
int (*l_wctomb) (struct _reent *, char *, wchar_t, const char *, mbstate_t *); int (*l_wctomb) (struct _reent *, char *, wchar_t, const char *, mbstate_t *);
int (*l_mbtowc) (struct _reent *, wchar_t *, const char *, size_t, int (*l_mbtowc) (struct _reent *, wchar_t *, const char *, size_t,
@ -496,11 +499,7 @@ restart:
if (!strcmp (locale, "POSIX")) if (!strcmp (locale, "POSIX"))
strcpy (locale, "C"); strcpy (locale, "C");
if (!strcmp (locale, "C")) /* Default "C" locale */ if (!strcmp (locale, "C")) /* Default "C" locale */
#if 0 /*def __CYGWIN__ TODO: temporarily(?) disable C == UTF-8 */
strcpy (charset, "UTF-8");
#else
strcpy (charset, "ASCII"); strcpy (charset, "ASCII");
#endif
else if (locale[0] == 'C' else if (locale[0] == 'C'
&& (locale[1] == '-' /* Old newlib style */ && (locale[1] == '-' /* Old newlib style */
|| locale[1] == '.')) /* Extension for the C locale to allow || locale[1] == '.')) /* Extension for the C locale to allow
@ -508,7 +507,16 @@ restart:
sticking to the C locale in terms sticking to the C locale in terms
of sort order, etc. Proposed in of sort order, etc. Proposed in
the Debian project. */ the Debian project. */
strcpy (charset, locale + 2); {
char *chp;
c = locale + 2;
strcpy (charset, c);
if ((chp = strchr (charset, '@')))
/* Strip off modifier */
*chp = '\0';
c += strlen (charset);
}
else /* POSIX style */ else /* POSIX style */
{ {
c = locale; c = locale;
@ -559,7 +567,8 @@ restart:
else else
/* Invalid string */ /* Invalid string */
FAIL; FAIL;
if (c[0] == '@') }
if (c && c[0] == '@')
{ {
/* Modifier */ /* Modifier */
/* Only one modifier is recognized right now. "cjknarrow" is used /* Only one modifier is recognized right now. "cjknarrow" is used
@ -568,7 +577,6 @@ restart:
if (!strcmp (c + 1, "cjknarrow")) if (!strcmp (c + 1, "cjknarrow"))
cjknarrow = 1; cjknarrow = 1;
} }
}
/* We only support this subset of charsets. */ /* We only support this subset of charsets. */
switch (charset[0]) switch (charset[0])
{ {
@ -845,16 +853,18 @@ restart:
__wctomb = l_wctomb; __wctomb = l_wctomb;
__mbtowc = l_mbtowc; __mbtowc = l_mbtowc;
__set_ctype (charset); __set_ctype (charset);
/* Check for the language part of the locale specifier. In case /* Determine the width for the "CJK Ambiguous Width" category of
of "ja", "ko", or "zh", assume the use of CJK fonts, unless the characters. This is used in wcwidth(). Assume single width for
"@cjknarrow" modifier has been specifed. single-byte charsets, and double width for multi-byte charsets
The result is stored in lc_ctype_cjk_lang and tested in wcwidth() other than UTF-8. For UTF-8, use double width for the East Asian
to figure out the width to return (1 or 2) for the "CJK Ambiguous languages ("ja", "ko", "zh"), and single width for everything else.
Width" category of characters. */ Single width can also be forced with the "@cjknarrow" modifier. */
lc_ctype_cjk_lang = !cjknarrow lc_ctype_cjk_lang = !cjknarrow
&& ((strncmp (locale, "ja", 2) == 0 && mbc_max > 1
&& (charset[0] != 'U'
|| strncmp (locale, "ja", 2) == 0
|| strncmp (locale, "ko", 2) == 0 || strncmp (locale, "ko", 2) == 0
|| strncmp (locale, "zh", 2) == 0)); || strncmp (locale, "zh", 2) == 0);
#ifdef __HAVE_LOCALE_INFO__ #ifdef __HAVE_LOCALE_INFO__
ret = __ctype_load_locale (locale, (void *) l_wctomb, charset, mbc_max); ret = __ctype_load_locale (locale, (void *) l_wctomb, charset, mbc_max);
#endif /* __HAVE_LOCALE_INFO__ */ #endif /* __HAVE_LOCALE_INFO__ */
@ -942,7 +952,7 @@ char *
_DEFUN_VOID(__locale_msgcharset) _DEFUN_VOID(__locale_msgcharset)
{ {
#ifdef __HAVE_LOCALE_INFO__ #ifdef __HAVE_LOCALE_INFO__
return __get_current_messages_locale ()->codeset; return (char *) __get_current_messages_locale ()->codeset;
#else #else
return lc_message_charset; return lc_message_charset;
#endif #endif
@ -962,21 +972,21 @@ _DEFUN(_localeconv_r, (data),
if (__nlocale_changed) if (__nlocale_changed)
{ {
struct lc_numeric_T *n = __get_current_numeric_locale (); struct lc_numeric_T *n = __get_current_numeric_locale ();
lconv.decimal_point = n->decimal_point; lconv.decimal_point = (char *) n->decimal_point;
lconv.thousands_sep = n->thousands_sep; lconv.thousands_sep = (char *) n->thousands_sep;
lconv.grouping = n->grouping; lconv.grouping = (char *) n->grouping;
__nlocale_changed = 0; __nlocale_changed = 0;
} }
if (__mlocale_changed) if (__mlocale_changed)
{ {
struct lc_monetary_T *m = __get_current_monetary_locale (); struct lc_monetary_T *m = __get_current_monetary_locale ();
lconv.int_curr_symbol = m->int_curr_symbol; lconv.int_curr_symbol = (char *) m->int_curr_symbol;
lconv.currency_symbol = m->currency_symbol; lconv.currency_symbol = (char *) m->currency_symbol;
lconv.mon_decimal_point = m->mon_decimal_point; lconv.mon_decimal_point = (char *) m->mon_decimal_point;
lconv.mon_thousands_sep = m->mon_thousands_sep; lconv.mon_thousands_sep = (char *) m->mon_thousands_sep;
lconv.mon_grouping = m->mon_grouping; lconv.mon_grouping = (char *) m->mon_grouping;
lconv.positive_sign = m->positive_sign; lconv.positive_sign = (char *) m->positive_sign;
lconv.negative_sign = m->negative_sign; lconv.negative_sign = (char *) m->negative_sign;
lconv.int_frac_digits = m->int_frac_digits[0]; lconv.int_frac_digits = m->int_frac_digits[0];
lconv.frac_digits = m->frac_digits[0]; lconv.frac_digits = m->frac_digits[0];
lconv.p_cs_precedes = m->p_cs_precedes[0]; lconv.p_cs_precedes = m->p_cs_precedes[0];

View File

@ -65,11 +65,13 @@ _DEFUN(_close_r, (ptr, fd),
fh = (__file_handle*) __getOSHandle( fd ); fh = (__file_handle*) __getOSHandle( fd );
_free_r(ptr, fh->name); if( fd > STDERR_FILENO )
_free_r(ptr, fh); {
_free_r(ptr, fh->name);
__freePOSIXHandle( fd ); _free_r(ptr, fh);
__SetIOMode_nogrow( fd, 0 ); __freePOSIXHandle( fd );
__SetIOMode_nogrow( fd, 0 );
}
return 0; return 0;
} }

View File

@ -29,6 +29,19 @@ void init_reent()
__sinit(ent); __sinit(ent);
} }
void init_global_reent()
{
struct _reent *ent;
ent =_GLOBAL_REENT;
_REENT_INIT_PTR(ent);
__asm__ __volatile__(
"movl %0, %%fs:12"
::"r"(ent));
__sinit(ent);
}
void __mutex_lock(volatile int *val) void __mutex_lock(volatile int *val)

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
FUNCTION
<<clearerr>>---clear file or stream error indicator
INDEX
clearerr
ANSI_SYNOPSIS
#include <stdio.h>
void clearerr(FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
void clearerr(<[fp]>)
FILE *<[fp]>;
DESCRIPTION
The <<stdio>> functions maintain an error indicator with each file
pointer <[fp]>, to record whether any read or write errors have
occurred on the associated file or stream. Similarly, it maintains an
end-of-file indicator to record whether there is no more data in the
file.
Use <<clearerr>> to reset both of these indicators.
See <<ferror>> and <<feof>> to query the two indicators.
RETURNS
<<clearerr>> does not return a result.
PORTABILITY
ANSI C requires <<clearerr>>.
No supporting OS subroutines are required.
*/
#include <_ansi.h>
#include <stdio.h>
#include "local.h"
/* A subroutine version of the macro clearerr. */
#undef clearerr
_VOID
_DEFUN(clearerr, (fp),
FILE * fp)
{
CHECK_INIT(_REENT, fp);
_flockfile (fp);
__sclearerr (fp);
_funlockfile (fp);
}

View File

@ -0,0 +1,82 @@
/* Copyright (C) 2005, 2007 Shaun Jackman
* Permission to use, copy, modify, and distribute this software
* is freely granted, provided that this notice is preserved.
*/
/*
FUNCTION
<<diprintf>>, <<vdiprintf>>---print to a file descriptor (integer only)
INDEX
diprintf
INDEX
_diprintf_r
INDEX
vdiprintf
INDEX
_vdiprintf_r
ANSI_SYNOPSIS
#include <stdio.h>
#include <stdarg.h>
int diprintf(int <[fd]>, const char *<[format]>, ...);
int vdiprintf(int <[fd]>, const char *<[format]>, va_list <[ap]>);
int _diprintf_r(struct _reent *<[ptr]>, int <[fd]>,
const char *<[format]>, ...);
int _vdiprintf_r(struct _reent *<[ptr]>, int <[fd]>,
const char *<[format]>, va_list <[ap]>);
DESCRIPTION
<<diprintf>> and <<vdiprintf>> are similar to <<dprintf>> and <<vdprintf>>,
except that only integer format specifiers are processed.
The functions <<_diprintf_r>> and <<_vdiprintf_r>> are simply
reentrant versions of the functions above.
RETURNS
Similar to <<dprintf>> and <<vdprintf>>.
PORTABILITY
This set of functions is an integer-only extension, and is not portable.
Supporting OS subroutines required: <<sbrk>>, <<write>>.
*/
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
int
_DEFUN(_diprintf_r, (ptr, fd, format),
struct _reent *ptr _AND
int fd _AND
const char *format _DOTS)
{
va_list ap;
int n;
va_start (ap, format);
n = _vdiprintf_r (ptr, fd, format, ap);
va_end (ap);
return n;
}
#ifndef _REENT_ONLY
int
_DEFUN(diprintf, (fd, format),
int fd _AND
const char *format _DOTS)
{
va_list ap;
int n;
va_start (ap, format);
n = _vdiprintf_r (_REENT, fd, format, ap);
va_end (ap);
return n;
}
#endif /* ! _REENT_ONLY */

View File

@ -0,0 +1,87 @@
/* Copyright 2005, 2007 Shaun Jackman
* Permission to use, copy, modify, and distribute this software
* is freely granted, provided that this notice is preserved.
*/
/*
FUNCTION
<<dprintf>>, <<vdprintf>>---print to a file descriptor
INDEX
dprintf
INDEX
_dprintf_r
INDEX
vdprintf
INDEX
_vdprintf_r
ANSI_SYNOPSIS
#include <stdio.h>
#include <stdarg.h>
int dprintf(int <[fd]>, const char *<[format]>, ...);
int vdprintf(int <[fd]>, const char *<[format]>, va_list <[ap]>);
int _dprintf_r(struct _reent *<[ptr]>, int <[fd]>,
const char *<[format]>, ...);
int _vdprintf_r(struct _reent *<[ptr]>, int <[fd]>,
const char *<[format]>, va_list <[ap]>);
DESCRIPTION
<<dprintf>> and <<vdprintf>> allow printing a format, similarly to
<<printf>>, but write to a file descriptor instead of to a <<FILE>>
stream.
The functions <<_dprintf_r>> and <<_vdprintf_r>> are simply
reentrant versions of the functions above.
RETURNS
The return value and errors are exactly as for <<write>>, except that
<<errno>> may also be set to <<ENOMEM>> if the heap is exhausted.
PORTABILITY
This function is originally a GNU extension in glibc and is not portable.
Supporting OS subroutines required: <<sbrk>>, <<write>>.
*/
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include "local.h"
int
_DEFUN(_dprintf_r, (ptr, fd, format),
struct _reent *ptr _AND
int fd _AND
const char *format _DOTS)
{
va_list ap;
int n;
_REENT_SMALL_CHECK_INIT (ptr);
va_start (ap, format);
n = _vdprintf_r (ptr, fd, format, ap);
va_end (ap);
return n;
}
#ifndef _REENT_ONLY
int
_DEFUN(dprintf, (fd, format),
int fd _AND
const char *format _DOTS)
{
va_list ap;
int n;
struct _reent *ptr = _REENT;
_REENT_SMALL_CHECK_INIT (ptr);
va_start (ap, format);
n = _vdprintf_r (ptr, fd, format, ap);
va_end (ap);
return n;
}
#endif /* ! _REENT_ONLY */

View File

@ -74,8 +74,6 @@ _DEFUN(_fclose_r, (rptr, fp),
if (fp == NULL) if (fp == NULL)
return (0); /* on NULL */ return (0); /* on NULL */
__sfp_lock_acquire ();
CHECK_INIT (rptr, fp); CHECK_INIT (rptr, fp);
_flockfile (fp); _flockfile (fp);
@ -83,7 +81,6 @@ _DEFUN(_fclose_r, (rptr, fp),
if (fp->_flags == 0) /* not open! */ if (fp->_flags == 0) /* not open! */
{ {
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return (0); return (0);
} }
/* Unconditionally flush to allow special handling for seekable read /* Unconditionally flush to allow special handling for seekable read
@ -98,6 +95,7 @@ _DEFUN(_fclose_r, (rptr, fp),
FREEUB (rptr, fp); FREEUB (rptr, fp);
if (HASLB (fp)) if (HASLB (fp))
FREELB (rptr, fp); FREELB (rptr, fp);
__sfp_lock_acquire ();
fp->_flags = 0; /* release this FILE for reuse */ fp->_flags = 0; /* release this FILE for reuse */
_funlockfile (fp); _funlockfile (fp);
#ifndef __SINGLE_THREAD__ #ifndef __SINGLE_THREAD__

View File

@ -67,37 +67,16 @@ No supporting OS subroutines are required.
/* Flush a single file, or (if fp is NULL) all files. */ /* Flush a single file, or (if fp is NULL) all files. */
/* Core function which does not lock file pointer. This gets called
directly from __srefill. */
int int
_DEFUN(_fflush_r, (ptr, fp), _DEFUN(__sflush_r, (ptr, fp),
struct _reent *ptr _AND struct _reent *ptr _AND
register FILE * fp) register FILE * fp)
{ {
register unsigned char *p; register unsigned char *p;
register int n, t; register int n, t;
#ifdef _REENT_SMALL
/* For REENT_SMALL platforms, it is possible we are being
called for the first time on a std stream. This std
stream can belong to a reentrant struct that is not
_REENT. If CHECK_INIT gets called below based on _REENT,
we will end up changing said file pointers to the equivalent
std stream off of _REENT. This causes unexpected behavior if
there is any data to flush on the _REENT std stream. There
are two alternatives to fix this: 1) make a reentrant fflush
or 2) simply recognize that this file has nothing to flush
and return immediately before performing a CHECK_INIT. Choice
2 is implemented here due to its simplicity. */
if (fp->_bf._base == NULL)
return 0;
#endif /* _REENT_SMALL */
CHECK_INIT (ptr, fp);
if (!fp->_flags)
return 0;
_flockfile (fp);
t = fp->_flags; t = fp->_flags;
if ((t & __SWR) == 0) if ((t & __SWR) == 0)
{ {
@ -150,7 +129,6 @@ _DEFUN(_fflush_r, (ptr, fp),
} }
else else
fp->_flags |= __SERR; fp->_flags |= __SERR;
_funlockfile (fp);
return result; return result;
} }
} }
@ -186,17 +164,14 @@ _DEFUN(_fflush_r, (ptr, fp),
else else
{ {
fp->_flags |= __SERR; fp->_flags |= __SERR;
_funlockfile (fp);
return EOF; return EOF;
} }
} }
_funlockfile (fp);
return 0; return 0;
} }
if ((p = fp->_bf._base) == NULL) if ((p = fp->_bf._base) == NULL)
{ {
/* Nothing to flush. */ /* Nothing to flush. */
_funlockfile (fp);
return 0; return 0;
} }
n = fp->_p - p; /* write this much */ n = fp->_p - p; /* write this much */
@ -215,16 +190,48 @@ _DEFUN(_fflush_r, (ptr, fp),
if (t <= 0) if (t <= 0)
{ {
fp->_flags |= __SERR; fp->_flags |= __SERR;
_funlockfile (fp);
return EOF; return EOF;
} }
p += t; p += t;
n -= t; n -= t;
} }
_funlockfile (fp);
return 0; return 0;
} }
int
_DEFUN(_fflush_r, (ptr, fp),
struct _reent *ptr _AND
register FILE * fp)
{
int ret;
#ifdef _REENT_SMALL
/* For REENT_SMALL platforms, it is possible we are being
called for the first time on a std stream. This std
stream can belong to a reentrant struct that is not
_REENT. If CHECK_INIT gets called below based on _REENT,
we will end up changing said file pointers to the equivalent
std stream off of _REENT. This causes unexpected behavior if
there is any data to flush on the _REENT std stream. There
are two alternatives to fix this: 1) make a reentrant fflush
or 2) simply recognize that this file has nothing to flush
and return immediately before performing a CHECK_INIT. Choice
2 is implemented here due to its simplicity. */
if (fp->_bf._base == NULL)
return 0;
#endif /* _REENT_SMALL */
CHECK_INIT (ptr, fp);
if (!fp->_flags)
return 0;
_flockfile (fp);
ret = __sflush_r (ptr, fp);
_funlockfile (fp);
return ret;
}
#ifndef _REENT_ONLY #ifndef _REENT_ONLY
int int

View File

@ -0,0 +1,106 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
FUNCTION
<<fgetc>>---get a character from a file or stream
INDEX
fgetc
INDEX
_fgetc_r
ANSI_SYNOPSIS
#include <stdio.h>
int fgetc(FILE *<[fp]>);
#include <stdio.h>
int _fgetc_r(struct _reent *<[ptr]>, FILE *<[fp]>);
TRAD_SYNOPSIS
#include <stdio.h>
int fgetc(<[fp]>)
FILE *<[fp]>;
#include <stdio.h>
int _fgetc_r(<[ptr]>, <[fp]>)
struct _reent *<[ptr]>;
FILE *<[fp]>;
DESCRIPTION
Use <<fgetc>> to get the next single character from the file or stream
identified by <[fp]>. As a side effect, <<fgetc>> advances the file's
current position indicator.
For a macro version of this function, see <<getc>>.
The function <<_fgetc_r>> is simply a reentrant version of
<<fgetc>> that is passed the additional reentrant structure
pointer argument: <[ptr]>.
RETURNS
The next character (read as an <<unsigned char>>, and cast to
<<int>>), unless there is no more data, or the host system reports a
read error; in either of these situations, <<fgetc>> returns <<EOF>>.
You can distinguish the two situations that cause an <<EOF>> result by
using the <<ferror>> and <<feof>> functions.
PORTABILITY
ANSI C requires <<fgetc>>.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
#include <_ansi.h>
#include <stdio.h>
#include "local.h"
int
_DEFUN(_fgetc_r, (ptr, fp),
struct _reent * ptr _AND
FILE * fp)
{
int result;
CHECK_INIT(ptr, fp);
_flockfile (fp);
result = __sgetc_r (ptr, fp);
_funlockfile (fp);
return result;
}
#ifndef _REENT_ONLY
int
_DEFUN(fgetc, (fp),
FILE * fp)
{
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
int result;
CHECK_INIT(_REENT, fp);
_flockfile (fp);
result = __sgetc_r (_REENT, fp);
_funlockfile (fp);
return result;
#else
return _fgetc_r (_REENT, fp);
#endif
}
#endif /* !_REENT_ONLY */

View File

@ -98,7 +98,6 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
CHECK_INIT(ptr, fp); CHECK_INIT(ptr, fp);
__sfp_lock_acquire ();
_flockfile (fp); _flockfile (fp);
#ifdef __SCLE #ifdef __SCLE
if (fp->_flags & __SCLE) if (fp->_flags & __SCLE)
@ -114,12 +113,10 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
if (c == EOF && s == buf) if (c == EOF && s == buf)
{ {
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return NULL; return NULL;
} }
*s = 0; *s = 0;
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return buf; return buf;
} }
#endif #endif
@ -138,7 +135,6 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
if (s == buf) if (s == buf)
{ {
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return 0; return 0;
} }
break; break;
@ -164,7 +160,6 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
_CAST_VOID memcpy ((_PTR) s, (_PTR) p, len); _CAST_VOID memcpy ((_PTR) s, (_PTR) p, len);
s[len] = 0; s[len] = 0;
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return (buf); return (buf);
} }
fp->_r -= len; fp->_r -= len;
@ -175,7 +170,6 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
while ((n -= len) != 0); while ((n -= len) != 0);
*s = 0; *s = 0;
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return buf; return buf;
} }

View File

@ -146,7 +146,6 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
CHECK_INIT(ptr, fp); CHECK_INIT(ptr, fp);
__sfp_lock_acquire ();
_flockfile (fp); _flockfile (fp);
ORIENT (fp, -1); ORIENT (fp, -1);
if (fp->_r < 0) if (fp->_r < 0)
@ -197,12 +196,10 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
if (fp->_flags & __SCLE) if (fp->_flags & __SCLE)
{ {
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return crlf_r (ptr, fp, buf, total-resid, 1) / size; return crlf_r (ptr, fp, buf, total-resid, 1) / size;
} }
#endif #endif
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return (total - resid) / size; return (total - resid) / size;
} }
} }
@ -224,12 +221,10 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
if (fp->_flags & __SCLE) if (fp->_flags & __SCLE)
{ {
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return crlf_r (ptr, fp, buf, total-resid, 1) / size; return crlf_r (ptr, fp, buf, total-resid, 1) / size;
} }
#endif #endif
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return (total - resid) / size; return (total - resid) / size;
} }
} }
@ -243,12 +238,10 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
if (fp->_flags & __SCLE) if (fp->_flags & __SCLE)
{ {
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return crlf_r(ptr, fp, buf, total, 0) / size; return crlf_r(ptr, fp, buf, total, 0) / size;
} }
#endif #endif
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return count; return count;
} }

View File

@ -98,8 +98,6 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
int flags, oflags; int flags, oflags;
int e = 0; int e = 0;
__sfp_lock_acquire ();
CHECK_INIT (ptr, fp); CHECK_INIT (ptr, fp);
_flockfile (fp); _flockfile (fp);
@ -108,7 +106,6 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
{ {
_funlockfile (fp); _funlockfile (fp);
_fclose_r (ptr, fp); _fclose_r (ptr, fp);
__sfp_lock_release ();
return NULL; return NULL;
} }
@ -208,6 +205,7 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
if (f < 0) if (f < 0)
{ /* did not get it after all */ { /* did not get it after all */
__sfp_lock_acquire ();
fp->_flags = 0; /* set it free */ fp->_flags = 0; /* set it free */
ptr->_errno = e; /* restore in case _close clobbered */ ptr->_errno = e; /* restore in case _close clobbered */
_funlockfile (fp); _funlockfile (fp);
@ -232,7 +230,6 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
#endif #endif
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return fp; return fp;
} }

View File

@ -45,7 +45,7 @@ fscanf(FILE *fp, fmt, va_alist)
#else #else
va_start (ap); va_start (ap);
#endif #endif
ret = __svfscanf_r (_REENT, fp, fmt, ap); ret = _vfscanf_r (_REENT, fp, fmt, ap);
va_end (ap); va_end (ap);
return ret; return ret;
} }
@ -71,7 +71,7 @@ _fscanf_r(ptr, FILE *fp, fmt, va_alist)
#else #else
va_start (ap); va_start (ap);
#endif #endif
ret = __svfscanf_r (ptr, fp, fmt, ap); ret = _vfscanf_r (ptr, fp, fmt, ap);
va_end (ap); va_end (ap);
return (ret); return (ret);
} }

View File

@ -138,7 +138,6 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
CHECK_INIT (ptr, fp); CHECK_INIT (ptr, fp);
__sfp_lock_acquire ();
_flockfile (fp); _flockfile (fp);
/* If we've been doing some writing, and we're in append mode /* If we've been doing some writing, and we're in append mode
@ -156,7 +155,6 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
{ {
ptr->_errno = ESPIPE; /* ??? */ ptr->_errno = ESPIPE; /* ??? */
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return EOF; return EOF;
} }
@ -182,7 +180,6 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
if (curoff == -1L) if (curoff == -1L)
{ {
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return EOF; return EOF;
} }
} }
@ -208,7 +205,6 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
default: default:
ptr->_errno = EINVAL; ptr->_errno = EINVAL;
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return (EOF); return (EOF);
} }
@ -268,7 +264,6 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
{ {
ptr->_errno = EOVERFLOW; ptr->_errno = EOVERFLOW;
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return EOF; return EOF;
} }
@ -325,7 +320,6 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
fp->_flags &= ~__SEOF; fp->_flags &= ~__SEOF;
memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return 0; return 0;
} }
@ -356,7 +350,6 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
} }
memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return 0; return 0;
/* /*
@ -369,7 +362,6 @@ dumb:
|| seekfn (ptr, fp->_cookie, offset, whence) == POS_ERR) || seekfn (ptr, fp->_cookie, offset, whence) == POS_ERR)
{ {
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return EOF; return EOF;
} }
/* success: clear EOF indicator and discard ungetc() data */ /* success: clear EOF indicator and discard ungetc() data */
@ -388,7 +380,6 @@ dumb:
fp->_flags &= ~__SNPT; fp->_flags &= ~__SNPT;
memset (&fp->_mbstate, 0, sizeof (_mbstate_t)); memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return 0; return 0;
} }

View File

@ -61,11 +61,7 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio),
/* make sure we can write */ /* make sure we can write */
if (cantwrite (ptr, fp)) if (cantwrite (ptr, fp))
{
fp->_flags |= __SERR;
ptr->_errno = EBADF;
return EOF; return EOF;
}
iov = uio->uio_iov; iov = uio->uio_iov;
len = 0; len = 0;

View File

@ -27,8 +27,8 @@ static char sccsid[] = "%W% (Berkeley) %G%";
#include <errno.h> #include <errno.h>
#include "local.h" #include "local.h"
static int int
_DEFUN(__fwalk, (ptr, function), _DEFUN(_fwalk, (ptr, function),
struct _reent *ptr _AND struct _reent *ptr _AND
register int (*function) (FILE *)) register int (*function) (FILE *))
{ {
@ -36,11 +36,19 @@ _DEFUN(__fwalk, (ptr, function),
register int n, ret = 0; register int n, ret = 0;
register struct _glue *g; register struct _glue *g;
/*
* It should be safe to walk the list without locking it;
* new nodes are only added to the end and none are ever
* removed.
*
* Avoid locking this list while walking it or else you will
* introduce a potential deadlock in [at least] refill.c.
*/
for (g = &ptr->__sglue; g != NULL; g = g->_next) for (g = &ptr->__sglue; g != NULL; g = g->_next)
for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++) for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
if (fp->_flags != 0) if (fp->_flags != 0)
{ {
if (fp->_flags != 0 && fp->_file != -1) if (fp->_flags != 0 && fp->_flags != 1 && fp->_file != -1)
ret |= (*function) (fp); ret |= (*function) (fp);
} }
@ -49,8 +57,8 @@ _DEFUN(__fwalk, (ptr, function),
/* Special version of __fwalk where the function pointer is a reentrant /* Special version of __fwalk where the function pointer is a reentrant
I/O function (e.g. _fclose_r). */ I/O function (e.g. _fclose_r). */
static int int
_DEFUN(__fwalk_reent, (ptr, reent_function), _DEFUN(_fwalk_reent, (ptr, reent_function),
struct _reent *ptr _AND struct _reent *ptr _AND
register int (*reent_function) (struct _reent *, FILE *)) register int (*reent_function) (struct _reent *, FILE *))
{ {
@ -58,51 +66,21 @@ _DEFUN(__fwalk_reent, (ptr, reent_function),
register int n, ret = 0; register int n, ret = 0;
register struct _glue *g; register struct _glue *g;
/*
* It should be safe to walk the list without locking it;
* new nodes are only added to the end and none are ever
* removed.
*
* Avoid locking this list while walking it or else you will
* introduce a potential deadlock in [at least] refill.c.
*/
for (g = &ptr->__sglue; g != NULL; g = g->_next) for (g = &ptr->__sglue; g != NULL; g = g->_next)
for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++) for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++)
if (fp->_flags != 0) if (fp->_flags != 0)
{ {
if (fp->_flags != 0 && fp->_file != -1) if (fp->_flags != 0 && fp->_flags != 1 && fp->_file != -1)
ret |= (*reent_function) (ptr, fp); ret |= (*reent_function) (ptr, fp);
} }
return ret; return ret;
} }
int
_DEFUN(_fwalk, (ptr, function),
struct _reent *ptr _AND
register int (*function)(FILE *))
{
register int ret = 0;
__sfp_lock_acquire ();
/* Must traverse given list for streams. Note that _GLOBAL_REENT
only walked once in exit(). */
ret |= __fwalk (ptr, function);
__sfp_lock_release ();
return ret;
}
/* Special version of _fwalk which handles a function pointer to a
reentrant I/O function (e.g. _fclose_r). */
int
_DEFUN(_fwalk_reent, (ptr, reent_function),
struct _reent *ptr _AND
register int (*reent_function) (struct _reent *, FILE *))
{
register int ret = 0;
__sfp_lock_acquire ();
/* Must traverse given list for streams. Note that _GLOBAL_REENT
only walked once in exit(). */
ret |= __fwalk_reent (ptr, reent_function);
__sfp_lock_release ();
return ret;
}

View File

@ -54,6 +54,7 @@ int _EXFUN(_svfiwprintf_r,(struct _reent *, FILE *, const wchar_t *,
va_list)); va_list));
extern FILE *_EXFUN(__sfp,(struct _reent *)); extern FILE *_EXFUN(__sfp,(struct _reent *));
extern int _EXFUN(__sflags,(struct _reent *,_CONST char*, int*)); extern int _EXFUN(__sflags,(struct _reent *,_CONST char*, int*));
extern int _EXFUN(__sflush_r,(struct _reent *,FILE *));
extern int _EXFUN(__srefill_r,(struct _reent *,FILE *)); extern int _EXFUN(__srefill_r,(struct _reent *,FILE *));
extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(struct _reent *, void *, char *, extern _READ_WRITE_RETURN_TYPE _EXFUN(__sread,(struct _reent *, void *, char *,
int)); int));
@ -112,7 +113,8 @@ extern _READ_WRITE_RETURN_TYPE _EXFUN(__swrite64,(struct _reent *, void *,
} \ } \
while (0) while (0)
/* Return true iff the given FILE cannot be written now. */ /* Return true and set errno and stream error flag iff the given FILE
cannot be written now. */
#define cantwrite(ptr, fp) \ #define cantwrite(ptr, fp) \
((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \ ((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \

View File

@ -102,9 +102,19 @@ _DEFUN(__srefill_r, (ptr, fp),
* flush all line buffered output files, per the ANSI C * flush all line buffered output files, per the ANSI C
* standard. * standard.
*/ */
if (fp->_flags & (__SLBF | __SNBF)) if (fp->_flags & (__SLBF | __SNBF))
{
/* Ignore this file in _fwalk to avoid potential deadlock. */
short orig_flags = fp->_flags;
fp->_flags = 1;
_CAST_VOID _fwalk (_GLOBAL_REENT, lflush); _CAST_VOID _fwalk (_GLOBAL_REENT, lflush);
fp->_flags = orig_flags;
/* Now flush this file without locking it. */
if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR))
__sflush_r (ptr, fp);
}
fp->_p = fp->_bf._base; fp->_p = fp->_bf._base;
fp->_r = fp->_read (ptr, fp->_cookie, (char *) fp->_p, fp->_bf._size); fp->_r = fp->_read (ptr, fp->_cookie, (char *) fp->_p, fp->_bf._size);
#ifndef __CYGWIN__ #ifndef __CYGWIN__

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 1990, 2007 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* This code created by modifying snprintf.c so copyright inherited. */
/* doc in siprintf.c */
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
#ifdef _HAVE_STDC
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <limits.h>
#include <errno.h>
#include "local.h"
int
#ifdef _HAVE_STDC
_DEFUN (_sniprintf_r, (ptr, str, size, fmt),
struct _reent *ptr _AND
char *str _AND
size_t size _AND
_CONST char *fmt _DOTS)
#else
_sniprintf_r (ptr, str, size, fmt, va_alist)
struct _reent *ptr;
char *str;
size_t size;
_CONST char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
FILE f;
if (size > INT_MAX)
{
ptr->_errno = EOVERFLOW;
return EOF;
}
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._w = (size > 0 ? size - 1 : 0);
f._file = -1; /* No file. */
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = _svfiprintf_r (ptr, &f, fmt, ap);
va_end (ap);
if (ret < EOF)
ptr->_errno = EOVERFLOW;
if (size > 0)
*f._p = 0;
return (ret);
}
#ifndef _REENT_ONLY
int
#ifdef _HAVE_STDC
_DEFUN (sniprintf, (str, size, fmt),
char *str _AND
size_t size _AND
_CONST char *fmt _DOTS)
#else
sniprintf (str, size, fmt, va_alist)
char *str;
size_t size;
_CONST char *fmt;
va_dcl
#endif
{
int ret;
va_list ap;
FILE f;
struct _reent *ptr = _REENT;
if (size > INT_MAX)
{
ptr->_errno = EOVERFLOW;
return EOF;
}
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *) str;
f._bf._size = f._w = (size > 0 ? size - 1 : 0);
f._file = -1; /* No file. */
#ifdef _HAVE_STDC
va_start (ap, fmt);
#else
va_start (ap);
#endif
ret = _svfiprintf_r (ptr, &f, fmt, ap);
va_end (ap);
if (ret < EOF)
ptr->_errno = EOVERFLOW;
if (size > 0)
*f._p = 0;
return (ret);
}
#endif

View File

@ -453,7 +453,9 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
wchar_t wc; /* wchar to use to read format string */ wchar_t wc; /* wchar to use to read format string */
wchar_t *wcp; /* handy wide character pointer */ wchar_t *wcp; /* handy wide character pointer */
size_t mbslen; /* length of converted multibyte sequence */ size_t mbslen; /* length of converted multibyte sequence */
#ifdef _MB_CAPABLE
mbstate_t state; /* value to keep track of multibyte state */ mbstate_t state; /* value to keep track of multibyte state */
#endif
#define CCFN_PARAMS _PARAMS((struct _reent *, const char *, char **, int)) #define CCFN_PARAMS _PARAMS((struct _reent *, const char *, char **, int))
u_long (*ccfn)CCFN_PARAMS=0; /* conversion function (strtol/strtoul) */ u_long (*ccfn)CCFN_PARAMS=0; /* conversion function (strtol/strtoul) */
@ -494,7 +496,6 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
# define GET_ARG(n, ap, type) (va_arg (ap, type)) # define GET_ARG(n, ap, type) (va_arg (ap, type))
#endif #endif
__sfp_lock_acquire ();
_flockfile (fp); _flockfile (fp);
ORIENT (fp, -1); ORIENT (fp, -1);
@ -795,7 +796,6 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
*/ */
case '\0': /* compat */ case '\0': /* compat */
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return EOF; return EOF;
default: /* compat */ default: /* compat */
@ -1596,13 +1596,11 @@ input_failure:
invalid format string), return EOF if no matches yet, else number invalid format string), return EOF if no matches yet, else number
of matches made prior to failure. */ of matches made prior to failure. */
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return nassigned && !(fp->_flags & __SERR) ? nassigned : EOF; return nassigned && !(fp->_flags & __SERR) ? nassigned : EOF;
match_failure: match_failure:
all_done: all_done:
/* Return number of matches, which can be 0 on match failure. */ /* Return number of matches, which can be 0 on match failure. */
_funlockfile (fp); _funlockfile (fp);
__sfp_lock_release ();
return nassigned; return nassigned;
} }

View File

@ -27,6 +27,8 @@ static char sccsid[] = "%W% (Berkeley) %G%";
#include <stdarg.h> #include <stdarg.h>
#include <errno.h> #include <errno.h>
#include "local.h"
#ifndef _REENT_ONLY #ifndef _REENT_ONLY
int int

View File

@ -26,6 +26,8 @@ static char sccsid[] = "%W% (Berkeley) %G%";
#include <limits.h> #include <limits.h>
#include <stdarg.h> #include <stdarg.h>
#include "local.h"
#ifndef _REENT_ONLY #ifndef _REENT_ONLY
int int

View File

@ -54,11 +54,7 @@ _DEFUN(__swbuf_r, (ptr, c, fp),
fp->_w = fp->_lbfsize; fp->_w = fp->_lbfsize;
if (cantwrite (ptr, fp)) if (cantwrite (ptr, fp))
{
fp->_flags |= __SERR;
ptr->_errno = EBADF;
return EOF; return EOF;
}
c = (unsigned char) c; c = (unsigned char) c;
ORIENT (fp, -1); ORIENT (fp, -1);

View File

@ -20,12 +20,13 @@
#include <_ansi.h> #include <_ansi.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include "local.h" #include "local.h"
/* /*
* Various output routines call wsetup to be sure it is safe to write, * Various output routines call wsetup to be sure it is safe to write,
* because either _flags does not include __SWR, or _buf is NULL. * because either _flags does not include __SWR, or _buf is NULL.
* _wsetup returns 0 if OK to write, nonzero otherwise. * _wsetup returns 0 if OK to write, nonzero and set errno otherwise.
*/ */
int int
@ -44,7 +45,11 @@ _DEFUN(__swsetup_r, (ptr, fp),
if ((fp->_flags & __SWR) == 0) if ((fp->_flags & __SWR) == 0)
{ {
if ((fp->_flags & __SRW) == 0) if ((fp->_flags & __SRW) == 0)
{
ptr->_errno = EBADF;
fp->_flags |= __SERR;
return EOF; return EOF;
}
if (fp->_flags & __SRD) if (fp->_flags & __SRD)
{ {
/* clobber any ungetc data */ /* clobber any ungetc data */
@ -79,5 +84,11 @@ _DEFUN(__swsetup_r, (ptr, fp),
else else
fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size; fp->_w = fp->_flags & __SNBF ? 0 : fp->_bf._size;
return (!fp->_bf._base && (fp->_flags & __SMBF)) ? EOF : 0; if (!fp->_bf._base && (fp->_flags & __SMBF))
{
/* __smakebuf_r set errno, but not flag */
fp->_flags |= __SERR;
return EOF;
}
return 0;
} }

View File

@ -0,0 +1,21 @@
/*
* Andy Wilson, 2-Oct-89.
*/
#include <stdlib.h>
#include <_ansi.h>
#ifndef _REENT_ONLY
long
_DEFUN (atol, (s), _CONST char *s)
{
return strtol (s, NULL, 10);
}
#endif /* !_REENT_ONLY */
long
_DEFUN (_atol_r, (ptr, s), struct _reent *ptr _AND _CONST char *s)
{
return _strtol_r (ptr, s, NULL, 10);
}

View File

@ -54,7 +54,7 @@ Supporting OS subroutines required: <<_exit>>.
* Exit, flushing stdio buffers if necessary. * Exit, flushing stdio buffers if necessary.
*/ */
void void
_DEFUN (exit, (code), _DEFUN (exit, (code),
int code) int code)
{ {

View File

@ -299,15 +299,17 @@ _DEFUN (_strtod_r, (ptr, s00, se),
} }
s0 = s; s0 = s;
y = z = 0; y = z = 0;
for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) {
if (nd < DBL_DIG + 1) {
if (nd < 9) if (nd < 9)
y = 10*y + c - '0'; y = 10*y + c - '0';
else if (nd < 16) else
z = 10*z + c - '0'; z = 10*z + c - '0';
}
}
nd0 = nd; nd0 = nd;
if (strncmp (s, _localeconv_r (ptr)->decimal_point, if (strncmp (s, _localeconv_r (ptr)->decimal_point,
strlen (_localeconv_r (ptr)->decimal_point)) == 0) strlen (_localeconv_r (ptr)->decimal_point)) == 0) {
{
decpt = 1; decpt = 1;
c = *(s += strlen (_localeconv_r (ptr)->decimal_point)); c = *(s += strlen (_localeconv_r (ptr)->decimal_point));
if (!nd) { if (!nd) {
@ -325,16 +327,24 @@ _DEFUN (_strtod_r, (ptr, s00, se),
have_dig: have_dig:
nz++; nz++;
if (c -= '0') { if (c -= '0') {
nf += nz; for(i = 1; i < nz; i++) {
for(i = 1; i < nz; i++) if (nd <= DBL_DIG + 1) {
if (nd++ < 9) if (nd + i < 10)
y *= 10; y *= 10;
else if (nd <= DBL_DIG + 1) else
z *= 10; z *= 10;
if (nd++ < 9) }
}
if (nd <= DBL_DIG + 1) {
if (nd + i < 10)
y = 10*y + c; y = 10*y + c;
else if (nd <= DBL_DIG + 1) else
z = 10*z + c; z = 10*z + c;
}
if (nd <= DBL_DIG + 1) {
nf += nz;
nd += nz;
}
nz = 0; nz = 0;
} }
} }

View File

@ -6,11 +6,11 @@ INDEX
strcasecmp strcasecmp
ANSI_SYNOPSIS ANSI_SYNOPSIS
#include <string.h> #include <strings.h>
int strcasecmp(const char *<[a]>, const char *<[b]>); int strcasecmp(const char *<[a]>, const char *<[b]>);
TRAD_SYNOPSIS TRAD_SYNOPSIS
#include <string.h> #include <strings.h>
int strcasecmp(<[a]>, <[b]>) int strcasecmp(<[a]>, <[b]>)
char *<[a]>; char *<[a]>;
char *<[b]>; char *<[b]>;
@ -38,7 +38,7 @@ QUICKREF
strcasecmp strcasecmp
*/ */
#include <string.h> #include <strings.h>
#include <ctype.h> #include <ctype.h>
int int

View File

@ -76,6 +76,7 @@ QUICKREF
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <strings.h>
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
# define RETURN_TYPE char * # define RETURN_TYPE char *

View File

@ -15,6 +15,8 @@ INDEX
ANSI_SYNOPSIS ANSI_SYNOPSIS
#include <string.h> #include <string.h>
char *strerror(int <[errnum]>); char *strerror(int <[errnum]>);
char *_strerror_r(struct _reent <[ptr]>, int <[errnum]>,
int <[internal]>, int *<[error]>);
TRAD_SYNOPSIS TRAD_SYNOPSIS
#include <string.h> #include <string.h>
@ -31,6 +33,9 @@ This implementation of <<strerror>> prints out the following strings
for each of the values defined in `<<errno.h>>': for each of the values defined in `<<errno.h>>':
o+ o+
o 0
Success
o E2BIG o E2BIG
Arg list too long Arg list too long
@ -288,6 +293,8 @@ Strings pipe error
o- o-
<<_strerror_r>> is a reentrant version of the above.
RETURNS RETURNS
This function returns a pointer to a string. Your application must This function returns a pointer to a string. Your application must
not modify that string. not modify that string.
@ -296,22 +303,45 @@ PORTABILITY
ANSI C requires <<strerror>>, but does not specify the strings used ANSI C requires <<strerror>>, but does not specify the strings used
for each error number. for each error number.
Although this implementation of <<strerror>> is reentrant, ANSI C Although this implementation of <<strerror>> is reentrant (depending
declares that subsequent calls to <<strerror>> may overwrite the on <<_user_strerror>>), ANSI C declares that subsequent calls to
result string; therefore portable code cannot depend on the reentrancy <<strerror>> may overwrite the result string; therefore portable
of this subroutine. code cannot depend on the reentrancy of this subroutine.
Although this implementation of <<strerror>> guarantees a non-null
result with a NUL-terminator, some implementations return <<NULL>>
on failure. Although POSIX allows <<strerror>> to set <<errno>>
to EINVAL on failure, this implementation does not do so (unless
you provide <<_user_strerror>>).
POSIX recommends that unknown <[errnum]> result in a message
including that value, however it is not a requirement and this
implementation does not provide that information (unless you
provide <<_user_strerror>>).
This implementation of <<strerror>> provides for user-defined This implementation of <<strerror>> provides for user-defined
extensibility. <<errno.h>> defines <[__ELASTERROR]>, which can be extensibility. <<errno.h>> defines <[__ELASTERROR]>, which can be
used as a base for user-defined error values. If the user supplies a used as a base for user-defined error values. If the user supplies a
routine named <<_user_strerror>>, and <[errnum]> passed to routine named <<_user_strerror>>, and <[errnum]> passed to
<<strerror>> does not match any of the supported values, <<strerror>> does not match any of the supported values,
<<_user_strerror>> is called with <[errnum]> as its argument. <<_user_strerror>> is called with three arguments. The first is of
type <[int]>, and is the <[errnum]> value unknown to <<strerror>>.
<<_user_strerror>> takes one argument of type <[int]>, and returns a The second is of type <[int]>, and matches the <[internal]> argument
character pointer. If <[errnum]> is unknown to <<_user_strerror>>, of <<_strerror_r>>; this should be zero if called from <<strerror>>
<<_user_strerror>> returns <[NULL]>. The default <<_user_strerror>> and non-zero if called from any other function; <<_user_strerror>> can
returns <[NULL]> for all input values. use this information to satisfy the POSIX rule that no other
standardized function can overwrite a static buffer reused by
<<strerror>>. The third is of type <[int *]>, and matches the
<[error]> argument of <<_strerror_r>>; if a non-zero value is stored
into that location (usually <[EINVAL]>), then <<strerror>> will set
<<errno>> to that value, and the XPG variant of <<strerror_r>> will
return that value instead of zero or <[ERANGE]>. <<_user_strerror>>
returns a <[char *]> value; returning <[NULL]> implies that the user
function did not choose to handle <[errnum]>. The default
<<_user_strerror>> returns <[NULL]> for all input values. Note that
<<_user_sterror>> must be thread-safe, and only denote errors via the
third argument rather than modifying <<errno>>, if <<strerror>> and
<<strerror_r>> are are to comply with POSIX.
<<strerror>> requires no supporting OS subroutines. <<strerror>> requires no supporting OS subroutines.
@ -323,14 +353,20 @@ QUICKREF
#include <string.h> #include <string.h>
char * char *
_DEFUN (strerror, (errnum), _DEFUN (_strerror_r, (ptr, errnum, internal, errptr),
int errnum) struct _reent *ptr _AND
int errnum _AND
int internal _AND
int *errptr)
{ {
char *error; char *error;
extern char *_user_strerror _PARAMS ((int)); extern char *_user_strerror _PARAMS ((int, int, int *));
switch (errnum) switch (errnum)
{ {
case 0:
error = "Success";
break;
/* go32 defines EPERM as EACCES */ /* go32 defines EPERM as EACCES */
#if defined (EPERM) && (!defined (EACCES) || (EPERM != EACCES)) #if defined (EPERM) && (!defined (EACCES) || (EPERM != EACCES))
case EPERM: case EPERM:
@ -784,10 +820,19 @@ _DEFUN (strerror, (errnum),
break; break;
#endif #endif
default: default:
if ((error = _user_strerror (errnum)) == 0) if (!errptr)
errptr = &ptr->_errno;
if ((error = _user_strerror (errnum, internal, errptr)) == 0)
error = ""; error = "";
break; break;
} }
return error; return error;
} }
char *
_DEFUN(strerror, (int),
int errnum)
{
return _strerror_r (_REENT, errnum, 0, NULL);
}

View File

@ -6,11 +6,11 @@ INDEX
strncasecmp strncasecmp
ANSI_SYNOPSIS ANSI_SYNOPSIS
#include <string.h> #include <strings.h>
int strncasecmp(const char *<[a]>, const char * <[b]>, size_t <[length]>); int strncasecmp(const char *<[a]>, const char * <[b]>, size_t <[length]>);
TRAD_SYNOPSIS TRAD_SYNOPSIS
#include <string.h> #include <strings.h>
int strncasecmp(<[a]>, <[b]>, <[length]>) int strncasecmp(<[a]>, <[b]>, <[length]>)
char *<[a]>; char *<[a]>;
char *<[b]>; char *<[b]>;
@ -40,7 +40,7 @@ QUICKREF
strncasecmp strncasecmp
*/ */
#include <string.h> #include <strings.h>
#include <ctype.h> #include <ctype.h>
int int

View File

@ -1,8 +1,10 @@
#include <_ansi.h> #include <_ansi.h>
char * char *
_DEFUN(_user_strerror, (errnum), _DEFUN(_user_strerror, (errnum, internal, errptr),
int errnum) int errnum _AND
int internal _AND
int *errptr)
{ {
return 0; return 0;
} }

View File

@ -18,7 +18,7 @@ _DEFUN (asctime_r, (tim_p, result),
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
}; };
sprintf (result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n", siprintf (result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
day_name[tim_p->tm_wday], day_name[tim_p->tm_wday],
mon_name[tim_p->tm_mon], mon_name[tim_p->tm_mon],
tim_p->tm_mday, tim_p->tm_hour, tim_p->tm_min, tim_p->tm_mday, tim_p->tm_hour, tim_p->tm_min,

View File

@ -107,7 +107,7 @@ _DEFUN(validate_structure, (tim_p),
} }
} }
if (tim_p->tm_mon > 11) if (tim_p->tm_mon < 0 || tim_p->tm_mon > 11)
{ {
res = div (tim_p->tm_mon, 12); res = div (tim_p->tm_mon, 12);
tim_p->tm_year += res.quot; tim_p->tm_year += res.quot;
@ -159,7 +159,7 @@ _DEFUN(mktime, (tim_p),
{ {
time_t tim = 0; time_t tim = 0;
long days = 0; long days = 0;
int year, isdst, tm_isdst; int year, isdst=0;
__tzinfo_type *tz = __gettzinfo (); __tzinfo_type *tz = __gettzinfo ();
/* validate structure */ /* validate structure */
@ -178,39 +178,35 @@ _DEFUN(mktime, (tim_p),
/* compute day of the year */ /* compute day of the year */
tim_p->tm_yday = days; tim_p->tm_yday = days;
if (tim_p->tm_year > 10000 if (tim_p->tm_year > 10000 || tim_p->tm_year < -10000)
|| tim_p->tm_year < -10000)
{
return (time_t) -1; return (time_t) -1;
}
/* compute days in other years */ /* compute days in other years */
if (tim_p->tm_year > 70) if ((year = tim_p->tm_year) > 70)
{ {
for (year = 70; year < tim_p->tm_year; year++) for (year = 70; year < tim_p->tm_year; year++)
days += _DAYS_IN_YEAR (year); days += _DAYS_IN_YEAR (year);
} }
else if (tim_p->tm_year < 70) else if (year < 70)
{ {
for (year = 69; year > tim_p->tm_year; year--) for (year = 69; year > tim_p->tm_year; year--)
days -= _DAYS_IN_YEAR (year); days -= _DAYS_IN_YEAR (year);
days -= _DAYS_IN_YEAR (year); days -= _DAYS_IN_YEAR (year);
} }
/* compute day of the week */
if ((tim_p->tm_wday = (days + 4) % 7) < 0)
tim_p->tm_wday += 7;
/* compute total seconds */ /* compute total seconds */
tim += (days * _SEC_IN_DAY); tim += (days * _SEC_IN_DAY);
TZ_LOCK;
if (_daylight)
{
int tm_isdst;
int y = tim_p->tm_year + YEAR_BASE;
/* Convert user positive into 1 */ /* Convert user positive into 1 */
tm_isdst = tim_p->tm_isdst > 0 ? 1 : tim_p->tm_isdst; tm_isdst = tim_p->tm_isdst > 0 ? 1 : tim_p->tm_isdst;
isdst = tm_isdst; isdst = tm_isdst;
if (_daylight)
{
int y = tim_p->tm_year + YEAR_BASE;
if (y == tz->__tzyear || __tzcalc_limits (y)) if (y == tz->__tzyear || __tzcalc_limits (y))
{ {
/* calculate start of dst in dst local time and /* calculate start of dst in dst local time and
@ -244,8 +240,29 @@ _DEFUN(mktime, (tim_p),
if (!isdst) if (!isdst)
diff = -diff; diff = -diff;
tim_p->tm_sec += diff; tim_p->tm_sec += diff;
validate_structure (tim_p);
tim += diff; /* we also need to correct our current time calculation */ tim += diff; /* we also need to correct our current time calculation */
int mday = tim_p->tm_mday;
validate_structure (tim_p);
mday = tim_p->tm_mday - mday;
/* roll over occurred */
if (mday) {
/* compensate for month roll overs */
if (mday > 1)
mday = -1;
else if (mday < -1)
mday = 1;
/* update days for wday calculation */
days += mday;
/* handle yday */
if ((tim_p->tm_yday += mday) < 0) {
--year;
tim_p->tm_yday = _DAYS_IN_YEAR(year) - 1;
} else {
mday = _DAYS_IN_YEAR(year);
if (tim_p->tm_yday > (mday - 1))
tim_p->tm_yday -= mday;
}
}
} }
} }
} }
@ -257,8 +274,14 @@ _DEFUN(mktime, (tim_p),
else /* otherwise assume std time */ else /* otherwise assume std time */
tim += (time_t) tz->__tzrule[0].offset; tim += (time_t) tz->__tzrule[0].offset;
TZ_UNLOCK;
/* reset isdst flag to what we have calculated */ /* reset isdst flag to what we have calculated */
tim_p->tm_isdst = isdst; tim_p->tm_isdst = isdst;
/* compute day of the week */
if ((tim_p->tm_wday = (days + 4) % 7) < 0)
tim_p->tm_wday += 7;
return tim; return tim;
} }

View File

@ -182,7 +182,7 @@ _DEFUN (_mktm_r, (tim_p, res, is_gmtime),
{ {
res->tm_mon = 11; res->tm_mon = 11;
res->tm_year -= 1; res->tm_year -= 1;
res->tm_yday = 365 + isleap(res->tm_year); res->tm_yday = 364 + isleap(res->tm_year + 1900);
} }
res->tm_mday = ip[res->tm_mon]; res->tm_mday = ip[res->tm_mon];
} }
@ -216,10 +216,13 @@ _DEFUN (__tzcalc_limits, (year),
for (i = 0; i < 2; ++i) for (i = 0; i < 2; ++i)
{ {
if (tz->__tzrule[i].ch == 'J') if (tz->__tzrule[i].ch == 'J') {
/* The Julian day n (1 <= n <= 365). */
days = year_days + tz->__tzrule[i].d + days = year_days + tz->__tzrule[i].d +
(isleap(year) && tz->__tzrule[i].d >= 60); (isleap(year) && tz->__tzrule[i].d >= 60);
else if (tz->__tzrule[i].ch == 'D') /* Convert to yday */
--days;
} else if (tz->__tzrule[i].ch == 'D')
days = year_days + tz->__tzrule[i].d; days = year_days + tz->__tzrule[i].d;
else else
{ {
@ -254,4 +257,3 @@ _DEFUN (__tzcalc_limits, (year),
return 1; return 1;
} }