diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 3072d9220..59dd3569c 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,9 @@ +2012-08-21 Christopher Faylor + + * libc/stdio/flags.c (__sflags): Rewrite recognition of extended mode + flags to just loop over more allowed flags. Support glibc 'e' flag on + systems defining _GLIBC_EXTENSION. Support C11 'x' flag. + 2012-08-10 Corinna Vinschen * libc/stdlib/btowc.c (btowc): Cast to avoid compiler warning. diff --git a/newlib/libc/stdio/flags.c b/newlib/libc/stdio/flags.c index 26d2f82fd..b2e4d1666 100644 --- a/newlib/libc/stdio/flags.c +++ b/newlib/libc/stdio/flags.c @@ -60,27 +60,38 @@ _DEFUN(__sflags, (ptr, mode, optr), ptr->_errno = EINVAL; return (0); } - if (mode[1] && (mode[1] == '+' || mode[2] == '+')) + while (*++mode) { - ret = (ret & ~(__SRD | __SWR)) | __SRW; - m = O_RDWR; - } - if (mode[1] && (mode[1] == 'b' || mode[2] == 'b')) - { -#ifdef O_BINARY - m |= O_BINARY; -#endif - } + switch (*mode) + { + case '+': + ret = (ret & ~(__SRD | __SWR)) | __SRW; + m = (m & ~O_ACCMODE) | O_RDWR; + break; + case 'b': + m |= O_BINARY; + break; #ifdef __CYGWIN__ - else if (mode[1] && (mode[1] == 't' || mode[2] == 't')) -#else - else + case 't': + m |= O_TEXT; + break; #endif - { -#ifdef O_TEXT - m |= O_TEXT; +#if defined (O_CLOEXEC) && defined (_GLIBC_EXTENSION) + case 'e': + m |= O_CLOEXEC; + break; #endif + case 'x': + m |= O_EXCL; + break; + default: + break; + } } +#if defined (O_TEXT) && !defined (__CYGWIN__) + if (!(m | O_BINARY)) + m |= O_TEXT; +#endif *optr = m | o; return ret; }