Changeset 2672


Ignore:
Timestamp:
Mar 19, 2006, 6:18:20 AM (19 years ago)
Author:
bird
Message:
  • *:

o Synced over changed from 0.6.1 bugfixing.

  • libc:

o Try put the log file handle above the range of the standard handles
o #71: Fixed incorrect fmutex padding in FILE which cause _fcloseall

(and perhaps others) to crash. (thanks to froloff)

o #69: Corrected a few problems related to dos drives and slashes in basename and dirname.
o read & write logging, and added support for more size flags to the log formatter.
o #68: Implemented the _GETOPT_DECLARED blocker in getopt.h too.
o #67: Removed termcap.h, curses.h, bsd/curses.h, bsd/termcap.h,

gnu/curses.h and gnu/termcap.h because we never built the libs for them.

o #65: Added sys/_timespec.h and uncommented it's inclusion in

sys/stat.h. This fixes the bustage in non-BSD source mode.

o Fixed wrong target name written into the symlink.
o #62: Fixed incorrect EOF treatment in getdelim (and in getline since that's just a

special case of getdelim).

o #49: Fixed stat backend so ctime is set, and made fstat, lstat and stat convert birthtime too.
o #61: Fixed incorrect ENOENT errno on symlink when it should return EEXIST.
o #60: Fixed blunder in exec/spawn filehandle inheritance code.
o #58: The standard file handles are always initialized as open.
o #54: Fixed unitialized directory handle member fInUnixTree.
o #53: Fixed LIBC panic when _openstream locks the stream vector

in any of it's error cases.

o #52: Fixed two 'symlink/' problems in the path resolver.
o #51: Made unlink able to delete readonly files.
o #50: Inherit umask.
o #30: Committed forgotten header.
o #48: Quick implementation of the freopen(NULL) operation

to make cat from coreutils happy.

o memalign and valloc shouldn't be in USE_GNU in malloc.h.
o #30: Fixed toupper / tolower EOF regression.
o Fixed incorrect assertion in
libc_back_fsInfoObjRelease.
o #41: And added special file mode mask getter and extra validations to check that

the mode mask we read has a valid type. This also shuts up some bad [f]chmod paths.

o #41: Calc st_ino and st_dev at the end of the unix attrib getter if they are not present.
o #40: Fixed double slash preventing root directories from being opened.
o #23: Fixed two incorrect EA size fields, now creating symlinks really works.
o #21: Restrict reading and writing of UnixEAs to HPFS, JFS, FAT and RAMFS.
o #38: Added DosSysCtl prototype and use it on panic to check for debugger.
o #33: Fixed a return path in libc_back_signalWait which didn't reacquire the semaphore.
o #32: Fixed incorrect readdir_r return code when out of files.
o #30: Fixed two locale bugs. First, setlocale called a locale

dependent function for getting ctype flags. Second, all the
is<>() macros / functions was busted for non-ascii chars (-1..-128).

o #23: Corrected EA name in template from "FLAGS" to "SYMLINK".
o #24: Fixed chdir() crash in fts.c.
o #24: Fixed dirfd() problem in fts.c which prevent us from getting

any results in child directories.

o #22: Added DosFindFirst() as fallback when DosQueryPathInfo() fails

to query the symlink EA in the path resolver. This problem occurs
when doing stat() on an open file (pwd_mkdb example).

  • libsocket:

o #25: Ensure correct address length returns from recvmsg and recvfrom.

Location:
trunk/libc
Files:
5 added
5 deleted
45 edited

Legend:

