diff options
author | craigm <none@none> | 2006-04-20 08:17:22 -0700 |
---|---|---|
committer | craigm <none@none> | 2006-04-20 08:17:22 -0700 |
commit | a5f69788de7ac07553de47f7fec8c05a9a94c105 (patch) | |
tree | 2004e6a579b5b69b2edd0a65453e5a2d7d174f4f /usr/src/lib | |
parent | 9c6cb9fca0da6c80b32c97869c5672999211da26 (diff) | |
download | illumos-gate-a5f69788de7ac07553de47f7fec8c05a9a94c105.tar.gz |
PSARC 2006/162 Extended FILE space for 32-bit Solaris processes
1085341 32-bit stdio routines should support file descriptors >255
6369408 fflush(NULL); will corrupt data written on files in multithreaded apps
Diffstat (limited to 'usr/src/lib')
30 files changed, 901 insertions, 236 deletions
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index b6caadbd20..3dfb55d6a2 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -177,6 +177,7 @@ SUBDIRS += \ libpctx .WAIT \ libcpc \ watchmalloc \ + extendedFILE \ madv \ mpss \ libdisasm \ diff --git a/usr/src/lib/extendedFILE/Makefile b/usr/src/lib/extendedFILE/Makefile new file mode 100644 index 0000000000..714a9f062b --- /dev/null +++ b/usr/src/lib/extendedFILE/Makefile @@ -0,0 +1,48 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# lib/extendedFILE/Makefile + +include ../Makefile.lib + +SUBDIRS= spec .WAIT $(MACH) + +LIBRARY= extendedFILE.a + +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint + +.KEEP_STATE: + +all install clean clobber lint: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/lib/extendedFILE/Makefile.com b/usr/src/lib/extendedFILE/Makefile.com new file mode 100644 index 0000000000..cc9da90fcf --- /dev/null +++ b/usr/src/lib/extendedFILE/Makefile.com @@ -0,0 +1,67 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# lib/extendedFILE/Makefile.com + +LIBRARY = extendedFILE.a +VERS = .1 + +OBJECTS = extendedFILE.o + +# include library definitions +include ../../Makefile.lib + +MAPFILE = $(MAPDIR)/mapfile +CLOBBERFILES += $(MAPFILE) + +SRCS = $(OBJECTS:%.o=../common/%.c) + +LIBS = $(DYNLIB) +LDLIBS += -lc +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -D_REENTRANT -I../common +DYNFLAGS += -M$(MAPFILE) $(ZINTERPOSE) + +CPPFLAGS += -I../../common/inc + +.KEEP_STATE: + +all: $(LIBS) + +lint: + $(LINT.c) $(SRCS) $(LDLIBS) + +$(DYNLIB): $(MAPFILE) + +$(MAPFILE): + @cd $(MAPDIR); $(MAKE) mapfile + +# include library targets +include ../../Makefile.targ + +pics/%.o: ../common/%.c + $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) diff --git a/usr/src/lib/extendedFILE/common/extendedFILE.c b/usr/src/lib/extendedFILE/common/extendedFILE.c new file mode 100644 index 0000000000..b3f4fc6721 --- /dev/null +++ b/usr/src/lib/extendedFILE/common/extendedFILE.c @@ -0,0 +1,90 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "c_synonyms.h" +#include <sys/types.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <signal.h> +#include <stdio.h> +#include <stdio_ext.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define _FILE_FD_MAX 255 + +/* + * This 32-bit only preloadable library enables extended fd FILE's. + */ + +#pragma init(init_STDIO_bad_fd) + +void +init_STDIO_bad_fd(void) +{ + int action = -1; /* default signal */ + int closed_fd = -1; /* default fd */ + char *ptr; + int signal; + int retval; + + /* + * user specified badfd + */ + if ((ptr = getenv("_STDIO_BADFD")) != NULL) { + closed_fd = atoi(ptr); + if (closed_fd < 3 || closed_fd > _FILE_FD_MAX) { + (void) fprintf(stderr, "File descriptor must be" + " in the range 3-%d inclusive.\n", _FILE_FD_MAX); + exit(1); + } + } + + /* + * user specified action + */ + if ((ptr = getenv("_STDIO_BADFD_SIGNAL")) != NULL) { + /* accept numbers or symbolic names */ + if (strncmp(ptr, "SIG", 3) == 0) /* begins with "SIG"? */ + ptr = ptr + 3; + retval = str2sig(ptr, &signal); + if (retval == -1) { + (void) fprintf(stderr, + "Invalid signal name or number.\n"); + exit(1); + } + action = signal; + } + + if ((closed_fd = enable_extended_FILE_stdio(closed_fd, action)) == -1) { + perror("enable_extended_FILE_stdio(3C)"); + exit(1); + } +} diff --git a/usr/src/lib/extendedFILE/i386/Makefile b/usr/src/lib/extendedFILE/i386/Makefile new file mode 100644 index 0000000000..85f8644b6f --- /dev/null +++ b/usr/src/lib/extendedFILE/i386/Makefile @@ -0,0 +1,34 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# lib/extendedFILE/i386/Makefile + +MAPDIR= ../spec/i386 +include ../Makefile.com + +.KEEP_STATE: + +install: all $(ROOTLIBS) diff --git a/usr/src/lib/extendedFILE/sparc/Makefile b/usr/src/lib/extendedFILE/sparc/Makefile new file mode 100644 index 0000000000..ec425e3705 --- /dev/null +++ b/usr/src/lib/extendedFILE/sparc/Makefile @@ -0,0 +1,34 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# lib/extendedFILE/sparc/Makefile + +MAPDIR= ../spec/sparc +include ../Makefile.com + +.KEEP_STATE: + +install: all $(ROOTLIBS) diff --git a/usr/src/lib/extendedFILE/spec/Makefile b/usr/src/lib/extendedFILE/spec/Makefile new file mode 100644 index 0000000000..78ba8b1869 --- /dev/null +++ b/usr/src/lib/extendedFILE/spec/Makefile @@ -0,0 +1,59 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +i386_ARCHITECTURES = i386 +sparc_ARCHITECTURES = sparc + +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint + +.KEEP_STATE: + +all install clean clobber: $($(MACH)_ARCHITECTURES) + +$($(MACH)_ARCHITECTURES): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +# +# This will make sure that any target not +# explicitly defined will not break the build. +# +# XXX pmake on intel does not like the following rules +# %: ignore_and_exit_quietly +# ignore_and_exit_quietly: +# +# So here it is manually +# +IGNORE= _msg catalog install_h delete \ + package tcov debug private_h \ + check analyse test dynamic lint +$(IGNORE): + +FRC: diff --git a/usr/src/lib/extendedFILE/spec/Makefile.targ b/usr/src/lib/extendedFILE/spec/Makefile.targ new file mode 100644 index 0000000000..13900068e7 --- /dev/null +++ b/usr/src/lib/extendedFILE/spec/Makefile.targ @@ -0,0 +1,35 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# lib/libplot/plot/spec/Makefile.targ + +LIBRARY = extendedFILE.a +VERS = .1 + +OBJECTS = extendedFILE.o + +TRANSCPP = +SPECCPP = diff --git a/usr/src/lib/extendedFILE/spec/extendedFILE.spec b/usr/src/lib/extendedFILE/spec/extendedFILE.spec new file mode 100644 index 0000000000..b916eb9dd4 --- /dev/null +++ b/usr/src/lib/extendedFILE/spec/extendedFILE.spec @@ -0,0 +1,26 @@ +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# ident "%Z%%M% %I% %E% SMI" +# +# lib/extendedFILE/spec/extendedFILE.spec diff --git a/usr/src/lib/extendedFILE/spec/i386/Makefile b/usr/src/lib/extendedFILE/spec/i386/Makefile new file mode 100644 index 0000000000..37a82ccaac --- /dev/null +++ b/usr/src/lib/extendedFILE/spec/i386/Makefile @@ -0,0 +1,41 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# lib/extendedFILE/spec/i386/Makefile + +include ../Makefile.targ + +# Add arch specific objects here +OBJECTS += + +include $(SRC)/lib/Makefile.lib + +# Uncomment the following if the linker complains +#i386_C_PICFLAGS = -K PIC + +include $(SRC)/lib/Makefile.spec + +install: $(ROOTABILIB) diff --git a/usr/src/lib/extendedFILE/spec/sparc/Makefile b/usr/src/lib/extendedFILE/spec/sparc/Makefile new file mode 100644 index 0000000000..53fe30b98a --- /dev/null +++ b/usr/src/lib/extendedFILE/spec/sparc/Makefile @@ -0,0 +1,43 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# lib/extendedFILE/spec/sparc/Makefile + +.KEEP_STATE: + +include ../Makefile.targ + +# Add arch specific objects here +OBJECTS += + +include $(SRC)/lib/Makefile.lib + +# Uncomment the following if the linker complains +#sparc_C_PICFLAGS = -K PIC + +include $(SRC)/lib/Makefile.spec + +install: $(ROOTABILIB) diff --git a/usr/src/lib/extendedFILE/spec/versions b/usr/src/lib/extendedFILE/spec/versions new file mode 100644 index 0000000000..7e4d533257 --- /dev/null +++ b/usr/src/lib/extendedFILE/spec/versions @@ -0,0 +1,25 @@ +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# ident "%Z%%M% %I% %E% SMI" +# diff --git a/usr/src/lib/libc/inc/file64.h b/usr/src/lib/libc/inc/file64.h index fd71c1c5df..40504d35ec 100644 --- a/usr/src/lib/libc/inc/file64.h +++ b/usr/src/lib/libc/inc/file64.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 1997-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -82,6 +82,7 @@ struct xFILEdata { unsigned char *_end; /* the end of the buffer */ rmutex_t _lock; /* lock for this structure */ mbstate_t _state; /* mbstate_t */ + int _altfd; /* alternate fd if > 255 */ }; #define XFILEINITIALIZER { 0, NULL, RECURSIVEMUTEX, DEFAULTMBSTATE } diff --git a/usr/src/lib/libc/inc/stdiom.h b/usr/src/lib/libc/inc/stdiom.h index d0e93d6efc..108ee6c529 100644 --- a/usr/src/lib/libc/inc/stdiom.h +++ b/usr/src/lib/libc/inc/stdiom.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -170,6 +169,36 @@ extern void close_pid(void); #endif /* _LP64 */ /* + * Internal routines from flush.c + */ +extern int _file_get(FILE *); +extern int _file_set(FILE *, int, const char *); + +/* + * Macros to aid the extended fd FILE work. + * This helps isolate the changes to only the 32-bit code + * since 64-bit Solaris is not affected by this. + */ +#ifdef _LP64 +#define GET_FD(iop) ((iop)->_file) +#define SET_FILE(iop, fd) ((iop)->_file = (fd)) +#else +#define GET_FD(iop) \ + (((iop)->__extendedfd) ? _file_get(iop) : (iop)->_magic) +#define SET_FILE(iop, fd) (iop)->_magic = (fd); (iop)->__extendedfd = 0 +#endif + +/* + * Maximum size of the file descriptor stored in the FILE structure. + */ + +#ifdef _LP64 +#define _FILE_FD_MAX INT_MAX +#else +#define _FILE_FD_MAX 255 +#endif + +/* * Internal routines from fileno.c */ extern int _fileno(FILE *iop); diff --git a/usr/src/lib/libc/port/llib-lc b/usr/src/lib/libc/port/llib-lc index 9930b72c9c..0c213a116c 100644 --- a/usr/src/lib/libc/port/llib-lc +++ b/usr/src/lib/libc/port/llib-lc @@ -145,6 +145,7 @@ #include <spawn.h> #include <inttypes.h> #include <getopt.h> +#include <stdio_ext.h> #if defined(__i386) #include <sys/sysi86.h> #endif @@ -1709,16 +1710,6 @@ extern int getloadavg(double [], int); extern long pcsample(uintptr_t [], long); -extern size_t __fbufsize(FILE *stream); -extern int __freading(FILE *stream); -extern int __fwriting(FILE *stream); -extern int __freadable(FILE *stream); -extern int __fwritable(FILE *stream); -extern int __flbf(FILE *stream); -extern void __fpurge(FILE *stream); -extern size_t __fpending(FILE *stream); -extern void _flushlbf(void); - int fstat(int, struct stat *); int stat(const char *_RESTRICT_KYWD, struct stat *_RESTRICT_KYWD); int lstat(const char *_RESTRICT_KYWD, struct stat *_RESTRICT_KYWD); diff --git a/usr/src/lib/libc/port/stdio/_endopen.c b/usr/src/lib/libc/port/stdio/_endopen.c index a0236497a0..e58a779cc5 100644 --- a/usr/src/lib/libc/port/stdio/_endopen.c +++ b/usr/src/lib/libc/port/stdio/_endopen.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -66,9 +65,8 @@ FILE * _endopen(const char *name, const char *type, FILE *iop, int largefile) { - int oflag, fd; + int oflag, fd, fflag; char plus; - rmutex_t *lk; if (iop == NULL) return (NULL); @@ -78,19 +76,24 @@ _endopen(const char *name, const char *type, FILE *iop, int largefile) return (NULL); case 'r': oflag = O_RDONLY; + fflag = _IOREAD; break; case 'w': oflag = O_WRONLY | O_TRUNC | O_CREAT; + fflag = _IOWRT; break; case 'a': oflag = O_WRONLY | O_APPEND | O_CREAT; + fflag = _IOWRT; break; } /* UNIX ignores 'b' and treats text and binary the same */ if ((plus = type[1]) == 'b') plus = type[2]; - if (plus == '+') + if (plus == '+') { oflag = (oflag & ~(O_RDONLY | O_WRONLY)) | O_RDWR; + fflag = _IORW; + } /* select small or large file open based on flag */ if (largefile) { @@ -101,36 +104,21 @@ _endopen(const char *name, const char *type, FILE *iop, int largefile) if (fd < 0) return (NULL); + /* As long as we make sure _flag stays != 0, we don't need to lock */ #ifdef _LP64 iop->_file = fd; + iop->_flag = (iop->_flag & ~0377) | fflag; #else - if (fd > UCHAR_MAX) { + if (fd <= _FILE_FD_MAX) { + SET_FILE(iop, fd); + } else if (_file_set(iop, fd, type) != 0) { + /* errno set in _file_set() */ (void) close(fd); - errno = EMFILE; return (NULL); } - iop->_file = (unsigned char)fd; /* assume fits in unsigned char */ + iop->_flag = fflag; #endif /* _LP64 */ - FLOCKFILE(lk, iop); /* this lock may be unnecessary */ - -#ifdef _LP64 - iop->_flag &= ~0377; /* clear lower 8-bits */ - if (plus == '+') - iop->_flag |= _IORW; - else if (type[0] == 'r') - iop->_flag |= _IOREAD; - else - iop->_flag |= _IOWRT; -#else - if (plus == '+') - iop->_flag = _IORW; - else if (type[0] == 'r') - iop->_flag = _IOREAD; - else - iop->_flag = _IOWRT; -#endif /* _LP64 */ - FUNLOCKFILE(lk); if (oflag == (O_WRONLY | O_APPEND | O_CREAT)) { /* type == "a" */ if (lseek64(fd, (off64_t)0, SEEK_END) < (off64_t)0) { (void) close(fd); diff --git a/usr/src/lib/libc/port/stdio/_filbuf.c b/usr/src/lib/libc/port/stdio/_filbuf.c index 19605a7ef7..a1c4591e46 100644 --- a/usr/src/lib/libc/port/stdio/_filbuf.c +++ b/usr/src/lib/libc/port/stdio/_filbuf.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,16 +18,17 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +#pragma ident "%Z%%M% %I% %E% SMI" + #pragma weak _filbuf = __filbuf @@ -117,7 +117,7 @@ _filbuf(FILE *iop) nbyte = 1; else nbyte = endbuf - iop->_base; - if ((res = read(iop->_file, (char *)iop->_base, nbyte)) > 0) { + if ((res = read(GET_FD(iop), (char *)iop->_base, nbyte)) > 0) { iop->_cnt = res - 1; return (*iop->_ptr++); } diff --git a/usr/src/lib/libc/port/stdio/_findbuf.c b/usr/src/lib/libc/port/stdio/_findbuf.c index d44b22817c..cbb323c3eb 100644 --- a/usr/src/lib/libc/port/stdio/_findbuf.c +++ b/usr/src/lib/libc/port/stdio/_findbuf.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,16 +18,17 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +#pragma ident "%Z%%M% %I% %E% SMI" + #define _LARGEFILE64_SOURCE 1 @@ -51,7 +51,7 @@ Uchar * _findbuf(FILE *iop) { - int fd = iop->_file; + int fd = GET_FD(iop); Uchar *buf; int size = BUFSIZ; Uchar *endbuf; diff --git a/usr/src/lib/libc/port/stdio/_flsbuf.c b/usr/src/lib/libc/port/stdio/_flsbuf.c index ad4683a868..a3f6e9cf68 100644 --- a/usr/src/lib/libc/port/stdio/_flsbuf.c +++ b/usr/src/lib/libc/port/stdio/_flsbuf.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,16 +18,17 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +#pragma ident "%Z%%M% %I% %E% SMI" + #pragma weak _flsbuf = __flsbuf #include "synonyms.h" @@ -71,7 +71,7 @@ _flsbuf(int ch, FILE *iop) /* flush (write) buffer, save ch, */ case _IONBF | _IOWRT: /* okay to do no-buffered case */ iop->_cnt = 0; uch = (unsigned char)ch; - if (write(iop->_file, (char *)&uch, 1) != 1) + if (write(GET_FD(iop), (char *)&uch, 1) != 1) iop->_flag |= _IOERR; goto out; } diff --git a/usr/src/lib/libc/port/stdio/fdopen.c b/usr/src/lib/libc/port/stdio/fdopen.c index c0908f5f89..4865ec9a39 100644 --- a/usr/src/lib/libc/port/stdio/fdopen.c +++ b/usr/src/lib/libc/port/stdio/fdopen.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -25,11 +24,10 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +#pragma ident "%Z%%M% %I% %E% SMI" /* * Unix routine to do an "fopen" on file descriptor @@ -62,28 +60,14 @@ fdopen(int fd, const char *type) /* associate file desc. with stream */ char plus; unsigned char flag; - /* Sets EBADF for bad fds */ if (fcntl(fd, F_GETFD) == -1) return (NULL); -#ifdef _LP64 if ((iop = _findiop()) == 0) { errno = ENOMEM; return (NULL); } - iop->_file = fd; -#else - if (fd > UCHAR_MAX) { - errno = EMFILE; - return (NULL); - } - if ((iop = _findiop()) == 0) { - errno = ENOMEM; - return (NULL); - } - iop->_file = (unsigned char)fd; -#endif /* _LP64 */ switch (type[0]) { default: @@ -106,5 +90,17 @@ fdopen(int fd, const char *type) /* associate file desc. with stream */ flag = _IORW; iop->_flag = flag; +#ifdef _LP64 + iop->_file = fd; +#else + if (fd <= _FILE_FD_MAX) { + SET_FILE(iop, fd); + } else if (_file_set(iop, fd, type) != 0) { + /* errno set by _file_set () */ + iop->_flag = 0; /* release iop */ + return (NULL); + } +#endif /* _LP64 */ + return (iop); } diff --git a/usr/src/lib/libc/port/stdio/fileno.c b/usr/src/lib/libc/port/stdio/fileno.c index 21fc215eba..643ee4cb01 100644 --- a/usr/src/lib/libc/port/stdio/fileno.c +++ b/usr/src/lib/libc/port/stdio/fileno.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -44,5 +43,5 @@ int _fileno(FILE *iop) { - return (iop->_file); + return (GET_FD(iop)); } diff --git a/usr/src/lib/libc/port/stdio/flush.c b/usr/src/lib/libc/port/stdio/flush.c index e0bdb699cd..02cb43249e 100644 --- a/usr/src/lib/libc/port/stdio/flush.c +++ b/usr/src/lib/libc/port/stdio/flush.c @@ -33,6 +33,7 @@ #include "synonyms.h" #include "mtlib.h" #include "file64.h" +#include "../gen/_libc_gettext.h" #define _iob __iob @@ -48,6 +49,7 @@ #include <sys/stat.h> #include <stddef.h> #include <errno.h> +#include <fcntl.h> #undef end @@ -63,6 +65,8 @@ #define FPDECL(fp) FILE *fp #define FIRSTFP(lp, fp) fp = lp->iobp #define NEXTFP(fp) fp++ +#define FPLOCK(fp) &fp->_lock +#define FPSTATE(fp) &fp->_state #define xFILE FILE @@ -72,6 +76,10 @@ #define FIRSTFP(lp, fp) x##fp = lp->iobp; \ fp = x##fp ? &x##fp->_iob : &_iob[0] #define NEXTFP(fp) (x##fp ? fp = &(++x##fp)->_iob : ++fp) +#define FPLOCK(fp) x##fp ? \ + &x##fp->xlock : &_xftab[IOPIND(fp)]._lock +#define FPSTATE(fp) x##fp ? \ + &x##fp->xstate : &_xftab[IOPIND(fp)]._state /* The extended 32-bit file structure for use in link buffers */ typedef struct xFILE { @@ -135,19 +143,11 @@ static struct _link_ *lastlink = NULL; static int fcloses; static int nchunks; -static rwlock_t _first_link_lock = DEFAULTRWLOCK; +static mutex_t _first_link_lock = DEFAULTMUTEX; -static int _fflush_u_iops(void); +static int _fflush_l_iops(void); static FILE *getiop(FILE *, rmutex_t *, mbstate_t *); -#define GETIOP(fp, lk, mb) {FILE *ret; \ - if ((ret = getiop((fp), __libc_threaded? (lk): NULL, (mb))) != NULL) { \ - if (__libc_threaded) \ - (void) __rw_unlock(&_first_link_lock); \ - return (ret); \ - }; \ - } - /* * All functions that understand the linked list of iob's follow. */ @@ -164,7 +164,7 @@ __cleanup(void) /* called at process end to flush ouput streams */ void stdio_locks() { - (void) __rw_wrlock(&_first_link_lock); + (void) __mutex_lock(&_first_link_lock); /* * XXX: We should acquire all of the iob locks here. */ @@ -176,7 +176,7 @@ stdio_unlocks() /* * XXX: We should release all of the iob locks here. */ - (void) __rw_unlock(&_first_link_lock); + (void) __mutex_unlock(&_first_link_lock); } void @@ -185,22 +185,43 @@ _flushlbf(void) /* fflush() all line-buffered streams */ FPDECL(fp); int i; struct _link_ *lp; + /* Allow compiler to optimize the loop */ + int threaded = __libc_threaded; - if (__libc_threaded) - (void) __rw_rdlock(&_first_link_lock); + if (threaded) + (void) __mutex_lock(&_first_link_lock); lp = &__first_link; do { FIRSTFP(lp, fp); for (i = lp->niob; --i >= 0; NEXTFP(fp)) { - if ((fp->_flag & (_IOLBF | _IOWRT)) == - (_IOLBF | _IOWRT)) - (void) _fflush_u(fp); + /* + * The additional _IONBF check guards againsts + * allocated but uninitialized iops (see _findiop). + * We also automatically skip non allocated iop's. + * Don't block on locks. + */ + if ((fp->_flag & (_IOLBF | _IOWRT | _IONBF)) == + (_IOLBF | _IOWRT)) { + if (threaded) { + rmutex_t *lk = FPLOCK(fp); + if (rmutex_trylock(lk) != 0) + continue; + /* Recheck after locking */ + if ((fp->_flag & (_IOLBF | _IOWRT)) == + (_IOLBF | _IOWRT)) { + (void) _fflush_u(fp); + } + (void) rmutex_unlock(lk); + } else { + (void) _fflush_u(fp); + } + } } } while ((lp = lp->next) != NULL); - if (__libc_threaded) - (void) __rw_unlock(&_first_link_lock); + if (threaded) + (void) __mutex_unlock(&_first_link_lock); } /* allocate an unused stream; NULL if cannot */ @@ -232,9 +253,10 @@ _findiop(void) struct _link_ *hdr; FPDECL(fp); int i; + int threaded = __libc_threaded; - if (__libc_threaded) - (void) __rw_wrlock(&_first_link_lock); + if (threaded) + (void) __mutex_lock(&_first_link_lock); if (lastlink == NULL) { rescan: @@ -258,13 +280,18 @@ rescan: FIRSTFP(lp, fp); for (i = lp->niob; --i >= 0; NEXTFP(fp)) { -#ifdef _LP64 - GETIOP(fp, &fp->_lock, &fp->_state); -#else - GETIOP(fp, - xfp ? &xfp->xlock : &_xftab[IOPIND(fp)]._lock, - xfp ? &xfp->xstate : &_xftab[IOPIND(fp)]._state); -#endif /* _LP64 */ + FILE *ret; + if (threaded) { + ret = getiop(fp, FPLOCK(fp), FPSTATE(fp)); + if (ret != NULL) { + (void) __mutex_unlock(&_first_link_lock); + return (ret); + } + } else { + ret = getiop(fp, NULL, FPSTATE(fp)); + if (ret != NULL) + return (ret); + } } } while ((lastlink = lp = lp->next) != NULL); @@ -288,8 +315,8 @@ rescan: * Need to allocate another and put it in the linked list. */ if ((pkgp = malloc(sizeof (Pkg))) == NULL) { - if (__libc_threaded) - (void) __rw_unlock(&_first_link_lock); + if (threaded) + (void) __mutex_unlock(&_first_link_lock); return (NULL); } @@ -355,8 +382,8 @@ rescan: fp->_ptr = 0; fp->_base = 0; fp->_flag = 0377; /* claim the fp by setting low 8 bits */ - if (__libc_threaded) - (void) __rw_unlock(&_first_link_lock); + if (threaded) + (void) __mutex_unlock(&_first_link_lock); return (fp); } @@ -369,7 +396,7 @@ isseekable(FILE *iop) save_errno = errno; - if (fstat64(iop->_file, &fstatbuf) != 0) { + if (fstat64(GET_FD(iop), &fstatbuf) != 0) { /* * when we don't know what it is we'll * do the old behaviour and flush @@ -452,8 +479,8 @@ _setbufend(FILE *iop, Uchar *end) /* set the end pointer for this iop */ * old _bufend macro. This is *so* broken, fileno() * is not the proper index. */ - if (iop->_file < _NFILE) - _bufendtab[iop->_file] = end; + if (iop->_magic < _NFILE) + _bufendtab[iop->_magic] = end; } @@ -523,8 +550,9 @@ _xflsbuf(FILE *iop) _bufsync(iop, bufend); if (n > 0) { + int fd = GET_FD(iop); while ((num_wrote = - write(iop->_file, base, (size_t)n)) != n) { + write(fd, base, (size_t)n)) != n) { if (num_wrote <= 0) { iop->_flag |= _IOERR; return (EOF); @@ -548,56 +576,86 @@ fflush(FILE *iop) res = _fflush_u(iop); FUNLOCKFILE(lk); } else { - res = _fflush_u_iops(); /* flush all iops */ + res = _fflush_l_iops(); /* flush all iops */ } return (res); } static int -_fflush_u_iops(void) /* flush all buffers */ +_fflush_l_iops(void) /* flush all buffers */ { FPDECL(iop); int i; struct _link_ *lp; int res = 0; + rmutex_t *lk; + /* Allow the compiler to optimize the load out of the loop */ + int threaded = __libc_threaded; - if (__libc_threaded) - (void) __rw_rdlock(&_first_link_lock); + if (threaded) + (void) __mutex_lock(&_first_link_lock); lp = &__first_link; do { /* - * Don't grab the locks for these file pointers - * since they are supposed to be flushed anyway - * It could also be the case in which the 2nd - * portion (base and lock) are not initialized + * We need to grab the file locks or file corruption + * will happen. But we first check the flags field + * knowing that when it is 0, it isn't allocated and + * cannot be allocated while we're holding the + * _first_link_lock. And when _IONBF is set (also the + * case when _flag is 0377, or alloc in progress), we + * also ignore it. + * + * Ignore locked streams; it will appear as if + * concurrent updates happened after fflush(NULL). Note + * that we even attempt to lock if the locking is set to + * "by caller". We don't want to penalize callers of + * __fsetlocking() by not flushing their files. Note: if + * __fsetlocking() callers don't employ any locking, they + * may still face corruption in fflush(NULL); but that's + * no change from earlier releases. */ FIRSTFP(lp, iop); for (i = lp->niob; --i >= 0; NEXTFP(iop)) { - if (!(iop->_flag & _IONBF)) { - /* - * don't need to worry about the _IORW case - * since the iop will also marked with _IOREAD - * or _IOWRT whichever we are really doing - */ - if (iop->_flag & _IOWRT) { /* flush write buffers */ - res |= _fflush_u(iop); - } else if (iop->_flag & _IOREAD) { + unsigned int flag = iop->_flag; + + /* flag 0, flag 0377, or _IONBF set */ + if (flag == 0 || (flag & _IONBF) != 0) + continue; + + if (threaded) { + lk = FPLOCK(iop); + if (rmutex_trylock(lk) != 0) + continue; + } + + if (!(iop->_flag & _IONBF)) { /* - * flush seekable read buffers - * don't flush non-seekable read buffers + * don't need to worry about the _IORW case + * since the iop will also marked with _IOREAD + * or _IOWRT whichever we are really doing */ - if (GET_SEEKABLE(iop)) { - res |= _fflush_u(iop); - } + if (iop->_flag & _IOWRT) { + /* Flush write buffers */ + res |= _fflush_u(iop); + } else if (iop->_flag & _IOREAD) { + /* + * flush seekable read buffers + * don't flush non-seekable read buffers + */ + if (GET_SEEKABLE(iop)) { + res |= _fflush_u(iop); + } + } } - } + if (threaded) + (void) rmutex_unlock(lk); } } while ((lp = lp->next) != NULL); - if (__libc_threaded) - (void) __rw_unlock(&_first_link_lock); + if (threaded) + (void) __mutex_unlock(&_first_link_lock); return (res); } @@ -609,7 +667,7 @@ _fflush_u(FILE *iop) /* this portion is always assumed locked */ if (!(iop->_flag & _IOWRT)) { - (void) lseek64(iop->_file, -iop->_cnt, SEEK_CUR); + (void) lseek64(GET_FD(iop), -iop->_cnt, SEEK_CUR); iop->_cnt = 0; /* needed for ungetc & multibyte pushbacks */ iop->_ptr = iop->_base; @@ -647,7 +705,7 @@ fclose(FILE *iop) /* Is not unbuffered and opened for read and/or write ? */ if (!(iop->_flag & _IONBF) && (iop->_flag & (_IOWRT | _IOREAD | _IORW))) res = _fflush_u(iop); - if (close(iop->_file) < 0) + if (close(GET_FD(iop)) < 0) res = EOF; if (iop->_flag & _IOMYBUF) { (void) free((char *)iop->_base - PUSHBACK); @@ -659,10 +717,10 @@ fclose(FILE *iop) FUNLOCKFILE(lk); if (__libc_threaded) - (void) __rw_wrlock(&_first_link_lock); + (void) __mutex_lock(&_first_link_lock); fcloses++; if (__libc_threaded) - (void) __rw_unlock(&_first_link_lock); + (void) __mutex_unlock(&_first_link_lock); return (res); } @@ -679,7 +737,7 @@ close_fd(FILE *iop) /* Is not unbuffered and opened for read and/or write ? */ if (!(iop->_flag & _IONBF) && (iop->_flag & (_IOWRT | _IOREAD | _IORW))) res = _fflush_u(iop); - if (close(iop->_file) < 0) + if (close(GET_FD(iop)) < 0) res = EOF; if (iop->_flag & _IOMYBUF) { (void) free((char *)iop->_base - PUSHBACK); @@ -736,4 +794,109 @@ _getmbstate(FILE *iop) return (NULL); } + +/* + * More 32-bit only functions. + * They lookup/set large fd's for extended FILE support. + */ + +/* + * The negative value indicates that Extended fd FILE's has not + * been enabled by the user. + */ +static int bad_fd = -1; + +int +_file_get(FILE *iop) +{ + int altfd; + + /* + * Failure indicates a FILE * not allocated through stdio; + * it means the flag values are probably bogus and that if + * a file descriptor is set, it's in _magic. + * Inline getxfdat() for performance reasons. + */ + if (STDIOP(iop)) + altfd = _xftab[IOPIND(iop)]._altfd; + else if (VALIDXFILE(FILEx(iop))) + altfd = FILEx(iop)->_xdat._altfd; + else + return (iop->_magic); + /* + * if this is not an internal extended FILE then check + * if _file is being changed from underneath us. + * It should not be because if + * it is then then we lose our ability to guard against + * silent data corruption. + */ + if (!iop->__xf_nocheck && bad_fd > -1 && iop->_magic != bad_fd) { + /* LINTED: variable format specifier */ + (void) fprintf(stderr, _libc_gettext( + "Application violated extended FILE safety mechanism.\n" + "Please read the man page for extendedFILE.\nAborting\n")); + abort(); + } + return (altfd); +} + +int +_file_set(FILE *iop, int fd, const char *type) +{ + struct xFILEdata *dat; + int Fflag; + + /* Already known to contain at least one byte */ + while (*++type != '\0') + ; + + Fflag = type[-1] == 'F'; + if (!Fflag && bad_fd < 0) { + errno = EMFILE; + return (-1); + } + + dat = getxfdat(iop); + iop->__extendedfd = 1; + iop->__xf_nocheck = Fflag; + dat->_altfd = fd; + iop->_magic = (unsigned char)bad_fd; + return (0); +} + +/* + * Activates extended fd's in FILE's + */ + +static const int tries[] = {196, 120, 60, 3}; +#define NTRIES (sizeof (tries)/sizeof (int)) + +int +enable_extended_FILE_stdio(int fd, int action) +{ + int i; + + if (action < 0) + action = SIGABRT; /* default signal */ + + if (fd < 0) { + /* + * search for an available fd and make it the badfd + */ + for (i = 0; i < NTRIES; i++) { + fd = fcntl(tries[i], F_BADFD, action); + if (fd >= 0) + break; + } + if (fd < 0) /* failed to find an available fd */ + return (-1); + } else { + /* caller requests that fd be the chosen badfd */ + int nfd = fcntl(fd, F_BADFD, action); + if (nfd < 0 || nfd != fd) + return (-1); + } + bad_fd = fd; + return (0); +} #endif diff --git a/usr/src/lib/libc/port/stdio/fputs.c b/usr/src/lib/libc/port/stdio/fputs.c index 58da9af2bc..1ab3c57be5 100644 --- a/usr/src/lib/libc/port/stdio/fputs.c +++ b/usr/src/lib/libc/port/stdio/fputs.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,16 +18,17 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +#pragma ident "%Z%%M% %I% %E% SMI" + /* * Ptr args aren't checked for NULL because the program would be a @@ -118,9 +118,9 @@ fputs(const char *ptr, FILE *iop) /* write out to an unbuffered file */ ssize_t num_wrote; ssize_t count = (ssize_t)ptrlen; + int fd = GET_FD(iop); - while ((num_wrote = write(iop->_file, ptr, - (size_t)count)) != count) { + while ((num_wrote = write(fd, ptr, (size_t)count)) != count) { if (num_wrote <= 0) { iop->_flag |= _IOERR; FUNLOCKFILE(lk); diff --git a/usr/src/lib/libc/port/stdio/popen.c b/usr/src/lib/libc/port/stdio/popen.c index c181f8abd8..6168a8c13b 100644 --- a/usr/src/lib/libc/port/stdio/popen.c +++ b/usr/src/lib/libc/port/stdio/popen.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,16 +18,17 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +#pragma ident "%Z%%M% %I% %E% SMI" + #pragma weak pclose = _pclose #pragma weak popen = _popen @@ -55,10 +55,6 @@ #define RDR 0 #define WTR 1 -#ifndef _LP64 -#define MAX_FD (1 << (NBBY * (unsigned)sizeof (_lastbuf->_file))) /* now 256 */ -#endif /* _LP64 */ - static int _insert_nolock(pid_t, int); extern int __xpg4; /* defined in _xpg4.c; 0 if not xpg4-compiled program */ @@ -96,16 +92,6 @@ popen(const char *cmd, const char *mode) if (pipe(p) < 0) return (NULL); -#ifndef _LP64 - /* check that the fd's are in range for a struct FILE */ - if ((p[WTR] >= MAX_FD) || (p[RDR] >= MAX_FD)) { - (void) close(p[WTR]); - (void) close(p[RDR]); - errno = EMFILE; - return (NULL); - } -#endif /* _LP64 */ - shpath = __xpg4? xpg4_path : sun_path; if (access(shpath, X_OK)) /* XPG4 Requirement: */ shpath = ""; /* force child to fail immediately */ @@ -115,12 +101,19 @@ popen(const char *cmd, const char *mode) /* myside and yourside reverse roles in child */ stdio = tst(0, 1); + /* This will fail more quickly if we run out of fds */ + if ((iop = fdopen(myside, mode)) == NULL) { + (void) close(yourside); + (void) close(myside); + return (NULL); + } + lmutex_lock(&popen_lock); /* in the child, close all pipes from other popen's */ if ((error = posix_spawn_file_actions_init(&fact)) != 0) { lmutex_unlock(&popen_lock); - (void) close(myside); + (void) fclose(iop); (void) close(yourside); errno = error; return (NULL); @@ -140,7 +133,7 @@ popen(const char *cmd, const char *mode) if (error) { lmutex_unlock(&popen_lock); (void) posix_spawn_file_actions_destroy(&fact); - (void) close(myside); + (void) fclose(iop); (void) close(yourside); errno = error; return (NULL); @@ -156,17 +149,12 @@ popen(const char *cmd, const char *mode) (void) close(yourside); if ((errno = error) != 0 || _insert_nolock(pid, myside) == -1) { lmutex_unlock(&popen_lock); - (void) close(myside); + (void) fclose(iop); return (NULL); } lmutex_unlock(&popen_lock); - if ((iop = fdopen(myside, mode)) == NULL) { - (void) _delete(myside); - (void) close(myside); - return (NULL); - } _SET_ORIENTATION_BYTE(iop); return (iop); diff --git a/usr/src/lib/libc/port/stdio/setbuf.c b/usr/src/lib/libc/port/stdio/setbuf.c index 7c96d0feb7..efd2bea743 100644 --- a/usr/src/lib/libc/port/stdio/setbuf.c +++ b/usr/src/lib/libc/port/stdio/setbuf.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,16 +18,17 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +#pragma ident "%Z%%M% %I% %E% SMI" + #include "synonyms.h" #include "file64.h" @@ -45,7 +45,7 @@ void setbuf(FILE *iop, char *abuf) { Uchar *buf = (Uchar *)abuf; - int fno = iop->_file; /* file number */ + int fno = GET_FD(iop); /* file number */ int size = BUFSIZ - _SMBFSZ; Uchar *temp; rmutex_t *lk; diff --git a/usr/src/lib/libc/port/stdio/setvbuf.c b/usr/src/lib/libc/port/stdio/setvbuf.c index 7a7b3957e2..40a075637f 100644 --- a/usr/src/lib/libc/port/stdio/setvbuf.c +++ b/usr/src/lib/libc/port/stdio/setvbuf.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,16 +18,17 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +#pragma ident "%Z%%M% %I% %E% SMI" + #include "synonyms.h" #include "file64.h" @@ -48,6 +48,7 @@ setvbuf(FILE *iop, char *abuf, int type, size_t size) Uchar *temp; int sflag = iop->_flag & _IOMYBUF; rmutex_t *lk; + int fd = GET_FD(iop); FLOCKFILE(lk, iop); iop->_flag &= ~(_IOMYBUF | _IONBF | _IOLBF); @@ -56,14 +57,14 @@ setvbuf(FILE *iop, char *abuf, int type, size_t size) case _IONBF: iop->_flag |= _IONBF; /* file is unbuffered */ #ifndef _STDIO_ALLOCATE - if (iop->_file < 2) { + if (fd < 2) { /* use special buffer for std{in,out} */ - buf = (iop->_file == 0) ? _sibuf : _sobuf; + buf = (fd == 0) ? _sibuf : _sobuf; size = BUFSIZ; } else /* needed for ifdef */ #endif - if (iop->_file < _NFILE) { - buf = _smbuf[iop->_file]; + if (fd < _NFILE) { + buf = _smbuf[fd]; size = _SMBFSZ - PUSHBACK; } else if ((buf = malloc(_SMBFSZ * sizeof (Uchar))) != NULL) { diff --git a/usr/src/lib/libc/port/stdio/vscanf.c b/usr/src/lib/libc/port/stdio/vscanf.c index 986feae37a..1ca2e8db2d 100644 --- a/usr/src/lib/libc/port/stdio/vscanf.c +++ b/usr/src/lib/libc/port/stdio/vscanf.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,16 +18,17 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +#pragma ident "%Z%%M% %I% %E% SMI" + #ifndef _C89_INTMAX32 #pragma weak vscanf = _vscanf @@ -125,7 +125,7 @@ vsscanf(const char *str, const char *fmt, va_list ap) strbuf._flag = _IOREAD | _IOWRT; strbuf._ptr = strbuf._base = (unsigned char *)str; strbuf._cnt = strlen(str); - strbuf._file = _NFILE; + SET_FILE(&strbuf, _NFILE); /* * Mark the stream so that routines called by __doscan_u() diff --git a/usr/src/lib/libc/port/stdio/vwscanf.c b/usr/src/lib/libc/port/stdio/vwscanf.c index 40f21ada91..684163a496 100644 --- a/usr/src/lib/libc/port/stdio/vwscanf.c +++ b/usr/src/lib/libc/port/stdio/vwscanf.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -132,7 +132,8 @@ vswscanf(const wchar_t *wstr, const wchar_t *fmt, va_list ap) strbuf._flag = _IOREAD | _IOWRT; strbuf._ptr = strbuf._base = (unsigned char *)tmp_buf; strbuf._cnt = strlen(tmp_buf); - strbuf._file = _NFILE; + SET_FILE(&strbuf, _NFILE); + /* Probably the following is not required. */ /* _setorientation(&strbuf, _WC_MODE); */ diff --git a/usr/src/lib/libc/spec/private.spec b/usr/src/lib/libc/spec/private.spec index ffe7c63f61..9bc14376fd 100644 --- a/usr/src/lib/libc/spec/private.spec +++ b/usr/src/lib/libc/spec/private.spec @@ -1,13 +1,8 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,6 +17,9 @@ # # CDDL HEADER END # +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# # ident "%Z%%M% %I% %E% SMI" # # lib/libc/spec/private.spec @@ -3346,7 +3344,7 @@ version SUNWprivate_1.1 end # PSARC/2000/492 UNIX03 project -# Bugid 4850735, functions needed to support printf/scanf variable +# Bugid 4850735, functions needed to support printf/scanf variable # sized u/intmax_t for 32-bit libc function _fprintf_c89 @@ -3483,3 +3481,7 @@ function __fseterror_u version SUNWprivate_1.1 end +function _file_set +arch sparc i386 +version SUNWprivate_1.1 +end diff --git a/usr/src/lib/libc/spec/stdio.spec b/usr/src/lib/libc/spec/stdio.spec index 86ed061d1f..561085ce1e 100644 --- a/usr/src/lib/libc/spec/stdio.spec +++ b/usr/src/lib/libc/spec/stdio.spec @@ -1,13 +1,8 @@ -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,6 +17,9 @@ # # CDDL HEADER END # +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# # ident "%Z%%M% %I% %E% SMI" # @@ -60,6 +58,11 @@ version sparc=SYSVABI_1.3 i386=SYSVABI_1.3 sparcv9=SUNW_0.7 \ amd64=SUNW_0.7 end +function enable_extended_FILE_stdio +arch sparc i386 +version sparc=SUNW_1.23 i386=SUNW_1.23 +end + function fclose include <stdio.h> declaration int fclose(FILE *stream) |