diff options
39 files changed, 2009 insertions, 1231 deletions
diff --git a/libc/sysdeps/linux/common/bits/in.h b/libc/sysdeps/linux/common/bits/in.h index 14d3db858..6880a2e63 100644 --- a/libc/sysdeps/linux/common/bits/in.h +++ b/libc/sysdeps/linux/common/bits/in.h @@ -25,13 +25,36 @@ /* Options for use with `getsockopt' and `setsockopt' at the IP level. The first word in the comment at the right is the data type used; "bool" means a boolean value stored in an `int'. */ -#define IP_TOS 1 /* int; IP type of service and precedence. */ -#define IP_TTL 2 /* int; IP time to live. */ -#define IP_HDRINCL 3 /* int; Header is included with data. */ -#define IP_OPTIONS 4 /* ip_opts; IP per-packet options. */ +#define IP_OPTIONS 4 /* ip_opts; IP per-packet options. */ +#define IP_HDRINCL 3 /* int; Header is included with data. */ +#define IP_TOS 1 /* int; IP type of service and precedence. */ +#define IP_TTL 2 /* int; IP time to live. */ +#define IP_RECVOPTS 6 /* bool; Receive all IP options w/datagram. */ +/* For BSD compatibility. */ +#define IP_RECVRETOPTS IP_RETOPTS /* bool; Receive IP options for response. */ +#define IP_RETOPTS 7 /* ip_opts; Set/get IP per-packet options. */ +#define IP_MULTICAST_IF 32 /* in_addr; set/get IP multicast i/f */ +#define IP_MULTICAST_TTL 33 /* u_char; set/get IP multicast ttl */ +#define IP_MULTICAST_LOOP 34 /* i_char; set/get IP multicast loopback */ +#define IP_ADD_MEMBERSHIP 35 /* ip_mreq; add an IP group membership */ +#define IP_DROP_MEMBERSHIP 36 /* ip_mreq; drop an IP group membership */ +#define IP_UNBLOCK_SOURCE 37 /* ip_mreq_source: unblock data from source */ +#define IP_BLOCK_SOURCE 38 /* ip_mreq_source: block data from source */ +#define IP_ADD_SOURCE_MEMBERSHIP 39 /* ip_mreq_source: join source group */ +#define IP_DROP_SOURCE_MEMBERSHIP 40 /* ip_mreq_source: leave source group */ +#define IP_MSFILTER 41 +#define MCAST_JOIN_GROUP 42 /* group_req: join any-source group */ +#define MCAST_BLOCK_SOURCE 43 /* group_source_req: block from given group */ +#define MCAST_UNBLOCK_SOURCE 44 /* group_source_req: unblock from given group*/ +#define MCAST_LEAVE_GROUP 45 /* group_req: leave any-source group */ +#define MCAST_JOIN_SOURCE_GROUP 46 /* group_source_req: join source-spec gr */ +#define MCAST_LEAVE_SOURCE_GROUP 47 /* group_source_req: leave source-spec gr*/ +#define MCAST_MSFILTER 48 + +#define MCAST_EXCLUDE 0 +#define MCAST_INCLUDE 1 + #define IP_ROUTER_ALERT 5 /* bool */ -#define IP_RECVOPTS 6 /* bool; Receive all IP options w/datagram. */ -#define IP_RETOPTS 7 /* bool; Set/get IP per-packet options. */ #define IP_PKTINFO 8 /* bool */ #define IP_PKTOPTIONS 9 #define IP_PMTUDISC 10 /* obsolete name? */ @@ -39,29 +62,7 @@ #define IP_RECVERR 11 /* bool */ #define IP_RECVTTL 12 /* bool */ #define IP_RECVTOS 13 /* bool */ -#define IP_MULTICAST_IF 32 /* in_addr; set/get IP multicast i/f */ -#define IP_MULTICAST_TTL 33 /* u_char; set/get IP multicast ttl */ -#define IP_MULTICAST_LOOP 34 /* i_char; set/get IP multicast loopback */ -#define IP_ADD_MEMBERSHIP 35 /* ip_mreq; add an IP group membership */ -#define IP_DROP_MEMBERSHIP 36 /* ip_mreq; drop an IP group membership */ -#define IP_UNBLOCK_SOURCE 37 /* ip_mreq_source: unblock data from source */ -#define IP_BLOCK_SOURCE 38 /* ip_mreq_source: block data from source */ -#define IP_ADD_SOURCE_MEMBERSHIP 39 /* ip_mreq_source: join source group */ -#define IP_DROP_SOURCE_MEMBERSHIP 40 /* ip_mreq_source: leave source group */ -#define IP_MSFILTER 41 -#define MCAST_JOIN_GROUP 42 /* group_req: join any-source group */ -#define MCAST_BLOCK_SOURCE 43 /* group_source_req: block from given group */ -#define MCAST_UNBLOCK_SOURCE 44 /* group_source_req: unblock from given group*/ -#define MCAST_LEAVE_GROUP 45 /* group_req: leave any-source group */ -#define MCAST_JOIN_SOURCE_GROUP 46 /* group_source_req: join source-spec gr */ -#define MCAST_LEAVE_SOURCE_GROUP 47 /* group_source_req: leave source-spec gr*/ -#define MCAST_MSFILTER 48 -#define MCAST_EXCLUDE 0 -#define MCAST_INCLUDE 1 - -/* For BSD compatibility. */ -#define IP_RECVRETOPTS IP_RETOPTS /* bool; Receive IP options for response. */ /* IP_MTU_DISCOVER arguments. */ #define IP_PMTUDISC_DONT 0 /* Never send DF frames. */ @@ -84,14 +85,7 @@ struct ip_opts char ip_opts[40]; /* Actually variable in size. */ }; -/* Structure used for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP. */ -struct ip_mreq - { - struct in_addr imr_multiaddr; /* IP multicast address of group */ - struct in_addr imr_interface; /* local IP address of interface */ - }; - -/* As above but including interface specification by index. */ +/* Like `struct ip_mreq' but including interface specification by index. */ struct ip_mreqn { struct in_addr imr_multiaddr; /* IP multicast address of group */ @@ -111,13 +105,16 @@ struct in_pktinfo The first word in the comment at the right is the data type used; "bool" means a boolean value stored in an `int'. */ #define IPV6_ADDRFORM 1 -#define IPV6_PKTINFO 2 -#define IPV6_HOPOPTS 3 -#define IPV6_DSTOPTS 4 -#define IPV6_RTHDR 5 -#define IPV6_PKTOPTIONS 6 +#define IPV6_2292PKTINFO 2 +#define IPV6_2292HOPOPTS 3 +#define IPV6_2292DSTOPTS 4 +#define IPV6_2292RTHDR 5 +#define IPV6_2292PKTOPTIONS 6 #define IPV6_CHECKSUM 7 -#define IPV6_HOPLIMIT 8 +#define IPV6_2292HOPLIMIT 8 + +#define SCM_SRCRT IPV6_RXSRCRT + #define IPV6_NEXTHOP 9 #define IPV6_AUTHHDR 10 #define IPV6_UNICAST_HOPS 16 @@ -136,7 +133,20 @@ struct in_pktinfo #define IPV6_IPSEC_POLICY 34 #define IPV6_XFRM_POLICY 35 -#define SCM_SRCRT IPV6_RXSRCRT +#define IPV6_RECVPKTINFO 49 +#define IPV6_PKTINFO 50 +#define IPV6_RECVHOPLIMIT 51 +#define IPV6_HOPLIMIT 52 +#define IPV6_RECVHOPOPTS 53 +#define IPV6_HOPOPTS 54 +#define IPV6_RTHDRDSTOPTS 55 +#define IPV6_RECVRTHDR 56 +#define IPV6_RTHDR 57 +#define IPV6_RECVDSTOPTS 58 +#define IPV6_DSTOPTS 59 + +#define IPV6_RECVTCLASS 66 +#define IPV6_TCLASS 67 /* Obsolete synonyms for the above. */ #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP diff --git a/libc/termios/Makefile.in b/libc/termios/Makefile.in index 415f32192..f35f78fa2 100644 --- a/libc/termios/Makefile.in +++ b/libc/termios/Makefile.in @@ -1,43 +1,20 @@ # Makefile for uClibc # # Copyright (C) 2000 by Lineo, inc. -# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -CSRC:=tcgetattr.c tcgetsid.c tcsetattr.c ttyname.c +TERMIOS_DIR := $(top_srcdir)libc/termios +TERMIOS_OUT := $(top_builddir)libc/termios -MSRC:= termios.c -MOBJ:= tcdrain.o tcflow.o tcflush.o tcsendbreak.o tcsetpgrp.o tcgetpgrp.o \ - isatty.o cfgetospeed.o cfgetispeed.o cfsetospeed.o cfsetispeed.o \ - cfmakeraw.o cfsetspeed.o +TERMIOS_SRC := $(wildcard $(TERMIOS_DIR)/*.c) +TERMIOS_OBJ := $(patsubst $(TERMIOS_DIR)/%.c,$(TERMIOS_OUT)/%.o,$(TERMIOS_SRC)) -TERMIOS_DIR:=$(top_srcdir)libc/termios -TERMIOS_OUT:=$(top_builddir)libc/termios +libc-y += $(TERMIOS_OBJ) -TERMIOS_SRC:=$(patsubst %.c,$(TERMIOS_DIR)/%.c,$(CSRC)) -TERMIOS_OBJ:=$(patsubst %.c,$(TERMIOS_OUT)/%.o,$(CSRC)) - -TERMIOS_MSRC:=$(patsubst %.c,$(TERMIOS_DIR)/%.c,$(MSRC)) -TERMIOS_MOBJ:=$(patsubst %.o,$(TERMIOS_OUT)/%.o,$(MOBJ)) -TERMIOS_DEF:=$(patsubst %,-DL_%,$(subst .o,,$(notdir $(TERMIOS_MOBJ)))) - -TERMIOS_OBJS:=$(TERMIOS_OBJ) $(TERMIOS_MOBJ) - -$(TERMIOS_MOBJ): $(TERMIOS_MSRC) - $(compile.m) - -$(TERMIOS_MOBJ:.o=.os): $(TERMIOS_MSRC) - $(compile.m) - -libc-a-y+=$(TERMIOS_OBJS) -libc-so-y+=$(TERMIOS_OBJS:.o=.os) - -CFLAGS-multi-y+=$(TERMIOS_DEF) -libc-multi-y+=$(TERMIOS_SRC) $(TERMIOS_MSRC) - -objclean-y+=termios_objclean +objclean-y += termios_objclean termios_objclean: $(RM) $(TERMIOS_OUT)/*.{o,os} diff --git a/libc/termios/cfmakeraw.c b/libc/termios/cfmakeraw.c new file mode 100644 index 000000000..bf2012489 --- /dev/null +++ b/libc/termios/cfmakeraw.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <termios.h> + +/* Set *T to indicate raw mode. */ +void cfmakeraw (struct termios *t) +{ + t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); + t->c_oflag &= ~OPOST; + t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + t->c_cflag &= ~(CSIZE|PARENB); + t->c_cflag |= CS8; + t->c_cc[VMIN] = 1; /* read returns when one char is available. */ + t->c_cc[VTIME] = 0; +} diff --git a/libc/termios/cfsetspeed.c b/libc/termios/cfsetspeed.c new file mode 100644 index 000000000..0d35d1474 --- /dev/null +++ b/libc/termios/cfsetspeed.c @@ -0,0 +1,173 @@ +/* Copyright (C) 1992,93,96,97,98,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <termios.h> +#include <errno.h> +#include <stddef.h> + +libc_hidden_proto(cfsetispeed) +libc_hidden_proto(cfsetospeed) + +struct speed_struct +{ + speed_t value; + speed_t internal; +}; + +static const struct speed_struct speeds[] = + { +#ifdef B0 + { 0, B0 }, +#endif +#ifdef B50 + { 50, B50 }, +#endif +#ifdef B75 + { 75, B75 }, +#endif +#ifdef B110 + { 110, B110 }, +#endif +#ifdef B134 + { 134, B134 }, +#endif +#ifdef B150 + { 150, B150 }, +#endif +#ifdef B200 + { 200, B200 }, +#endif +#ifdef B300 + { 300, B300 }, +#endif +#ifdef B600 + { 600, B600 }, +#endif +#ifdef B1200 + { 1200, B1200 }, +#endif +#ifdef B1200 + { 1200, B1200 }, +#endif +#ifdef B1800 + { 1800, B1800 }, +#endif +#ifdef B2400 + { 2400, B2400 }, +#endif +#ifdef B4800 + { 4800, B4800 }, +#endif +#ifdef B9600 + { 9600, B9600 }, +#endif +#ifdef B19200 + { 19200, B19200 }, +#endif +#ifdef B38400 + { 38400, B38400 }, +#endif +#ifdef B57600 + { 57600, B57600 }, +#endif +#ifdef B76800 + { 76800, B76800 }, +#endif +#ifdef B115200 + { 115200, B115200 }, +#endif +#ifdef B153600 + { 153600, B153600 }, +#endif +#ifdef B230400 + { 230400, B230400 }, +#endif +#ifdef B307200 + { 307200, B307200 }, +#endif +#ifdef B460800 + { 460800, B460800 }, +#endif +#ifdef B500000 + { 500000, B500000 }, +#endif +#ifdef B576000 + { 576000, B576000 }, +#endif +#ifdef B921600 + { 921600, B921600 }, +#endif +#ifdef B1000000 + { 1000000, B1000000 }, +#endif +#ifdef B1152000 + { 1152000, B1152000 }, +#endif +#ifdef B1500000 + { 1500000, B1500000 }, +#endif +#ifdef B1843200 + { 1843200, B1843200 }, +#endif +#ifdef B2000000 + { 2000000, B2000000 }, +#endif +#ifdef B2500000 + { 2500000, B2500000 }, +#endif +#ifdef B3000000 + { 3000000, B3000000 }, +#endif +#ifdef B3500000 + { 3500000, B3500000 }, +#endif +#ifdef B4000000 + { 4000000, B4000000 }, +#endif +#ifdef B6250000 + { 6250000, B6250000 }, +#endif +#ifdef B12500000 + { 12500000, B12500000 }, +#endif + }; + + +/* Set both the input and output baud rates stored in *TERMIOS_P to SPEED. */ +int cfsetspeed (struct termios *termios_p, speed_t speed) +{ + size_t cnt; + + for (cnt = 0; cnt < sizeof (speeds) / sizeof (speeds[0]); ++cnt) + if (speed == speeds[cnt].internal) + { + cfsetispeed (termios_p, speed); + cfsetospeed (termios_p, speed); + return 0; + } + else if (speed == speeds[cnt].value) + { + cfsetispeed (termios_p, speeds[cnt].internal); + cfsetospeed (termios_p, speeds[cnt].internal); + return 0; + } + + __set_errno (EINVAL); + + return -1; +} diff --git a/libc/termios/isatty.c b/libc/termios/isatty.c new file mode 100644 index 000000000..7532f334b --- /dev/null +++ b/libc/termios/isatty.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <unistd.h> +#include <termios.h> + +libc_hidden_proto(isatty) +libc_hidden_proto(tcgetattr) + +/* Return 1 if FD is a terminal, 0 if not. */ +int isatty (int fd) +{ + struct termios term; + + return tcgetattr (fd, &term) == 0; +} +libc_hidden_def(isatty) diff --git a/libc/termios/speed.c b/libc/termios/speed.c new file mode 100644 index 000000000..52647b9cc --- /dev/null +++ b/libc/termios/speed.c @@ -0,0 +1,97 @@ +/* `struct termios' speed frobnication functions. Linux version. + Copyright (C) 1991,1992,1993,1995,1996,1997,1998,2000,2002,2003 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stddef.h> +#include <errno.h> +#include <termios.h> + +libc_hidden_proto(cfsetispeed) +libc_hidden_proto(cfsetospeed) + +/* This is a gross hack around a kernel bug. If the cfsetispeed functions + is called with the SPEED argument set to zero this means use the same + speed as for output. But we don't have independent input and output + speeds and therefore cannot record this. + + We use an unused bit in the `c_iflag' field to keep track of this + use of `cfsetispeed'. The value here must correspond to the one used + in `tcsetattr.c'. */ +#define IBAUD0 020000000000 + + +/* Return the output baud rate stored in *TERMIOS_P. */ +speed_t cfgetospeed (const struct termios *termios_p) +{ + return termios_p->c_cflag & (CBAUD | CBAUDEX); +} + +/* Return the input baud rate stored in *TERMIOS_P. + Although for Linux there is no difference between input and output + speed, the numerical 0 is a special case for the input baud rate. It + should set the input baud rate to the output baud rate. */ +speed_t cfgetispeed (const struct termios *termios_p) +{ + return ((termios_p->c_iflag & IBAUD0) + ? 0 : termios_p->c_cflag & (CBAUD | CBAUDEX)); +} + +/* Set the output baud rate stored in *TERMIOS_P to SPEED. */ +int cfsetospeed (struct termios *termios_p, speed_t speed) +{ + if ((speed & ~CBAUD) != 0 + && (speed < B57600 || speed > __MAX_BAUD)) + { + __set_errno (EINVAL); + return -1; + } + + termios_p->c_cflag &= ~(CBAUD | CBAUDEX); + termios_p->c_cflag |= speed; + + return 0; +} +libc_hidden_def (cfsetospeed) + + +/* Set the input baud rate stored in *TERMIOS_P to SPEED. + Although for Linux there is no difference between input and output + speed, the numerical 0 is a special case for the input baud rate. It + should set the input baud rate to the output baud rate. */ +int cfsetispeed (struct termios *termios_p, speed_t speed) +{ + if ((speed & ~CBAUD) != 0 + && (speed < B57600 || speed > __MAX_BAUD)) + { + __set_errno (EINVAL); + return -1; + } + + if (speed == 0) + termios_p->c_iflag |= IBAUD0; + else + { + termios_p->c_iflag &= ~IBAUD0; + termios_p->c_cflag &= ~(CBAUD | CBAUDEX); + termios_p->c_cflag |= speed; + } + + return 0; +} +libc_hidden_def (cfsetispeed) diff --git a/libc/termios/tcdrain.c b/libc/termios/tcdrain.c new file mode 100644 index 000000000..a13374cb5 --- /dev/null +++ b/libc/termios/tcdrain.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1995, 1996, 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <termios.h> +#include <sys/ioctl.h> + +libc_hidden_proto(ioctl) + +extern __typeof(tcdrain) __libc_tcdrain; +/* Wait for pending output to be written on FD. */ +int __libc_tcdrain (int fd) +{ + return ioctl(fd, TCSBRK, 1); +} +weak_alias(__libc_tcdrain,tcdrain) diff --git a/libc/termios/tcflow.c b/libc/termios/tcflow.c new file mode 100644 index 000000000..63f96a860 --- /dev/null +++ b/libc/termios/tcflow.c @@ -0,0 +1,30 @@ +/* tcflow -- Suspend or restart transmission on termios file descriptor. + Copyright (C) 1993,1997,2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <termios.h> +#include <sys/ioctl.h> + +libc_hidden_proto(ioctl) + +/* Suspend or restart transmission on FD. */ +int tcflow (int fd, int action) +{ + return ioctl (fd, TCXONC, action); +} diff --git a/libc/termios/tcflush.c b/libc/termios/tcflush.c new file mode 100644 index 000000000..159231fb1 --- /dev/null +++ b/libc/termios/tcflush.c @@ -0,0 +1,31 @@ +/* tcflush -- Flush pending data on termios file descriptor. Linux version. + Copyright (C) 1993,1997,2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <termios.h> +#include <sys/ioctl.h> + +libc_hidden_proto(ioctl) + +/* Flush pending data on FD. */ +int +tcflush (int fd, int queue_selector) +{ + return ioctl (fd, TCFLSH, queue_selector); +} diff --git a/libc/termios/tcgetattr.c b/libc/termios/tcgetattr.c index 3fd6d29d6..726c83a44 100644 --- a/libc/termios/tcgetattr.c +++ b/libc/termios/tcgetattr.c @@ -16,28 +16,31 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define mempcpy __mempcpy - #include <features.h> -#define __USE_GNU #include <string.h> #include <termios.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> +libc_hidden_proto(ioctl) +libc_hidden_proto(memset) +libc_hidden_proto(memcpy) +libc_hidden_proto(mempcpy) +libc_hidden_proto(tcgetattr) + /* The difference here is that the termios structure used in the kernel is not the same as we use in the libc. Therefore we must translate it here. */ #include "kernel_termios.h" /* Put the state of FD into *TERMIOS_P. */ -int attribute_hidden __tcgetattr (int fd, struct termios *termios_p) +int tcgetattr (int fd, struct termios *termios_p) { struct __kernel_termios k_termios; int retval; - retval = __ioctl (fd, TCGETS, &k_termios); + retval = ioctl (fd, TCGETS, &k_termios); termios_p->c_iflag = k_termios.c_iflag; termios_p->c_oflag = k_termios.c_oflag; @@ -55,18 +58,18 @@ int attribute_hidden __tcgetattr (int fd, struct termios *termios_p) if (sizeof (cc_t) == 1 || _POSIX_VDISABLE == 0 || (unsigned char) _POSIX_VDISABLE == (unsigned char) -1) { - __memset (mempcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], + memset (mempcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], __KERNEL_NCCS * sizeof (cc_t)), _POSIX_VDISABLE, (NCCS - __KERNEL_NCCS) * sizeof (cc_t)); #if 0 - __memset ( (__memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], + memset ( (memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], __KERNEL_NCCS * sizeof (cc_t)) + (__KERNEL_NCCS * sizeof (cc_t))) , _POSIX_VDISABLE, (NCCS - __KERNEL_NCCS) * sizeof (cc_t)); #endif } else { size_t cnt; - __memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], + memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], __KERNEL_NCCS * sizeof (cc_t)); for (cnt = __KERNEL_NCCS; cnt < NCCS; ++cnt) @@ -75,4 +78,4 @@ int attribute_hidden __tcgetattr (int fd, struct termios *termios_p) return retval; } -strong_alias(__tcgetattr,tcgetattr) +libc_hidden_def(tcgetattr) diff --git a/libc/termios/tcgetpgrp.c b/libc/termios/tcgetpgrp.c new file mode 100644 index 000000000..241670770 --- /dev/null +++ b/libc/termios/tcgetpgrp.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sys/ioctl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +libc_hidden_proto(tcgetpgrp) +libc_hidden_proto(ioctl) + +/* Return the foreground process group ID of FD. */ +pid_t tcgetpgrp (int fd) +{ + int pgrp; + + if (ioctl (fd, TIOCGPGRP, &pgrp) < 0) + return (pid_t) -1; + return (pid_t) pgrp; +} +libc_hidden_def (tcgetpgrp) diff --git a/libc/termios/tcgetsid.c b/libc/termios/tcgetsid.c index e4ba87ac5..ede8958af 100644 --- a/libc/termios/tcgetsid.c +++ b/libc/termios/tcgetsid.c @@ -2,66 +2,66 @@ This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#define getsid __getsid -#define tcgetpgrp __tcgetpgrp + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ #include <errno.h> #include <termios.h> #include <sys/ioctl.h> #include <sys/types.h> -#define __USE_XOPEN_EXTENDED #include <unistd.h> +libc_hidden_proto(ioctl) +libc_hidden_proto(getsid) +libc_hidden_proto(tcgetpgrp) /* Return the session ID of FD. */ -pid_t tcgetsid (int fd) +pid_t +tcgetsid (fd) + int fd; { - pid_t pgrp; - pid_t sid; + pid_t pgrp; + pid_t sid; #ifdef TIOCGSID - static int tiocgsid_does_not_work; + static int tiocgsid_does_not_work; - if (! tiocgsid_does_not_work) + if (! tiocgsid_does_not_work) { - int serrno = errno; - int sid; + int serrno = errno; - if (__ioctl (fd, TIOCGSID, &sid) < 0) + if (ioctl (fd, TIOCGSID, &sid) < 0) { - if (errno == EINVAL) + if (errno == EINVAL) { - tiocgsid_does_not_work = 1; - __set_errno(serrno); + tiocgsid_does_not_work = 1; + __set_errno (serrno); } - else - return (pid_t) -1; + else + return (pid_t) -1; } - else - return (pid_t) sid; + else + return (pid_t) sid; } #endif - pgrp = tcgetpgrp (fd); - if (pgrp == -1) - return (pid_t) -1; + pgrp = tcgetpgrp (fd); + if (pgrp == -1) + return (pid_t) -1; - sid = getsid (pgrp); - if (sid == -1 && errno == ESRCH) - __set_errno(ENOTTY); + sid = getsid (pgrp); + if (sid == -1 && errno == ESRCH) + __set_errno (ENOTTY); - return sid; + return sid; } diff --git a/libc/termios/tcsendbrk.c b/libc/termios/tcsendbrk.c new file mode 100644 index 000000000..ae04cb947 --- /dev/null +++ b/libc/termios/tcsendbrk.c @@ -0,0 +1,48 @@ +/* Send break to terminal. + Copyright (C) 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <stddef.h> +#include <termios.h> +#include <sys/ioctl.h> + +libc_hidden_proto(ioctl) + +/* Send zero bits on FD. */ +int +tcsendbreak (int fd, int duration) +{ + /* The break lasts 0.25 to 0.5 seconds if DURATION is zero, + and an implementation-defined period if DURATION is nonzero. + We define a positive DURATION to be number of milliseconds to break. */ + if (duration <= 0) + return ioctl (fd, TCSBRK, 0); + +#ifdef TCSBRKP + /* Probably Linux-specific: a positive third TCSBRKP ioctl argument is + defined to be the number of 100ms units to break. */ + return ioctl (fd, TCSBRKP, (duration + 99) / 100); +#else + /* ioctl can't send a break of any other duration for us. + This could be changed to use trickery (e.g. lower speed and + send a '\0') to send the break, but for now just return an error. */ + __set_errno (EINVAL); + return -1; +#endif +} diff --git a/libc/termios/tcsetattr.c b/libc/termios/tcsetattr.c index 3afa1012c..847023f86 100644 --- a/libc/termios/tcsetattr.c +++ b/libc/termios/tcsetattr.c @@ -22,6 +22,10 @@ #include <sys/ioctl.h> #include <sys/types.h> +libc_hidden_proto(tcsetattr) +libc_hidden_proto(memcpy) +libc_hidden_proto(ioctl) + /* The difference here is that the termios structure used in the kernel is not the same as we use in the libc. Therefore we must translate it here. */ @@ -47,7 +51,7 @@ /* Set the state of FD to *TERMIOS_P. */ -int attribute_hidden __tcsetattr (int fd, int optional_actions, const struct termios *termios_p) +int tcsetattr (int fd, int optional_actions, const struct termios *termios_p) { struct __kernel_termios k_termios; unsigned long int cmd; @@ -80,17 +84,17 @@ int attribute_hidden __tcsetattr (int fd, int optional_actions, const struct ter #ifdef _HAVE_C_OSPEED k_termios.c_ospeed = termios_p->c_ospeed; #endif - __memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0], + memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0], __KERNEL_NCCS * sizeof (cc_t)); - retval = __ioctl (fd, cmd, &k_termios); + retval = ioctl (fd, cmd, &k_termios); if (retval == 0 && cmd == TCSETS) { /* The Linux kernel has a bug which silently ignore the invalid c_cflag on pty. We have to check it here. */ int save = errno; - retval = __ioctl (fd, TCGETS, &k_termios); + retval = ioctl (fd, TCGETS, &k_termios); if (retval) { /* We cannot verify if the setting is ok. We don't return @@ -114,4 +118,4 @@ int attribute_hidden __tcsetattr (int fd, int optional_actions, const struct ter return retval; } -strong_alias(__tcsetattr,tcsetattr) +libc_hidden_def(tcsetattr) diff --git a/libc/termios/tcsetpgrp.c b/libc/termios/tcsetpgrp.c new file mode 100644 index 000000000..9bf1cdaef --- /dev/null +++ b/libc/termios/tcsetpgrp.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <unistd.h> + +libc_hidden_proto(ioctl) + +/* Set the foreground process group ID of FD set PGRP_ID. */ +int tcsetpgrp (int fd, pid_t pgrp_id) +{ + return ioctl (fd, TIOCSPGRP, &pgrp_id); +} diff --git a/libc/termios/termios.c b/libc/termios/termios.c deleted file mode 100644 index 680796e16..000000000 --- a/libc/termios/termios.c +++ /dev/null @@ -1,327 +0,0 @@ -/* Copyright (C) 1992, 1993, 1996, 1997, 1998 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - - About the only thing remaining here fromthe original Linux-8086 C library - version by Robert de Bath <robert@mayday.compulink.co.uk>, is the general - layout. All else has been recently stolen from GNU libc, since that was - much more current. - */ - -#define tcgetattr __tcgetattr - -#include <errno.h> -#include <stddef.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <unistd.h> -#include <termios.h> - -#ifdef L_isatty -/* Return 1 if FD is a terminal, 0 if not. */ - -int attribute_hidden __isatty(int fd) -{ - struct termios term; - return (tcgetattr (fd, &term) == 0); -} -strong_alias(__isatty,isatty) -#endif - -#ifdef L_tcdrain -/* Wait for pending output to be written on FD. */ -int __libc_tcdrain (int fd) -{ - /* With an argument of 1, TCSBRK waits for the output to drain. */ - return __ioctl(fd, TCSBRK, 1); -} -weak_alias(__libc_tcdrain, tcdrain) -#endif - -#ifdef L_tcflow -/* Suspend or restart transmission on FD. */ -int tcflow ( int fd, int action) -{ - return __ioctl(fd, TCXONC, action); -} -#endif - -#ifdef L_tcflush -/* Flush pending data on FD. */ -int tcflush ( int fd, int queue_selector) -{ - return __ioctl(fd, TCFLSH, queue_selector); -} -#endif - -#ifdef L_tcsendbreak -/* Send zero bits on FD. */ -int tcsendbreak( int fd, int duration) -{ - /* The break lasts 0.25 to 0.5 seconds if DURATION is zero, - and an implementation-defined period if DURATION is nonzero. - We define a positive DURATION to be number of milliseconds to break. */ - if (duration <= 0) - return __ioctl(fd, TCSBRK, 0); - -#ifdef TCSBRKP - /* Probably Linux-specific: a positive third TCSBRKP ioctl argument is - defined to be the number of 100ms units to break. */ - return __ioctl(fd, TCSBRKP, (duration + 99) / 100); -#else - /* ioctl can't send a break of any other duration for us. - This could be changed to use trickery (e.g. lower speed and - send a '\0') to send the break, but for now just return an error. */ - __set_errno (EINVAL); - return -1; -#endif -} -#endif - -#ifdef L_tcsetpgrp -/* Set the foreground process group ID of FD set PGRP_ID. */ -int tcsetpgrp ( int fd, pid_t pgrp_id) -{ - return __ioctl (fd, TIOCSPGRP, &pgrp_id); -} -#endif - -#ifdef L_tcgetpgrp -/* Return the foreground process group ID of FD. */ -pid_t attribute_hidden __tcgetpgrp ( int fd) -{ - int pgrp; - - if (__ioctl (fd, TIOCGPGRP, &pgrp) < 0) - return (pid_t) -1; - return (pid_t) pgrp; -} -strong_alias(__tcgetpgrp,tcgetpgrp) -#endif - -/* This is a gross hack around a kernel bug. If the cfsetispeed functions is - * called with the SPEED argument set to zero this means use the same speed as - * for output. But we don't have independent input and output speeds and - * therefore cannot record this. - * - * We use an unused bit in the `c_iflag' field to keep track of this use of - * `cfsetispeed'. The value here must correspond to the one used in - * `tcsetattr.c'. */ -#define IBAUD0 020000000000 - -#ifdef L_cfgetospeed -/* Return the output baud rate stored in *TERMIOS_P. */ -speed_t cfgetospeed ( const struct termios *termios_p) -{ - return termios_p->c_cflag & (CBAUD | CBAUDEX); -} -#endif - -#ifdef L_cfgetispeed - -/* Return the input baud rate stored in *TERMIOS_P. - * Although for Linux there is no difference between input and output - * speed, the numerical 0 is a special case for the input baud rate. It - * should set the input baud rate to the output baud rate. */ -speed_t cfgetispeed (const struct termios *termios_p) -{ - return ((termios_p->c_iflag & IBAUD0) - ? 0 : termios_p->c_cflag & (CBAUD | CBAUDEX)); -} -#endif - -#ifdef L_cfsetospeed -/* Set the output baud rate stored in *TERMIOS_P to SPEED. */ -int attribute_hidden __cfsetospeed (struct termios *termios_p, speed_t speed) -{ - if ((speed & ~CBAUD) != 0 - && (speed < B57600 || speed > B460800)) - { - __set_errno(EINVAL); - return -1; - } - - termios_p->c_cflag &= ~(CBAUD | CBAUDEX); - termios_p->c_cflag |= speed; - - return 0; -} -strong_alias(__cfsetospeed,cfsetospeed) -#endif - -#ifdef L_cfsetispeed -/* Set the input baud rate stored in *TERMIOS_P to SPEED. - * Although for Linux there is no difference between input and output - * speed, the numerical 0 is a special case for the input baud rate. It - * should set the input baud rate to the output baud rate. */ -int attribute_hidden __cfsetispeed ( struct termios *termios_p, speed_t speed) -{ - if ((speed & ~CBAUD) != 0 - && (speed < B57600 || speed > B460800)) - { - __set_errno(EINVAL); - return -1; - } - - if (speed == 0) - termios_p->c_iflag |= IBAUD0; - else - { - termios_p->c_iflag &= ~IBAUD0; - termios_p->c_cflag &= ~(CBAUD | CBAUDEX); - termios_p->c_cflag |= speed; - } - - return 0; -} -strong_alias(__cfsetispeed,cfsetispeed) -#endif - -#ifdef L_cfsetspeed - -extern int __cfsetospeed (struct termios *__termios_p, speed_t __speed) __THROW attribute_hidden; -extern int __cfsetispeed (struct termios *__termios_p, speed_t __speed) __THROW attribute_hidden; - -struct speed_struct -{ - speed_t value; - speed_t internal; -}; - -static const struct speed_struct speeds[] = - { -#ifdef B0 - { 0, B0 }, -#endif -#ifdef B50 - { 50, B50 }, -#endif -#ifdef B75 - { 75, B75 }, -#endif -#ifdef B110 - { 110, B110 }, -#endif -#ifdef B134 - { 134, B134 }, -#endif -#ifdef B150 - { 150, B150 }, -#endif -#ifdef B200 - { 200, B200 }, -#endif -#ifdef B300 - { 300, B300 }, -#endif -#ifdef B600 - { 600, B600 }, -#endif -#ifdef B1200 - { 1200, B1200 }, -#endif -#ifdef B1200 - { 1200, B1200 }, -#endif -#ifdef B1800 - { 1800, B1800 }, -#endif -#ifdef B2400 - { 2400, B2400 }, -#endif -#ifdef B4800 - { 4800, B4800 }, -#endif -#ifdef B9600 - { 9600, B9600 }, -#endif -#ifdef B19200 - { 19200, B19200 }, -#endif -#ifdef B38400 - { 38400, B38400 }, -#endif -#ifdef B57600 - { 57600, B57600 }, -#endif -#ifdef B76800 - { 76800, B76800 }, -#endif -#ifdef B115200 - { 115200, B115200 }, -#endif -#ifdef B153600 - { 153600, B153600 }, -#endif -#ifdef B230400 - { 230400, B230400 }, -#endif -#ifdef B307200 - { 307200, B307200 }, -#endif -#ifdef B460800 - { 460800, B460800 }, -#endif - }; - - -/* Set both the input and output baud rates stored in *TERMIOS_P to SPEED. */ -int cfsetspeed (struct termios *termios_p, speed_t speed) -{ - size_t cnt; - - for (cnt = 0; cnt < sizeof (speeds) / sizeof (speeds[0]); ++cnt) - if (speed == speeds[cnt].internal) - { - __cfsetispeed (termios_p, speed); - __cfsetospeed (termios_p, speed); - return 0; - } - else if (speed == speeds[cnt].value) - { - __cfsetispeed (termios_p, speeds[cnt].internal); - __cfsetospeed (termios_p, speeds[cnt].internal); - return 0; - } - - __set_errno (EINVAL); - - return -1; -} -#endif - -#ifdef L_cfmakeraw -/* Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. -*/ -#include <termios.h> - -/* Set *T to indicate raw mode. */ -void -cfmakeraw (struct termios *t) -{ - t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); - t->c_oflag &= ~OPOST; - t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); - t->c_cflag &= ~(CSIZE|PARENB); - t->c_cflag |= CS8; - t->c_cc[VMIN] = 1; /* read returns when one char is available. */ - t->c_cc[VTIME] = 0; -} -#endif - diff --git a/libc/termios/ttyname.c b/libc/termios/ttyname.c index 271c9a4ab..001681caa 100644 --- a/libc/termios/ttyname.c +++ b/libc/termios/ttyname.c @@ -1,17 +1,11 @@ -#define opendir __opendir -#define closedir __closedir -#define readdir __readdir -#define isatty __isatty - -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <unistd.h> -#include <dirent.h> -#include <sys/stat.h> - -/* Jan 1, 2004 Manuel Novoa III +/* + * Copyright (C) Jan 1, 2004 Manuel Novoa III + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +/* * Kept the same approach, but rewrote the code for the most part. * Fixed some minor issues plus (as I recall) one SUSv3 errno case. */ @@ -29,6 +23,24 @@ * * If you change this, also change _SC_TTY_NAME_MAX in libc/unistd/sysconf.c */ + +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <unistd.h> +#include <dirent.h> +#include <sys/stat.h> + +libc_hidden_proto(ttyname_r) +libc_hidden_proto(fstat) +libc_hidden_proto(lstat) +libc_hidden_proto(strcpy) +libc_hidden_proto(strlen) +libc_hidden_proto(opendir) +libc_hidden_proto(closedir) +libc_hidden_proto(readdir) +libc_hidden_proto(isatty) + #define TTYNAME_BUFLEN 32 static const char dirlist[] = @@ -39,7 +51,7 @@ static const char dirlist[] = "\011/dev/pts/\0" /* and try /dev/pts next */ "\005/dev/\0"; /* and try walking through /dev last */ -int attribute_hidden __ttyname_r(int fd, char *ubuf, size_t ubuflen) +int ttyname_r(int fd, char *ubuf, size_t ubuflen) { struct dirent *d; struct stat st; @@ -51,7 +63,7 @@ int attribute_hidden __ttyname_r(int fd, char *ubuf, size_t ubuflen) size_t len; char buf[TTYNAME_BUFLEN]; - if (__fstat(fd, &st) < 0) { + if (fstat(fd, &st) < 0) { return errno; } @@ -66,7 +78,7 @@ int attribute_hidden __ttyname_r(int fd, char *ubuf, size_t ubuflen) assert(len + 2 <= TTYNAME_BUFLEN); /* dirname + 1 char + nul */ - __strcpy(buf, p); + strcpy(buf, p); s = buf + len; len = (TTYNAME_BUFLEN-2) - len; /* Available non-nul space. */ @@ -77,13 +89,13 @@ int attribute_hidden __ttyname_r(int fd, char *ubuf, size_t ubuflen) while ((d = readdir(fp)) != NULL) { /* This should never trigger for standard names, but we * check it to be safe. */ - if (__strlen(d->d_name) > len) { /* Too big? */ + if (strlen(d->d_name) > len) { /* Too big? */ continue; } - __strcpy(s, d->d_name); + strcpy(s, d->d_name); - if ((__lstat(buf, &dst) == 0) + if ((lstat(buf, &dst) == 0) #if 0 /* Stupid filesystems like cramfs fail to guarantee that * st_ino and st_dev uniquely identify a file, contrary to @@ -98,8 +110,8 @@ int attribute_hidden __ttyname_r(int fd, char *ubuf, size_t ubuflen) /* We treat NULL buf as ERANGE rather than EINVAL. */ rv = ERANGE; - if (ubuf && (__strlen(buf) <= ubuflen)) { - __strcpy(ubuf, buf); + if (ubuf && (strlen(buf) <= ubuflen)) { + strcpy(ubuf, buf); rv = 0; } goto DONE; @@ -114,11 +126,11 @@ int attribute_hidden __ttyname_r(int fd, char *ubuf, size_t ubuflen) return rv; } -strong_alias(__ttyname_r,ttyname_r) +libc_hidden_def(ttyname_r) char *ttyname(int fd) { static char name[TTYNAME_BUFLEN]; - return __ttyname_r(fd, name, TTYNAME_BUFLEN) ? NULL : name; + return ttyname_r(fd, name, TTYNAME_BUFLEN) ? NULL : name; } diff --git a/libc/unistd/Makefile.in b/libc/unistd/Makefile.in index 84b83b854..4a0bb0734 100644 --- a/libc/unistd/Makefile.in +++ b/libc/unistd/Makefile.in @@ -1,57 +1,39 @@ # Makefile for uClibc # -# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> # # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -CSRC:= sleep.c usleep.c ualarm.c getpass.c sysconf.c getlogin.c \ - fpathconf.c confstr.c pathconf.c swab.c usershell.c \ - getsubopt.c daemon.c +UNISTD_DIR := $(top_srcdir)libc/unistd +UNISTD_OUT := $(top_builddir)libc/unistd -MSRC:=exec.c -MOBJ:=execl.o execv.o execle.o execlp.o execvp.o +CSRC := $(notdir $(wildcard $(UNISTD_DIR)/*.c)) +# multi source +CSRC := $(filter-out exec.c,$(CSRC)) -ifneq ($(ARCH_HAS_MMU),y) -MOBJ+=__exec_alloc.o +ifeq ($(ARCH_USE_MMU),y) +CSRC := $(filter-out __exec_alloc.c,$(CSRC)) +else +CSRC := $(filter-out daemon.c,$(CSRC)) endif ifeq ($(UCLIBC_HAS_GNU_GETOPT),y) -CSRC+=getopt.c +CSRC := $(filter-out getopt-susv3.c,$(CSRC)) else -CSRC+=getopt-susv3.c +CSRC := $(filter-out getopt.c,$(CSRC)) endif ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y) -CSRC:=$(filter-out sleep.c,$(CSRC)) +CSRC := $(filter-out sleep.c,$(CSRC)) endif -UNISTD_DIR:=$(top_srcdir)libc/unistd -UNISTD_OUT:=$(top_builddir)libc/unistd - -UNISTD_SRC:=$(patsubst %.c,$(UNISTD_DIR)/%.c,$(CSRC)) -UNISTD_OBJ:=$(patsubst %.c,$(UNISTD_OUT)/%.o,$(CSRC)) - -UNISTD_MSRC:=$(patsubst %.c,$(UNISTD_DIR)/%.c,$(MSRC)) -UNISTD_MOBJ:=$(patsubst %.o,$(UNISTD_OUT)/%.o,$(MOBJ)) - -UNISTD_DEF:=$(patsubst %,-DL_%,$(subst .o,,$(notdir $(UNISTD_MOBJ)))) - -UNISTD_OBJS:=$(UNISTD_OBJ) $(UNISTD_MOBJ) - -$(UNISTD_MOBJ): $(UNISTD_MSRC) - $(compile.m) - -$(UNISTD_MOBJ:.o=.os): $(UNISTD_MSRC) - $(compile.m) - -libc-a-y+=$(UNISTD_OBJS) -libc-so-y+=$(UNISTD_OBJS:.o=.os) +UNISTD_SRC := $(patsubst %.c,$(UNISTD_DIR)/%.c,$(CSRC)) +UNISTD_OBJ := $(patsubst %.c,$(UNISTD_OUT)/%.o,$(CSRC)) -CFLAGS-multi-y+=$(UNISTD_DEF) -libc-multi-y+=$(UNISTD_SRC) $(UNISTD_MSRC) +libc-y += $(UNISTD_OBJ) -objclean-y+=unistd_objclean +objclean-y += unistd_objclean unistd_objclean: $(RM) $(UNISTD_OUT)/*.{o,os} diff --git a/libc/unistd/__exec_alloc.c b/libc/unistd/__exec_alloc.c new file mode 100644 index 000000000..837ffb472 --- /dev/null +++ b/libc/unistd/__exec_alloc.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L___exec_alloc +#include "exec.c" diff --git a/libc/unistd/confstr.c b/libc/unistd/confstr.c index bfaecb198..8d1c8d303 100644 --- a/libc/unistd/confstr.c +++ b/libc/unistd/confstr.c @@ -21,6 +21,8 @@ #include <unistd.h> #include <string.h> +libc_hidden_proto(memcpy) + #define CS_PATH "/bin:/usr/bin" /* If BUF is not NULL and LEN > 0, fill in at most LEN - 1 bytes @@ -48,10 +50,10 @@ size_t confstr ( int name, char *buf, size_t len) if (len > 0 && buf != NULL) { if (string_len <= len) - __memcpy (buf, string, string_len); + memcpy (buf, string, string_len); else { - __memcpy (buf, string, len - 1); + memcpy (buf, string, len - 1); buf[len - 1] = '\0'; } } diff --git a/libc/unistd/exec.c b/libc/unistd/exec.c index e61ff1988..3563723ad 100644 --- a/libc/unistd/exec.c +++ b/libc/unistd/exec.c @@ -30,11 +30,6 @@ * to free the storage allocated for the copy. Better ideas anyone? */ -#define mmap __mmap -#define munmap __munmap -#define execve __execve - -#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -44,10 +39,21 @@ #include <unistd.h> #include <sys/mman.h> -extern char *__strchrnul(const char *s, int c); +libc_hidden_proto(execl) +libc_hidden_proto(execvp) + +libc_hidden_proto(memcpy) +libc_hidden_proto(strchr) +libc_hidden_proto(strlen) +libc_hidden_proto(strchrnul) +libc_hidden_proto(execve) +libc_hidden_proto(mmap) +libc_hidden_proto(munmap) +libc_hidden_proto(getenv) +libc_hidden_proto(__environ) /**********************************************************************/ -#if defined(__ARCH_HAS_MMU__) || defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__) +#if defined(__ARCH_USE_MMU__) || defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__) /* We have an MMU, so use alloca() to grab space for buffers and * arg lists. Also fall back to alloca() if munmap() is broken. */ @@ -68,12 +74,12 @@ extern char *__strchrnul(const char *s, int c); # define EXEC_ALLOC(SIZE,VAR) __exec_alloc((VAR = (SIZE))) # define EXEC_FREE(PTR,VAR) __exec_free((PTR),(VAR)) -extern void *__exec_alloc(size_t size); -extern void __exec_free(void *ptr, size_t size); +extern void *__exec_alloc(size_t size) attribute_hidden; +extern void __exec_free(void *ptr, size_t size) attribute_hidden; # ifdef L___exec_alloc -void *__exec_alloc(size_t size) +void attribute_hidden *__exec_alloc(size_t size) { void *p; @@ -82,7 +88,7 @@ void *__exec_alloc(size_t size) return (p != MAP_FAILED) ? p : NULL; } -void __exec_free(void *ptr, size_t size) +void attribute_hidden __exec_free(void *ptr, size_t size) { if (ptr) { munmap(ptr, size); @@ -95,7 +101,7 @@ void __exec_free(void *ptr, size_t size) /**********************************************************************/ #ifdef L_execl -int attribute_hidden __execl(const char *path, const char *arg, ...) +int execl(const char *path, const char *arg, ...) { EXEC_ALLOC_SIZE(size) /* Do NOT add a semicolon! */ int n; @@ -126,7 +132,7 @@ int attribute_hidden __execl(const char *path, const char *arg, ...) return n; } -strong_alias(__execl,execl) +libc_hidden_def(execl) #endif /**********************************************************************/ @@ -179,8 +185,6 @@ int execle(const char *path, const char *arg, ...) /**********************************************************************/ #ifdef L_execlp -extern int __execvp(const char *path, char *const argv[]) attribute_hidden; - int execlp(const char *file, const char *arg, ...) { EXEC_ALLOC_SIZE(size) /* Do NOT add a semicolon! */ @@ -206,7 +210,7 @@ int execlp(const char *file, const char *arg, ...) } while (--n); va_end(args); - n = __execvp(file, (char *const *) argv); + n = execvp(file, (char *const *) argv); EXEC_FREE(argv, size); @@ -222,7 +226,7 @@ int execlp(const char *file, const char *arg, ...) * /bin, and then /usr/bin. */ static const char default_path[] = ":/bin:/usr/bin"; -int attribute_hidden __execvp(const char *path, char *const argv[]) +int execvp(const char *path, char *const argv[]) { char *buf = NULL; char *p; @@ -239,7 +243,7 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) return -1; } - if (__strchr(path, '/')) { + if (strchr(path, '/')) { execve(path, argv, __environ); CHECK_ENOEXEC: if (errno == ENOEXEC) { @@ -252,12 +256,12 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) nargv = (char **) EXEC_ALLOC((n+2) * sizeof(char *), size2); nargv[0] = argv[0]; nargv[1] = (char *)path; - __memcpy(nargv+2, argv+1, n*sizeof(char *)); + memcpy(nargv+2, argv+1, n*sizeof(char *)); execve("/bin/sh", nargv, __environ); EXEC_FREE(nargv, size2); } } else { - if ((p = __getenv("PATH")) != NULL) { + if ((p = getenv("PATH")) != NULL) { if (!*p) { goto BAD; } @@ -265,7 +269,7 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) p = (char *) default_path; } - plen = __strlen(path); + plen = strlen(path); if (plen > (FILENAME_MAX - 1)) { ALL_TOO_LONG: __set_errno(ENAMETOOLONG); @@ -276,11 +280,11 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) if ((buf = EXEC_ALLOC(FILENAME_MAX, size)) != NULL) { int seen_small = 0; s0 = buf + len; - __memcpy(s0, path, plen+1); + memcpy(s0, path, plen+1); do { s = s0; - e = __strchrnul(p, ':'); + e = strchrnul(p, ':'); if (e > p) { plen = e - p; if (e[-1] != '/') { @@ -290,7 +294,7 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) goto NEXT; } s -= plen; - __memcpy(s, p, plen); + memcpy(s, p, plen); s[plen-1] = '/'; } @@ -319,7 +323,7 @@ int attribute_hidden __execvp(const char *path, char *const argv[]) return -1; } -strong_alias(__execvp,execvp) +libc_hidden_def(execvp) #endif /**********************************************************************/ diff --git a/libc/unistd/execl.c b/libc/unistd/execl.c new file mode 100644 index 000000000..176b18bcc --- /dev/null +++ b/libc/unistd/execl.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_execl +#include "exec.c" diff --git a/libc/unistd/execle.c b/libc/unistd/execle.c new file mode 100644 index 000000000..05dd3a028 --- /dev/null +++ b/libc/unistd/execle.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_execle +#include "exec.c" diff --git a/libc/unistd/execlp.c b/libc/unistd/execlp.c new file mode 100644 index 000000000..b7e615d7b --- /dev/null +++ b/libc/unistd/execlp.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_execlp +#include "exec.c" diff --git a/libc/unistd/execv.c b/libc/unistd/execv.c new file mode 100644 index 000000000..25030428d --- /dev/null +++ b/libc/unistd/execv.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_execv +#include "exec.c" diff --git a/libc/unistd/execvp.c b/libc/unistd/execvp.c new file mode 100644 index 000000000..9fc025fcb --- /dev/null +++ b/libc/unistd/execvp.c @@ -0,0 +1,8 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_execvp +#include "exec.c" diff --git a/libc/unistd/fpathconf.c b/libc/unistd/fpathconf.c index 5404e7b01..9cb66a927 100644 --- a/libc/unistd/fpathconf.c +++ b/libc/unistd/fpathconf.c @@ -32,6 +32,8 @@ //#include "linux_fsinfo.h" +libc_hidden_proto(fstat) +libc_hidden_proto(fstatfs) /* The Linux kernel headers mention this as a kind of generic value. */ #define LINUX_LINK_MAX 127 @@ -53,7 +55,7 @@ long int fpathconf(int fd, int name) struct statfs fsbuf; /* Determine the filesystem type. */ - if (__fstatfs (fd, &fsbuf) < 0) + if (fstatfs (fd, &fsbuf) < 0) { if (errno == ENOSYS) /* not possible, return the default value. */ @@ -127,7 +129,7 @@ long int fpathconf(int fd, int name) struct statfs buf; int save_errno = errno; - if (__fstatfs (fd, &buf) < 0) + if (fstatfs (fd, &buf) < 0) { if (errno == ENOSYS) { @@ -201,7 +203,7 @@ long int fpathconf(int fd, int name) /* AIO is only allowed on regular files and block devices. */ struct stat st; - if (__fstat (fd, &st) < 0 || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode))) + if (fstat (fd, &st) < 0 || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode))) return -1; else return 1; diff --git a/libc/unistd/getlogin.c b/libc/unistd/getlogin.c index 0747a49f6..296d8d7fc 100644 --- a/libc/unistd/getlogin.c +++ b/libc/unistd/getlogin.c @@ -22,6 +22,12 @@ #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <stdio.h> + +libc_hidden_proto(strcpy) +libc_hidden_proto(strncpy) +libc_hidden_proto(getenv) /* uClibc makes it policy to not mess with the utmp file whenever * possible, since I consider utmp a complete waste of time. Since @@ -29,29 +35,30 @@ * the user specify whatever they want via the LOGNAME environment * variable, or we return NULL if getenv() fails to find anything */ -extern char attribute_hidden * __getlogin(void) +libc_hidden_proto(getlogin) +char * getlogin(void) { - return (__getenv("LOGNAME")); + return (getenv("LOGNAME")); } -strong_alias(__getlogin,getlogin) +libc_hidden_def(getlogin) int getlogin_r(char *name, size_t len) { - char * foo = __getenv("LOGNAME"); + char * foo = getenv("LOGNAME"); if (! foo) return -1; - __strncpy(name, foo, len); + strncpy(name, foo, len); name[len-1] = '\0'; return 0; } char *cuserid(char *s) { - char *name = __getlogin(); + char *name = getlogin(); if (s) { - return(__strcpy(s, name ? name : "")); + return(strcpy(s, name ? name : "")); } return name; } diff --git a/libc/unistd/getopt-susv3.c b/libc/unistd/getopt-susv3.c index d9ee18c43..70a616011 100644 --- a/libc/unistd/getopt-susv3.c +++ b/libc/unistd/getopt-susv3.c @@ -30,10 +30,14 @@ * Initial version of a SUSv3 compliant getopt(). */ -#define _GNU_SOURCE #include <unistd.h> #include <string.h> #include <stdio.h> +#include <getopt.h> + +libc_hidden_proto(fprintf) +libc_hidden_proto(strchr) +libc_hidden_proto(stderr) #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Enable gettext awareness. @@ -87,7 +91,7 @@ int getopt(int argc, char * const argv[], const char *optstring) #endif retval = (unsigned char) *o; /* Avoid problems for char val of -1. */ - if ((*o == ':') || !(s = __strchr(optstring, *o))) { /* Illegal option? */ + if ((*o == ':') || !(s = strchr(optstring, *o))) { /* Illegal option? */ s = illegal; retval = '?'; goto BAD; diff --git a/libc/unistd/getopt.c b/libc/unistd/getopt.c index 2cf5dbb73..cffde47e1 100644 --- a/libc/unistd/getopt.c +++ b/libc/unistd/getopt.c @@ -2,7 +2,7 @@ NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! - Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001 + Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -25,26 +25,85 @@ * Modified for uClibc by Manuel Novoa III on 1/5/01. * Modified once again for uClibc by Erik Andersen 8/7/02 */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. + Ditto for AIX 3.2 and <stdlib.h>. */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#define __FORCE_GLIBC #include <features.h> + #include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include <gnu-versions.h> +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include <stdlib.h> +# include <unistd.h> +#endif /* GNU C library. */ + #include <string.h> -#include <stdlib.h> -#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__ -#include <libintl.h> + +#ifdef VMS +# include <unixlib.h> #endif +#if !defined __UCLIBC__ && !defined __UCLIBC_HAS_GETTEXT_AWARENESS__ +#ifdef _LIBC +# include <libintl.h> +#else +# include "gettext.h" +# define _(msgid) gettext (msgid) +#endif +#else #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Enable gettext awareness. #endif /* __UCLIBC_MJN3_ONLY__ */ #undef _ -#define _(X) X +#define _(X) X + +#endif /* Treat '-W foo' the same as the long option '--foo', * disabled for the moment since it costs about 2k... */ #undef SPECIAL_TREATMENT_FOR_W +#if defined _LIBC && defined USE_IN_LIBIO +# include <wchar.h> +#endif + +#ifndef attribute_hidden +# define attribute_hidden +#endif + /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. @@ -59,11 +118,16 @@ GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ -#include "getopt.h" - -extern int _getopt_internal (int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, int long_only) attribute_hidden; +#include <getopt.h> +#include "getopt_int.h" +libc_hidden_proto(strchr) +libc_hidden_proto(strcmp) +libc_hidden_proto(strlen) +libc_hidden_proto(strncmp) +libc_hidden_proto(getenv) +libc_hidden_proto(fprintf) +libc_hidden_proto(stderr) /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, @@ -71,7 +135,7 @@ extern int _getopt_internal (int argc, char *const *argv, const char *optstring, Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ -char *optarg = NULL; +char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller @@ -99,66 +163,49 @@ int opterr = 1; int optopt = '?'; -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Formerly, initialization of getopt depended on optind==0, which - causes problems with re-calling getopt as programs generally don't - know that. */ - -static int __getopt_initialized; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. +/* Keep a global copy of all internal members of getopt_data. */ - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. +static struct _getopt_data getopt_data; - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. + +#ifndef __GNU_LIBRARY__ - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return -1 with `optind' != ARGC. */ +/* Avoid depending on library functions or files + whose names are inconsistent. */ -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; +#ifndef getenv +extern char *getenv (); +#endif -# include <string.h> -# define my_index __strchr +#endif /* not __GNU_LIBRARY__ */ -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; +#ifdef _LIBC +/* Stored original parameters. + XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ +# ifdef USE_NONOPTION_FLAGS +extern int __libc_argc; +extern char **__libc_argv; + +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +# define SWAP_FLAGS(ch1, ch2) \ + if (d->__nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +# else +# define SWAP_FLAGS(ch1, ch2) +# endif +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) @@ -169,90 +216,149 @@ static int last_nonopt; `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ -static void exchange (char **argv) +static void +exchange (char **argv, struct _getopt_data *d) { - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ + int bottom = d->__first_nonopt; + int middle = d->__last_nonopt; + int top = d->optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + d->__nonoption_flags_max_len), + '\0', top + 1 - d->__nonoption_flags_max_len); + d->__nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif - while (top > middle && middle > bottom) + while (top > middle && middle > bottom) { - if (top - middle > middle - bottom) + if (top - middle > middle - bottom) { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; + /* Exclude the moved bottom segment from further swapping. */ + top -= len; } - else + else { - /* Top segment is the short one. */ - int len = top - middle; - register int i; + /* Top segment is the short one. */ + int len = top - middle; + register int i; - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); } - /* Exclude the moved top segment from further swapping. */ - bottom += len; + /* Exclude the moved top segment from further swapping. */ + bottom += len; } } - /* Update records for the slots the non-options now occupy. */ + /* Update records for the slots the non-options now occupy. */ - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; + d->__first_nonopt += (d->optind - d->__last_nonopt); + d->__last_nonopt = d->optind; } /* Initialize the internal data when the first call is made. */ -static const char *_getopt_initialize (attribute_unused int argc, attribute_unused char *const * argv, const char *optstring) +static const char * +_getopt_initialize (attribute_unused int argc, attribute_unused char *const *argv, const char *optstring, + struct _getopt_data *d) { - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ - first_nonopt = last_nonopt = optind; + d->__first_nonopt = d->__last_nonopt = d->optind; - nextchar = NULL; + d->__nextchar = NULL; - /* Determine how to handle the ordering of options and nonoptions. */ + d->__posixly_correct = !!getenv ("POSIXLY_CORRECT"); - if (optstring[0] == '-') + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + d->__ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') { - ordering = RETURN_IN_ORDER; - ++optstring; + d->__ordering = REQUIRE_ORDER; + ++optstring; } - else if (optstring[0] == '+') + else if (d->__posixly_correct) + d->__ordering = REQUIRE_ORDER; + else + d->__ordering = PERMUTE; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + if (!d->__posixly_correct + && argc == __libc_argc && argv == __libc_argv) { - ordering = REQUIRE_ORDER; - ++optstring; + if (d->__nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + d->__nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = d->__nonoption_flags_max_len = strlen (orig_str); + if (d->__nonoption_flags_max_len < argc) + d->__nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (d->__nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + d->__nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', d->__nonoption_flags_max_len - len); + } + } + d->__nonoption_flags_len = d->__nonoption_flags_max_len; } - else if (__getenv ("POSIXLY_CORRECT") != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; + else + d->__nonoption_flags_len = 0; +#endif - return optstring; + return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters @@ -311,489 +417,776 @@ static const char *_getopt_initialize (attribute_unused int argc, attribute_unus If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ -int attribute_hidden _getopt_internal (int argc, char *const *argv, const char *optstring, - const struct option *longopts, int *longind, int long_only) +static int +_getopt_internal_r (int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, + int long_only, struct _getopt_data *d) { - int print_errors = opterr; - if (optstring[0] == ':') - print_errors = 0; + int print_errors = d->opterr; + if (optstring[0] == ':') + print_errors = 0; - if (argc < 1) - return -1; + if (argc < 1) + return -1; - optarg = NULL; + d->optarg = NULL; - if (optind == 0 || !__getopt_initialized) + if (d->optind == 0 || !d->__initialized) { - if (optind == 0) - optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring); - __getopt_initialized = 1; + if (d->optind == 0) + d->optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring, d); + d->__initialized = 1; } - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#if defined _LIBC && defined USE_NONOPTION_FLAGS +# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \ + || (d->optind < d->__nonoption_flags_len \ + && __getopt_nonoption_flags[d->optind] == '1')) +#else +# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') +#endif - if (nextchar == NULL || *nextchar == '\0') + if (d->__nextchar == NULL || *d->__nextchar == '\0') { - /* Advance to the next ARGV-element. */ + /* Advance to the next ARGV-element. */ - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (last_nonopt > optind) - last_nonopt = optind; - if (first_nonopt > optind) - first_nonopt = optind; + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (d->__last_nonopt > d->optind) + d->__last_nonopt = d->optind; + if (d->__first_nonopt > d->optind) + d->__first_nonopt = d->optind; - if (ordering == PERMUTE) + if (d->__ordering == PERMUTE) { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange ((char **) argv, d); + else if (d->__last_nonopt != d->optind) + d->__first_nonopt = d->optind; - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ - while (optind < argc && NONOPTION_P) - optind++; - last_nonopt = optind; + while (d->optind < argc && NONOPTION_P) + d->optind++; + d->__last_nonopt = d->optind; } - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ - if (optind != argc && !__strcmp (argv[optind], "--")) + if (d->optind != argc && !strcmp (argv[d->optind], "--")) { - optind++; + d->optind++; - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange ((char **) argv, d); + else if (d->__first_nonopt == d->__last_nonopt) + d->__first_nonopt = d->optind; + d->__last_nonopt = argc; - optind = argc; + d->optind = argc; } - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ - if (optind == argc) + if (d->optind == argc) { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return -1; + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (d->__first_nonopt != d->__last_nonopt) + d->optind = d->__first_nonopt; + return -1; } - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ - if (NONOPTION_P) + if (NONOPTION_P) { - if (ordering == REQUIRE_ORDER) - return -1; - optarg = argv[optind++]; - return 1; + if (d->__ordering == REQUIRE_ORDER) + return -1; + d->optarg = argv[d->optind++]; + return 1; } - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); + d->__nextchar = (argv[d->optind] + 1 + + (longopts != NULL && argv[d->optind][1] == '-')); } - /* Decode the current option-ARGV-element. */ + /* Decode the current option-ARGV-element. */ - /* Check whether the ARGV-element is a long option. + /* Check whether the ARGV-element is a long option. - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". - This distinction seems to be the most useful approach. */ + This distinction seems to be the most useful approach. */ - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + if (longopts != NULL + && (argv[d->optind][1] == '-' + || (long_only && (argv[d->optind][2] + || !strchr (optstring, argv[d->optind][1]))))) { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!__strncmp (p->name, nextchar, nameend - nextchar)) + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) + { + if ((unsigned int) (nameend - d->__nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) { - if ((unsigned int) (nameend - nextchar) - == (unsigned int) __strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[d->optind]) >= 0) { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } + _IO_flockfile (stderr); - if (ambig && !exact) - { - if (print_errors) - { - fprintf (stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[optind]); + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[d->optind]); +#endif } - nextchar += __strlen (nextchar); - optind++; - optopt = 0; - return '?'; + d->__nextchar += strlen (d->__nextchar); + d->optind++; + d->optopt = 0; + return '?'; } - if (pfound != NULL) + if (pfound != NULL) { - option_index = indfound; - optind++; - if (*nameend) + option_index = indfound; + d->optind++; + if (*nameend) { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + d->optarg = nameend + 1; + else { - if (print_errors) + if (print_errors) { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif - if (argv[optind - 1][1] == '-') + if (argv[d->optind - 1][1] == '-') { - /* --option */ - fprintf (stderr, _("\ - %s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("\ +%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#else + fprintf (stderr, _("\ +%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif } - else + else { - /* +option or -option */ - fprintf (stderr, _("\ - %s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[optind - 1][0], pfound->name); + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("\ +%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[d->optind - 1][0], + pfound->name); +#else + fprintf (stderr, _("\ +%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[d->optind - 1][0], + pfound->name); +#endif } +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif } - nextchar += __strlen (nextchar); + d->__nextchar += strlen (d->__nextchar); - optopt = pfound->val; - return '?'; + d->optopt = pfound->val; + return '?'; } } - else if (pfound->has_arg == 1) + else if (pfound->has_arg == 1) { - if (optind < argc) - optarg = argv[optind++]; - else + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else { - if (print_errors) + if (print_errors) { - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `%s' requires an argument\n"), + argv[0], argv[d->optind - 1]) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[d->optind - 1]); +#endif } - nextchar += __strlen (nextchar); - optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; + d->__nextchar += strlen (d->__nextchar); + d->optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; } } - nextchar += __strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) + d->__nextchar += strlen (d->__nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) { - *(pfound->flag) = pfound->val; - return 0; + *(pfound->flag) = pfound->val; + return 0; } - return pfound->val; + return pfound->val; } - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[d->optind][1] == '-' + || strchr (optstring, *d->__nextchar) == NULL) { - if (print_errors) + if (print_errors) { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif - if (argv[optind][1] == '-') + if (argv[d->optind][1] == '-') { - /* --option */ - fprintf (stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], nextchar); + /* --option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"), + argv[0], d->__nextchar); +#else + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], d->__nextchar); +#endif } - else + else { - /* +option or -option */ - fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[optind][0], nextchar); + /* +option or -option */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[d->optind][0], d->__nextchar); +#else + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[d->optind][0], d->__nextchar); +#endif } +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif } - nextchar = (char *) ""; - optind++; - optopt = 0; - return '?'; + d->__nextchar = (char *) ""; + d->optind++; + d->optopt = 0; + return '?'; } } - /* Look at and handle the next short option-character. */ + /* Look at and handle the next short option-character. */ - { - char c = *nextchar++; - char *temp = my_index (optstring, c); + { + char c = *d->__nextchar++; + char *temp = strchr (optstring, c); - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; + /* Increment `optind' when we start to process its last character. */ + if (*d->__nextchar == '\0') + ++d->optind; - if (temp == NULL || c == ':') - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); - } - optopt = c; - return '?'; - } + if (temp == NULL || c == ':') + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + int n; +#endif + + if (d->__posixly_correct) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: illegal option -- %c\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); +#endif + } + else + { +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: invalid option -- %c\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); +#endif + } + +#if defined _LIBC && defined USE_IN_LIBIO + if (n >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#endif + } + d->optopt = c; + return '?'; + } #ifdef SPECIAL_TREATMENT_FOR_W - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, + _("%s: option requires an argument -- %c\n"), + argv[0], c) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); +#endif + } + d->optopt = c; + if (optstring[0] == ':') + c = ':'; else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; + c = '?'; + return c; + } + else + /* We already incremented `d->optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; - /* optarg is now the argument, see if it's in the - table of longopts. */ + /* optarg is now the argument, see if it's in the + table of longopts. */ - for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; + for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; + nameend++) + /* Do nothing. */ ; - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!__strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) == __strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (print_errors) - { - fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[optind]); - } - nextchar += __strlen (nextchar); - optind++; - return '?'; - } - if (pfound != NULL) + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) { - option_index = indfound; - if (*nameend) + if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name)) { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (print_errors) - { - fprintf (stderr, _("\ - %s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); - } - - nextchar += __strlen (nextchar); - return '?'; - } + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; } - else if (pfound->has_arg == 1) + else if (pfound == NULL) { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (print_errors) - { - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - } - nextchar += __strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += __strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; + /* First nonexact match found. */ + pfound = p; + indfound = option_index; } - return pfound->val; + else + /* Second or later nonexact match found. */ + ambig = 1; } - nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } + if (ambig && !exact) + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[d->optind]) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[d->optind]); #endif - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } + } + d->__nextchar += strlen (d->__nextchar); + d->optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + d->optarg = nameend + 1; else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { + { if (print_errors) - { - /* 1003.2 specifies the format of this message. */ + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); +#endif + } + + d->__nextchar += strlen (d->__nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else + { + if (print_errors) + { +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option `%s' requires an argument\n"), + argv[0], argv[d->optind - 1]) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else fprintf (stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } + _("%s: option `%s' requires an argument\n"), + argv[0], argv[d->optind - 1]); +#endif + } + d->__nextchar += strlen (d->__nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + d->__nextchar += strlen (d->__nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + d->__nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } +#endif + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + d->optind++; + } + else + d->optarg = NULL; + d->__nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + char *buf; + + if (__asprintf (&buf, _("\ +%s: option requires an argument -- %c\n"), + argv[0], c) >= 0) + { + _IO_flockfile (stderr); + + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + + __fxprintf (NULL, "%s", buf); + + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); + + free (buf); + } +#else + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); +#endif + } + d->optopt = c; + if (optstring[0] == ':') + c = ':'; else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; + d->__nextchar = NULL; + } + } + return c; + } +} + +int +_getopt_internal (int argc, char *const *argv, const char *optstring, + const struct option *longopts, int *longind, int long_only) +{ + int result; + + getopt_data.optind = optind; + getopt_data.opterr = opterr; + + result = _getopt_internal_r (argc, argv, optstring, longopts, + longind, long_only, &getopt_data); + + optind = getopt_data.optind; + optarg = getopt_data.optarg; + optopt = getopt_data.optopt; + + return result; } -int getopt (int argc, char *const *argv, const char *optstring) +int +getopt (int argc, char *const *argv, const char *optstring) { - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, (int *) 0, 0); + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); } -int getopt_long (int argc, char *const *argv, const char *options, - const struct option *long_options, int *opt_index) +int +getopt_long (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) { - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. @@ -801,9 +1194,11 @@ int getopt_long (int argc, char *const *argv, const char *options, but does match a short option, it is parsed as a short option instead. */ -int getopt_long_only (int argc, char *const *argv, const char *options, - const struct option *long_options, int *opt_index) +int +getopt_long_only (int argc, char *const *argv, const char *options, + const struct option *long_options, int *opt_index) { - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } +#endif /* Not ELIDE_CODE. */ diff --git a/libc/unistd/getopt_int.h b/libc/unistd/getopt_int.h new file mode 100644 index 000000000..e2a005db9 --- /dev/null +++ b/libc/unistd/getopt_int.h @@ -0,0 +1,132 @@ +/* Internal declarations for getopt. + Copyright (C) 1989-1994,1996-1999,2001,2003,2004 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _GETOPT_INT_H +#define _GETOPT_INT_H 1 + +extern int _getopt_internal (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only) attribute_hidden; + + +/* Reentrant versions which can handle parsing multiple argument + vectors at the same time. */ + +/* Data type for reentrant functions. */ +struct _getopt_data +{ + /* These have exactly the same meaning as the corresponding global + variables, except that they are used for the reentrant + versions of getopt. */ + int optind; + int opterr; + int optopt; + char *optarg; + + /* Internal members. */ + + /* True if the internal members have been initialized. */ + int __initialized; + + /* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + char *__nextchar; + + /* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we + scan, so that eventually all the non-options are at the end. + This allows options to be given in any order, even with programs + that were not written to expect this. + + RETURN_IN_ORDER is an option available to programs that were + written to expect options and other ARGV-elements in any order + and that care about the ordering of the two. We describe each + non-option ARGV-element as if it were the argument of an option + with character code 1. Using `-' as the first character of the + list of option characters selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + + enum + { + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER + } __ordering; + + /* If the POSIXLY_CORRECT environment variable is set. */ + int __posixly_correct; + + + /* Handle permutation of arguments. */ + + /* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first + of them; `last_nonopt' is the index after the last of them. */ + + int __first_nonopt; + int __last_nonopt; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + int __nonoption_flags_max_len; + int __nonoption_flags_len; +# endif +}; + +/* The initializer is necessary to set OPTIND and OPTERR to their + default values and to clear the initialization flag. */ +#define _GETOPT_DATA_INITIALIZER { 1, 1 } + +#if 0 /* first is static on uClibc, the others not used */ +extern int _getopt_internal_r (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only, struct _getopt_data *__data); + +extern int _getopt_long_r (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + struct _getopt_data *__data); + +extern int _getopt_long_only_r (int ___argc, char *const *___argv, + const char *__shortopts, + const struct option *__longopts, + int *__longind, + struct _getopt_data *__data); +#endif + +#endif /* getopt_int.h */ diff --git a/libc/unistd/getpass.c b/libc/unistd/getpass.c index 834fba9d9..455838c62 100644 --- a/libc/unistd/getpass.c +++ b/libc/unistd/getpass.c @@ -16,21 +16,27 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define setvbuf __setvbuf -#define tcsetattr __tcsetattr -#define tcgetattr __tcgetattr -#define fileno __fileno -#define fflush __fflush -#define fgets __fgets -#define fputs __fputs - #include <stdio.h> #include <string.h> #include <termios.h> #include <unistd.h> #include <string.h> -extern int __putc(int c, FILE *stream) attribute_hidden; +libc_hidden_proto(strlen) +libc_hidden_proto(tcsetattr) +libc_hidden_proto(tcgetattr) +libc_hidden_proto(setvbuf) +libc_hidden_proto(fopen) +libc_hidden_proto(fclose) +libc_hidden_proto(fileno) +libc_hidden_proto(fflush) +libc_hidden_proto(fgets) +libc_hidden_proto(fputs) +libc_hidden_proto(fputc) +libc_hidden_proto(putc) +libc_hidden_proto(__fputc_unlocked) +libc_hidden_proto(stdin) +libc_hidden_proto(stderr) /* It is desirable to use this bit on systems that have it. The only bit of terminal state we want to twiddle is echoing, which is @@ -90,7 +96,7 @@ getpass (prompt) fgets (buf, PWD_BUFFER_SIZE-1, in); if (buf != NULL) { - nread = __strlen(buf); + nread = strlen(buf); if (nread < 0) buf[0] = '\0'; else if (buf[nread - 1] == '\n') @@ -99,7 +105,7 @@ getpass (prompt) buf[nread - 1] = '\0'; if (tty_changed) /* Write the newline that was not echoed. */ - __putc('\n', out); + putc('\n', out); } } diff --git a/libc/unistd/getsubopt.c b/libc/unistd/getsubopt.c index bebfbc4ed..3cac432ec 100644 --- a/libc/unistd/getsubopt.c +++ b/libc/unistd/getsubopt.c @@ -1,5 +1,5 @@ /* Parse comma separate list into words. - Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -18,12 +18,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define memchr __memchr - #include <stdlib.h> #include <string.h> -extern char *__strchrnul(const char *s, int c); +libc_hidden_proto(memchr) +libc_hidden_proto(strncmp) +libc_hidden_proto(strchrnul) /* Parse comma separated suboption from *OPTIONP and match against strings in TOKENS. If found return index and set *VALUEP to @@ -31,7 +31,8 @@ extern char *__strchrnul(const char *s, int c); not part of TOKENS return in *VALUEP beginning of unknown suboption. On exit *OPTIONP is set to the beginning of the next token or at the terminating NUL character. */ -int getsubopt(char **optionp, char *const *tokens, char **valuep) +int +getsubopt (char **optionp, char *const *tokens, char **valuep) { char *endp, *vstart; int cnt; @@ -40,7 +41,7 @@ int getsubopt(char **optionp, char *const *tokens, char **valuep) return -1; /* Find end of next token. */ - endp = __strchrnul (*optionp, ','); + endp = strchrnul (*optionp, ','); /* Find start of value. */ vstart = memchr (*optionp, '=', endp - *optionp); @@ -50,7 +51,7 @@ int getsubopt(char **optionp, char *const *tokens, char **valuep) /* Try to match the characters between *OPTIONP and VSTART against one of the TOKENS. */ for (cnt = 0; tokens[cnt] != NULL; ++cnt) - if (__memcmp (*optionp, tokens[cnt], vstart - *optionp) == 0 + if (strncmp (*optionp, tokens[cnt], vstart - *optionp) == 0 && tokens[cnt][vstart - *optionp] == '\0') { /* We found the current option in TOKENS. */ diff --git a/libc/unistd/pathconf.c b/libc/unistd/pathconf.c index 579b99be0..8e3c0a352 100644 --- a/libc/unistd/pathconf.c +++ b/libc/unistd/pathconf.c @@ -1,5 +1,5 @@ -/* pathconf -- adjusted for busybox - Copyright (C) 1991,95,96,98,99,2000,2001 Free Software Foundation, Inc. +/* Copyright (C) 1991,1995,1996,1998,2000,2001,2003 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,15 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +/* pathconf -- adjusted for busybox */ /* It would be great it this could be implemented using fpathconf, * but that doesn't work out very well (think FIFOs and sockets) */ #include <errno.h> -#include <unistd.h> -#include <limits.h> -#include <sys/statfs.h> -#include <errno.h> #include <stddef.h> #include <unistd.h> #include <limits.h> @@ -34,217 +31,171 @@ #include <sys/statfs.h> //#include <sys/statvfs.h> -//#include "linux_fsinfo.h" - +libc_hidden_proto(statfs) +libc_hidden_proto(stat) -/* The Linux kernel headers mention this as a kind of generic value. */ -#define LINUX_LINK_MAX 127 +/* The Linux kernel headers mention this as a kind of generic value. */ +#ifndef LINK_MAX +# define LINK_MAX 127 +#endif -/* Get file-specific information about descriptor FD. */ -long int pathconf(const char *path, int name) +/* Get file-specific information about PATH. */ +long int +pathconf (const char *path, int name) { - if (path[0] == '\0') + if (path[0] == '\0') { - __set_errno (ENOENT); - return -1; + __set_errno (ENOENT); + return -1; } - if (name == _PC_LINK_MAX) + switch (name) { - /* Cut some corners */ -#if 0 - struct statfs fsbuf; - - /* Determine the filesystem type. */ - if (__statfs (path, &fsbuf) < 0) - { - if (errno == ENOSYS) - /* not possible, return the default value. */ - return LINUX_LINK_MAX; - - /* Some error occured. */ - return -1; - } - - switch (fsbuf.f_type) - { - case EXT2_SUPER_MAGIC: - return EXT2_LINK_MAX; + default: + __set_errno (EINVAL); + return -1; - case MINIX_SUPER_MAGIC: - case MINIX_SUPER_MAGIC2: - return MINIX_LINK_MAX; - - case MINIX2_SUPER_MAGIC: - case MINIX2_SUPER_MAGIC2: - return MINIX2_LINK_MAX; - - case XENIX_SUPER_MAGIC: - return XENIX_LINK_MAX; - - case SYSV4_SUPER_MAGIC: - case SYSV2_SUPER_MAGIC: - return SYSV_LINK_MAX; - - case COH_SUPER_MAGIC: - return COH_LINK_MAX; - - case UFS_MAGIC: - case UFS_CIGAM: - return UFS_LINK_MAX; - - case REISERFS_SUPER_MAGIC: - return REISERFS_LINK_MAX; - - default: - return LINUX_LINK_MAX; - } + case _PC_LINK_MAX: +#ifdef LINK_MAX + return LINK_MAX; #else - return LINUX_LINK_MAX; + return -1; #endif - } - switch (name) - { - default: - __set_errno (EINVAL); - return -1; - - case _PC_MAX_CANON: + case _PC_MAX_CANON: #ifdef MAX_CANON - return MAX_CANON; + return MAX_CANON; #else - return -1; + return -1; #endif - case _PC_MAX_INPUT: + case _PC_MAX_INPUT: #ifdef MAX_INPUT - return MAX_INPUT; + return MAX_INPUT; #else - return -1; + return -1; #endif - case _PC_NAME_MAX: + case _PC_NAME_MAX: #ifdef NAME_MAX - { - struct statfs buf; - int save_errno = errno; - - if (__statfs (path, &buf) < 0) - { - if (errno == ENOSYS) - { - errno = save_errno; - return NAME_MAX; - } - return -1; - } - else - { + { + struct statfs buf; + int save_errno = errno; + + if (statfs (path, &buf) < 0) + { + if (errno == ENOSYS) + { + errno = save_errno; + return NAME_MAX; + } + return -1; + } + else + { #ifdef _STATFS_F_NAMELEN - return buf.f_namelen; + return buf.f_namelen; #else # ifdef _STATFS_F_NAME_MAX - return buf.f_name_max; + return buf.f_name_max; # else - return NAME_MAX; + return NAME_MAX; # endif #endif - } - } + } + } #else - return -1; + return -1; #endif - case _PC_PATH_MAX: + case _PC_PATH_MAX: #ifdef PATH_MAX - return PATH_MAX; + return PATH_MAX; #else - return -1; + return -1; #endif - case _PC_PIPE_BUF: + case _PC_PIPE_BUF: #ifdef PIPE_BUF - return PIPE_BUF; + return PIPE_BUF; #else - return -1; + return -1; #endif - case _PC_CHOWN_RESTRICTED: + case _PC_CHOWN_RESTRICTED: #ifdef _POSIX_CHOWN_RESTRICTED - return _POSIX_CHOWN_RESTRICTED; + return _POSIX_CHOWN_RESTRICTED; #else - return -1; + return -1; #endif - case _PC_NO_TRUNC: + case _PC_NO_TRUNC: #ifdef _POSIX_NO_TRUNC - return _POSIX_NO_TRUNC; + return _POSIX_NO_TRUNC; #else - return -1; + return -1; #endif - case _PC_VDISABLE: + case _PC_VDISABLE: #ifdef _POSIX_VDISABLE - return _POSIX_VDISABLE; + return _POSIX_VDISABLE; #else - return -1; + return -1; #endif - case _PC_SYNC_IO: + case _PC_SYNC_IO: #ifdef _POSIX_SYNC_IO - return _POSIX_SYNC_IO; + return _POSIX_SYNC_IO; #else - return -1; + return -1; #endif - case _PC_ASYNC_IO: -#if defined _POSIX_ASYNC_IO && defined __UCLIBC_HAS_LFS__ - { - /* AIO is only allowed on regular files and block devices. */ - struct stat st; - - if (__stat (path, &st) < 0 || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode))) - return -1; - else - return 1; - } + case _PC_ASYNC_IO: +#if defined _POSIX_ASYNC_IO && defined __UCLIBC_HAS_LFS__ + { + /* AIO is only allowed on regular files and block devices. */ + struct stat st; + + if (stat (path, &st) < 0 + || (! S_ISREG (st.st_mode) && ! S_ISBLK (st.st_mode))) + return -1; + else + return 1; + } #else - return -1; + return -1; #endif - case _PC_PRIO_IO: + case _PC_PRIO_IO: #ifdef _POSIX_PRIO_IO - return _POSIX_PRIO_IO; + return _POSIX_PRIO_IO; #else - return -1; + return -1; #endif - case _PC_SOCK_MAXBUF: + case _PC_SOCK_MAXBUF: #ifdef SOCK_MAXBUF - return SOCK_MAXBUF; + return SOCK_MAXBUF; #else - return -1; + return -1; #endif - case _PC_FILESIZEBITS: + case _PC_FILESIZEBITS: #ifdef FILESIZEBITS - return FILESIZEBITS; + return FILESIZEBITS; #else - /* We let platforms with larger file sizes overwrite this value. */ - return 32; + /* We let platforms with larger file sizes overwrite this value. */ + return 32; #endif - /* Be lazy -- skip these */ - case _PC_REC_INCR_XFER_SIZE: - case _PC_REC_MAX_XFER_SIZE: - case _PC_REC_MIN_XFER_SIZE: - case _PC_REC_XFER_ALIGN: - case _PC_ALLOC_SIZE_MIN: - case _PC_SYMLINK_MAX: - return -1; + /* Be lazy -- skip these */ + case _PC_REC_INCR_XFER_SIZE: + case _PC_REC_MAX_XFER_SIZE: + case _PC_REC_MIN_XFER_SIZE: + case _PC_REC_XFER_ALIGN: + case _PC_ALLOC_SIZE_MIN: + case _PC_SYMLINK_MAX: + return -1; } - } - diff --git a/libc/unistd/sleep.c b/libc/unistd/sleep.c index 3d3d516ab..92944af18 100644 --- a/libc/unistd/sleep.c +++ b/libc/unistd/sleep.c @@ -18,19 +18,25 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define sigaction __sigaction -#define nanosleep __nanosleep - #include <errno.h> #include <time.h> #include <signal.h> #include <unistd.h> +libc_hidden_proto(sleep) + +libc_hidden_proto(sigaction) +libc_hidden_proto(sigprocmask) +//libc_hidden_proto(__sigaddset) +//libc_hidden_proto(__sigemptyset) +//libc_hidden_proto(__sigismember) +libc_hidden_proto(nanosleep) + #if 0 /* This is a quick and dirty, but not 100% compliant with * the stupid SysV SIGCHLD vs. SIG_IGN behaviour. It is * fine unless you are messing with SIGCHLD... */ -unsigned int attribute_hidden __sleep (unsigned int sec) +unsigned int sleep (unsigned int sec) { unsigned int res; struct timespec ts = { .tv_sec = (long int) seconds, .tv_nsec = 0 }; @@ -44,7 +50,7 @@ unsigned int attribute_hidden __sleep (unsigned int sec) /* We are going to use the `nanosleep' syscall of the kernel. But the kernel does not implement the sstupid SysV SIGCHLD vs. SIG_IGN behaviour for this syscall. Therefore we have to emulate it here. */ -unsigned int attribute_hidden __sleep (unsigned int seconds) +unsigned int sleep (unsigned int seconds) { struct timespec ts = { .tv_sec = (long int) seconds, .tv_nsec = 0 }; sigset_t set, oset; @@ -59,7 +65,7 @@ unsigned int attribute_hidden __sleep (unsigned int seconds) in libc. We block SIGCHLD first. */ if (__sigemptyset (&set) < 0 || __sigaddset (&set, SIGCHLD) < 0 - || __sigprocmask (SIG_BLOCK, &set, &oset)) + || sigprocmask (SIG_BLOCK, &set, &oset)) return -1; /* If SIGCHLD is already blocked, we don't have to do anything. */ @@ -76,7 +82,7 @@ unsigned int attribute_hidden __sleep (unsigned int seconds) { saved_errno = errno; /* Restore the original signal mask. */ - (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); + (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); __set_errno (saved_errno); return -1; } @@ -88,13 +94,13 @@ unsigned int attribute_hidden __sleep (unsigned int seconds) saved_errno = errno; /* Restore the original signal mask. */ - (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); + (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); __set_errno (saved_errno); } else { /* We should unblock SIGCHLD. Restore the original signal mask. */ - (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); + (void) sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); result = nanosleep (&ts, &ts); } } @@ -108,4 +114,4 @@ unsigned int attribute_hidden __sleep (unsigned int seconds) return result; } #endif -strong_alias(__sleep,sleep) +libc_hidden_def(sleep) diff --git a/libc/unistd/sysconf.c b/libc/unistd/sysconf.c index c80a9e94e..0dde75102 100644 --- a/libc/unistd/sysconf.c +++ b/libc/unistd/sysconf.c @@ -16,9 +16,6 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define getpagesize __getpagesize_internal -#define getdtablesize __getdtablesize - #define _XOPEN_SOURCE 500 #include <features.h> #include <errno.h> @@ -36,6 +33,11 @@ #include <regex.h> #endif +libc_hidden_proto(sysconf) + +libc_hidden_proto(getpagesize) +libc_hidden_proto(getdtablesize) + #ifndef __UCLIBC_CLK_TCK_CONST #error __UCLIBC_CLK_TCK_CONST not defined! #endif @@ -71,7 +73,7 @@ #endif /* _UCLIBC_GENERATE_SYSCONF_ARCH */ /* Get the value of the system variable NAME. */ -long int attribute_hidden __sysconf(int name) +long int sysconf(int name) { switch (name) { @@ -883,4 +885,4 @@ long int attribute_hidden __sysconf(int name) #endif } } -strong_alias(__sysconf,sysconf) +libc_hidden_def(sysconf) diff --git a/libc/unistd/ualarm.c b/libc/unistd/ualarm.c index 3bcb8e463..07bea2a50 100644 --- a/libc/unistd/ualarm.c +++ b/libc/unistd/ualarm.c @@ -1,11 +1,16 @@ -#define setitimer __setitimer +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ -#define _GNU_SOURCE #include <time.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> +libc_hidden_proto(setitimer) + useconds_t ualarm(useconds_t value, useconds_t interval) { struct itimerval otimer; diff --git a/libc/unistd/usershell.c b/libc/unistd/usershell.c index bc29cf247..e053d94b7 100644 --- a/libc/unistd/usershell.c +++ b/libc/unistd/usershell.c @@ -30,11 +30,6 @@ * November 2002, Erik Andersen <andersen@codepoet.org> */ -#define __fsetlocking __fsetlocking_internal -#define fileno __fileno -#define fgets_unlocked __fgets_unlocked - -#define _GNU_SOURCE #include <sys/param.h> #include <sys/file.h> #include <sys/stat.h> @@ -45,6 +40,18 @@ #include <unistd.h> #include <paths.h> +libc_hidden_proto(fstat) +libc_hidden_proto(fopen) +libc_hidden_proto(fclose) +libc_hidden_proto(__fsetlocking) +libc_hidden_proto(fileno) +libc_hidden_proto(fgets_unlocked) +#ifdef __UCLIBC_HAS_XLOCALE__ +libc_hidden_proto(__ctype_b_loc) +#else +libc_hidden_proto(__ctype_b) +#endif + /* * Local shells should NOT be added here. They should be added in * /etc/shells. @@ -104,7 +111,7 @@ static char ** initshells(void) if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) return (char **) validsh; - if (__fstat(fileno(fp), &statb) == -1) { + if (fstat(fileno(fp), &statb) == -1) { goto cleanup; } if ((strings = malloc((unsigned)statb.st_size + 1)) == NULL) { diff --git a/libc/unistd/usleep.c b/libc/unistd/usleep.c index db8b8710c..09bb09f41 100644 --- a/libc/unistd/usleep.c +++ b/libc/unistd/usleep.c @@ -1,10 +1,16 @@ -#define nanosleep __nanosleep +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ #include <time.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> +libc_hidden_proto(nanosleep) + int usleep (__useconds_t usec) { const struct timespec ts = { |