Unmodified
Added
Removed
  • trunk/libc/ChangeLog.LIBC

    r2483 r2672  
    22
    33TODO: open replace on RAMFS fails with error 32!
     4
     52006-03-19: knut st. osmundsen <bird-gccos2-spam@anduin.net>
     6    - *:
     7        o Synced over changed from 0.6.1 bugfixing.
     8    - libc:
     9        o Try put the log file handle above the range of the standard handles
     10        o #71: Fixed incorrect fmutex padding in FILE which cause _fcloseall
     11         (and perhaps others) to crash. (thanks to froloff)
     12        o #69: Corrected a few problems related to dos drives and slashes in basename and dirname.
     13        o __read & __write logging, and added support for more size flags to the log formatter.
     14        o #68: Implemented the _GETOPT_DECLARED blocker in getopt.h too.
     15        o #67: Removed termcap.h, curses.h, bsd/curses.h, bsd/termcap.h,
     16          gnu/curses.h and gnu/termcap.h because we never built the libs for them.
     17        o #65: Added sys/_timespec.h and uncommented it's inclusion in
     18          sys/stat.h. This fixes the bustage in non-BSD source mode.
     19        o Fixed wrong target name written into the symlink.
     20        o #62: Fixed incorrect EOF treatment in getdelim (and in getline since that's just a
     21          special case of getdelim).
     22        o #49: Fixed stat backend so ctime is set, and made fstat, lstat and stat convert birthtime too.
     23        o #61: Fixed incorrect ENOENT errno on symlink when it should return EEXIST.
     24        o #60: Fixed blunder in exec/spawn filehandle inheritance code.
     25        o #58: The standard file handles are always initialized as open.
     26        o #54: Fixed unitialized directory handle member fInUnixTree.
     27        o #53: Fixed LIBC panic when _openstream locks the stream vector
     28          in any of it's error cases.
     29        o #52: Fixed two 'symlink/' problems in the path resolver.
     30        o #51: Made unlink able to delete readonly files.
     31        o #50: Inherit umask.
     32        o #30: Committed forgotten header.
     33        o #48: Quick implementation of the freopen(NULL,,) operation
     34          to make cat from coreutils happy.
     35        o memalign and valloc shouldn't be in __USE_GNU in malloc.h.
     36        o #30: Fixed toupper / tolower EOF regression.
     37        o Fixed incorrect assertion in __libc_back_fsInfoObjRelease.
     38        o #41: And added special file mode mask getter and extra validations to check that
     39          the mode mask we read has a valid type. This also shuts up some bad [f]chmod paths.
     40        o #41: Calc st_ino and st_dev at the end of the unix attrib getter if they are not present.
     41        o #40: Fixed double slash preventing root directories from being opened.
     42        o #23: Fixed two incorrect EA size fields, now creating symlinks really works.
     43        o #21: Restrict reading and writing of UnixEAs to HPFS, JFS, FAT and RAMFS.
     44        o #38: Added DosSysCtl prototype and use it on panic to check for debugger.
     45        o #33: Fixed a return path in __libc_back_signalWait which didn't reacquire the semaphore.
     46        o #32: Fixed incorrect readdir_r return code when out of files.
     47        o #30: Fixed two locale bugs. First, setlocale called a locale
     48          dependent function for getting ctype flags. Second, all the
     49          is<>() macros / functions was busted for non-ascii chars (-1..-128).
     50        o #23: Corrected EA name in template from "FLAGS" to "SYMLINK".
     51        o #24: Fixed chdir() crash in fts.c.
     52        o #24: Fixed dirfd() problem in fts.c which prevent us from getting
     53          any results in child directories.
     54        o #22: Added DosFindFirst() as fallback when DosQueryPathInfo() fails
     55          to query the symlink EA in the path resolver. This problem occurs
     56          when doing stat() on an open file (pwd_mkdb example).
     57    - libsocket:
     58        o #25: Ensure correct address length returns from recvmsg and recvfrom.
    459
    5602005-12-11: knut st. osmundsen <bird-gccos2-spam@anduin.net>
  • trunk/libc/include/InnoTekLIBC/locale.h

    r2163 r2672  
    316316/** @} */
    317317
     318#include <ctype.h>
     319
     320/**
     321 * Convert the type info we get from the unicode lib to libc talk.
     322 * ASSUMES that none of the locals differs from the unicode spec
     323 *
     324 * @returns libc ctype flags.
     325 * @param   pUniType    The unicode type info to translate.
     326 * @param   wc          The unicode code point.
     327 */
     328static inline unsigned ___wctype_uni(const UNICTYPE *pUniType, wchar_t wc)
     329{
     330    unsigned    ufType = 0;
     331    /* ASSUMES CT_* << 8 == __* ! */
     332    ufType = ((unsigned)pUniType->itype << 8)
     333           & (__CT_UPPER  | __CT_LOWER  | __CT_DIGIT | __CT_SPACE |
     334              __CT_PUNCT  | __CT_CNTRL  | __CT_BLANK | __CT_XDIGIT |
     335              __CT_ALPHA  | __CT_ALNUM  | __CT_GRAPH | __CT_PRINT |
     336              __CT_NUMBER | __CT_SYMBOL | __CT_ASCII);
     337    if (pUniType->extend & C3_IDEOGRAPH)
     338        ufType |= __CT_IDEOGRAM;
     339    if (ufType & (__CT_XDIGIT | __CT_DIGIT))
     340    {
     341        if (     (unsigned)wc - 0x30U <= (0x39 - 0x30))
     342            ufType |= (unsigned)wc - 0x30;
     343        else if ((unsigned)wc - 0x41U <= (0x46 - 0x41))
     344            ufType |= (unsigned)wc - 0x41 + 0xa;
     345        else
     346        {
     347            unsigned uVal = UniQueryNumericValue(wc);
     348            if (!(uVal & ~0xffU))
     349                ufType |= uVal;
     350        }
     351    }
     352    ufType |= (pUniType->bidi & 0xf << 24);
     353
     354    /** @todo screen width. */
     355    return ufType;
     356}
     357
    318358__END_DECLS
    319359
  • trunk/libc/include/InnoTekLIBC/sharedpm.h

    r2323 r2672  
    278278
    279279/**
    280  * SPM fs inherit data.
     280 * The SPM fs inherit data, part 1.
     281 * The FS data is stored in two sections for legacy reasons.
    281282 */
    282283typedef struct __libc_SPMInhFS
     
    291292/** Pointer to FS inherit data. */
    292293typedef __LIBC_SPMINHFS *__LIBC_PSPMINHFS;
     294
     295/**
     296 * SPM fs inherit data, part two.
     297 */
     298typedef struct __libc_SPMInhFS2
     299{
     300    /** The size of this structure. */
     301    unsigned    cb;
     302    /** The umask value. */
     303    unsigned    fUMask;
     304} __LIBC_SPMINHFS2;
     305/** Pointer to FS inherit data, part two. */
     306typedef __LIBC_SPMINHFS2 *__LIBC_PSPMINHFS2;
    293307
    294308/**
     
    326340     * All the strings are NULL terminated and referenced by offset. */
    327341    char                   *pszStrings;
     342    /** More file system stuff. */
     343    __LIBC_PSPMINHFS2       pFS2;
    328344} __LIBC_SPMINHERIT;
    329345/** Pointer to inherit data. */
  • trunk/libc/include/_ctype.h

    r2058 r2672  
    166166static __inline__ unsigned __ctype(__ct_rune_t __ch, unsigned __f)
    167167{
    168     return !(__ch & ~0xffU)
    169         ? __libc_GLocaleCtype.aufType[__ch] & __f
     168    return __ch < 256 && __ch >= -128
     169        ? __libc_GLocaleCtype.aufType[__ch & 0xff] & __f
    170170        : 0;
    171171}
     
    178178static __inline__ int __isctype(__ct_rune_t __ch, unsigned __f)
    179179{
    180     return !(__ch & ~0xffU)
    181         ? !!(__libc_GLocaleCtypeDefault.aufType[__ch] & __f)
     180    return __ch <= 255 && __ch >= -128
     181        ? !!(__libc_GLocaleCtypeDefault.aufType[__ch & 0xff] & __f)
    182182        : 0;
    183183}
     
    185185static __inline__ __ct_rune_t __toupper(__ct_rune_t __ch)
    186186{
    187     return !(__ch & ~0xffU)
    188         ? __libc_GLocaleCtype.auchUpper[__ch]
     187    return __ch <= 255 && __ch >= -128 && __ch != -1 /*EOF*/
     188        ? __libc_GLocaleCtype.auchUpper[__ch & 0xff]
    189189        : (__ch);
    190190}
     
    192192static __inline__ __ct_rune_t __tolower(__ct_rune_t __ch)
    193193{
    194     return !(__ch & ~0xffU)
    195         ? __libc_GLocaleCtype.auchLower[__ch]
     194    return __ch <= 255 && __ch >= -128 && __ch != -1 /*EOF*/
     195        ? __libc_GLocaleCtype.auchLower[__ch & 0xff]
    196196        : __ch;
    197197}
  • trunk/libc/include/emx/io.h

    r2439 r2672  
    320320    /** Does the file system automatically zero the new space when a file is extended? */
    321321    unsigned            fZeroNewBytes : 1;
     322    /** Does the file system provide sufficient EA support for UNIX attributes? */
     323    unsigned            fUnixEAs : 1;
    322324    /** Device number of the device the filesystem resides on.
    323325     * On OS/2 the device number is derived from the driveletter. */
  • trunk/libc/include/getopt.h

    r2144 r2672  
    2121/** @file
    2222 * GLIBC 2.3.4
     23 * @changed bird: Added _GETOPT_DECLARED check and def.
    2324 */
    2425
     
    5556#endif
    5657
     58#ifndef _GETOPT_DECLARED /* bird: see next usage */
     59
    5760/* For communication from `getopt' to the caller.
    5861   When `getopt' finds an option that takes an argument,
     
    8588
    8689extern int optopt;
     90
     91#endif /* bird */
    8792
    8893#ifndef __need_getopt
     
    150155   `getopt'.  */
    151156
     157#ifndef _GETOPT_DECLARED /* bird: Also defined in unistd.h, this is the blocker. */
     158#define _GETOPT_DECLARED /* bird */
    152159#ifdef __GNU_LIBRARY__
    153160/* Many other libraries have conflicting prototypes for getopt, with
     
    159166extern int getopt ();
    160167#endif /* __GNU_LIBRARY__ */
     168#endif /* bird */
     169
    161170
    162171#ifndef __need_getopt
  • trunk/libc/include/malloc.h

    r1560 r2672  
    6363#endif
    6464
    65 #ifdef  __USE_GNU
    6665void    *valloc(size_t);
    6766void    *memalign(size_t, size_t);
    68 #endif
    6967
    7068#if defined (__cplusplus)
  • trunk/libc/include/os2emx.h

    r2273 r2672  
    1346713467
    1346813468
     13469#ifdef INCL_DOSUNDOCUEMENTED
     13470
     13471/** Check if the current process is being debugged.
     13472 * No parameter. Returns TRUE or FALSE. */
     13473#define DOSSYSCTL_AM_I_DEBUGGED 2
     13474
     13475/**
     13476 * System Control Function.
     13477 *
     13478 * @returns Depends on function.
     13479 * @param   ulFunction      Which function to execute.
     13480 *                          Any of the DOSSYSCTL_* #defines.
     13481 */
     13482APIRET APIENTRY DosSysCtl(ULONG ulFunction, PVOID pvParameter);
     13483
     13484#endif /* INCL_DOSUNDOCUEMENTED */
     13485
     13486
    1346913487#ifdef INCL_EXAPIS
    1347013488
  • trunk/libc/include/stdio.h

    r2223 r2672  
    204204        _fmutex   __fsem;
    205205#endif
    206         char      __rsem_ersatz[12];
     206        char      __rsem_ersatz[16];
    207207    } __u;
    208208    /** Pointer to the stream vector which this FILE belongs to.
  • trunk/libc/include/unistd.h

    r2323 r2672  
    44 *
    55 * @changed Commented out stuff which isn't implemented, TCPIP stuff at bottom.
     6 * @changed setkey returns void not int in the standard and our implementation (glibc).
    67 * @todo    Several man-years.. ;) Serious, complete the FreeBSD 5.3 merge and
    78 *          implement all the functions. Currently there is a bunch of POSIX
     
    540541/** @todo int    sethostname(const char *, int); */
    541542#ifndef _SETKEY_DECLARED
    542 int      setkey(const char *);
     543/*int    setkey(const char *); bird: SUS say void return and so does glibc! */
     544void     setkey(const char *);
    543545#define _SETKEY_DECLARED
    544546#endif
  • trunk/libc/src/fbsdlibc/gen/fts.c

    r2323 r2672  
    4040#endif
    4141#ifndef __EMX__
     42# define HAVE_FCHDIR
     43# define HAVE_DIRFD
    4244# define IS_SLASH(ch)   ( (ch) == '/' )
    4345#else
    4446# define NEED_STRRSLASH
     47# define HAVE_FCHDIR
     48# undef HAVE_DIRFD
    4549# define IS_SLASH(ch)   ( (ch) == '/' || (ch) == '\\' )
    4650#endif
     
    224228         * descriptor we run anyway, just more slowly.
    225229         */
     230#ifdef HAVE_FCHDIR
    226231        if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = _open(".", O_RDONLY, 0)) < 0)
    227                 SET(FTS_NOCHDIR);
     232#else
     233        if (!ISSET(FTS_NOCHDIR) && (sp->fts_rdir = getcwd(NULL, 0)) != NULL)
     234#endif
     235            SET(FTS_NOCHDIR);
    228236
    229237        return (sp);
     
    314322        /* Return to original directory, save errno if necessary. */
    315323        if (!ISSET(FTS_NOCHDIR)) {
     324#ifdef HAVE_FCHDIR
    316325                saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
    317326                (void)_close(sp->fts_rfd);
     327#else
     328                saved_errno = chdir(sp->fts_rdir) ? errno : 0;
     329                free(sp->fts_rdir); sp->fts_rdir = NULL;
     330#endif
    318331
    319332                /* Set errno and return. */
     
    375388                p->fts_info = fts_stat(sp, p, 1);
    376389                if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
     390#ifdef HAVE_FCHDIR
    377391                        if ((p->fts_symfd = _open(".", O_RDONLY, 0)) < 0) {
    378392                                p->fts_errno = errno;
     
    380394                        } else
    381395                                p->fts_flags |= FTS_SYMFOLLOW;
     396#endif
    382397                }
    383398                return (p);
     
    389404                if (instr == FTS_SKIP ||
    390405                    (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
     406#ifdef HAVE_FCHDIR
    391407                        if (p->fts_flags & FTS_SYMFOLLOW)
    392408                                (void)_close(p->fts_symfd);
     409#endif
    393410                        if (sp->fts_child) {
    394411                                fts_lfree(sp->fts_child);
     
    447464                 */
    448465                if (p->fts_level == FTS_ROOTLEVEL) {
     466#ifdef HAVE_FCHDIR
    449467                        if (FCHDIR(sp, sp->fts_rfd)) {
     468#else
     469                        if (FCHDIR(sp, sp->fts_rdir)) {
     470#endif
    450471                                SET(FTS_STOP);
    451472                                return (NULL);
     
    465486                        p->fts_info = fts_stat(sp, p, 1);
    466487                        if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
     488#ifdef HAVE_FCHDIR
    467489                                if ((p->fts_symfd =
    468490                                    _open(".", O_RDONLY, 0)) < 0) {
     
    471493                                } else
    472494                                        p->fts_flags |= FTS_SYMFOLLOW;
     495#endif
    473496                        }
    474497                        p->fts_instr = FTS_NOINSTR;
     
    504527         */
    505528        if (p->fts_level == FTS_ROOTLEVEL) {
     529#ifdef HAVE_FCHDIR
    506530                if (FCHDIR(sp, sp->fts_rfd)) {
     531#else
     532                if (FCHDIR(sp, sp->fts_rdir)) {
     533#endif
    507534                        SET(FTS_STOP);
    508535                        return (NULL);
    509536                }
     537#ifdef HAVE_FCHDIR
    510538        } else if (p->fts_flags & FTS_SYMFOLLOW) {
    511539                if (FCHDIR(sp, p->fts_symfd)) {
     
    517545                }
    518546                (void)_close(p->fts_symfd);
     547#else
     548        (void)saved_errno;
     549#endif
    519550        } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
    520551            fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
     
    554585{
    555586        FTSENT *p;
     587#ifdef HAVE_FCHDIR
    556588        int fd;
    557 
     589#else
     590        char *pszRoot;
     591        int rc;
     592#endif
    558593        if (instr != 0 && instr != FTS_NAMEONLY) {
    559594                errno = EINVAL;
     
    607642                return (sp->fts_child = fts_build(sp, instr));
    608643
     644#ifdef HAVE_FCHDIR
    609645        if ((fd = _open(".", O_RDONLY, 0)) < 0)
     646#else
     647        if ((pszRoot = getcwd(NULL, 0)) == NULL)
     648#endif
    610649                return (NULL);
    611650        sp->fts_child = fts_build(sp, instr);
     651#ifdef HAVE_FCHDIR
    612652        if (fchdir(fd))
    613653                return (NULL);
    614654        (void)_close(fd);
     655#else
     656        rc = chdir(pszRoot);
     657        free(pszRoot);
     658        if (rc)
     659            return NULL;
     660#endif
    615661        return (sp->fts_child);
    616662}
     
    740786        cderrno = 0;
    741787        if (nlinks || type == BREAD) {
     788#ifdef HAVE_DIRFD
    742789                if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
     790#else
     791                if (fts_safe_changedir(sp, cur, -1, cur->fts_accpath)) {
     792#endif
    743793                        if (nlinks && type == BREAD)
    744794                                cur->fts_errno = errno;
     
    905955        if (descend && (type == BCHILD || !nitems) &&
    906956            (cur->fts_level == FTS_ROOTLEVEL ?
     957#ifdef HAVE_FCHDIR
    907958            FCHDIR(sp, sp->fts_rfd) :
     959#else
     960            FCHDIR(sp, sp->fts_rdir) :
     961#endif
    908962            fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
    909963                cur->fts_info = FTS_ERR;
     
    12071261        if (ISSET(FTS_NOCHDIR))
    12081262                return (0);
     1263#ifdef HAVE_FCHDIR
    12091264        if (fd < 0 && (newfd = _open(path, O_RDONLY, 0)) < 0)
    12101265                return (-1);
    12111266        if (_fstat(newfd, &sb)) {
     1267#else
     1268        (void)newfd;
     1269        if (_stat(path, &sb)) {
     1270#endif
    12121271                ret = -1;
    12131272                goto bail;
     
    12181277                goto bail;
    12191278        }
     1279#ifdef HAVE_FCHDIR
    12201280        ret = fchdir(newfd);
     1281#else
     1282        ret = chdir(path);
     1283#endif
    12211284bail:
     1285#ifdef HAVE_FCHDIR
    12221286        oerrno = errno;
    12231287        if (fd < 0)
    12241288                (void)_close(newfd);
    12251289        errno = oerrno;
     1290#else
     1291        (void)oerrno;
     1292#endif
    12261293        return (ret);
    12271294}
  • trunk/libc/src/libc/app/stdio.c

    r2120 r2672  
    9292    {
    9393        PLIBCFH pFH = __libc_FH(i);
    94         if (pFH)
     94        if (!pFH)
     95            LIBCLOG_MSG("No open file for %d\n", i);
     96
     97        /*
     98         * Common init - recall everything is ZERO.
     99         */
     100        gPreStreamVec.cFree--;
     101        gaPreFiles[i].__uVersion = _FILE_STDIO_VERSION;
     102        gaPreFiles[i]._flags    |= _IOOPEN | _IONOCLOSEALL;
     103        gaPreFiles[i]._handle    = i;
     104        gaPreFiles[i]._flush     = _flushstream;
     105        if (_fmutex_create2(&gaPreFiles[i].__u.__fsem, 0, "LIBC stream") != 0)
    95106        {
    96             /*
    97              * Common init - recall everything is ZERO.
    98              */
    99             gPreStreamVec.cFree--;
    100             gaPreFiles[i].__uVersion = _FILE_STDIO_VERSION;
    101             gaPreFiles[i]._flags    |= _IOOPEN | _IONOCLOSEALL;
    102             gaPreFiles[i]._handle    = i;
    103             gaPreFiles[i]._flush     = _flushstream;
    104             if (_fmutex_create2(&gaPreFiles[i].__u.__fsem, 0, "LIBC stream") != 0)
    105             {
    106                 LIBC_ASSERTM_FAILED("_setmore failed for i=%d\n", i);
    107                 abort();
    108             }
     107            LIBC_ASSERTM_FAILED("_setmore failed for i=%d\n", i);
     108            abort();
     109        }
    109110
    110             /*
    111              * Specific init.
    112              */
    113             switch (i)
    114             {
    115                 case 0:
    116                     /* stdin is always buffered. */
    117                     gaPreFiles[0]._flags    |= _IOREAD | _IOFBF | _IOBUFUSER;
    118                     gaPreFiles[0]._ptr       = gachStdIn;
    119                     gaPreFiles[0]._buffer    = gachStdIn;
    120                     gaPreFiles[0]._buf_size  = BUFSIZ;
    121                     LIBCLOG_MSG("__stdinp=%p\n", (void *)__stdinp);
    122                     break;
     111        /*
     112         * Specific init.
     113         */
     114        switch (i)
     115        {
     116            case 0:
     117                /* stdin is always buffered. */
     118                gaPreFiles[0]._flags    |= _IOREAD | _IOFBF | _IOBUFUSER;
     119                gaPreFiles[0]._ptr       = gachStdIn;
     120                gaPreFiles[0]._buffer    = gachStdIn;
     121                gaPreFiles[0]._buf_size  = BUFSIZ;
     122                LIBCLOG_MSG("__stdinp=%p\n", (void *)__stdinp);
     123                break;
    123124
    124                 case 1:
    125                     /* stdout is buffered unless it's connected to a device. */
    126                     gaPreFiles[1]._flags |= _IOWRT | _IOBUFNONE
    127                         | ((pFH->fFlags & __LIBC_FH_TYPEMASK) == F_DEV ? _IONBF : _IOFBF);
    128                     LIBCLOG_MSG("__stdoutp=%p flags=%#x (%s)\n", (void *)__stdoutp, gaPreFiles[1]._flags,
    129                                 (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_DEV ? "dev" : "none-dev");
    130                     break;
     125            case 1:
     126                /* stdout is buffered unless it's connected to a device. */
     127                gaPreFiles[1]._flags |= _IOWRT | _IOBUFNONE
     128                    | (pFH && (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_DEV ? _IONBF : _IOFBF);
     129                LIBCLOG_MSG("__stdoutp=%p flags=%#x (%s)\n", (void *)__stdoutp, gaPreFiles[1]._flags,
     130                            pFH && (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_DEV ? "dev" : "none-dev");
     131                break;
    131132
    132                 case 2:
    133                     /* stderr is always unbuffered. */
    134                     gaPreFiles[2]._flags |= _IOWRT | _IOBUFNONE | _IONBF;
    135                     LIBCLOG_MSG("__stderrp=%p\n", (void *)__stderrp);
    136                     break;
    137             }
     133            case 2:
     134                /* stderr is always unbuffered. */
     135                gaPreFiles[2]._flags |= _IOWRT | _IOBUFNONE | _IONBF;
     136                LIBCLOG_MSG("__stderrp=%p\n", (void *)__stderrp);
     137                break;
    138138        }
    139         else
    140             LIBCLOG_MSG("No open file for %d\n", i);
    141139    } /* for standard handles. */
    142140    LIBCLOG_RETURN_VOID();
  • trunk/libc/src/libc/io/_fopen.c

    r1661 r2672  
    3535    default:
    3636      errno = EINVAL;
    37       STREAMV_LOCK;
     37      if (lock)
     38        STREAMV_LOCK;
    3839      _closestream (dst);
    39       STREAMV_UNLOCK;
     40      if (lock)
     41        STREAMV_UNLOCK;
    4042      return NULL;
    4143    }
     
    8385  if (_fmutex_create2 (&dst->__u.__fsem, 0, "LIBC stream fopen") != 0)
    8486    {
    85       STREAMV_LOCK;
     87      if (lock)
     88        STREAMV_LOCK;
    8689      _closestream (dst);
    87       STREAMV_UNLOCK;
     90      if (lock)
     91        STREAMV_UNLOCK;
    8892      return NULL;
    8993    }
     
    9195  if (dst->_handle < 0)
    9296    {
    93       STREAMV_LOCK;
     97      if (lock)
     98        STREAMV_LOCK;
    9499      _closestream (dst);
    95       STREAMV_UNLOCK;
     100      if (lock)
     101        STREAMV_UNLOCK;
    96102      return NULL;
    97103    }
  • trunk/libc/src/libc/io/freopen.c

    r1604 r2672  
    66#include <string.h>
    77#include <share.h>
     8#include <errno.h>
     9#include <sys/fcntl.h>
    810#include <sys/builtin.h>        /* For <sys/fmutex.h> */
    911#include <sys/fmutex.h>
    1012#include <emx/io.h>
    1113
     14#define FALSE   0
     15#define TRUE    1
     16
     17/**
     18 * Interprets the stream mode string.
     19 *
     20 * @returns the basic stream flags and *pmode set to the open mode.
     21 * @returns -1 and *pomode unset on failure.
     22 * @param   mode    The mode string.
     23 * @param   pomode  Where to store the open mode.
     24 */
     25static int _interpret_stream_mode(const char *mode, unsigned *pomode)
     26{
     27    int flags = 0;
     28    int omode = 0;
     29    char bt, ok;
     30
     31    switch (*mode)
     32      {
     33      case 'r':
     34        flags = _IOREAD;
     35        omode = O_RDONLY;
     36        break;
     37      case 'w':
     38        flags = _IOWRT;
     39        omode = O_WRONLY|O_CREAT|O_TRUNC;
     40        break;
     41      case 'a':
     42        flags = _IOWRT;
     43        omode = O_WRONLY|O_CREAT|O_APPEND;
     44        break;
     45      default:
     46        errno = EINVAL;
     47        return -1;
     48      }
     49
     50    ok = TRUE;
     51    bt = FALSE;
     52    while (ok && *++mode)
     53      {
     54        switch (*mode)
     55          {
     56          case 't':
     57            if (bt)
     58              ok = FALSE;
     59            else
     60              {
     61                bt = TRUE;
     62                omode |= O_TEXT;
     63              }
     64            break;
     65          case 'b':
     66            if (bt)
     67              ok = FALSE;
     68            else
     69              {
     70                bt = TRUE;
     71                omode |= O_BINARY;
     72              }
     73            break;
     74          case '+':
     75            if (flags & _IORW)
     76              ok = FALSE;
     77            else
     78              {
     79                omode &= ~(O_RDONLY|O_WRONLY);
     80                omode |= O_RDWR;
     81                flags &= ~(_IOREAD|_IOWRT);
     82                flags |= _IORW;
     83              }
     84            break;
     85          default:
     86            ok = FALSE;
     87            break;
     88          }
     89      }
     90    *pomode = omode;
     91    return flags;
     92}
     93
    1294FILE *_STD(freopen) (const char *fname, const char *mode, FILE *stream)
    1395{
    14   FILE *result;
     96  FILE *result = NULL;
    1597
    1698  STREAMV_LOCK;
    17   if (stream->_flags & _IOOPEN)
    18     { /* duplication of fclose(), but no _closestream lock. */
    19       int result;
    20       char buf[L_tmpnam];
     99  if (!fname)
     100    {
     101      /*
     102       * Change the stream mode.
     103       */
     104      if (stream->_flags & _IOOPEN)
     105        {
     106          int omode;
     107          int flags = _interpret_stream_mode(mode, &omode);
     108          if (flags != -1)
     109            {
     110              if (   ((flags & _IORW)   && !(stream->_flags & _IORW))
     111                  || ((flags & _IOREAD) && !(stream->_flags & (_IORW | _IOREAD)))
     112                  || ((flags & _IOWRT)  && !(stream->_flags & (_IORW | _IOWRT)))
     113                  )
     114                  errno = EINVAL;
     115              else
     116                {
     117                  if (!(stream->_flags & _IOSPECIAL))
     118                    {
     119                      /* flush it and set the new mode */
     120                      fflush(stream);
     121                      if (!fcntl(fileno(stream), F_SETFL, omode))
     122                        stream = stream;
     123                    }
     124                  else
     125                    errno = EBADF; /* doesn't support the mode. */
     126                }
     127            }
     128        }
     129      else
     130        errno = EBADF;
     131    }
     132  else
     133    {
     134      if (stream->_flags & _IOOPEN)
     135        { /* duplication of fclose(), but no _closestream lock. */
     136          int result;
     137          char buf[L_tmpnam];
    21138
    22       result = EOF;
    23       if ((stream->_flags & _IOOPEN) && !(stream->_flags & _IOSPECIAL))
    24         {
    25           result = 0;
    26           result = fflush (stream);
    27           if (close (stream->_handle) < 0)
    28             result = EOF;
    29           if (result == 0 && (stream->_flags & _IOTMP))
     139          result = EOF;
     140          if ((stream->_flags & _IOOPEN) && !(stream->_flags & _IOSPECIAL))
    30141            {
    31               _itoa (stream->_tmpidx, buf, 10);
    32               strcat (buf, ".tmp");
    33               if (remove (buf) != 0)
     142              result = 0;
     143              result = fflush (stream);
     144              if (close (stream->_handle) < 0)
    34145                result = EOF;
     146              if (result == 0 && (stream->_flags & _IOTMP))
     147                {
     148                  _itoa (stream->_tmpidx, buf, 10);
     149                  strcat (buf, ".tmp");
     150                  if (remove (buf) != 0)
     151                    result = EOF;
     152                }
     153              if ((stream->_flags & _IOBUFMASK) == _IOBUFLIB)
     154                free (stream->_buffer);
    35155            }
    36           if ((stream->_flags & _IOBUFMASK) == _IOBUFLIB)
    37             free (stream->_buffer);
     156          _closestream (stream);
    38157        }
    39       _closestream (stream);
     158      result = _openstream (stream, fname, mode, SH_DENYNO, 0);
    40159    }
    41   result = _openstream (stream, fname, mode, SH_DENYNO, 0);
    42160  STREAMV_UNLOCK;
    43161  return result;
  • trunk/libc/src/libc/io/fstat.c

    r1519 r2672  
    2121      _loc2gmt (&buffer->st_mtime, -1);
    2222      _loc2gmt (&buffer->st_ctime, -1);
     23      _loc2gmt (&buffer->st_birthtime, -1);
    2324    }
    2425  else
  • trunk/libc/src/libc/io/getdelim.c

    r2254 r2672  
    4646 *
    4747 * @returns number of bytes read.
    48  * @returns -1 on failure, including EOF.
     48 * @returns -1 on failure - this includes EOF when nothing was retrieved.
    4949 * @param   ppszString      Where to buffer pointer is stored. *ppszString can of course be NULL.
    5050 * @param   pcchString      Size of the buffer pointed to by *ppszString.
     
    8181     */
    8282    STREAM_LOCK(pStream);
    83     ssize_t rc = -1;
     83    ssize_t rc = 0;
    8484    char *psz = *ppszString;
    8585    char *pszEnd = psz + *pcchString - 1;
     
    9090        int ch = _getc_inline(pStream);
    9191        if (ch == EOF)
     92        {
     93            if (psz == *ppszString)
     94                rc = -1;
    9295            break;
     96        }
    9397        if (psz == pszEnd)
    9498        {
     
    100104            char *pszNew = (char *)realloc(*ppszString, cch);
    101105            if (!pszNew)
     106            {
     107                rc = -1;
    102108                break;
     109            }
    103110
    104111            psz = pszNew + (psz - *ppszString);
     
    109116        *psz++ = (char)ch;
    110117        if (ch == chDelim)
    111         {
    112             rc = psz - *ppszString;
    113118            break;
    114         }
    115119    }
    116120    STREAM_UNLOCK(pStream);
     121
     122    if (!rc)
     123        rc = psz - *ppszString;
    117124
    118125    *psz = '\0';
  • trunk/libc/src/libc/io/lstat.c

    r2254 r2672  
    5050        _loc2gmt(&buffer->st_mtime, -1);
    5151        _loc2gmt(&buffer->st_ctime, -1);
     52        _loc2gmt(&buffer->st_birthtime, -1);
    5253        LIBCLOG_RETURN_INT(0);
    5354    }
  • trunk/libc/src/libc/io/stat.c

    r2254 r2672  
    2121        _loc2gmt(&buffer->st_mtime, -1);
    2222        _loc2gmt(&buffer->st_ctime, -1);
     23        _loc2gmt(&buffer->st_birthtime, -1);
    2324        LIBCLOG_RETURN_INT(rc);
    2425    }
  • trunk/libc/src/libc/locale/locale_ctype.c

    r2058 r2672  
    220220unsigned __ctype(__ct_rune_t __ch, unsigned __f)
    221221{
    222     return !((__ch) & ~0xffU)
    223         ? __libc_GLocaleCtype.aufType[(__ch)/* & 0xff*/] & (__f)
     222    return __ch <= 255 && __ch >= -128
     223        ? __libc_GLocaleCtype.aufType[__ch & 0xff] & __f
    224224        : 0;
    225225}
     
    227227int __istype(__ct_rune_t __ch, unsigned __f)
    228228{
    229     return !!__ctype((__ch), (__f));
     229    return !!__ctype(__ch, __f);
    230230}
    231231
    232232__ct_rune_t __toupper(__ct_rune_t __ch)
    233233{
    234     return !((__ch) & ~0xffU)
    235         ? __libc_GLocaleCtype.auchUpper[(__ch)/* & 0xff*/]
    236         : (__ch);
     234    return __ch <= 255 && __ch >= -128 && __ch != -1 /* EOF */
     235        ? __libc_GLocaleCtype.auchUpper[__ch & 0xff]
     236        : __ch;
    237237}
    238238
    239239__ct_rune_t __tolower(__ct_rune_t __ch)
    240240{
    241     return !((__ch) & ~0xffU)
    242         ? __libc_GLocaleCtype.auchLower[(__ch)/* & 0xff*/]
    243         : (__ch);
     241    return __ch <= 255 && __ch >= 128 && __ch != -1 /* EOF */
     242        ? __libc_GLocaleCtype.auchLower[__ch & 0xff]
     243        : __ch;
    244244}
    245245
     
    397397}
    398398
    399 
    400399/**
    401400 * Get unicode type.
     
    404403unsigned ___wctype(__wchar_t wc)
    405404{
    406     unsigned    ufType = 0;
    407405    if (    __libc_GLocaleWCtype.uMask != ~0x7f
    408406        ||  wc <= 127)
    409407    {
    410         UNICTYPE   *pUniType = UniQueryCharType(wc);
     408        UNICTYPE *pUniType = UniQueryCharType(wc);
    411409        if (pUniType)
    412         {
    413             /* ASSUMES CT_* << 8 == __* ! */
    414             ufType = ((unsigned)pUniType->itype << 8)
    415                    & (__CT_UPPER  | __CT_LOWER  | __CT_DIGIT | __CT_SPACE |
    416                       __CT_PUNCT  | __CT_CNTRL  | __CT_BLANK | __CT_XDIGIT |
    417                       __CT_ALPHA  | __CT_ALNUM  | __CT_GRAPH | __CT_PRINT |
    418                       __CT_NUMBER | __CT_SYMBOL | __CT_ASCII);
    419             if (pUniType->extend & C3_IDEOGRAPH)
    420                 ufType |= __CT_IDEOGRAM;
    421             if (ufType & (__CT_XDIGIT | __CT_DIGIT))
    422             {
    423                 if (     (unsigned)wc - 0x30U <= (0x39 - 0x30))
    424                     ufType |= (unsigned)wc - 0x30;
    425                 else if ((unsigned)wc - 0x41U <= (0x46 - 0x41))
    426                     ufType |= (unsigned)wc - 0x41 + 0xa;
    427                 else
    428                 {
    429                     unsigned uVal = UniQueryNumericValue(wc);
    430                     if (!(uVal & ~0xffU))
    431                         ufType |= uVal;
    432                 }
    433             }
    434             ufType |= (pUniType->bidi & 0xf << 24);
    435 
    436             /** @todo screen width. */
    437         }
    438     }
    439     return ufType;
     410            return ___wctype_uni(pUniType, wc);
     411    }
     412    return 0;
    440413}
    441414
  • trunk/libc/src/libc/locale/setlocale.c

    r2262 r2672  
    599599        UniChar         uc = 0xffff;
    600600
    601         /* isxxx() do not support MBCS characters at all. */
     601        /* isxxx() does not support MBCS characters at all. */
    602602        if (!pCtype->mbcs || !IS_MBCS_PREFIX(pCtype, i))
    603603        {
     
    609609                if (pUniType)
    610610                {
    611                     ufType = ___wctype(uc);
     611                    ufType = ___wctype_uni(pUniType, uc);
    612612                    if (ufType & __CT_LOWER)
    613613                        uchUpper = Transform(lobj, uobj, UniTransUpper, uc, i);
  • trunk/libc/src/libc/misc/basename.c

    r1506 r2672  
    7171        }
    7272
     73        /* d:/ */
     74        if (*endp == ':' && endp == path + 1) {
     75                (void)strncpy(bname, path, 3);
     76                bname[3] = '\0';
     77                return(bname);
     78        }
     79
    7380        /* Find the start of the base */
    7481        startp = endp;
    75         while (startp > path && *(startp - 1) != '/' && *(startp - 1) != '\\' && *(startp - 1) != ':')
     82        while (    startp > path
     83               &&  *(startp - 1) != '/'
     84               &&  *(startp - 1) != '\\'
     85               &&  (*(startp - 1) != ':' || startp != path + 2))
    7686                startp--;
    7787
  • trunk/libc/src/libc/misc/dirent.c

    r2254 r2672  
    169169        //errno = ENOENT;
    170170        *ppdent = NULL;
    171         LIBCLOG_RETURN_P(-1); /** @todo readdir_r return code is wrong */
     171        LIBCLOG_RETURN_P(0);
    172172    }
    173173
  • trunk/libc/src/libc/misc/dirname.c

    r1506 r2672  
    6767
    6868        /* Find the start of the dir */
    69         while (endp > path && *endp != '/' && *endp != '/' && *endp != ':')
     69        while (endp > path && *endp != '/' && *endp != '\\' && (*endp != ':' || endp != path + 1))
    7070                endp--;
    7171
     
    7474                (void)strcpy(bname, *endp == '/' || *endp == '\\' ? "/" : ".");
    7575                return(bname);
    76         } else {
     76        }
     77
     78        if (*endp == ':' && endp == path + 1) {
     79                if (endp[1] == '/' || endp[1] == '\\')
     80                        endp++;
     81        } else if (endp != path + 2 || path[1] != ':') {
    7782                do {
    7883                        endp--;
  • trunk/libc/src/libc/sys/__read.c

    r2437 r2672  
    1515#include <emx/syscalls.h>
    1616#include "syscalls.h"
     17#define __LIBC_LOG_GROUP    __LIBC_LOG_GRP_BACK_IO
     18#include <InnoTekLIBC/logstrict.h>
    1719
    1820int __read (int handle, void *buf, size_t cbToRead)
    1921{
     22    LIBCLOG_ENTER("fd=%d buf=%p cbToRead=%zu\n", handle, buf, cbToRead);
    2023    int     rc;
    2124    PLIBCFH pFH;
     
    2932    {
    3033        errno = EBADF;
    31         return -1;
     34        LIBCLOG_ERROR_RETURN_INT(-1);
    3235    }
    3336
     
    5053            pvBuf_safe = _lmalloc(cbToRead);
    5154            if (!pvBuf_safe)
    52                 return ERROR_NOT_ENOUGH_MEMORY;
     55            {
     56                errno = ENOMEM;
     57                LIBCLOG_ERROR_RETURN_INT(-1);
     58            }
    5359            memcpy(pvBuf_safe, buf, cbToRead);
    5460        }
     
    8995            rc = -EBADF;
    9096        errno = -rc;
    91         return -1;
     97        LIBCLOG_ERROR_RETURN_INT(-1);
    9298    }
    93 
    94     return cbRead;
     99    LIBCLOG_RETURN_INT(cbRead);
    95100}
  • trunk/libc/src/libc/sys/__spawnve.c

    r2323 r2672  
    5858        size_t              cbFS;
    5959        __LIBC_PSPMINHFS    pFS;
    60         if (!__libc_back_fsInheritPack(&pFS, &cbFS))
     60        size_t              cbFS2;
     61        __LIBC_PSPMINHFS2   pFS2;
     62        if (!__libc_back_fsInheritPack(&pFS, &cbFS, &pFS2, &cbFS2))
    6163        {
    6264            /*
     
    7173                 */
    7274                #define ALIGNIT(cb) (((cb) + 3) & ~3)
    73                 size_t  cb = sizeof(__LIBC_SPMINHERIT) + ALIGNIT(cbFH) + ALIGNIT(cbFS) + ALIGNIT(cbSig) + ALIGNIT(cbStrings);
     75                size_t  cb = sizeof(__LIBC_SPMINHERIT) + ALIGNIT(cbFH) + ALIGNIT(cbFS) + ALIGNIT(cbFS2) + ALIGNIT(cbSig) + ALIGNIT(cbStrings);
    7476                pRet = __libc_spmAlloc(cb);
    7577                if (pRet)
     
    9496                    else
    9597                        pRet->pFS = NULL;
     98
     99                    /* fs2 */
     100                    if (pFS2)
     101                    {
     102                        pRet->pFS2 = (__LIBC_PSPMINHFS2)p;
     103                        p += ALIGNIT(cbFS2);
     104                        memcpy(pRet->pFS2, pFS2, cbFS2);
     105                        free(pFS2);
     106                    }
     107                    else
     108                        pRet->pFS2 = NULL;
    96109
    97110                    /* sig */
     
    123136            }
    124137            free(pFS);
     138            free(pFS2);
    125139        }
    126140
  • trunk/libc/src/libc/sys/__write.c

    r2437 r2672  
    1515#include <emx/syscalls.h>
    1616#include "syscalls.h"
     17#define __LIBC_LOG_GROUP    __LIBC_LOG_GRP_BACK_IO
     18#include <InnoTekLIBC/logstrict.h>
    1719
    1820int __write(int handle, const void *buf, size_t cbToWrite)
    1921{
     22    LIBCLOG_ENTER("fd=%d buf=%p cbToWrite=%zu\n", handle, buf, cbToWrite);
    2023    PLIBCFH pFH;
    2124    int     rc;
     
    3235    {
    3336        errno = EBADF;
    34         return -1;
     37        LIBCLOG_ERROR_RETURN_INT(-1);
    3538    }
    3639
     
    5255                pvBuf_safe = _lmalloc(cbToWrite);
    5356                if (!pvBuf_safe)
    54                     return ERROR_NOT_ENOUGH_MEMORY;
     57                {
     58                    errno = ENOMEM;
     59                    LIBCLOG_ERROR_RETURN_INT(-1);
     60                }
    5561                memcpy(pvBuf_safe, buf, cbToWrite);
    5662                buf = pvBuf_safe;
     
    98104            rc = -EBADF;
    99105        errno = -rc;
    100         return -1;
     106        LIBCLOG_ERROR_RETURN_INT(-1);
    101107    }
    102     return cbWritten;
     108    LIBCLOG_RETURN_INT(cbWritten);
    103109}
    104110
  • trunk/libc/src/libc/sys/b_dir.c

    r2424 r2672  
    368368             */
    369369            char   *psz = strchr(pszNativePath, '\0');
    370             psz[0] = '/';
    371             psz[1] = '*';
    372             psz[2] = '\0';
     370            if (psz[-1] != '/' && psz[-1] != '\\')
     371            {
     372                psz[0] = '/';
     373                psz[1] = '*';
     374                psz[2] = '\0';
     375            }
     376            else
     377            {
     378                psz[0] = '*';
     379                psz[1] = '\0';
     380            }
    373381            bzero(Tmp.uBuf.pv, Tmp.cbBuf);
    374382            FS_VAR_SAVE_LOAD();
     
    380388                              &Tmp.cFiles,
    381389                              Tmp.fType);
     390            *psz = '\0';
    382391            if (!rc)
    383392            {
     
    390399
    391400                    __LIBC_PFHDIR pFHDir = (__LIBC_PFHDIR)pFH;
    392                     pFHDir->hDir        = Tmp.hDir;
     401                    pFHDir->fInUnixTree = 0;
    393402                    pFHDir->fType       = Tmp.fType;
    394403                    pFHDir->uBuf.pv     = Tmp.uBuf.pv;
     
    396405                    pFHDir->cFiles      = Tmp.cFiles;
    397406                    pFHDir->cbBuf       = Tmp.cbBuf;
     407                    pFHDir->hDir        = Tmp.hDir;
    398408                    pFHDir->uCurEntry   = 0;
    399409
     
    447457        pFHDir->Core.Inode = Inode;
    448458        pFHDir->Core.Dev   = Dev;
     459        pFHDir->fInUnixTree = fInUnixTree;
    449460
    450461        /*
     
    508519        pFHDir->Core.Inode = pStat->st_ino;
    509520        pFHDir->Core.Dev   = pStat->st_dev;
     521        pFHDir->fInUnixTree = fInUnixTree;
    510522
    511523        LIBCLOG_MSG("pFHDir=%p:{.hDir=%#lx, .fType=%d, .cFiles=%ld, .cbBuf=%#x} fh=%d\n",
  • trunk/libc/src/libc/sys/b_fs.h

    r2328 r2672  
    242242 * @returns 0 on success.
    243243 * @returns -1 on failure.
    244  * @param   ppFS    Where to store the pointer to the inherit data.
    245  * @param   pcbFS   Where to store the size of the inherit data.
    246  */
    247 int __libc_back_fsInheritPack(__LIBC_PSPMINHFS *ppFS, size_t *pcbFS);
     244 * @param   ppFS    Where to store the pointer to the inherit data, part 1.
     245 * @param   pcbFS   Where to store the size of the inherit data, part 1.
     246 * @param   ppFS2   Where to store the pointer to the inherit data, part 2.
     247 * @param   pcbFS2  Where to store the size of the inherit data, part 2.
     248 */
     249int __libc_back_fsInheritPack(__LIBC_PSPMINHFS *ppFS, size_t *pcbFS, __LIBC_PSPMINHFS2 *ppFS2, size_t *pcbFS2);
    248250
    249251/**
     
    332334int __libc_back_fsUnixAttribsGet(int hFile, const char *pszNativePath, struct stat *pStat);
    333335
     336/**
     337 * Reads the unix file mode EA.
     338 *
     339 * @returns 0 on success.
     340 * @returns -ENOTSUP if the file mode EA is not present or if Unix EAs isn't supported on the volume.
     341 * @returns Negative errno on failure.
     342 * @param   hFile           File handle to the fs object. If no handle handy, set to -1.
     343 * @param   pszNativePath   Native path to the fs object. If handle is give this will be ignored.
     344 * @param   pMode           Where to store the mode mask.
     345 */
     346int __libc_back_fsUnixAttribsGetMode(int hFile, const char *pszNativePath, mode_t *pMode);
    334347
    335348/**
     
    411424
    412425/**
     426 * Gets the fs info object for the specfied path.
     427 *
     428 * @returns Pointer to info object for the path, if it got one.
     429 * @param   pszNativePath   The native path as returned by the resolver.
     430 */
     431__LIBC_PFSINFO __libc_back_fsInfoObjByPath(const char *pszNativePath);
     432
     433/**
     434 * Gets the fs info object for the specfied path, with cache.
     435 *
     436 * @returns Pointer to info object for the path, if it got one.
     437 * @param   pszNativePath   The native path as returned by the resolver.
     438 * @param   pCached         An cached fs info object reference. Can be NULL.
     439 */
     440__LIBC_PFSINFO __libc_back_fsInfoObjByPathCached(const char *pszNativePath, __LIBC_PFSINFO pCached);
     441
     442/**
    413443 * Adds a reference to an existing FS info object.
    414444 *
     
    428458void __libc_back_fsInfoObjRelease(__LIBC_PFSINFO pFsInfo);
    429459
     460/**
     461 * Checks if the path supports Unix EAs or not.
     462 *
     463 * @returns true / false.
     464 * @param   pszNativePath       The native path to check.
     465 */
     466int __libc_back_fsInfoSupportUnixEAs(const char *pszNativePath);
     467
    430468__END_DECLS
    431469
  • trunk/libc/src/libc/sys/b_fsDirCreate.c

    r2313 r2672  
    6969     */
    7070    PEAOP2 pEaOp2 = NULL;
    71     if (__predict_true(!__libc_gfNoUnix))
     71    if (__predict_true(__libc_back_fsInfoSupportUnixEAs(szNativePath)))
    7272    {
    7373        Mode &= ~__libc_gfsUMask;
  • trunk/libc/src/libc/sys/b_fsFileModeSetFH.c

    r2313 r2672  
    121121         * If in unix mode we'll have to update/add the MODE too.
    122122         */
    123         if (!__libc_gfNoUnix)
     123        if (    !__libc_gfNoUnix
     124            &&  pFH->pFsInfo
     125            &&  pFH->pFsInfo->fUnixEAs)
    124126        {
    125             struct stat st = {0};
    126             rc = __libc_back_fsUnixAttribsGet(fh, pFH->pszNativePath, &st);
     127            mode_t CurMode;
     128            rc = __libc_back_fsUnixAttribsGetMode(fh, pFH->pszNativePath, &CurMode);
    127129            if (__predict_true(!rc))
    128130            {
    129131                /* correct the passed in Mode mask. */
    130132                Mode &= ALLPERMS; /** @todo sticky bit and set uid/gid access validation... */
    131                 Mode |= st.st_mode & ~ALLPERMS;
     133                Mode |= CurMode & ~ALLPERMS;
    132134
    133135                /* construct FEA2 stuff. */
  • trunk/libc/src/libc/sys/b_fsFileStatFH.c

    r2316 r2672  
    7171        LIBCLOG_ERROR_RETURN_INT(rc);
    7272
     73    int fUnixEAs = !__libc_gfNoUnix && pFH->pFsInfo && pFH->pFsInfo->fUnixEAs;
    7374    if (/*!pFH->pOps*/ 1)
    7475    {
     
    110111            if (__libc_gpfnDosOpenL)
    111112            {
    112                 rc = DosQueryFileInfo(fh, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
     113                if (fUnixEAs)
     114                    rc = DosQueryFileInfo(fh, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
     115                else
     116                    rc = -1;
    113117                if (rc)
    114118                {
     
    121125#endif
    122126            {
    123                 rc = DosQueryFileInfo(fh, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
     127                if (fUnixEAs)
     128                    rc = DosQueryFileInfo(fh, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
     129                else
     130                    rc = -1;
    124131                if (rc)
    125132                {
     
    175182
    176183            /* If in unix mode we'll check the EAs (if any). */
    177             if (    !__libc_gfNoUnix
     184            if (   fUnixEAs
    178185                && (fLarge ? info.fsts4L.cbList : info.fsts4.cbList) >= LIBC_UNIX_EA_MIN)
    179186                __libc_back_fsUnixAttribsGet(fh, pFH->pszNativePath, pStat);
  • trunk/libc/src/libc/sys/b_fsNativeFileModeSet.c

    r2313 r2672  
    8989    FS_SAVE_LOAD();
    9090    int rc;
    91 #if OFF_MAX > LONG_MAX
    92     if (__libc_gpfnDosOpenL)
    93     {
    94         rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
    95         fLarge = 1;
     91    const int fUnixEAs = __libc_back_fsInfoSupportUnixEAs(pszNativePath);
     92    if (fUnixEAs)
     93    {
     94#if OFF_MAX > LONG_MAX
     95        if (__libc_gpfnDosOpenL)
     96        {
     97            rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
     98            fLarge = 1;
     99        }
     100        else
     101#endif
     102            rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
     103        /* If the file is open in write mode, we cannot even get the EA size. stupid.
     104         * It'll fail with ERROR_SHARING_VIOLATION, which we handle rigth below. */
    96105    }
    97106    else
    98 #endif
    99         rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
    100     /* Now, if the file is open in write mode, we cannot even get the EA size. stupid. */
     107        rc = ERROR_SHARING_VIOLATION; /* take the fallback path if we don't want EAs. */
    101108    if (rc == ERROR_SHARING_VIOLATION)
    102109    {
     
    150157     * If in unix mode we'll have to update/add the MODE too.
    151158     */
    152     if (!__libc_gfNoUnix)
    153     {
    154         struct stat st = {0};
    155         rc = __libc_back_fsUnixAttribsGet(-1, pszNativePath, &st);
     159    if (fUnixEAs)
     160    {
     161        mode_t CurMode;
     162        rc = __libc_back_fsUnixAttribsGetMode(-1, pszNativePath, &CurMode);
    156163        if (__predict_true(!rc))
    157164        {
    158165            /* correct the passed in Mode mask. */
    159166            Mode &= ALLPERMS; /** @todo sticky bit and set uid/gid access validation... */
    160             Mode |= st.st_mode & ~ALLPERMS;
     167            Mode |= CurMode & ~ALLPERMS;
    161168
    162169            /* construct FEA2 stuff. */
  • trunk/libc/src/libc/sys/b_fsNativeFileStat.c

    r2316 r2672  
    8686     */
    8787    /** @todo copy device check from the path resolver. */
     88
    8889    /*
    8990     * Get path info.
     
    9192    FS_SAVE_LOAD();
    9293    int rc;
    93 #if OFF_MAX > LONG_MAX
    94     if (__libc_gpfnDosOpenL)
    95     {
    96         rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
    97         fLarge = 1;
    98     }
    99     else
    100 #endif
    101         rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
     94    const int fUnixEAs = __libc_back_fsInfoSupportUnixEAs(pszNativePath);
     95    if (fUnixEAs)
     96    {
     97#if OFF_MAX > LONG_MAX
     98        if (__libc_gpfnDosOpenL)
     99        {
     100            rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZEL, &info, sizeof(info.fsts4L));
     101            fLarge = 1;
     102        }
     103        else
     104#endif
     105            rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASIZE, &info, sizeof(info.fsts4));
     106        /* If the file is open in write mode, we cannot even get the EA size. stupid.
     107         * It'll fail with ERROR_SHARING_VIOLATION, which we handle rigth below. */
     108    }
     109    else
     110        rc = ERROR_SHARING_VIOLATION; /* take the fallback path if we don't want EAs. */
     111
    102112    /* Now, if the file is open in write mode, we cannot even get the EA size. stupid. */
    103113    if (rc == ERROR_SHARING_VIOLATION)
     
    128138     */
    129139    /* Times: FAT might not return create and access time. */
    130     pStat->st_mtime = pStat->st_mtime = _sys_p2t(info.fsts4.ftimeLastWrite, info.fsts4.fdateLastWrite);
     140    pStat->st_mtime = pStat->st_ctime = _sys_p2t(info.fsts4.ftimeLastWrite, info.fsts4.fdateLastWrite);
    131141    if (   FTIMEZEROP(info.fsts4.ftimeCreation)
    132142        && FDATEZEROP(info.fsts4.fdateCreation))
     
    198208    /* If in unix mode we'll check the EAs (if any). */
    199209    rc = 1;
    200     if (    !__libc_gfNoUnix
     210    if (    fUnixEAs
    201211        && (fLarge ? info.fsts4L.cbList : info.fsts4.cbList) >= LIBC_UNIX_EA_MIN)
    202212        rc = __libc_back_fsUnixAttribsGet(-1, pszNativePath, pStat);
  • trunk/libc/src/libc/sys/b_fsUnlink.c

    r2254 r2672  
    8080     * times.
    8181     */
    82     static int fUseForce = 0; /* state: 0 - uninit, 1 - DosForceDelete, -1 - DosDelete */
    83     if (fUseForce == 0)
     82    static int s_fUseForce = 0; /* state: 0 - uninit, 1 - DosForceDelete, -1 - DosDelete */
     83    if (s_fUseForce == 0)
    8484    {
    8585        PSZ psz = NULL;
    8686        if (DosScanEnv((PCSZ)"DELDIR", &psz) || !psz)
    87             fUseForce = 1;
     87            s_fUseForce = 1;
    8888        else
    89             fUseForce = -1;
     89            s_fUseForce = -1;
    9090    }
    9191
     
    9393     * We'll attempt delete it as a file first.
    9494     */
    95     if (fUseForce == 1)
     95    if (s_fUseForce == 1)
    9696        rc = DosForceDelete((PCSZ)&szNativePath[0]);
    9797    else
     
    100100    {
    101101        /*
    102          * Ok, try delete it as a directory then.
     102         * There are three causes here:
     103         *      1) the file is marked read-only.
     104         *      2) it's a directory.
     105         *      3) we are denied access - network, hpfs386 or SES.
     106         *
     107         * If it's either of the first two we are subject to race conditions, so we
     108         * have to retry. The third cause is distiguishable from the two othes by
     109         * the failing DosSetPathInfo.
    103110         */
    104         rc = DosDeleteDir((PCSZ)&szNativePath[0]);
     111        int fDirectory = 0;
     112        for (unsigned i = 0; (rc == ERROR_ACCESS_DENIED || rc == ERROR_PATH_NOT_FOUND) && i < 2; i++)
     113        {
     114            FILESTATUS3 fsts3;
     115            rc = DosQueryPathInfo((PCSZ)&szNativePath[0], FIL_STANDARD, &fsts3, sizeof(fsts3));
     116            if (!rc)
     117            {
     118                fDirectory = (fsts3.attrFile & FILE_DIRECTORY) != 0;
     119
     120                /* turn of the read-only attribute */
     121                if (fsts3.attrFile & FILE_READONLY)
     122                {
     123                    fsts3.attrFile &= ~FILE_READONLY;
     124                    rc = DosSetPathInfo((PCSZ)&szNativePath[0], FIL_STANDARD, &fsts3, sizeof(fsts3), 0);
     125                    LIBCLOG_MSG("attempt at disabling the R attribute -> %d\n", rc);
     126                    if (    rc == ERROR_ACCESS_DENIED
     127                        ||  rc == ERROR_SHARING_VIOLATION)
     128                    {
     129                        rc = ERROR_ACCESS_DENIED;
     130                        break;
     131                    }
     132                }
     133
     134                /* retry */
     135                if (fDirectory)
     136                    rc = DosDeleteDir((PCSZ)&szNativePath[0]);
     137                else if (s_fUseForce == 1)
     138                    rc = DosForceDelete((PCSZ)&szNativePath[0]);
     139                else
     140                    rc = DosDelete((PCSZ)&szNativePath[0]);
     141            }
     142            else
     143            {
     144                rc = ERROR_ACCESS_DENIED;
     145                break;
     146            }
     147        }
     148
     149        /*
     150         * OS/2 returns access denied when the directory
     151         * contains files or it is not a directory. Check for
     152         * directory/other and return failure accordingly.
     153         */
    105154        if (rc)
    106155        {
    107             /*
    108              * OS/2 returns access denied when the directory
    109              * contains files or it is not a directory. Check for
    110              * directory/other and return failure accordingly.
    111              */
    112156            if (rc == ERROR_ACCESS_DENIED)
    113             {
    114                 struct stat s;
    115                 rc = __libc_back_fsNativeFileStat(&szNativePath[0], &s);
    116                 if (!rc && S_ISDIR(s.st_mode))
    117                     rc = -ENOTEMPTY;
    118                 else
    119                     rc = -EACCES;
    120             }
     157                rc = fDirectory ? -ENOTEMPTY : -EACCES;
    121158            else
    122159                rc = -__libc_native2errno(rc);
  • trunk/libc/src/libc/sys/b_ioFileOpen.c

    r2424 r2672  
    259259        Mode &= ACCESSPERMS;
    260260        Mode |= S_IFREG;
    261         if (flOpenFlags & (OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS))
     261        if (    (flOpenFlags & (OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS))
     262            &&  __libc_back_fsInfoSupportUnixEAs(szNativePath))
    262263        {
    263264            pEaOp2 = alloca(sizeof(EAOP2) + sizeof(__libc_gFsUnixAttribsCreateFEA2List));
  • trunk/libc/src/libc/sys/b_nativeSymlinkCreate.c

    r2313 r2672  
    5858    BYTE    fSymlinkEA;
    5959    BYTE    cbSymlinkName;
    60     USHORT  usSymlinkValue;
     60    USHORT  cbSymlinkValue;
    6161    CHAR    szSymlinkName[sizeof(EA_SYMLINK)];
    6262    USHORT  usSymlinkType;
     
    7777        OFF(offSymlink,     Core.offFlags), FEA_NEEDEA,  sizeof(EA_FLAGS) - 1, sizeof(uint32_t) + 4, EA_FLAGS, EAT_BINARY, sizeof(uint32_t), 0, "",
    7878    },
    79     0,                                      FEA_NEEDEA,  sizeof(EA_SYMLINK) - 1, 0              + 4, EA_FLAGS, EAT_ASCII, 0,                ""
     79    0,                                      FEA_NEEDEA,  sizeof(EA_SYMLINK) - 1, 0              + 4, EA_SYMLINK,EAT_ASCII, 0,                ""
    8080#undef OFF
    8181};
     
    112112
    113113    /*
     114     * Do we have UnixEAs on this path?
     115     */
     116    if (__predict_false(!__libc_back_fsInfoSupportUnixEAs(pszNativePath)))
     117        LIBCLOG_ERROR_RETURN(-ENOTSUP, "ret -ENOTSUP - no Unix EAs on '%s'\n", pszNativePath);
     118
     119    /*
    114120     * Allocate FEA buffer.
    115121     */
     
    126132    *pFEas = __libc_gFsUnixAttribsCreateSymlinkFEA2List;
    127133    __libc_back_fsUnixAttribsInit(&pFEas->Core, pszNativePath, S_IFLNK | S_IRWXO | S_IRWXG | S_IRWXU);
    128     pFEas->Core.cbList = cchTarget + sizeof(USHORT) * 2;
    129     pFEas->cbSymlinkData = cchTarget;
     134    pFEas->Core.cbList = cchTarget + sizeof(__libc_gFsUnixAttribsCreateSymlinkFEA2List) - 1;
     135    pFEas->cbSymlinkValue += cchTarget;
     136    pFEas->cbSymlinkData  = cchTarget;
    130137    memcpy(pFEas->szSymlink, pszTarget, cchTarget);
    131138
     
    141148    if (__predict_true(rc == NO_ERROR))
    142149    {
    143         DosWrite(hf, &pFEas->szSymlink[0], cchTarget, &ul);
     150        DosWrite(hf, &pszTarget, cchTarget, &ul);
    144151        DosClose(hf);
    145152        LIBCLOG_RETURN_INT(0);
    146153    }
    147154
     155    struct stat s;
    148156    if (rc == ERROR_EAS_NOT_SUPPORTED)
    149157        rc = -EOPNOTSUPP;
     158    else if (   rc == ERROR_OPEN_FAILED
     159             && !__libc_back_fsNativeFileStat(pszNativePath, &s))
     160        rc = -EEXIST;
    150161    else
    151162        rc = -__libc_native2errno(rc);
  • trunk/libc/src/libc/sys/b_panic.c

    r2321 r2672  
    3030*   Header Files                                                               *
    3131*******************************************************************************/
     32#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_NOGROUP
    3233#define INCL_BASE
    3334#define INCL_ERRORS
    3435#define INCL_FSMACROS
     36#define INCL_DOSUNDOCUEMENTED
    3537#define _GNU_SOURCE
    3638#include <string.h>
    3739#include <InnotekLIBC/backend.h>
    3840#include <InnotekLIBC/sharedpm.h>
    39 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_NOGROUP
    4041#include <InnotekLIBC/logstrict.h>
    4142#include <os2emx.h>
     
    185186    BOOL fQuiet = FALSE;
    186187    BOOL fVerbose = TRUE;
    187     BOOL fBreakpoint = FALSE;
     188    BOOL fBreakpoint = DosSysCtl(DOSSYSCTL_AM_I_DEBUGGED, NULL) == TRUE;
    188189    BOOL fDumpProcess = TRUE;
    189190    const char *pszPanicCfg = NULL;
     
    204205            else if (panicStrICmp(&pszPanicCfg, "breakpoint", "BREAKPOINT"))
    205206                fBreakpoint = TRUE;
     207            else if (panicStrICmp(&pszPanicCfg, "nobreakpoint", "NOBREAKPOINT"))
     208                fBreakpoint = FALSE;
    206209            //else if (panicStrICmp(&pszPanicCfg, "dump", "DUMP"))
    207210            //    fDumpProcess = TRUE;
     
    415418        {
    416419            if (!rc)
    417                 PRINT_C("Process have been dumped\r\n");
     420                PRINT_C("Process has been dumped\r\n");
    418421            else if (rc == 0x00011176 || rc == ERROR_INVALID_PARAMETER) /* first is actual, 2nd is docs */
    419                 PRINT_C("Process dumping was disabled, use DUMPPROC to enable it.\r\n");
     422                PRINT_C("Process dumping was disabled, use DUMPPROC / PROCDUMP to enable it.\r\n");
    420423            else
    421424            {
  • trunk/libc/src/libc/sys/filehandles.c

    r2324 r2672  
    186186            {
    187187                case __LIBC_SPM_INH_FHB_TYPE_STANDARD:
    188                     for (i = 0; i < c; i++)
     188                    for (i = 0; i < c; i++, iFH++)
    189189                    {
    190190                        __LIBC_PFH pFH;
     
    205205
    206206                case __LIBC_SPM_INH_FHB_TYPE_DIRECTORY:
    207                     for (i = 0; i < c; i++)
     207                    for (i = 0; i < c; i++, iFH++)
    208208                    {
    209209                        const char *pszPath = u.pDirs->aHandles[i].offNativePath ? pInherit->pszStrings + u.pDirs->aHandles[i].offNativePath : NULL;
     
    222222
    223223                case __LIBC_SPM_INH_FHB_TYPE_SOCKET_44:
    224                     for (i = 0; i < c; i++)
     224                    for (i = 0; i < c; i++, iFH++)
    225225                    {
    226226                        int rc = TCPNAMEG44(AllocFHEx)(iFH, u.pSockets->aHandles[i].usSocket, u.pSockets->aHandles[i].fFlags, 0, NULL, NULL);
     
    237237
    238238                case __LIBC_SPM_INH_FHB_TYPE_SOCKET_43:
    239                     for (i = 0; i < c; i++)
     239                    for (i = 0; i < c; i++, iFH++)
    240240                    {
    241241                        int rc = TCPNAMEG43(AllocFHEx)(iFH, u.pSockets->aHandles[i].usSocket, u.pSockets->aHandles[i].fFlags, 0, NULL, NULL);
  • trunk/libc/src/libc/sys/fs.c

    r2328 r2672  
    141141
    142142/**
     143 * The prefilled GEA2LIST construct for querying all the mode attribute.
     144 */
     145#pragma pack(1)
     146static const struct
     147{
     148    ULONG   cbList;
     149    ULONG   oNextEntryOffset;
     150    BYTE    cbName;
     151    CHAR    szName[sizeof(EA_MODE)];
     152} gGEA2ListMode =
     153{
     154    sizeof(gGEA2ListMode),
     155    0,
     156    sizeof(EA_MODE) - 1,
     157    EA_MODE
     158};
     159#pragma pack()
     160
     161/**
    143162 * The prefilled FEA2LIST construct for setting all attributes during a creation operation.
    144163 */
     
    231250     */
    232251    __LIBC_PSPMINHERIT  pInherit = __libc_spmInheritRequest();
     252
     253    /* part 2, the umask. */
     254    __LIBC_PSPMINHFS2   pFS2;
     255    if (    pInherit
     256        &&  pInherit->cb > offsetof(__LIBC_SPMINHERIT, pFS2)
     257        &&  (pFS2 = pInherit->pFS2) != NULL
     258        &&  !(pFS2->fUMask & ~0777))
     259    {
     260        LIBCLOG_MSG("Inherited fUMask=%04o\n", pFS2->fUMask);
     261        __libc_gfsUMask = pFS2->fUMask & 0777;
     262    }
     263
     264    /* part 1, the unixroot. */
    233265    __LIBC_PSPMINHFS    pFS;
    234266    if (    pInherit
     
    320352 * @returns 0 on success.
    321353 * @returns -1 on failure.
    322  * @param   ppFS    Where to store the pointer to the inherit data.
    323  * @param   pcbFS   Where to store the size of the inherit data.
    324  */
    325 int __libc_back_fsInheritPack(__LIBC_PSPMINHFS *ppFS, size_t *pcbFS)
    326 {
    327     LIBCLOG_ENTER("ppFS=%p pcbFS=%p\n", (void *)ppFS, (void *)pcbFS);
     354 * @param   ppFS    Where to store the pointer to the inherit data, part 1.
     355 * @param   pcbFS   Where to store the size of the inherit data, part 1.
     356 * @param   ppFS2   Where to store the pointer to the inherit data, part 2.
     357 * @param   pcbFS2  Where to store the size of the inherit data, part 2.
     358 */
     359int __libc_back_fsInheritPack(__LIBC_PSPMINHFS *ppFS, size_t *pcbFS, __LIBC_PSPMINHFS2 *ppFS2, size_t *pcbFS2)
     360{
     361    LIBCLOG_ENTER("ppFS=%p pcbFS=%p ppFS2=%p pcbFS2=%p\n", (void *)ppFS, (void *)pcbFS, (void *)ppFS2, (void *)pcbFS2);
    328362
    329363    *ppFS = NULL;
    330364    *pcbFS = 0;
     365    *ppFS2 = NULL;
     366    *pcbFS2 = 0;
    331367
    332368    if (__libc_back_fsMutexRequest())
     
    347383            *pcbFS = cb;
    348384            *ppFS = pFS;
     385        }
     386        else
     387            rc = -1;
     388    }
     389
     390    if (!rc)
     391    {
     392        __LIBC_PSPMINHFS2 pFS2 = (__LIBC_PSPMINHFS2)malloc(sizeof(*pFS2));
     393        if (pFS2)
     394        {
     395            pFS2->cb = sizeof(*pFS2);
     396            pFS2->fUMask = __libc_gfsUMask;
     397            LIBCLOG_MSG("fUMask=%04o\n", pFS2->fUMask);
     398
     399            *pcbFS2 = sizeof(*pFS2);
     400            *ppFS2 = pFS2;
    349401        }
    350402        else
     
    446498    LIBCLOG_ERROR_RETURN_INT(rc);
    447499}
     500
     501
     502/**
     503 * Checks if the specified path is a symlink or not.
     504 * @returns true / false.
     505 * @param   pszNativePath       Path to the potential symlink.
     506 */
     507static int fsIsSymlink(const char *pszNativePath)
     508{
     509    char sz[16];
     510    return __libc_back_fsNativeSymlinkRead(pszNativePath, sz, sizeof(sz)) >= 0;
     511}
     512
    448513
    449514#if 0 //just testing, not useful.
     
    570635    /*
    571636     * Remove trailing slash if the path may be pointing to a directory.
     637     * A symlink search is converted to a directory search if this is encountered.
    572638     */
    573639    int cch = pszTrg - pszPath;
    574     if (    (fFlags & BACKFS_FLAGS_RESOLVE_DIR)
     640    if (    (fFlags & (BACKFS_FLAGS_RESOLVE_DIR | BACKFS_FLAGS_RESOLVE_FULL_SYMLINK))
    575641        &&  cch > 1
    576642        &&  pszTrg[-1] == '/'
     
    580646        pszPath[--cch] = '\0';
    581647        if (pfFlags)
    582             *pfFlags &= ~BACKFS_FLAGS_RESOLVE_DIR_MAYBE_;
     648        {
     649            *pfFlags &= ~(BACKFS_FLAGS_RESOLVE_DIR_MAYBE_ | BACKFS_FLAGS_RESOLVE_FULL_SYMLINK);
     650            if (fFlags & BACKFS_FLAGS_RESOLVE_FULL_SYMLINK)
     651                *pfFlags |= BACKFS_FLAGS_RESOLVE_DIR | BACKFS_FLAGS_RESOLVE_FULL;
     652        }
    583653    }
    584654
     
    637707    LIBCLOG_ENTER("pszUserPath=%p:{%s} pszNativePath=%p *pfInUnixTree=%p\n",
    638708                  (void *)pszUserPath, pszUserPath, (void *)pszNativePath, (void *)pfInUnixTree);
    639     const char *pszUserPathIn = pszUserPath;
    640     char        _achBuffer[SIZEOF_ACHBUFFER + 4];
    641     char       *pachBuffer = (char *)((uintptr_t)&_achBuffer[3] & ~3);
    642     unsigned    cLoopsLeft = 8;
    643     int         fInUnixTree = __libc_gfInUnixTree;
    644     int         rcRet = 0;
    645     HDIR        hDir = HDIR_CREATE;
     709    const char     *pszUserPathIn = pszUserPath;
     710    char            _achBuffer[SIZEOF_ACHBUFFER + 4];
     711    char           *pachBuffer = (char *)((uintptr_t)&_achBuffer[3] & ~3);
     712    unsigned        cLoopsLeft = 8;
     713    int             fInUnixTree = __libc_gfInUnixTree;
     714    int             rcRet = 0;
     715    HDIR            hDir = HDIR_CREATE;
     716    __LIBC_PFSINFO  pFsInfo = NULL;
     717    int             fUnixEAs;
    646718    FS_VAR()
    647719    FS_SAVE_LOAD();
     
    889961            iRoot = psz - pszNativePath;
    890962            psz = strchr(psz, '/');
     963
     964            /* We don't do UNIX EAs on UNCs */
     965            fUnixEAs = 0;
    891966        }
    892967        else
     
    898973            pszPrev = &pszNativePath[iRoot + 1];
    899974            psz = strchr(pszPrev, '/');
     975
     976            /* Unix EAs? */
     977            pFsInfo = __libc_back_fsInfoObjByPathCached(pszNativePath, pFsInfo);
     978            LIBC_ASSERTM(pFsInfo, "%s\n", pszNativePath);
     979            fUnixEAs = pFsInfo ? pFsInfo->fUnixEAs : 0;
    900980        }
    901981        LIBC_ASSERTM(pszPrev - pszNativePath >= iRoot, "iRoot=%d  pszPrev offset %d  pszNativePath=%s\n", iRoot, pszPrev - pszNativePath, pszNativePath);
     
    9731053             * This'll of course also provide proper verification of the path too. :-)
    9741054             *
    975              * (This is a little bit messed up since we'll have to use wildcard for
    976              * getting the caseing resolved.)
     1055             * This is a little bit messed up since we'll have to use wildcard for
     1056             * getting the casing resolved.
     1057             *
     1058             * The two find buffers are assumed to be equal down thru attrFile.
    9771059             */
    9781060            //LIBC_ASSERT(psz - pszNativePath == cchNativePath); - figure this one.
    979             PFILEFINDBUF4 pFindBuf = (PFILEFINDBUF4)pachBuffer;
     1061            PFILEFINDBUF4 pFindBuf4 = (PFILEFINDBUF4)pachBuffer;
     1062            PFILEFINDBUF3 pFindBuf3 = (PFILEFINDBUF3)pachBuffer;
    9801063            ULONG cFiles = 1;
    9811064            char chNext = psz[1];
     
    9831066            psz[1] = '\0';
    9841067            int rc = DosFindFirst((PCSZ)pszNativePath, &hDir, FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED,
    985                                   pFindBuf, SIZEOF_ACHBUFFER, &cFiles, FIL_QUERYEASIZE);
     1068                                  pachBuffer, SIZEOF_ACHBUFFER, &cFiles, fUnixEAs ? FIL_QUERYEASIZE : FIL_STANDARD);
    9861069            psz[0] = '\0';
    9871070            psz[1] = chNext;
    9881071            if (rc || cFiles == 0)
    989             {
    9901072                hDir = HDIR_CREATE;
    991             }
    992             while (!rc && cFiles == 1 && pFindBuf->cchName != psz - pszPrev)
    993                 rc = DosFindNext(hDir, pFindBuf, SIZEOF_ACHBUFFER, &cFiles);
     1073            while (!rc && cFiles == 1 && (fUnixEAs ? pFindBuf4->cchName : pFindBuf3->cchName) != psz - pszPrev)
     1074                rc = DosFindNext(hDir, pachBuffer, SIZEOF_ACHBUFFER, &cFiles);
    9941075            if (rc || cFiles == 0)
    9951076            {
     
    10041085                break;
    10051086            }
    1006             memcpy(pszPrev, pFindBuf->achName, psz - pszPrev);
    1007             int     fIsDirectory = (pFindBuf->attrFile & FILE_DIRECTORY) != 0;
     1087            memcpy(pszPrev, fUnixEAs ? pFindBuf4->achName : pFindBuf3->achName, psz - pszPrev);
     1088            int     fIsDirectory = (pFindBuf4->attrFile & FILE_DIRECTORY) != 0;
    10081089
    10091090            /*
    1010              * Try querying the symlink EA value
    1011              * (This operation will reuse the achBuffer overwriting the pFindBuf data!)
     1091             * Try querying the symlink EA value.
     1092             * (This operation will reuse the achBuffer overwriting the pFindBuf[3/4] data!)
    10121093             *
    10131094             * Yeah, we could do this in the same operation as the DosFindFirst() but
     
    10151096             * returning the right things at some point, and besides it's return data
    10161097             * is rather clumsily laid out. So, I decided not to try my luck on it.
     1098             *
     1099             * On second thought, we seems to end up having to use DosFindFirst in some
     1100             * cases anyway... very nice.
    10171101             */
    1018             if (    pFindBuf->cbList > sizeof(USHORT) * 2 + 1
     1102            if (    fUnixEAs
     1103                &&   pFindBuf4->cbList > sizeof(USHORT) * 2 + 1
    10191104                &&  (   (fFlags & BACKFS_FLAGS_RESOLVE_FULL)
    1020                      || chSlash))
    1021             {
    1022                 EAOP2   EaOp;
    1023                 EaOp.fpGEA2List = (PGEA2LIST)&gGEA2ListSymlink;
    1024                 EaOp.fpFEA2List = (PFEA2LIST)pachBuffer;
    1025                 EaOp.oError     = 0;
    1026                 EaOp.fpFEA2List->cbList = SIZEOF_ACHBUFFER;
    1027                 rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASFROMLIST, &EaOp, sizeof(EaOp));
     1105                     || chSlash)
     1106                &&  !fIsDirectory)
     1107            {
     1108                PEAOP2  pEaOp2 = (PEAOP2)pachBuffer;
     1109                pEaOp2->fpGEA2List = (PGEA2LIST)&gGEA2ListSymlink;
     1110                pEaOp2->fpFEA2List = (PFEA2LIST)(pEaOp2 + 1);
     1111                pEaOp2->oError     = 0;
     1112                pEaOp2->fpFEA2List->cbList = SIZEOF_ACHBUFFER - sizeof(*pEaOp2);
     1113                rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASFROMLIST, pEaOp2, sizeof(*pEaOp2));
    10281114                if (rc)
    10291115                {
    1030                     LIBCLOG_MSG("DosQueryPathInfo('%s',,,) -> %d resolving '%s'\n", pszNativePath, rc, pszUserPathIn);
    1031                     if ((fFlags & BACKFS_FLAGS_RESOLVE_FULL_MAYBE_) && !chSlash)
    1032                         rcRet = 0;
    1033                     else
    1034                         rcRet = rc == ERROR_FILE_NOT_FOUND && chSlash ? -ENOENT : -__libc_native2errno(rc);
    1035                     break;
     1116                    cFiles = 1;
     1117                    pEaOp2->fpGEA2List = (PGEA2LIST)&gGEA2ListSymlink;
     1118                    pEaOp2->fpFEA2List = (PFEA2LIST)(pEaOp2 + 1);
     1119                    pEaOp2->oError     = 0;
     1120                    pEaOp2->fpFEA2List->cbList = SIZEOF_ACHBUFFER - sizeof(*pEaOp2);
     1121                    rc = DosFindFirst((PCSZ)pszNativePath, &hDir, 0, pEaOp2, pEaOp2->fpFEA2List->cbList + sizeof(*pEaOp2), &cFiles, FIL_QUERYEASFROMLIST);
     1122                    if (rc || cFiles == 0)
     1123                    {
     1124                        hDir = HDIR_CREATE;
     1125                        LIBCLOG_MSG("DosFindFirst('%s',,,pEaOp2,) -> %d resolving '%s'\n", pszNativePath, rc, pszUserPathIn);
     1126                        if ((fFlags & BACKFS_FLAGS_RESOLVE_FULL_MAYBE_) && !chSlash)
     1127                            rcRet = 0;
     1128                        else
     1129                            rcRet = rc == ERROR_FILE_NOT_FOUND && chSlash ? -ENOENT : -__libc_native2errno(rc);
     1130                        break;
     1131                    }
     1132                    pEaOp2->fpFEA2List = (PFEA2LIST)((char *)pEaOp2 + sizeof(EAOP2) + offsetof(FILEFINDBUF3, cchName));
    10361133                }
    10371134
     
    10391136                 * Did we find any symlink EA?
    10401137                 */
    1041                 if (    EaOp.fpFEA2List->cbList > sizeof(EaOp.fpFEA2List->list[0])
    1042                     &&  EaOp.fpFEA2List->list[0].cbValue)
     1138                if (    pEaOp2->fpFEA2List->cbList > sizeof(pEaOp2->fpFEA2List->list[0])
     1139                    &&  pEaOp2->fpFEA2List->list[0].cbValue)
    10431140                {
    10441141                    /* Validate the EA. */
    1045                     PUSHORT pusType = (PUSHORT)((char *)&EaOp.fpFEA2List->list[1] + EaOp.fpFEA2List->list[0].cbName);
     1142                    PUSHORT pusType = (PUSHORT)((char *)&pEaOp2->fpFEA2List->list[1] + pEaOp2->fpFEA2List->list[0].cbName);
    10461143                    char   *pszSymlink = (char *)&pusType[2];
    10471144                    if (    pusType[0] != EAT_ASCII
    1048                         ||  pusType[1] > EaOp.fpFEA2List->list[0].cbValue
     1145                        ||  pusType[1] > pEaOp2->fpFEA2List->list[0].cbValue
    10491146                        ||  !pusType[1]
    10501147                        ||  !*pszSymlink)
    10511148                    {
    10521149                        LIBCLOG_ERROR("Invalid symlink EA! type=%x len=%d cbValue=%d *pszSymlink=%c\n",
    1053                                       pusType[0], pusType[1], EaOp.fpFEA2List->list[0].cbValue, *pszSymlink);
     1150                                      pusType[0], pusType[1], pEaOp2->fpFEA2List->list[0].cbValue, *pszSymlink);
    10541151                        rcRet = -EFTYPE;
    10551152                        break;
     
    11501247                rcRet = 0;
    11511248                if (    (fFlags & (BACKFS_FLAGS_RESOLVE_DIR | BACKFS_FLAGS_RESOLVE_DIR_MAYBE_)) == BACKFS_FLAGS_RESOLVE_DIR
    1152                     &&  !fIsDirectory)
     1249                    &&  !fIsDirectory
     1250                    &&  (     !fUnixEAs
     1251                         ||    pFindBuf4->cbList <= sizeof(USHORT) * 2 + 1
     1252                         ||   !fsIsSymlink(pszNativePath)))
    11531253                    rcRet = -ENOTDIR;
    11541254                break;
     
    11751275
    11761276    /*
    1177      * Cleanup find handle.
     1277     * Cleanup find handle and fs object.
    11781278     */
    11791279    if (hDir != HDIR_CREATE)
    11801280        DosFindClose(hDir);
     1281    if (pFsInfo)
     1282        __libc_back_fsInfoObjRelease(pFsInfo);
    11811283    FS_RESTORE();
    11821284
     
    14031505                            pStat->st_gid  = u32;
    14041506                        else if (COMPARE_EANAME(__libc_gszModeEA))
    1405                             pStat->st_mode = u32;
     1507                        {
     1508                            if (    S_ISDIR(u32)  || S_ISCHR(u32) || S_ISBLK(u32)  || S_ISREG(u32)
     1509                                ||  S_ISFIFO(u32) || S_ISLNK(u32) || S_ISSOCK(u32) || S_ISWHT(u32))
     1510                                pStat->st_mode = u32;
     1511                            else
     1512                                LIBC_ASSERTM_FAILED("Invalid file mode EA: u32=0%o (st_mode=0%o)\n", u32, pStat->st_mode);
     1513                        }
    14061514                        else if (COMPARE_EANAME(__libc_gszRDevEA))
    14071515                            pStat->st_rdev = u32;
     
    14371545    }
    14381546
     1547    /*
     1548     * Calc st_ino and st_dev if not found.
     1549     */
     1550    if ((!pStat->st_ino || !pStat->st_dev) && pszNativePath)
     1551    {
     1552        ino_t Inode;
     1553        dev_t Dev = __libc_back_fsPathCalcInodeAndDev(pszNativePath, &Inode);
     1554        if (!pStat->st_ino)
     1555            pStat->st_ino = Inode;
     1556        if (!pStat->st_dev)
     1557            pStat->st_dev = Dev;
     1558    }
     1559
    14391560    LIBCLOG_RETURN_INT(0);
     1561}
     1562
     1563
     1564/**
     1565 * Reads the unix file mode EA.
     1566 *
     1567 * @returns 0 on success.
     1568 * @returns -ENOTSUP if the file mode EA is not present or if Unix EAs isn't supported on the volume.
     1569 * @returns Negative errno on failure.
     1570 * @param   hFile           File handle to the fs object. If no handle handy, set to -1.
     1571 * @param   pszNativePath   Native path to the fs object. If handle is give this will be ignored.
     1572 * @param   pMode           Where to store the mode mask.
     1573 */
     1574int __libc_back_fsUnixAttribsGetMode(int hFile, const char *pszNativePath, mode_t *pMode)
     1575{
     1576     LIBCLOG_ENTER("hFile=%d pszNativePath=%p:{%s} pMode=%p\n", hFile, (void *)pszNativePath, pszNativePath, (void *)pMode);
     1577
     1578     /* Try come up with an accurate max estimate of a maximum result. */
     1579     char    achBuffer[sizeof(EAOP2) + sizeof(FILEFINDBUF3) + sizeof(gGEA2ListMode) + 1 * (sizeof(USHORT) * 2 + sizeof(BYTE)) + 1 * sizeof(uint32_t) + 0x30];
     1580     char   *pachBuffer = (char *)((uintptr_t)&achBuffer[3] & ~3);
     1581     PEAOP2  pEaOp2 = (PEAOP2)pachBuffer;
     1582     int     rc = -1000;
     1583
     1584     *pMode = 0;
     1585
     1586/** @todo the following query is generic! It's repeated 3 times already in this file (only the gea list and buffer size varies). */
     1587     /*
     1588      * Issue the query.
     1589      */
     1590     if (hFile >= 0)
     1591     {
     1592         pEaOp2->fpGEA2List = (PGEA2LIST)&gGEA2ListMode;
     1593         pEaOp2->fpFEA2List = (PFEA2LIST)(pEaOp2 + 1);
     1594         pEaOp2->oError     = 0;
     1595         pEaOp2->fpFEA2List->cbList = sizeof(achBuffer) - 4 - sizeof(EAOP2);
     1596         rc = DosQueryFileInfo(hFile, FIL_QUERYEASFROMLIST, pEaOp2, sizeof(EAOP2));
     1597     }
     1598     if (rc && pszNativePath)
     1599     {
     1600         pEaOp2->fpGEA2List = (PGEA2LIST)&gGEA2ListMode;
     1601         pEaOp2->fpFEA2List = (PFEA2LIST)(pEaOp2 + 1);
     1602         pEaOp2->oError     = 0;
     1603         pEaOp2->fpFEA2List->cbList = sizeof(achBuffer) - 4 - sizeof(EAOP2);
     1604         rc = DosQueryPathInfo((PCSZ)pszNativePath, FIL_QUERYEASFROMLIST, pEaOp2, sizeof(EAOP2));
     1605         if (rc == ERROR_SHARING_VIOLATION || rc == ERROR_ACCESS_DENIED || rc == ERROR_INVALID_ACCESS)
     1606         {
     1607             HDIR hDir = HDIR_CREATE;
     1608             ULONG cFiles = 1;
     1609             pEaOp2->fpGEA2List = (PGEA2LIST)&gGEA2ListMode;
     1610             pEaOp2->fpFEA2List = (PFEA2LIST)(pEaOp2 + 1);
     1611             pEaOp2->oError     = 0;
     1612             pEaOp2->fpFEA2List->cbList = sizeof(achBuffer) - 4 - sizeof(EAOP2);
     1613             rc = DosFindFirst((PCSZ)pszNativePath, &hDir, 0, pEaOp2, pEaOp2->fpFEA2List->cbList + sizeof(*pEaOp2), &cFiles, FIL_QUERYEASFROMLIST);
     1614             if (!rc)
     1615             {
     1616                 DosFindClose(hDir);
     1617                 pEaOp2->fpFEA2List = (PFEA2LIST)((char *)pEaOp2 + sizeof(EAOP2) + offsetof(FILEFINDBUF3, cchName));
     1618             }
     1619         }
     1620     }
     1621     if (rc)
     1622     {
     1623         LIBC_ASSERTM(rc == ERROR_ACCESS_DENIED || rc == ERROR_SHARING_VIOLATION || rc == ERROR_EAS_NOT_SUPPORTED,
     1624                      "Bogus EAs? rc=%d oError=%ld\n", rc, pEaOp2->oError);
     1625         rc = -__libc_native2errno(rc);
     1626         LIBCLOG_ERROR_RETURN_INT(rc);
     1627     }
     1628
     1629     /*
     1630      * Parse the result.
     1631      * There is only one EA here, so this is gonna be pretty simple...
     1632      */
     1633     rc = -ENOTSUP;
     1634     PFEA2   pFea2 = &pEaOp2->fpFEA2List->list[0];
     1635     if (   pEaOp2->fpFEA2List->cbList > sizeof(*pFea2)
     1636         && pFea2->cbValue > 0
     1637         && pFea2->cbName == sizeof(EA_MODE) - 1
     1638         && !memcmp(EA_MODE, pFea2->szName, sizeof(EA_MODE) - 1)
     1639        )
     1640     {
     1641         PUSHORT pusType = (PUSHORT)&pFea2->szName[pFea2->cbName + 1];
     1642         if (   pusType[0] == EAT_BINARY
     1643             && pusType[1] == sizeof(uint32_t)
     1644             )
     1645         {
     1646             uint32_t u32 = *(uint32_t *)(pusType + 2);
     1647             if (    S_ISDIR(u32)  || S_ISCHR(u32) || S_ISBLK(u32)  || S_ISREG(u32)
     1648                 ||  S_ISFIFO(u32) || S_ISLNK(u32) || S_ISSOCK(u32) || S_ISWHT(u32))
     1649             {
     1650                 *pMode = u32;
     1651                 rc = 0;
     1652             }
     1653             else
     1654                 LIBC_ASSERTM_FAILED("Invalid file mode EA: u32=0%o\n", u32);
     1655         }
     1656         else
     1657             LIBC_ASSERTM_FAILED("Invalid LIBC EA! '%s' type=%#x len=%#x, expected type=%#x and len=4.\n",
     1658                                 pFea2->szName, pusType[0], pusType[1], EAT_BINARY);
     1659     }
     1660
     1661     LIBCLOG_RETURN_MSG(rc, "ret %d *pMode=#%x\n", rc, *pMode);
    14401662}
    14411663
     
    14891711    /* init the structure */
    14901712    pFsInfo->fZeroNewBytes = 0;
     1713    pFsInfo->fUnixEAs = 0;
    14911714    pFsInfo->Dev = Dev;
    14921715    pFsInfo->szName[0] = '\0';
     
    15041727    if (    !strcmp(pFsInfo->szName, "JFS")
    15051728        ||  !strcmp(pFsInfo->szName, "HPFS")
    1506         ||  !strcmp(pFsInfo->szName, "FAT")
    1507         ||  !strcmp(pFsInfo->szName, "LAN"))
    1508         pFsInfo->fZeroNewBytes = 1;   /* RAMFS does not do this. */
    1509     LIBCLOG_MSG2("fsInfoObjUpdate: dev:%#x mp:%s fsd:%s fZeroNewBytes=%d\n",
    1510                  pFsInfo->Dev, pFsInfo->szMountpoint, pFsInfo->szName, pFsInfo->fZeroNewBytes);
     1729        ||  !strcmp(pFsInfo->szName, "FAT"))
     1730    {
     1731        pFsInfo->fZeroNewBytes  = 1;
     1732        pFsInfo->fUnixEAs       = 1;
     1733    }
     1734    else if (!strcmp(pFsInfo->szName, "LAN"))
     1735    {
     1736        /* should find a way of getting the remote fs... */
     1737        pFsInfo->fZeroNewBytes  = 1;    /* for performance reasons, assume it zeros. */
     1738        pFsInfo->fUnixEAs       = 0;
     1739    }
     1740    else if (!strcmp(pFsInfo->szName, "RAMFS"))
     1741    {
     1742        pFsInfo->fZeroNewBytes  = 0;
     1743        pFsInfo->fUnixEAs       = 1; /* but it doesn't zero */
     1744    }
     1745    /*else if (!strcmp(pFsInfo->szName, "FAT32"))
     1746    {
     1747        pFsInfo->fZeroNewBytes  = 0;
     1748        pFsInfo->fUnixEAs       = 0;
     1749    }*/
     1750    else
     1751    {
     1752        pFsInfo->fZeroNewBytes  = 0;
     1753        pFsInfo->fUnixEAs       = 0;
     1754    }
     1755
     1756    LIBCLOG_MSG2("fsInfoObjUpdate: dev:%#x mp:%s fsd:%s fZeroNewBytes=%d fUnixEAs=%d\n",
     1757                 pFsInfo->Dev, pFsInfo->szMountpoint, pFsInfo->szName, pFsInfo->fZeroNewBytes,
     1758                 pFsInfo->fUnixEAs);
    15111759    FS_RESTORE();
    15121760}
     
    15461794
    15471795
    1548 #if 0
    15491796/**
    15501797 * Gets the fs info object for the specfied path.
     
    15691816    return __libc_back_fsInfoObjByDev(Dev);
    15701817}
    1571 #endif
     1818
     1819
     1820/**
     1821 * Gets the fs info object for the specfied path, with cache.
     1822 *
     1823 * @returns Pointer to info object for the path, if it got one.
     1824 * @param   pszNativePath   The native path as returned by the resolver.
     1825 * @param   pCached         An cached fs info object reference. Can be NULL.
     1826 */
     1827__LIBC_PFSINFO __libc_back_fsInfoObjByPathCached(const char *pszNativePath, __LIBC_PFSINFO pCached)
     1828{
     1829    /*
     1830     * Calc device.
     1831     */
     1832    dev_t   Dev;
     1833    char    chDrv = *pszNativePath;
     1834    if (chDrv == '/' || chDrv == '\\')
     1835        Dev = makedev('U', 0);          /* U as in UNC */
     1836    else
     1837    {
     1838        LIBC_ASSERT(chDrv >= 'A' && chDrv <= 'Z');
     1839        Dev = makedev('V', chDrv);      /* V as in Volume */
     1840    }
     1841    if (!pCached)
     1842        return __libc_back_fsInfoObjByDev(Dev);
     1843    if (pCached->Dev == Dev)
     1844        return pCached;
     1845    __libc_back_fsInfoObjRelease(pCached);
     1846    return __libc_back_fsInfoObjByDev(Dev);
     1847}
    15721848
    15731849
     
    16021878    {
    16031879        int cRefs = __atomic_decrement_s32(&pFsInfo->cRefs);
    1604         LIBC_ASSERT(cRefs > 1); (void)cRefs;
    1605     }
     1880        LIBC_ASSERT(cRefs >= 0); (void)cRefs;
     1881    }
     1882}
     1883
     1884
     1885/**
     1886 * Checks if the path supports Unix EAs or not.
     1887 *
     1888 * @returns true / false.
     1889 * @param   pszNativePath       The native path to check.
     1890 */
     1891int __libc_back_fsInfoSupportUnixEAs(const char *pszNativePath)
     1892{
     1893    if (__libc_gfNoUnix)
     1894        return 0;
     1895
     1896    __LIBC_PFSINFO pFsInfo = __libc_back_fsInfoObjByPath(pszNativePath);
     1897    const int fUnixEAs = pFsInfo && pFsInfo->fUnixEAs;
     1898    __libc_back_fsInfoObjRelease(pFsInfo);
     1899    return fUnixEAs;
    16061900}
    16071901
  • trunk/libc/src/libc/sys/logstrict.c

    r2260 r2672  
    218218    /*
    219219     * Open the file.
     220     * Make sure the filehandle is above the frequently used range (esp. std handles).
    220221     */
    221222    rc = DosOpen((PCSZ)pszFilename, &pInst->hFile, &ulAction, 0, FILE_NORMAL,
     
    228229        FS_RESTORE();
    229230        return NULL;
     231    }
     232    if (pInst->hFile < 10)
     233    {
     234        int     i;
     235        HFILE   ah[10];
     236        for (i = 0; i < 10; i++)
     237        {
     238            ah[i] = -1;
     239            rc = DosDupHandle(pInst->hFile, &ah[i]);
     240            if (rc)
     241                break;
     242        }
     243        if (i-- > 0)
     244        {
     245            DosClose(pInst->hFile);
     246            pInst->hFile = ah[i];
     247            while (i-- > 0)
     248                DosClose(ah[i]);
     249        }
    230250    }
    231251
     
    18481868                /* argsize */
    18491869                chArgSize = *pszFormat;
    1850                 if (chArgSize != 'l' && chArgSize != 'L' && chArgSize != 'H')
     1870                if (    chArgSize != 'l' && chArgSize != 'L' && chArgSize != 'h'  && chArgSize != 'H'
     1871                    &&  chArgSize != 'j' && chArgSize != 'z' && chArgSize != 't')
    18511872                    chArgSize = 0;
    1852                 else if (*++pszFormat == 'l' && chArgSize == 'l')
     1873                else
    18531874                {
    1854                     chArgSize = 'L';
    18551875                    pszFormat++;
     1876                    if (*pszFormat == 'l' && chArgSize == 'l')
     1877                    {
     1878                        chArgSize = 'L';
     1879                        pszFormat++;
     1880                    }
     1881                    else if (*pszFormat == 'h' && chArgSize == 'h')
     1882                    {
     1883                        chArgSize = 'H';
     1884                        pszFormat++;
     1885                    }
    18561886                }
    18571887
     
    19882018                            else if (chArgSize == 'h')
    19892019                                ulValue = va_arg(args, signed /*short*/ int); /* the great GCC pedantically saith use int. */
     2020                            else if (chArgSize == 'H')
     2021                                ulValue = va_arg(args, /* int8_t */ int); /* the great GCC pedantically saith use int. */
     2022                            else if (chArgSize == 'j')
     2023                                ulValue = va_arg(args, intmax_t);
     2024                            else if (chArgSize == 'z')
     2025                                ulValue = va_arg(args, size_t);
     2026                            else if (chArgSize == 't')
     2027                                ulValue = va_arg(args, ptrdiff_t);
    19902028                            else
    19912029                                ulValue = va_arg(args, signed int);
  • trunk/libc/src/libc/sys/signals.c

    r2427 r2672  
    29672967        if (*pfDone)
    29682968        {
    2969             rc = -EINTR;
     2969            rc = __libc_back_signalSemRequest();
     2970            if (!rc)
     2971                rc = -EINTR;
    29702972            break;
    29712973        }
     
    29752977         * We returned from the wait, but did we do so for the right reason?
    29762978         */
    2977         if (__libc_back_signalSemRequest())
    2978             rc = -EDEADLK;
     2979        int rc2 = __libc_back_signalSemRequest();
     2980        if (rc2 < 0)
     2981            rc = rc2;
    29792982        else if (*pfDone)
    29802983            rc = -EINTR;
  • trunk/libc/src/libsocket/recvfrom.c

    r1517 r2672  
    3030#include "libc-alias.h"
    3131#include <errno.h>
     32#include <netinet/in.h>
    3233#include <sys/socket.h>
    3334#include <sys/fcntl.h>
     
    4748        rc = __libsocket_recvfrom(pFHSocket->iSocket, buf, len, flags, from, fromlen);
    4849        if (rc >= 0)
     50        {
     51            if (from && fromlen)
     52            {
     53#ifdef TCPV40HDRS
     54                if (*fromlen > sizeof(struct sockaddr_in) && from->sa_family == AF_INET)
     55                    *fromlen = sizeof(struct sockaddr_in);
     56#else
     57                if (*fromlen > from->sa_len)
     58                    *fromlen = from->sa_len;
     59#endif
     60            }
    4961            LIBCLOG_RETURN_INT(rc);
     62        }
    5063        __libc_TcpipUpdateErrno();
    5164    }
  • trunk/libc/src/libsocket/recvmsg.c

    r1454 r2672  
    3131#include <errno.h>
    3232#include <sys/socket.h>
     33#include <netinet/in.h>
    3334#include <sys/fcntl.h>
    3435#include <emx/io.h>
     
    4647        rc = __libsocket_recvmsg(pFHSocket->iSocket, msg, flags);
    4748        if (rc >= 0)
     49        {
     50            /* Workaround for missing msg_namelen update. Required if a IPV6 sized buffer is given.
     51             * (This problem hasn't been explored well enough, so this workaround is rather cautious.)
     52             */
     53            if (msg)
     54            {
     55                struct sockaddr_in *pAddr = (struct sockaddr_in *)msg->msg_name;
     56#ifndef TCPV40HDRS
     57                if (pAddr && msg->msg_namelen > pAddr->sin_len)
     58                    msg->msg_namelen = pAddr->sin_len;
     59#else
     60
     61                if (    pAddr
     62                    &&  pAddr->sin_family == AF_INET
     63                    &&  msg->msg_namelen > sizeof(struct sockaddr_in))
     64                    msg->msg_namelen = sizeof(struct sockaddr_in);
     65#endif
     66
     67            }
    4868            LIBCLOG_RETURN_INT(rc);
     69        }
    4970        __libc_TcpipUpdateErrno();
    5071    }
  • trunk/libc/tests/libc/Makefile

    r2508 r2672  
    3232ifeq ($(TARGET),innoteklibc)
    3333SKIPPED    :=
    34 EXPECTED   := smoketests/usleep-1.c \
    35         smoketests/fchmod-1.c
     34EXPECTED   := smoketests/usleep-1.c
    3635_TARGET_OK := ok
    3736endif
     
    8180        smoketests/strnlen-1.c \
    8281        smoketests/strtof-1.c \
     82        smoketests/symlink-1.c \
    8383        smoketests/sysctl-1.c \
    8484        smoketests/socket-1.c \
     
    9595        smoketests/fstat-1.c \
    9696        smoketests/fchmod-1.c \
    97         smoketests/nonblock-1.c
     97        smoketests/nonblock-1.c \
     98        smoketests/fclose-2.c \
     99        smoketests/basename-dirname-1.c \
     100        smoketests/fcloseall-1.c
    98101       
    99102#       smoketests/weak-export-1.c - dll
     
    121124        emxomf -m__text -o $(OUTDIR)/smoketests/asmstub-omf.obj $(OUTDIR)/smoketests/asmstub-omf.o
    122125        gcc -Zomf -lend -s -nostdlib -o $@ $(OUTDIR)/smoketests/asmstub-omf.obj
    123        
    124 
    125 BUGS := \
    126         bugs/19-limits.c
    127126       
    128127SUBTESTS := \
  • trunk/libc/tests/libc/smoketests/fchmod-1.c

    r2311 r2672  
    1313    if (!rc)
    1414    {
    15         if ((st.st_mode & 0777) != Mode)
     15        if ((st.st_mode & (0777 | S_IFMT)) != Mode)
    1616        {
    1717            printf("Invalid mode 0%o, expected 0%o\n", st.st_mode & 0777, Mode);
     
    3535    if (fh >= 0)
    3636    {
    37         check_mode(fh, 0766);
     37        check_mode(fh, 0766 | S_IFREG);
    3838        rc = fchmod(fh, 0744);
    3939        if (!rc)
    4040        {
    41             check_mode(fh, 0744);
     41            check_mode(fh, 0744 | S_IFREG);
    4242            rc = futimes(fh, NULL);
    43             check_mode(fh, 0744);
     43            check_mode(fh, 0744 | S_IFREG);
    4444        }
    4545        else
     
    6363    if (fh >= 0)
    6464    {
    65         check_mode(fh, 0744);
     65        check_mode(fh, 0744 | S_IFREG);
    6666        rc = chmod("fchmod-1.tst", 0700);
    6767        if (!rc)
    68             check_mode(fh, 0700);
     68            check_mode(fh, 0700 | S_IFREG);
    6969        else
    7070        {
    71             printf("fchmod-1: rdonly chmod: fh=%d rc=%d errno=%d (%m)\n", fh, rc, errno);
    72             cErrors++;
     71            printf("fchmod-1: rdonly chmod: fh=%d rc=%d errno=%d (%m) - expected failure, ignored\n", fh, rc, errno);
     72            /*cErrors++; - ignored */
    7373        }
    7474        rc = fchmod(fh, 0777);
    7575        if (!rc)
    76             check_mode(fh, 0777);
     76            check_mode(fh, 0777 | S_IFREG);
    7777        else
    78             cErrors++;
     78        {
     79            printf("fchmod-1: rdonly: fh=%d rc=%d errno=%d (%m) - expected failure, ignored\n", fh, rc, errno);
     80            /*cErrors++; - ignored */
     81        }
    7982    }
    8083    else
     84    {
     85        printf("fchmod-1: rdonly: open failed errno=%d (%m)\n", errno);
    8186        cErrors++;
    82     printf("fchmod-1: rdonly: fh=%d rc=%d errno=%d (%m)\n", fh, rc, errno);
     87    }
    8388    close(fh);
    8489
Note: See TracChangeset for help on using the changeset viewer.