summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorcraigm <none@none>2006-04-20 08:17:22 -0700
committercraigm <none@none>2006-04-20 08:17:22 -0700
commita5f69788de7ac07553de47f7fec8c05a9a94c105 (patch)
tree2004e6a579b5b69b2edd0a65453e5a2d7d174f4f /usr/src/lib
parent9c6cb9fca0da6c80b32c97869c5672999211da26 (diff)
downloadillumos-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')
-rw-r--r--usr/src/lib/Makefile1
-rw-r--r--usr/src/lib/extendedFILE/Makefile48
-rw-r--r--usr/src/lib/extendedFILE/Makefile.com67
-rw-r--r--usr/src/lib/extendedFILE/common/extendedFILE.c90
-rw-r--r--usr/src/lib/extendedFILE/i386/Makefile34
-rw-r--r--usr/src/lib/extendedFILE/sparc/Makefile34
-rw-r--r--usr/src/lib/extendedFILE/spec/Makefile59
-rw-r--r--usr/src/lib/extendedFILE/spec/Makefile.targ35
-rw-r--r--usr/src/lib/extendedFILE/spec/extendedFILE.spec26
-rw-r--r--usr/src/lib/extendedFILE/spec/i386/Makefile41
-rw-r--r--usr/src/lib/extendedFILE/spec/sparc/Makefile43
-rw-r--r--usr/src/lib/extendedFILE/spec/versions25
-rw-r--r--usr/src/lib/libc/inc/file64.h9
-rw-r--r--usr/src/lib/libc/inc/stdiom.h35
-rw-r--r--usr/src/lib/libc/port/llib-lc11
-rw-r--r--usr/src/lib/libc/port/stdio/_endopen.c46
-rw-r--r--usr/src/lib/libc/port/stdio/_filbuf.c14
-rw-r--r--usr/src/lib/libc/port/stdio/_findbuf.c14
-rw-r--r--usr/src/lib/libc/port/stdio/_flsbuf.c14
-rw-r--r--usr/src/lib/libc/port/stdio/fdopen.c34
-rw-r--r--usr/src/lib/libc/port/stdio/fileno.c7
-rw-r--r--usr/src/lib/libc/port/stdio/flush.c295
-rw-r--r--usr/src/lib/libc/port/stdio/fputs.c16
-rw-r--r--usr/src/lib/libc/port/stdio/popen.c44
-rw-r--r--usr/src/lib/libc/port/stdio/setbuf.c14
-rw-r--r--usr/src/lib/libc/port/stdio/setvbuf.c21
-rw-r--r--usr/src/lib/libc/port/stdio/vscanf.c14
-rw-r--r--usr/src/lib/libc/port/stdio/vwscanf.c11
-rw-r--r--usr/src/lib/libc/spec/private.spec18
-rw-r--r--usr/src/lib/libc/spec/stdio.spec17
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)