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 | |
parent | 9c6cb9fca0da6c80b32c97869c5672999211da26 (diff) | |
download | illumos-joyent-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
49 files changed, 1115 insertions, 348 deletions
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint index a3c57b9c20..35250a419f 100644 --- a/usr/src/Makefile.lint +++ b/usr/src/Makefile.lint @@ -286,6 +286,7 @@ COMMON_SUBDIRS = \ lib/abi \ lib/auditd_plugins \ lib/crypt_modules \ + lib/extendedFILE \ lib/libadt_jni \ lib/libaio \ lib/libavl \ diff --git a/usr/src/cmd/fmtmsg/Makefile b/usr/src/cmd/fmtmsg/Makefile index 7c8b77a890..c99807ce23 100644 --- a/usr/src/cmd/fmtmsg/Makefile +++ b/usr/src/cmd/fmtmsg/Makefile @@ -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. @@ -22,9 +21,12 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1989 by Sun Microsystems, Inc. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # +#ident "%Z%%M% %I% %E% SMI" + PROG= fmtmsg OBJS= main.o SRCS= $(OBJS:%.o=%.c) @@ -33,7 +35,7 @@ include ../Makefile.cmd .KEEP_STATE: -all: $(PROG) +all: $(PROG) $(PROG): $(OBJS) $(LINK.c) $(OBJS) -o $@ $(LDLIBS) @@ -44,7 +46,6 @@ install: all $(ROOTPROG) clean: $(RM) $(OBJS) -lint: - $(LINT.c) $(SRCS) +lint: lint_SRCS include ../Makefile.targ diff --git a/usr/src/cmd/perl/5.8.4/distrib/patchlevel.h b/usr/src/cmd/perl/5.8.4/distrib/patchlevel.h index 44fc40739c..5d0b31b4d7 100644 --- a/usr/src/cmd/perl/5.8.4/distrib/patchlevel.h +++ b/usr/src/cmd/perl/5.8.4/distrib/patchlevel.h @@ -147,6 +147,7 @@ static char *local_patches[] = { "23106 Numeric comparison operators mustn't compare addresses of ...", "23320 [perl #30066] Memory leak in nested shared data structures ...", "23321 [perl #31459] Bug in read()", + "27722 perlio.c breaks on Solaris/gcc when > 256 FDs are available", "SPRINTF0 - fixes for sprintf formatting issues - CVE-2005-3962", NULL }; diff --git a/usr/src/cmd/perl/5.8.4/distrib/perlio.c b/usr/src/cmd/perl/5.8.4/distrib/perlio.c index 35a982ecc1..618c929cc9 100644 --- a/usr/src/cmd/perl/5.8.4/distrib/perlio.c +++ b/usr/src/cmd/perl/5.8.4/distrib/perlio.c @@ -2831,31 +2831,7 @@ PerlIOStdio_invalidate_fileno(pTHX_ FILE *f) f->_fileno = -1; return 1; # elif defined(__sun__) -# if defined(_LP64) - /* On solaris, if _LP64 is defined, the FILE structure is this: - * - * struct FILE { - * long __pad[16]; - * }; - * - * It turns out that the fd is stored in the top 32 bits of - * file->__pad[4]. The lower 32 bits contain flags. file->pad[5] appears - * to contain a pointer or offset into another structure. All the - * remaining fields are zero. - * - * We set the top bits to -1 (0xFFFFFFFF). - */ - f->__pad[4] |= 0xffffffff00000000L; - assert(fileno(f) == 0xffffffff); -# else /* !defined(_LP64) */ - /* _file is just a unsigned char :-( - Not clear why we dup() rather than using -1 - even if that would be treated as 0xFF - so will - a dup fail ... - */ - f->_file = PerlLIO_dup(fileno(f)); -# endif /* defined(_LP64) */ - return 1; + return 0; # elif defined(__hpux) f->__fileH = 0xff; f->__fileL = 0xff; diff --git a/usr/src/cmd/prtfru/Makefile b/usr/src/cmd/prtfru/Makefile index a35b25c3cb..b200681342 100644 --- a/usr/src/cmd/prtfru/Makefile +++ b/usr/src/cmd/prtfru/Makefile @@ -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. # #pragma ident "%Z%%M% %I% %E% SMI" @@ -38,7 +37,7 @@ CFLAGS += $(CCVERBOSE) CPPFLAGS += -I$(SRC)/lib/libfru/include \ -I$(SRC)/lib/libfruutils LINTFLAGS += -u -LDLIBS += -lfru -lfrureg -lfruutils +EXTRA_LDLIBS = -lfru -lfrureg -lfruutils FILEMODE = 755 OWNER = root @@ -49,7 +48,7 @@ GROUP = bin all: $(PROG) $(PROG): $(OBJS) - $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) $(EXTRA_LDLIBS) $(POST_PROCESS) install: all $(ROOTUSRSBIN) $(ROOTUSRSBINPROG) @@ -57,7 +56,6 @@ install: all $(ROOTUSRSBIN) $(ROOTUSRSBINPROG) $(ROOTUSRSBIN): $(INS.dir) -lint := LDLIBS = lint: lint_SRCS POFILE = $(PROG)_msg.po diff --git a/usr/src/cmd/streams/strcmd/Makefile b/usr/src/cmd/streams/strcmd/Makefile index d286ee1246..181844ba31 100644 --- a/usr/src/cmd/streams/strcmd/Makefile +++ b/usr/src/cmd/streams/strcmd/Makefile @@ -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. @@ -21,7 +20,7 @@ # # ident "%Z%%M% %I% %E% SMI" # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -34,14 +33,14 @@ GROUP= root .KEEP_STATE: -all: $(PROG) +all: $(PROG) install: all $(ROOTPROG) clean: lint: - $(LINT.c) strchg.c - $(LINT.c) strconf.c + $(LINT.c) strchg.c $(LDLIBS) + $(LINT.c) strconf.c $(LDLIBS) include ../../Makefile.targ diff --git a/usr/src/cmd/tip/aculib/Makefile b/usr/src/cmd/tip/aculib/Makefile index 7e90f0bebd..4b35f0edca 100644 --- a/usr/src/cmd/tip/aculib/Makefile +++ b/usr/src/cmd/tip/aculib/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright (c) 1983 Regents of the University of California. @@ -42,4 +42,4 @@ clean: $(RM) $(ACULIB) $(OBJS) core errs lint: - $(LINT.c) $(OBJS:%.o=%.c) + $(LINT.c) $(OBJS:%.o=%.c) $(LDLIBS) diff --git a/usr/src/cmd/users/Makefile b/usr/src/cmd/users/Makefile index 9713429781..78887bc15e 100644 --- a/usr/src/cmd/users/Makefile +++ b/usr/src/cmd/users/Makefile @@ -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. @@ -23,7 +22,7 @@ #ident "%Z%%M% %I% %E% SMI" # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -46,7 +45,6 @@ install: all $(ROOTPROG) clean: $(RM) $(OBJS) -lint: - $(LINT.c) $(SRCS) +lint: lint_SRCS include ../Makefile.targ diff --git a/usr/src/head/stdio_ext.h b/usr/src/head/stdio_ext.h index f3e52daeb1..13e19d171a 100644 --- a/usr/src/head/stdio_ext.h +++ b/usr/src/head/stdio_ext.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,9 +18,10 @@ * * CDDL HEADER END */ + /* - * Copyright (c) 1998, by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ /* @@ -72,6 +72,15 @@ extern size_t __fpending(FILE *stream); extern void _flushlbf(void); extern int __fsetlocking(FILE *stream, int type); +/* + * Extended FILE enabling function. + */ +#if defined(_LP64) && !defined(__lint) +#define enable_extended_FILE_stdio(fd, act) (255) +#else +extern int enable_extended_FILE_stdio(int, int); +#endif + #ifdef __cplusplus } #endif diff --git a/usr/src/head/stdio_impl.h b/usr/src/head/stdio_impl.h index 145af56b4c..54ca353aab 100644 --- a/usr/src/head/stdio_impl.h +++ b/usr/src/head/stdio_impl.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 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -58,11 +58,14 @@ struct __FILE_TAG /* needs to be binary-compatible with old versions */ #endif unsigned char *_base; /* the buffer */ unsigned char _flag; /* the state of the stream */ - unsigned char _file; /* UNIX System file descriptor */ + unsigned char _magic; /* Old home of the file descriptor */ + /* Only fileno(3C) can retrieve the value now */ unsigned __orientation:2; /* the orientation of the stream */ unsigned __ionolock:1; /* turn off implicit locking */ unsigned __seekable:1; /* is file seekable? */ - unsigned __filler:4; + unsigned __extendedfd:1; /* enable extended FILE */ + unsigned __xf_nocheck:1; /* no extended FILE runtime check */ + unsigned __filler:10; }; #endif /* _LP64 */ 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) diff --git a/usr/src/pkgdefs/SUNWcsl/prototype_com b/usr/src/pkgdefs/SUNWcsl/prototype_com index cd058cbfc1..e77828edc6 100644 --- a/usr/src/pkgdefs/SUNWcsl/prototype_com +++ b/usr/src/pkgdefs/SUNWcsl/prototype_com @@ -67,6 +67,7 @@ f none usr/lib/dns/cylink.so.1 755 root bin f none usr/lib/dns/dnssafe.so.1 755 root bin # EXPORT DELETE END f none usr/lib/dns/irs.so.1 755 root bin +f none usr/lib/extendedFILE.so.1 755 root bin f none usr/lib/lib.b 444 root bin s none usr/lib/libadm.so=../../lib/libadm.so.1 s none usr/lib/libadm.so.1=../../lib/libadm.so.1 @@ -152,8 +153,8 @@ s none usr/lib/libldap.so=libldap.so.5 f none usr/lib/libldap.so.5 755 root bin f none usr/lib/libldap.so.4 755 root bin s none usr/lib/liblddbg.so.4=../../lib/liblddbg.so.4 -s none usr/lib/liblgrp.so=./liblgrp.so.1 -f none usr/lib/liblgrp.so.1 755 root bin +s none usr/lib/liblgrp.so=./liblgrp.so.1 +f none usr/lib/liblgrp.so.1 755 root bin s none usr/lib/liblm.so=./liblm.so.1 f none usr/lib/liblm.so.1 755 root bin f none usr/lib/libmail.so.1 755 root bin diff --git a/usr/src/ucblib/libucb/inc/stdiom.h b/usr/src/ucblib/libucb/inc/stdiom.h index 0ec6e4940b..0cd4d59114 100644 --- a/usr/src/ucblib/libucb/inc/stdiom.h +++ b/usr/src/ucblib/libucb/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. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1997 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -98,6 +97,12 @@ extern int _xflsbuf(FILE *iop); */ extern Uchar *_findbuf(FILE *iop); +#ifndef _LP64 +extern int _file_set(FILE *, int, const char *); +#define SET_FILE(iop, fd) (iop)->_magic = (fd); (iop)->__extendedfd = 0 +#define _FILE_FD_MAX 255 +#endif + /* * The following macros improve performance of the stdio by reducing the * number of calls to _bufsync and _wrtchk. _needsync checks whether diff --git a/usr/src/ucblib/libucb/port/gen/setbuffer.c b/usr/src/ucblib/libucb/port/gen/setbuffer.c index 65983dca4b..47aa76f88b 100644 --- a/usr/src/ucblib/libucb/port/gen/setbuffer.c +++ b/usr/src/ucblib/libucb/port/gen/setbuffer.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,11 +18,6 @@ * * CDDL HEADER END */ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ @@ -37,6 +31,11 @@ * contributors. */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + #pragma ident "%Z%%M% %I% %E% SMI" /*LINTLIBRARY*/ @@ -53,7 +52,7 @@ void setbuffer(FILE *iop, char *abuf, int asize) { Uchar *buf = (Uchar *)abuf; - int fno = iop->_file; /* file number */ + int fno = fileno(iop); /* file number */ int size = asize - _SMBFSZ; Uchar *temp; diff --git a/usr/src/ucblib/libucb/port/stdio/fopen.c b/usr/src/ucblib/libucb/port/stdio/fopen.c index edfa76228e..c6fcb4ee42 100644 --- a/usr/src/ucblib/libucb/port/stdio/fopen.c +++ b/usr/src/ucblib/libucb/port/stdio/fopen.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 1998 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -74,6 +74,7 @@ _endopen(const char *file, const char *mode, FILE *iop, int largefile) default: return (NULL); } + if (largefile) { fd = open64(file, oflag, 0666); /* mapped to open() for V9 */ } else { @@ -82,7 +83,17 @@ _endopen(const char *file, const char *mode, FILE *iop, int largefile) if (fd < 0) return (NULL); iop->_cnt = 0; - iop->_file = (unsigned char) fd; +#ifdef _LP64 + iop->_file = fd; +#else + if (fd <= _FILE_FD_MAX) { + SET_FILE(iop, fd); + } else if (_file_set(iop, fd, mode) != 0) { + /* errno set in _file_set() */ + (void) close(fd); + return (NULL); + } +#endif iop->_flag = plus ? _IORW : (mode[0] == 'r') ? _IOREAD : _IOWRT; if (mode[0] == 'a') { if ((lseek64(fd, 0L, SEEK_END)) < 0) { diff --git a/usr/src/uts/common/os/fio.c b/usr/src/uts/common/os/fio.c index 4531e27cd2..b31c9c7c2e 100644 --- a/usr/src/uts/common/os/fio.c +++ b/usr/src/uts/common/os/fio.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,14 +18,15 @@ * * CDDL HEADER END */ + +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - #pragma ident "%Z%%M% %I% %E% SMI" #include <sys/types.h> @@ -577,6 +577,10 @@ getf(int fd) UF_ENTER(ufp, fip, fd); if ((fp = ufp->uf_file) == NULL) { UF_EXIT(ufp); + + if (fd == fip->fi_badfd && fip->fi_action > 0) + tsignal(curthread, fip->fi_action); + return (NULL); } ufp->uf_refcnt++; @@ -599,7 +603,9 @@ getf(int fd) * Close whatever file currently occupies the file descriptor slot * and install the new file, usually NULL, in the file descriptor slot. * The close must complete before we release the file descriptor slot. - * We return the error number from closef(). + * If newfp != NULL we only return an error if we can't allocate the + * slot so the caller knows that it needs to free the filep; + * in the other cases we return the error number from closef(). */ int closeandsetf(int fd, file_t *newfp) @@ -626,6 +632,12 @@ closeandsetf(int fd, file_t *newfp) * new non-NULL file pointer. */ mutex_enter(&fip->fi_lock); + if (fd == fip->fi_badfd) { + mutex_exit(&fip->fi_lock); + if (fip->fi_action > 0) + tsignal(curthread, fip->fi_action); + return (EBADF); + } UF_ENTER(ufp, fip, fd); while (ufp->uf_busy && ufp->uf_file == NULL) { mutex_exit(&fip->fi_lock); @@ -755,7 +767,8 @@ closeandsetf(int fd, file_t *newfp) setf(fd, newfp); - return (error); + /* Only return closef() error when closing is all we do */ + return (newfp == NULL ? error : 0); } /* @@ -950,6 +963,11 @@ ufalloc_file(int start, file_t *fp) for (;;) { mutex_enter(&fip->fi_lock); fd = fd_find(fip, start); + if (fd >= 0 && fd == fip->fi_badfd) { + start = fd + 1; + mutex_exit(&fip->fi_lock); + continue; + } if ((uint_t)fd < filelimit) break; if (fd >= filelimit) { @@ -1255,6 +1273,66 @@ f_setfd(int fd, char flags) (void) f_setfd_error(fd, flags); } +#define BADFD_MIN 3 +#define BADFD_MAX 255 + +/* + * Attempt to allocate a file descriptor which is bad and which + * is "poison" to the application. It cannot be closed (except + * on exec), allocated for a different use, etc. + */ +int +f_badfd(int start, int *fdp, int action) +{ + int fdr; + int badfd; + uf_info_t *fip = P_FINFO(curproc); + +#ifdef _LP64 + /* No restrictions on 64 bit _file */ + if (get_udatamodel() != DATAMODEL_ILP32) + return (EINVAL); +#endif + + if (start > BADFD_MAX || start < BADFD_MIN) + return (EINVAL); + + if (action >= NSIG || action < 0) + return (EINVAL); + + mutex_enter(&fip->fi_lock); + badfd = fip->fi_badfd; + mutex_exit(&fip->fi_lock); + + if (badfd != -1) + return (EAGAIN); + + fdr = ufalloc(start); + + if (fdr > BADFD_MAX) { + setf(fdr, NULL); + return (EMFILE); + } + if (fdr < 0) + return (EMFILE); + + mutex_enter(&fip->fi_lock); + if (fip->fi_badfd != -1) { + /* Lost race */ + mutex_exit(&fip->fi_lock); + setf(fdr, NULL); + return (EAGAIN); + } + fip->fi_action = action; + fip->fi_badfd = fdr; + mutex_exit(&fip->fi_lock); + setf(fdr, NULL); + + *fdp = fdr; + + return (0); +} + /* * Allocate a file descriptor and assign it to the vnode "*vpp", * performing the usual open protocol upon it and returning the @@ -1360,6 +1438,10 @@ close_exec(uf_info_t *fip) (void) closef(fp); } } + + /* Reset bad fd */ + fip->fi_badfd = -1; + fip->fi_action = -1; } /* diff --git a/usr/src/uts/common/sys/fcntl.h b/usr/src/uts/common/sys/fcntl.h index 395cbd1a7a..22050a3d54 100644 --- a/usr/src/uts/common/sys/fcntl.h +++ b/usr/src/uts/common/sys/fcntl.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. @@ -20,7 +19,7 @@ * 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. */ @@ -196,6 +195,8 @@ extern "C" { #define F_UNSHARE 41 /* Remove a file share reservation */ #define F_SHARE_NBMAND 43 /* private */ +#define F_BADFD 46 /* Create Poison FD */ + /* * File segment locking set data type - information passed to system by user. */ diff --git a/usr/src/uts/common/sys/file.h b/usr/src/uts/common/sys/file.h index b18c92391d..20300002c5 100644 --- a/usr/src/uts/common/sys/file.h +++ b/usr/src/uts/common/sys/file.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. @@ -24,7 +23,7 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -193,6 +192,7 @@ extern char f_getfd(int); extern int f_setfd_error(int, int); extern void f_setfd(int, char); extern int f_getfl(int, int *); +extern int f_badfd(int, int *, int); extern int fassign(struct vnode **, int, int *); extern void fcnt_add(uf_info_t *, int); extern void close_exec(uf_info_t *); diff --git a/usr/src/uts/common/sys/user.h b/usr/src/uts/common/sys/user.h index f73a462574..7d58d69e8c 100644 --- a/usr/src/uts/common/sys/user.h +++ b/usr/src/uts/common/sys/user.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. @@ -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. */ @@ -117,7 +116,8 @@ typedef struct uf_rlist { */ typedef struct uf_info { kmutex_t fi_lock; /* see below */ - kmutex_t fi_pad; /* unused -- remove in next release */ + int fi_badfd; /* bad file descriptor # */ + int fi_action; /* action to take on bad fd use */ int fi_nfiles; /* number of entries in fi_list[] */ uf_entry_t *volatile fi_list; /* current file list */ uf_rlist_t *fi_rlist; /* retired file lists */ diff --git a/usr/src/uts/common/syscall/fcntl.c b/usr/src/uts/common/syscall/fcntl.c index eec59fd21a..15245e4c8c 100644 --- a/usr/src/uts/common/syscall/fcntl.c +++ b/usr/src/uts/common/syscall/fcntl.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. @@ -21,7 +20,7 @@ */ /* ONC_PLUS EXTRACT START */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -89,6 +88,7 @@ fcntl(int fdes, int cmd, intptr_t arg) struct shr_locowner shr_own; offset_t maxoffset; model_t datamodel; + int fdres; #if defined(_ILP32) && !defined(lint) && defined(_SYSCALL32) ASSERT(sizeof (struct flock) == sizeof (struct flock32)); @@ -123,6 +123,11 @@ fcntl(int fdes, int cmd, intptr_t arg) if ((error = f_getfl(fdes, &flag)) == 0) retval = flag + FOPEN; goto out; + + case F_BADFD: + if ((error = f_badfd(fdes, &fdres, (int)arg)) == 0) + retval = fdres; + goto out; } /* @@ -172,13 +177,25 @@ fcntl(int fdes, int cmd, intptr_t arg) * (which we have to do anyway), then releasef(fdes), * then closeandsetf(). Incrementing f_count ensures * that fp won't disappear after we call releasef(). + * When closeandsetf() fails, we try avoid calling + * closef() because of all the side effects. */ mutex_enter(&fp->f_tlock); fp->f_count++; mutex_exit(&fp->f_tlock); releasef(fdes); - (void) closeandsetf(iarg, fp); - retval = iarg; + if ((error = closeandsetf(iarg, fp)) == 0) { + retval = iarg; + } else { + mutex_enter(&fp->f_tlock); + if (fp->f_count > 1) { + fp->f_count--; + mutex_exit(&fp->f_tlock); + } else { + mutex_exit(&fp->f_tlock); + (void) closef(fp); + } + } goto out; } goto done; |