Changeset 2739


Ignore:
Timestamp:
Jul 23, 2006, 7:23:46 AM (19 years ago)
Author:
bird
Message:

Started backend cleanup for portability. Work in progress.

Location:
trunk/libc
Files:
25 added
3 deleted
64 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/libc/Config.kmk

    r2723 r2739  
    5151        __IN_INNOTEK_LIBC__
    5252DEFS.os2   = __OS2__
    53 DEFS.win32 = __NT__
    54 DEFS.win64 = __NT__
     53DEFS.nt    = __NT__
    5554
    5655
     
    6362LIBC-STD.H = $(PATH_OBJ)/libc/libc-std.h
    6463LIBC_GENALIAS = $(PATH_TARGET)/genalias/genalias$(HOSTSUFF_EXE)
    65 LIBC_GENALIAS_FORMAT.win32 = coff
    66 LIBC_GENALIAS_FORMAT.win64 = coff
     64LIBC_GENALIAS_FORMAT.nt = coff
    6765ifdef LIBC_GENALIAS_FORMAT.$(BUILD_TARGET)
    6866LIBC_GENALIAS_FORMAT := $(LIBC_GENALIAS_FORMAT.$(BUILD_TARGET))
     
    7775TEMPLATE_libc_TOOL = GCC3
    7876TEMPLATE_libc_INCS = $(PATH_LIBC_INC) $(dir $(LIBC-STD.H))
    79 TEMPLATE_libc_INCS.win32 = $(PATH_LIBC_SRC)/w32api/include
    80 TEMPLATE_libc_INCS.win64 = $(TEMPLATE_libc_INCS.win32)
     77TEMPLATE_libc_INCS.nt = $(PATH_LIBC_SRC)/w32api/include
    8178TEMPLATE_libc_DEPS = $(LIBC-STD.H)
    8279TEMPLATE_libc_INST = usr/lib/
     
    8683TEMPLATE_libc.logstrict_TOOL = GCC3
    8784TEMPLATE_libc.logstrict_INCS = $(TEMPLATE_libc_INCS)
    88 TEMPLATE_libc.logstrict_INCS.win32 = $(TEMPLATE_libc_INCS.win32)
    89 TEMPLATE_libc.logstrict_INCS.win64 = $(TEMPLATE_libc_INCS.win64)
     85TEMPLATE_libc.logstrict_INCS.nt = $(TEMPLATE_libc_INCS.nt)
    9086TEMPLATE_libc.logstrict_DEFS = $(TEMPLATE_libc_DEFS) __LIBC_STRICT DEBUG_LOGGING
    9187TEMPLATE_libc.logstrict_DEPS = $(TEMPLATE_libc_DEPS)
     
    9692TEMPLATE_libc.profiled_TOOL = GCC3
    9793TEMPLATE_libc.profiled_INCS = $(TEMPLATE_libc_INCS)
    98 TEMPLATE_libc.profiled_INCS.win32 = $(TEMPLATE_libc_INCS.win32)
    99 TEMPLATE_libc.profiled_INCS.win64 = $(TEMPLATE_libc_INCS.win64)
     94TEMPLATE_libc.profiled_INCS.nt = $(TEMPLATE_libc_INCS.nt)
    10095TEMPLATE_libc.profiled_DEFS = $(TEMPLATE_libc_DEFS) __LIBC_PROFILED
    10196TEMPLATE_libc.profiled_DEPS = $(TEMPLATE_libc_DEPS)
  • trunk/libc/Makefile.kmk

    r2733 r2739  
    5656        $(TARGET_libc_libsocket) \
    5757        $(TARGET_libc_libsyslog)
    58 libc_SOURCES.win32 = $(TARGET_kNIX.nt)
     58libc_SOURCES.nt = $(TARGET_kNIX.nt)
    5959
    6060ifdef CFG_LIBC_LOGSTRICT_LIBS
  • trunk/libc/alias.kmk

    r2717 r2739  
    6363$(foreach pair,$(ALIASPAIRS),$(eval libc_alias_SOURCES += $$(PATH_TARGET)/libc_alias/$(word 1, $(subst =, ,$(pair))).o))
    6464
    65 $(libc_alias_SOURCES): $(LIBC_GENALIAS) alias.kmk
     65$(libc_alias_SOURCES): $(LIBC_GENALIAS) alias.kmk | $(call DIRDEP,$(PATH_TARGET)/libc_alias)
    6666        $(RM) -f $(PATH_TARGET)/aliases.rsp $(libc_alias_SOURCES)
    6767        $(foreach pair,$(ALIASPAIRS) \
  • trunk/libc/include/386/_limits.h

    r1574 r2739  
    113113/* bird: Real time signals. */
    114114#define __RTSIG_MAX     32
     115/* bird: wchar_t & wint_t */
     116#if 1
     117#define __WCHAR_MIN     0
     118#define __WCHAR_MAX     __USHRT_MAX
     119#else
     120#define __WCHAR_MIN     __INT_MIN
     121#define __WCHAR_MAX     __INT_MAX
     122#endif
     123#define __WINT_MIN      __INT_MIN
     124#define __WINT_MAX      __INT_MAX
     125
    115126#endif /* !_MACHINE__LIMITS_H_ */
  • trunk/libc/include/386/_stdint.h

    r659 r2739  
    4040/** @file
    4141 * FreeBSD 5.1
     42 * @changed bird: corrected wchar_t and wint_t min/max constants.
    4243 */
    4344
     
    151152 */
    152153/* Limits of ptrdiff_t. */
    153 #define PTRDIFF_MIN     INT32_MIN       
     154#define PTRDIFF_MIN     INT32_MIN
    154155#define PTRDIFF_MAX     INT32_MAX
    155156
     
    162163
    163164#ifndef WCHAR_MIN /* Also possibly defined in <wchar.h> */
     165#include <machine/_limits.h>            /* bird */
    164166/* Limits of wchar_t. */
    165 #define WCHAR_MIN       INT32_MIN
    166 #define WCHAR_MAX       INT32_MAX
     167#define WCHAR_MIN       __WCHAR_MIN     /* bird */
     168#define WCHAR_MAX       __WCHAR_MAX     /* bird */
     169#endif                                  /* bird */
    167170
     171#ifdef WINT_MIN                         /* bird */
     172#include <machine/_limits.h>            /* bird */
    168173/* Limits of wint_t. */
    169 #define WINT_MIN        INT32_MIN
    170 #define WINT_MAX        INT32_MAX
    171 #endif
     174#define WINT_MIN        __WINT_MIN      /* bird */
     175#define WINT_MAX        __WINT_MAX      /* bird */
     176#endif                                  /* bird */
    172177
    173178#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */
  • trunk/libc/include/386/builtin.h

    r2723 r2739  
    6767    return u16;
    6868}
    69 
    70 /**
    71  * Atomically sets a bit and return the old one.
    72  *
    73  * @returns 1 if the bwit was set, 0 if it was clear.
    74  * @param   pv      Pointer to base of bitmap.
    75  * @param   uBit    Bit in question.
    76  */
    77 static __inline__ int __atomic_set_bit(__volatile__ void *pv, unsigned uBit)
    78 {
    79     __asm__ __volatile__("lock; btsl %2, %1\n\t"
    80                          "sbbl %0,%0"
    81                          : "=r" (uBit),
    82                            "=m" (*(__volatile__ unsigned *)pv)
    83                          : "0"  (uBit)
    84                          : "memory");
    85     return uBit;
    86 }
    87 
    88 
    89 /**
    90  * Atomically clears a bit.
    91  *
    92  * @param   pv      Pointer to base of bitmap.
    93  * @param   uBit    Bit in question.
    94  */
    95 static __inline__ void __atomic_clear_bit(__volatile__ void *pv, unsigned uBit)
    96 {
    97     __asm__ __volatile__("lock; btrl %1, %0"
    98                          : "=m" (*(__volatile__ unsigned *)pv)
    99                          : "r" (uBit));
    100 }
    101 
    102 
    103 /**
    104  * Atomically (er?) tests if a bit is set.
    105  *
    106  * @returns non zero if the bit was set.
    107  * @returns 0 if the bit was clear.
    108  * @param   pv      Pointer to base of bitmap.
    109  * @param   uBit    Bit in question.
    110  */
    111 static __inline__ int __atomic_test_bit(const __volatile__ void *pv, unsigned uBit)
    112 {
    113     __asm__ __volatile__("btl %0, %1\n\t"
    114                          "sbbl %0, %0\t\n"
    115                          : "=r" (uBit)
    116                          : "m"  (*(const __volatile__ unsigned *)pv),
    117                            "0"  (uBit));
    118     return uBit;
    119 }
    120 
    12169
    12270/**
     
    448396}
    449397
     398
     399/**
     400 * Sets a bitmap bit.
     401 *
     402 * @param   pvBitmap    The bitmap base.
     403 * @param   iBit        The bit to be set.
     404 */
     405static inline void __bit_set(void volatile *pvBitmap, uint32_t iBit)
     406{
     407    __asm__ __volatile__("btsl %1, %0" : "=m" (*(uint32_t *)pvBitmap) : "Ir" (iBit) : "memory");
     408}
     409
     410/**
     411 * Clears a bitmap bit.
     412 *
     413 * @param   pvBitmap    The bitmap base.
     414 * @param   iBit        The bit to be cleared.
     415 */
     416static inline void __bit_clear(void volatile *pvBitmap, uint32_t iBit)
     417{
     418    __asm__ __volatile__("btrl %1, %0" : "=m" (*(uint32_t *)pvBitmap) : "Ir" (iBit) : "memory");
     419}
     420
     421/**
     422 * Clears a bitmap bit.
     423 *
     424 * @param   pvBitmap    The bitmap base.
     425 * @param   iBit        The bit to be cleared.
     426 */
     427static inline void __bit_toggle(void volatile *pvBitmap, uint32_t iBit)
     428{
     429    __asm__ __volatile__("btcl %1, %0" : "=m" (*(uint32_t *)pvBitmap) : "Ir" (iBit) : "memory");
     430}
     431
     432/**
     433 * Tests if a bitmap bit is set.
     434 *
     435 * @returns true if set, false if clear.
     436 * @param   pvBitmap    The bitmap base.
     437 * @param   iBit        The bit to be tested.
     438 */
     439static inline _Bool __bit_test(void volatile *pvBitmap, uint32_t iBit)
     440{
     441    union { _Bool f; uint32_t u32; } u;
     442
     443    __asm__ __volatile__("btl %2, %1\n\t"
     444                         "sbbl %0, %0"
     445                         : "=r" (u.u32), "=m" (*(uint32_t *)pvBitmap)
     446                         : "Ir" (iBit));
     447    return u.f;
     448}
     449
     450/**
     451 * Tests if a bitmap bit is set and then sets it.
     452 *
     453 * @returns true if set, false if clear.
     454 * @param   pvBitmap    The bitmap base.
     455 * @param   iBit        The bit to be tested and set.
     456 */
     457static inline _Bool __bit_test_and_set(void volatile *pvBitmap, uint32_t iBit)
     458{
     459    union { _Bool f; uint32_t u32; } u;
     460
     461    __asm__ __volatile__("btsl %2, %1\n\t"
     462                         "sbbl %0, %0"
     463                         : "=r" (u.u32), "=m" (*(uint32_t *)pvBitmap)
     464                         : "Ir" (iBit));
     465    return u.f;
     466}
     467
     468/**
     469 * Tests if a bitmap bit is set and then clears it.
     470 *
     471 * @returns true if set, false if clear.
     472 * @param   pvBitmap    The bitmap base.
     473 * @param   iBit        The bit to be tested and cleared.
     474 */
     475static inline _Bool __bit_test_and_clear(void volatile *pvBitmap, uint32_t iBit)
     476{
     477    union { _Bool f; uint32_t u32; } u;
     478
     479    __asm__ __volatile__("btrl %2, %1\n\t"
     480                         "sbbl %0, %0"
     481                         : "=r" (u.u32), "=m" (*(uint32_t *)pvBitmap)
     482                         : "Ir" (iBit));
     483    return u.f;
     484}
     485
     486/**
     487 * Tests if a bitmap bit is set and then toggles it.
     488 *
     489 * @returns true if set, false if clear.
     490 * @param   pvBitmap    The bitmap base.
     491 * @param   iBit        The bit to be tested and toggled.
     492 */
     493static inline _Bool __bit_test_and_toggle(void volatile *pvBitmap, uint32_t iBit)
     494{
     495    union { _Bool f; uint32_t u32; } u;
     496
     497    __asm__ __volatile__("btcl %2, %1\n\t"
     498                         "sbbl %0, %0"
     499                         : "=r" (u.u32), "=m" (*(uint32_t *)pvBitmap)
     500                         : "Ir" (iBit));
     501    return u.f;
     502}
     503
     504/**
     505 * Sets a bitmap bit.
     506 *
     507 * @param   pvBitmap    The bitmap base.
     508 * @param   iBit        The bit to be set.
     509 */
     510static inline void __atomic_bit_set(void volatile *pvBitmap, uint32_t iBit)
     511{
     512    __asm__ __volatile__("btsl %1, %0" : "=m" (*(uint32_t *)pvBitmap) : "Ir" (iBit) : "memory");
     513}
     514
     515/**
     516 * Clears a bitmap bit.
     517 *
     518 * @param   pvBitmap    The bitmap base.
     519 * @param   iBit        The bit to be cleared.
     520 */
     521static inline void __atomic_bit_clear(void volatile *pvBitmap, uint32_t iBit)
     522{
     523    __asm__ __volatile__("btrl %1, %0" : "=m" (*(uint32_t *)pvBitmap) : "Ir" (iBit) : "memory");
     524}
     525
     526/**
     527 * Clears a bitmap bit.
     528 *
     529 * @param   pvBitmap    The bitmap base.
     530 * @param   iBit        The bit to be cleared.
     531 */
     532static inline void __atomic_bit_toggle(void volatile *pvBitmap, uint32_t iBit)
     533{
     534    __asm__ __volatile__("btcl %1, %0" : "=m" (*(uint32_t *)pvBitmap) : "Ir" (iBit) : "memory");
     535}
     536
     537/**
     538 * Atomically tests if a bitmap bit is set and then sets it.
     539 *
     540 * @returns true if set, false if clear.
     541 * @param   pvBitmap    The bitmap base.
     542 * @param   iBit        The bit to be tested and set.
     543 */
     544static inline _Bool __atomic_bit_test_and_set(void volatile *pvBitmap, uint32_t iBit)
     545{
     546    union { _Bool f; uint32_t u32; } u;
     547
     548    __asm__ __volatile__("lock; btsl %2, %1\n\t"
     549                         "sbbl %0, %0"
     550                         : "=r" (u.u32), "=m" (*(uint32_t *)pvBitmap)
     551                         : "Ir" (iBit));
     552    return u.f;
     553}
     554
     555/**
     556 * Atomically tests if a bitmap bit is set and then clears it.
     557 *
     558 * @returns true if set, false if clear.
     559 * @param   pvBitmap    The bitmap base.
     560 * @param   iBit        The bit to be tested and cleared.
     561 */
     562static inline _Bool __atomic_bit_test_and_clear(void volatile *pvBitmap, uint32_t iBit)
     563{
     564    union { _Bool f; uint32_t u32; } u;
     565
     566    __asm__ __volatile__("lock; btrl %2, %1\n\t"
     567                         "sbbl %0, %0"
     568                         : "=r" (u.u32), "=m" (*(uint32_t *)pvBitmap)
     569                         : "Ir" (iBit));
     570    return u.f;
     571}
     572
     573/**
     574 * Atomically tests if a bitmap bit is set and then toggles it.
     575 *
     576 * @returns true if set, false if clear.
     577 * @param   pvBitmap    The bitmap base.
     578 * @param   iBit        The bit to be tested and toggled.
     579 */
     580static inline _Bool __atomic_bit_test_and_toggle(void volatile *pvBitmap, uint32_t iBit)
     581{
     582    union { _Bool f; uint32_t u32; } u;
     583
     584    __asm__ __volatile__("lock; btcl %2, %1\n\t"
     585                         "sbbl %0, %0"
     586                         : "=r" (u.u32), "=m" (*(uint32_t *)pvBitmap)
     587                         : "Ir" (iBit));
     588    return u.f;
     589}
     590
     591
     592/**
     593 * Scans the bitmap from head to tail looking for the first clear bit.
     594 *
     595 * @returns the bit number on success.
     596 * @returns -1 if the end of the bitmap was reached without finind a clear bit.
     597 *
     598 * @param   pvBitmap    Pointer to the bitmap. Better be 8 byte aligned.
     599 * @param   cbBitmap    Size (in bytes) of the bitmap. Must be a multiple of 8.
     600 */
     601static inline int32_t __bit_scan_clear_forward(void volatile *pvBitmap, uint32_t cbBitmap)
     602{
     603    int32_t iBit;
     604    __asm__ __volatile__("cld\n\t"
     605                         "repe scasl\n\t"
     606                         "jne 1f\n\t"
     607                         "subl  $4, %%edi\n\t"
     608                         "xorl  (%%edi), %%eax\n\t"
     609                         "bsfl  %%eax, %%eax\n\t"
     610                         "subl  %3, %%edi\n\t"
     611                         "lea   (%%eax,%%edi,8), %%eax\n\t"
     612                         "1:\n\t"
     613                         : "=a" (iBit)
     614                         : "D" (pvBitmap),
     615                           "c" (cbBitmap >> 2),
     616                           "m" (pvBitmap),
     617                           "0" (0xffffffff));
     618    return iBit;
     619}
     620
     621
    450622#define __ROTATE_FUN(F,I,T) \
    451623  static __inline__ T F (T value, int shift) \
  • trunk/libc/include/InnoTekLIBC/backend.h

    r2439 r2739  
    44 * LIBC - Backend header.
    55 *
    6  * Copyright (c) 2004 knut st. osmundsen <bird-srcspam@anduin.net>
     6 * Copyright (c) 2004-2006 knut st. osmundsen <bird-srcspam@anduin.net>
    77 *
    88 *
     
    2828#define __InnoTekLIBC_backend_h__
    2929
     30#include <stdarg.h>
    3031#include <sys/cdefs.h>
    3132#include <sys/types.h>
     
    3738#include <sys/shm.h>
    3839#include <signal.h>
    39 #include <emx/io.h>
    40 #include <stdarg.h>
     40#include <klibc/io.h>
    4141
    4242
     
    420420 *                      for the opened file.
    421421 */
    422 int __libc_Back_ioFileOpen(const char *pszFile, unsigned fLibc, int fShare, off_t cbInitial, mode_t Mode, PLIBCFH *ppFH);
     422int __libc_Back_ioFileOpen(const char *pszFile, unsigned fLibc, int fShare, off_t cbInitial, mode_t Mode, __LIBC_PPFH ppFH);
     423
     424/**
     425 * Closes a file handle.
     426 *
     427 * @returns 0 on success.
     428 * @returns Negated errno on failure.
     429 * @param   fh          The file handle.
     430 */
     431int __libc_Back_ioClose(int fh);
     432
     433/**
     434 * Reads from a file handle.
     435 *
     436 * @returns 0 on success.
     437 * @returns Negated errno on failure.
     438 * @param   fh          The file handle.
     439 * @param   pvBuf       The buffer to read into.
     440 * @param   cbToRead    The number of bytes to read.
     441 * @param   pcbRead     Where to store the number of bytes actually read.
     442 */
     443int __libc_Back_ioRead(int fh, void *pvBuf, size_t cbToRead, size_t *pcbRead);
     444
     445/**
     446 * Write to a file handle.
     447 *
     448 * @returns 0 on success.
     449 * @returns Negated errno on failure.
     450 * @param   fh          The file handle.
     451 * @param   pvBuf       The buffer containing the bytes to write.
     452 * @param   cbToWrite   The number of bytes to write.
     453 * @param   pcbWritten  Where to store the number of bytes actually written.
     454 */
     455int __libc_Back_ioWrite(int fh, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
    423456
    424457/**
     
    467500/**
    468501 * File Control.
    469  * 
     502 *
    470503 * Deals with file descriptor flags, file descriptor duplication and locking.
    471  * 
     504 *
    472505 * @returns 0 on success and *piRet set.
    473506 * @returns Negated errno on failure and *piRet set to -1.
     
    483516/**
    484517 * File Control operation - OS/2 standard handle.
    485  * 
     518 *
    486519 * @returns 0 on success.
    487520 * @returns OS/2 error code or negated errno on failure.
    488  * 
     521 *
    489522 * @param   pFH         Pointer to the handle structure to operate on.
    490523 * @param   fh          It's associated filehandle.
     
    496529 */
    497530int __libc_Back_ioFileControlStandard(__LIBC_PFH pFH, int fh, int iRequest, intptr_t iArg, int *prc);
    498    
     531
    499532/**
    500533 * Try resolve a filehandle to a path.
     
    605638 * on any memory the native apis works on.
    606639 *
     640 * @returns 0 on success.
    607641 * @returns Negative error code (errno.h) on failure.
    608642 * @param   pv      Pointer to first page - page aligned!
     
    611645 */
    612646int __libc_Back_mmanProtect(void *pv, size_t cb, unsigned fFlags);
     647
     648/**
     649 * Sets the the break value (end of the dynamic data segment).
     650 *
     651 * @returns 0 on success.
     652 * @returns Negative error code (errno.h) on failure.
     653 * @param   pvNewBreak      The requested new break.
     654 */
     655int __libc_Back_mmanBrk(void *pvNewBreak);
     656
     657/**
     658 * Adds a delta to the break value (end of the dynamic data segment).
     659 *
     660 * @returns 0 on success.
     661 * @returns Negative error code (errno.h) on failure.
     662 * @param   iDelta          The delta to add to the current break value.
     663 * @param   ppvOldBreak     Where to store the old break value.
     664 */
     665int __libc_Back_mmanSBrk(intptr_t iDelta, void **ppvOldBreak);
     666
     667/**
     668 * SBrk model.
     669 */
     670typedef enum __LIBCSBRKMODEL
     671{
     672    __LIBC_SBRK_MODEL_INVALID = 0,
     673    __LIBC_SBRK_MODEL_CONTIGUOUS = 1,
     674    __LIBC_SBRK_MODEL_MONOTONOUS = 2,
     675    __LIBC_SBRK_MODEL_ARBITRARY  = 4
     676} __LIBCSBRKMODEL;
     677
     678/**
     679 * Sets the model used by the __libc_Back_mmanSBrk() and
     680 * __libc_Back_mmanBrk() APIs.
     681 *
     682 * @returns The old module on success.
     683 * @returns __LIBC_SBRK_MODEL_INVALID on invalid enmModule value.
     684 * @param   enmModel        The new model.
     685 */
     686__LIBCSBRKMODEL __libc_Back_mmanSBrkSetModel(__LIBCSBRKMODEL enmModel);
     687
     688/**
     689 * Gets the model used by the __libc_Back_mmanSBrk() and
     690 * __libc_Back_mmanBrk() APIs.
     691 *
     692 * @returns The current break model.
     693 */
     694__LIBCSBRKMODEL __libc_Back_mmanSBrkGetModel(void);
    613695
    614696/** @} */
  • trunk/libc/include/InnoTekLIBC/tcpip.h

    r2004 r2739  
    105105{
    106106    /** the common fh core. */
    107     LIBCFH      core;
     107    __LIBC_FH   core;
    108108
    109109    /** OS/2 socket number. */
     
    345345
    346346/**
    347  * Retrieve the socket handle structure for a given handle.
     347 * Retrieve the socket handle structure for a given file handle.
    348348 *
    349349 * @returns Pointer to socket handle structure on success.
     
    351351 * @param   iSocket  Socket handle number.
    352352 */
    353 static inline PLIBCSOCKETFH   __libc_TcpipFH(int iSocket)
    354 {
    355     PLIBCSOCKETFH   pFHSocket = (PLIBCSOCKETFH)__libc_FH(iSocket);
    356     if (pFHSocket)
     353static inline PLIBCSOCKETFH __libc_TcpipFH(int iSocket)
     354{
     355    union
    357356    {
    358         if ((pFHSocket->core.fFlags & __LIBC_FH_TYPEMASK) == F_SOCKET)
    359             return pFHSocket;
     357        __LIBC_PFH      pFH;
     358        PLIBCSOCKETFH   pFHSocket;
     359    } u;
     360    int rc = __libc_FHGet(iSocket, &u.pFH);
     361    if (!rc)
     362    {
     363        if ((u.pFHSocket->core.fFlags & __LIBC_FH_TYPEMASK) == F_SOCKET)
     364            return u.pFHSocket;
    360365        __libc_TcpipSetErrno(ENOTSOCK);
    361366    }
    362367    else
    363         __libc_TcpipSetErrno(EBADF);
     368        __libc_TcpipSetErrno(-rc);
    364369    return NULL;
    365370}
  • trunk/libc/include/InnoTekLIBC/thread.h

    r2254 r2739  
    44 * LIBC Thread Handling.
    55 *
    6  * Copyright (c) 2004 knut st. osmundsen <bird-srcspam@anduin.net>
     6 * Copyright (c) 2004-2006 knut st. osmundsen <bird-srcspam@anduin.net>
    77 *
    88 *
     
    4444#include <time.h>                       /* struct tm; */
    4545#include <signal.h>
     46#ifdef __NT__
     47# include <klibc/nt/fib.h>
     48#endif
    4649
    4750
     
    289292*******************************************************************************/
    290293__BEGIN_DECLS
     294#ifdef __OS2__
    291295/** Pointer to the TLS ULONG (OS/2 rules) which will point to the LIBC thread
    292296 * structure for the current thread.
     
    294298 * is allocated on demand. */
    295299extern __LIBC_PPTHREAD  __libc_gpTLS;
     300#endif /* __OS2__ */
    296301__END_DECLS
    297302
     
    301306*******************************************************************************/
    302307__BEGIN_DECLS
     308
     309
    303310/**
    304311 * Get the thread structure for the current thread.
    305312 *
    306  * Will automatically allocate a thread structure if such is not yet done
    307  * for the thread.
     313 * Used by the __libc_threadCurrent() macro for allocating a thread structure for the
     314 * current thread when such doesn't exist.
    308315 *
    309316 * @returns pointer to current thread struct.
    310 
     317 *
     318 * @remark  No reference counting here, the current thread have a permanent
     319 *          reference to it self.
     320 * @remark  This API is considered to be internal to LIBC and is thus not
     321 *          exposed in the shared library version of LIBC. Please don't call it.
     322 *          External LIBs should use the __libc_TLS*() API.
     323 */
     324__LIBC_PTHREAD __libc_threadCurrentSlow(void);
     325
     326/**
     327 * Get the thread structure for the current thread.
     328 *
     329 * Do not create anything automatically.
     330 *
     331 * @returns pointer to current thread struct.
     332 * @returns NULL if not initiated.
     333 *
    311334 * @remark  No reference counting here, current thread have a permanent
    312335 *          reference to it self.
     
    315338 *          External LIBs should use the __libc_TLS*() API.
    316339 */
    317 #define __libc_threadCurrent()   (*__libc_gpTLS ? *__libc_gpTLS : __libc_threadCurrentSlow())
    318 
     340#ifdef __OS2__
     341# define __libc_threadCurrentNoAuto()   (__libc_gpTLS ? *__libc_gpTLS : NULL)
     342#elif defined(__NT__)
     343# define __libc_threadCurrentNoAuto()   (fibGetLibcThread())
     344#else
     345# error "Port me!"
     346#endif
    319347
    320348/**
    321349 * Get the thread structure for the current thread.
    322350 *
    323  * Used by the __libc_threadCurrent() macro for allocating a thread structure for the
    324  * current thread when such doesn't exist.
     351 * Will automatically allocate a thread structure if such is not yet done
     352 * for the thread.
    325353 *
    326354 * @returns pointer to current thread struct.
    327 
    328  * @remark  No reference counting here, current thread have a permanent
     355 *
     356 * @remark  No reference counting here, the current thread have a permanent
    329357 *          reference to it self.
    330358 * @remark  This API is considered to be internal to LIBC and is thus not
     
    332360 *          External LIBs should use the __libc_TLS*() API.
    333361 */
    334 __LIBC_PTHREAD __libc_threadCurrentSlow(void);
    335 
    336 
    337 /**
    338  * Get the thread structure for the current thread.
    339  *
    340  * Do not create anything automatically.
    341  *
    342  * @returns pointer to current thread struct.
    343  * @returns NULL if not initiated.
    344  *
    345  * @remark  No reference counting here, current thread have a permanent
    346  *          reference to it self.
    347  * @remark  This API is considered to be internal to LIBC and is thus not
    348  *          exposed in the shared library version of LIBC. Please don't call it.
    349  *          External LIBs should use the __libc_TLS*() API.
    350  */
    351 #define __libc_threadCurrentNoAuto()   (__libc_gpTLS ? *__libc_gpTLS : NULL)
    352 
     362static __inline__ __LIBC_PTHREAD __libc_threadCurrent(void)
     363{
     364#ifdef __OS2__
     365    __LIBC_PTHREAD pThread = *__libc_gpTLS;
     366#else
     367    __LIBC_PTHREAD pThread = __libc_threadCurrentNoAuto();
     368#endif
     369    if (__predict_true(pThread != (__LIBC_PTHREAD)0))
     370        return pThread;
     371    return __libc_threadCurrentSlow();
     372}
    353373
    354374/**
     
    576596
    577597#endif
     598
  • trunk/libc/include/emx/io.h

    r2672 r2739  
    305305#endif /* __FILE_FSEM_DECLARED */
    306306
    307 struct __libc_FileHandle;
    308 
    309 /**
    310  * Information struct about a mounted file system.
    311  *
    312  * Used to track down the filesystem of an open file handle and
    313  * so we can optimize certain operations like expanding a file.
    314  */
    315 typedef struct __libc_FileSystemInfo
    316 {
    317     /** Number of references to this file system info object.
    318      * The structure can be shared by many handles. */
    319     volatile int32_t    cRefs;
    320     /** Does the file system automatically zero the new space when a file is extended? */
    321     unsigned            fZeroNewBytes : 1;
    322     /** Does the file system provide sufficient EA support for UNIX attributes? */
    323     unsigned            fUnixEAs : 1;
    324     /** Device number of the device the filesystem resides on.
    325      * On OS/2 the device number is derived from the driveletter. */
    326     dev_t               Dev;
    327     /** The filesystem driver name. */
    328     char                szName[16];
    329     /** The mount point - may extend beyond the 4 bytes on some OSes. */
    330     char                szMountpoint[4];
    331 } __LIBC_FSINFO;
    332 /** Pointer to information about an open filesystem. */
    333 typedef __LIBC_FSINFO *__LIBC_PFSINFO;
    334 
    335 
    336 /**
    337  * Filehandle type.
    338  */
    339 typedef enum __libc_FileHandleType
    340 {
    341     /** Anything which is supported by the OS/2 file API.
    342      * (not used at present as those handles doesn't need special ops). */
    343     enmFH_File,
    344     /** Socket handle (BSD 4.3 stack). */
    345     enmFH_Socket43,
    346     /** Socket handle (BSD 4.4 stack). */
    347     enmFH_Socket44,
    348     /** Directory handle. */
    349     enmFH_Directory
    350 } __LIBC_FHTYPE;
    351 
    352 /**
    353  * File handle Operations.
    354  * (for non standard handles (like sockets))
    355  */
    356 typedef struct __libc_FileHandleOperations
    357 {
    358     /** Handle type. */
    359     __LIBC_FHTYPE       enmType;
    360     /** Close operation.
    361      * @returns 0 on success.
    362      * @returns OS/2 error code or negated errno on failure.
    363      * @param   pFH         Pointer to the handle structure to operate on.
    364      * @param   fh          It's associated filehandle.
    365      */
    366     int (*pfnClose)(struct __libc_FileHandle *pFH, int fh);
    367     /** Read operation.
    368      * @returns 0 on success.
    369      * @returns OS/2 error code or negated errno on failure.
    370      * @param   pFH         Pointer to the handle structure to operate on.
    371      * @param   fh          It's associated filehandle.
    372      * @param   pvBuf       Pointer to the buffer to read into.
    373      * @param   cbRead      Number of bytes to read.
    374      * @param   pcbRead     Where to store the count of bytes actually read.
    375      */
    376     int (*pfnRead)(struct __libc_FileHandle *pFH, int fh, void *pvBuf, size_t cbRead, size_t *pcbRead);
    377     /** Write operation.
    378      * @returns 0 on success.
    379      * @returns OS/2 error code or negated errno on failure.
    380      * @param   pFH         Pointer to the handle structure to operate on.
    381      * @param   fh          It's associated filehandle.
    382      * @param   pvBuf       Pointer to the buffer which contains the data to write.
    383      * @param   cbWrite     Number of bytes to write.
    384      * @param   pcbWritten  Where to store the count of bytes actually written.
    385      */
    386     int (*pfnWrite)(struct __libc_FileHandle *pFH, int fh, const void *pvBuf, size_t cbWrite, size_t *pcbWritten);
    387     /** Duplicate handle operation.
    388      * @returns 0 on success, OS/2 error code on failure.
    389      * @param   pFH         Pointer to the handle structure to operate on.
    390      * @param   fh          It's associated filehandle.
    391      * @param   pfhNew      Where to store the duplicate filehandle.
    392      *                      The input value describe how the handle is to be
    393      *                      duplicated. If it's -1 a new handle is allocated.
    394      *                      Any other value will result in that value to be
    395      *                      used as handle. Any existing handle with that
    396      *                      value will be closed.
    397      */
    398     int (*pfnDuplicate)(struct __libc_FileHandle *pFH, int fh, int *pfhNew);
    399     /** File Control operation.
    400      * @returns 0 on success.
    401      * @returns OS/2 error code or negated errno on failure.
    402      * @param   pFH         Pointer to the handle structure to operate on.
    403      * @param   fh          It's associated filehandle.
    404      * @param   iRequest    Which file file descriptior request to perform.
    405      * @param   iArg        Argument which content is specific to each
    406      *                      iRequest operation.
    407      * @param   prc         Where to store the value which upon success is
    408      *                      returned to the caller.
    409      */
    410     int (*pfnFileControl)(struct __libc_FileHandle *pFH, int fh, int iRequest, int iArg, int *prc);
    411     /** I/O Control operation.
    412      * @returns 0 on success.
    413      * @returns OS/2 error code or negated errno on failure.
    414      * @param   pFH         Pointer to the handle structure to operate on.
    415      * @param   fh          It's associated filehandle.
    416      * @param   iIOControl  Which I/O control operation to perform.
    417      * @param   iArg        Argument which content is specific to each
    418      *                      iIOControl operation.
    419      * @param   prc         Where to store the value which upon success is
    420      *                      returned to the caller.
    421      */
    422     int (*pfnIOControl)(struct __libc_FileHandle *pFH, int fh, int iIOControl, int iArg, int *prc);
    423     /** Select operation.
    424      * The select operation is only performed if all handles have the same
    425      * select routine (the main worker checks this).
    426      *
    427      * @returns 0 on success.
    428      * @returns OS/2 error code or negated errno on failure.
    429      * @param   cFHs        Range of handles to be tested.
    430      * @param   pRead       Bitmap for file handles to wait upon to become ready for reading.
    431      * @param   pWrite      Bitmap for file handles to wait upon to become ready for writing.
    432      * @param   pExcept     Bitmap of file handles to wait on (error) exceptions from.
    433      * @param   tv          Timeout value.
    434      * @param   prc         Where to store the value which upon success is
    435      *                      returned to the caller.
    436      */
    437     int (*pfnSelect)(int cFHs, struct fd_set *pRead, struct fd_set *pWrite, struct fd_set *pExcept, struct timeval *tv, int *prc);
    438     /** Fork notification - parent context.
    439      * If NULL it's assumed that no notifiction is needed.
    440      *
    441      * @returns 0 on success.
    442      * @returns OS/2 error code or negated errno on failure.
    443      * @param   pFH             Pointer to the handle structure to operate on.
    444      * @param   fh              It's associated filehandle.
    445      * @param   pForkHandle     The fork handle.
    446      * @param   enmOperation    The fork operation.
    447      */
    448     int (*pfnForkParent)(struct __libc_FileHandle *pFH, int fh, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
    449     /** Fork notification - child context.
    450      * Only the __LIBC_FORK_OP_FORK_CHILD operation is forwarded atm.
    451      * If NULL it's assumed that no notifiction is needed.
    452      *
    453      * @returns 0 on success.
    454      * @returns OS/2 error code or negated errno on failure.
    455      * @param   pFH             Pointer to the handle structure to operate on.
    456      * @param   fh              It's associated filehandle.
    457      * @param   pForkHandle     The fork handle.
    458      * @param   enmOperation    The fork operation.
    459      */
    460     int (*pfnForkChild)(struct __libc_FileHandle *pFH, int fh, __LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
    461 
    462 } __LIBC_FHOPS;
    463 /** Pointer to file handle operations. */
    464 typedef __LIBC_FHOPS *__LIBC_PFHOPS;
    465 /** Pointer to const file handle operations. */
    466 typedef const __LIBC_FHOPS *__LIBC_PCFHOPS;
    467 
    468 /**
    469  * Common part of a per 'file' handle structure.
    470  */
    471 typedef struct __libc_FileHandle
    472 {
    473     /** Handle flags.
    474      * See group @ref libc_ioflags in include/emx/io.h.
    475      * @remark For thread safety update this atomically. */
    476     volatile unsigned int   fFlags;
    477 
    478     /** Lookahead. (whoever uses that?)
    479      * Previously represented by _files / *fd_vec->flags.
    480      * @remark For thread safety update this atomically. */
    481     volatile int            iLookAhead;
    482 
    483     /** Pointer to the operations one can perform on the handle.
    484      * Only for special handles not supported by the OS/2 file API. */
    485     __LIBC_PCFHOPS          pOps;
    486 
    487     /** Device number of the device containing the file.
    488      * The device number is also determined from the path, more correctly the
    489      * driveletter determins this. */
    490     dev_t                   Dev;
    491     /** Inode number of the file.
    492      * Since the inode number is usually calculated from the path we need to
    493      * determin this at handle creation time. */
    494     ino_t                   Inode;
    495     /** Pointer to the filesystem information object for the filesystem which
    496      * this file resides on. This might be NULL... */
    497     __LIBC_PFSINFO          pFsInfo;
    498     /** Pointer to the native path to this file as specified in the open call.
    499      * This is required to read the unix attributes from EAs if the file isn't
    500      * opened with exclusive access. */
    501     char                   *pszNativePath;
    502 } __LIBC_FH;
    503 /** Pointer to filehandle. */
    504 typedef __LIBC_FH *__LIBC_PFH;
    505 /* fixme!! */
    506 #define LIBCFH __LIBC_FH
    507 #define PLIBCFH __LIBC_PFH
    508 
    509 
    510 int     __libc_FHEnsureHandles(int fh);
    511 int     __libc_FHMoreHandles(void);
    512 int     __libc_FHAllocate(int fh, unsigned fFlags, int cb, __LIBC_PCFHOPS pOps, PLIBCFH *ppFH, int *pfh);
    513 int     __libc_FHClose(int fh);
    514 PLIBCFH __libc_FH(int fh);
    515 int     __libc_FHEx(int fh, __LIBC_PFH *ppFH);
    516 int     __libc_FHSetFlags(__LIBC_PFH pFH, int fh, unsigned fFlags);
    517 
    518307
    519308int _endbuf1 (struct __sFILE *);
  • trunk/libc/include/emx/syscalls.h

    r2439 r2739  
    216216int __wait (int *status);
    217217int __waitpid (int pid, int *status, int options);
    218 int __write (int handle, __const__ void *buf, size_t nbyte);
     218//int __write (int handle, __const__ void *buf, size_t nbyte);
    219219
    220220#if defined (__cplusplus)
  • trunk/libc/include/klibc/nt/fib.h

    r2727 r2739  
    2828#define __klibc_nt_fib_h__
    2929
    30 #include <sys/cdefs.h>
     30//#include <sys/cdefs.h>
    3131#include <stdint.h>
    3232
    33 __BEGIN_DECLS
     33//__BEGIN_DECLS
    3434
    3535
     
    275275{
    276276    uint32_t ret;
    277     __asm__ __volatile__("fs; movl (%0), %0\n" : "=r" (ret) : "0" (off));
     277    __asm__ __volatile__("fs; movl (%1), %0\n" : "=r" (ret) : "r" (off));
    278278    return ret;
    279279}
     
    289289    void *ret;
    290290#if defined(__AMD64__) || defined(__x86_64__) || defined(__amd64__)
    291     __asm__ __volatile__("fs; movq (%1), %0\n" : "=r" (ret) : "r" (off));s
     291    __asm__ __volatile__("fs; movq (%1), %0\n" : "=r" (ret) : "r" (off));
    292292#else
    293     __asm__ __volatile__("fs; movl (%0), %0\n" : "=r" (ret) : "0" (off));
    294 
     293    __asm__ __volatile__("fs; movl (%1), %0\n" : "=r" (ret) : "r" (off));
    295294#endif
    296295    return ret;
     
    352351 * Gets the current Thread ID.
    353352 */
    354 #define fibGetTid()             (__libc_fibGetTEB_UPTR(ClientId.UniqueThread))
     353#define fibGetTid()                 (__libc_fibGetTEB_UPTR(ClientId.UniqueThread))
    355354
    356355/**
     
    360359 * @todo Need validate that the value ranges here are within 16-bit. (seems correct on 64-bit xp)
    361360 */
    362 #define fibGetTidPid()          ((uint16_t)fibGetTid() | ((uint16_t)fibGetPid() << 16))
     361#define fibGetTidPid()              ((uint16_t)fibGetTid() | ((uint16_t)fibGetPid() << 16))
    363362
    364363/**
    365364 * Gets the handle of the executable of this process.
    366365 */
    367 #define fibGetExeHandle()       (fibGetPEB()->ImageBaseAddress)
     366#define fibGetExeHandle()           (fibGetPEB()->ImageBaseAddress)
    368367
    369368
     
    372371 */
    373372/** Get the current millisecond counter value. */
    374 #define fibGetMsCount()         ((uint32_t)(fibGetNtMonotime() / 10000))
     373#define fibGetMsCount()             ((uint32_t)(fibGetNtMonotime() / 10000))
    375374
    376375/**
    377376 * Get the NT monotone time.
    378377 */
    379 #define fibGetNtMonotime()      __libc_fibGetNtMonotime_()
     378#define fibGetNtMonotime()          __libc_fibGetNtMonotime_()
    380379
    381380/**
     
    398397 * Checks if we're being debugged.
    399398 */
    400 #define fibIsBeingDebugged()    (fibGetPEB()->BeingDebugged)
    401 
    402 __END_DECLS
    403 
    404 #endif
    405 
     399#define fibIsBeingDebugged()        (fibGetPEB()->BeingDebugged)
     400
     401/**
     402 * We're abusing the ArbitraryUserPointer pointer member of the TIB.
     403 *
     404 * In our own subsystem we are allowed to define this to be the thread pointer.
     405 * In foreign processes, this is possibly a bit intrusive. But for now, I'm feeling
     406 * lazy and is not going to reimplement TlsAlloc and all that to make it work 100%
     407 * safely in win32/64 processes. I'll do that once the first conflicts surfaces.
     408 */
     409#define fibGetLibcThread()          ((__LIBC_PTHREAD)__libc_fibGetTEB_UPTR(ArbitraryUserPointer))
     410
     411/**
     412 * We're abusing the ArbitraryUserPointer pointer member of the TIB.
     413 * @param   pThread     The new thread pointer.
     414 */
     415#define fibSetLibcThread(pThread)   do { fibGetTEB()->ArbitraryUserPointer = (pThread); } while (0)
     416
     417
     418//__END_DECLS
     419
     420#endif
     421
  • trunk/libc/include/klibc/nt/nt.h

    r2727 r2739  
    3939    OUT PUNICODE_STRING VariableValue);
    4040
     41int __libc_back_NtStatus2Errno(NTSTATUS Status);
     42
    4143#endif
    4244
  • trunk/libc/include/sys/uflags.h

    r18 r2739  
    44#define _SYS_UFLAGS_H
    55
     6#include <sys/cdefs.h>
     7
    68/* Constants for _uflags() */
    7 
    8 #define _UF_SIG_MODEL           0x0003  /* Mask */
    9 #define _UF_SIG_EMX             0x0000
    10 #define _UF_SIG_SYSV            0x0001
    11 #define _UF_SIG_BSD             0x0002
    12 #define _UF_SIG_RESERVED        0x0003
    139
    1410#define _UF_SBRK_MODEL          0x000c  /* Mask */
     
    1814#define _UF_SBRK_RESERVED1      0x000c
    1915
     16#if 0/* not implemented */
    2017#define _UF_PTRACE_MODEL        0x0030  /* Mask */
    2118#define _UF_PTRACE_STANDARD     0x0000
    2219#define _UF_PTRACE_NOTIFY       0x0010
    2320#define _UF_PTRACE_MULTITHREAD  0x0020
    24 
    25 #if defined (__cplusplus)
    26 extern "C" {
    2721#endif
    2822
    29 int _uflags (int, int);
    30 
    31 #if defined (__cplusplus)
    32 }
    33 #endif
     23__BEGIN_DECLS
     24int _uflags(int, int);
     25__END_DECLS
    3426
    3527#endif /* not _SYS_UFLAGS_H */
  • trunk/libc/include/wchar.h

    r2120 r2739  
    22 * FreeBSD 5.3
    33 * @changed bird: Disabled all stream related and some other stuff we don't do yet.
     4 * @changed bird: wchar_t min/max.
    45 */
    56/*-
     
    102103
    103104#ifndef WCHAR_MIN
    104 #define WCHAR_MIN       __INT_MIN
    105 #define WCHAR_MAX       __INT_MAX
     105#define WCHAR_MIN       __WCHAR_MIN     /* bird */
     106#define WCHAR_MAX       __WCHAR_MAX     /* bird */
    106107#endif
    107108
  • trunk/libc/src/fbsdlibc/Makefile.kmk

    r2717 r2739  
    3434ifeq ($(BUILD_TARGET),os2) ## @todo make portable
    3535include $(wildcard $(PATH_LIBC_SRC)/fbsdlibc/*/Makefile.kmk)
     36else
     37include $(PATH_LIBC_SRC)/fbsdlibc/locale/Makefile.kmk
    3638endif
    3739
  • trunk/libc/src/fbsdlibc/locale/utf8.c

    r2058 r2739  
    3131#include <errno.h>
    3232#include <limits.h>
    33 #ifdef __INNOTEK_LIBC__
     33#ifdef IN_INNOTEK_LIBC
    3434#include <InnotekLIBC/locale.h>
    3535#else
     
    5656} _UTF8State;
    5757
    58 #ifndef __INNOTEK_LIBC__
     58#ifndef IN_INNOTEK_LIBC
    5959int
    6060_UTF8_init(_RuneLocale *rl)
     
    8080    pFuncs->pfnwcsnrtombs = _UTF8_wcsnrtombs;
    8181}
    82 #endif /* __INNOTEK_LIBC__ */
     82#endif /* IN_INNOTEK_LIBC */
    8383
    8484int
     
    9595        _UTF8State *us;
    9696        int ch, i, mask = 0, want;      /* bird: gcc shut */
    97 #ifdef __INNOTEK_LIBC__
     97#if WCHAR_MAX == 0xffff
    9898        wint_t lbound, wch;
    9999#else
     
    209209                return ((size_t)-1);
    210210        }
    211 #ifdef __INNOTEK_LIBC__
     211#if WCHAR_MAX == 0xffff
    212212        if (wch > 0xffff || wch < 0)
    213213            wch = 0xffff;
  • trunk/libc/src/genalias/Makefile.kmk

    r2717 r2739  
    3535PROGRAMS += genalias
    3636genalias_TEMPLATE = bldprog
    37 ifeq ($(filter-out os2 win32,$(BUILD_TARGET)),)
     37ifeq ($(filter-out os2.x86 nt.x86,$(BUILD_TARGET).$(BUILD_TARGET_ARCH)),)
    3838genalias_DEFS = GENALIAS_UNDERSCORED=1
    3939else
  • trunk/libc/src/kNIX/Makefile.kmk

    r2733 r2739  
    3434libc_kNIX_TEMPLATE = libcsub
    3535libc_kNIX_SOURCES = \
     36    $(PATH_LIBC_SRC)/kNIX/b_ioClose.c \
     37    $(PATH_LIBC_SRC)/kNIX/b_ioRead.c \
     38    $(PATH_LIBC_SRC)/kNIX/b_ioWrite.c \
     39    $(PATH_LIBC_SRC)/kNIX/b_mmanBrk.c \
     40    $(PATH_LIBC_SRC)/kNIX/b_mmanSBrk.c \
     41    $(PATH_LIBC_SRC)/kNIX/b_mmanSBrkGetModel.c \
     42    $(PATH_LIBC_SRC)/kNIX/b_mmanSBrkSetModel.c \
    3643    $(PATH_LIBC_SRC)/kNIX/filehandles.c \
     44    $(PATH_LIBC_SRC)/kNIX/heap.c \
     45    $(PATH_LIBC_SRC)/kNIX/heapdata.c \
     46
     47#    $(PATH_LIBC_SRC)/kNIX/b_ioDuplicate.c \
    3748
    3849
     
    182193    $(PATH_LIBC_SRC)/kNIX/os2/386/__init_environ.s \
    183194
    184 $(PATH_LIBC_SRC)/kNIX/os2/heapsize.c_DEFS = HEAPSIZE=0x2000000
    185 
    186 
    187 libc_kNIX_SOURCES.win32 = \
     195
     196
     197libc_kNIX_SOURCES.nt = \
    188198        $(PATH_LIBC_SRC)/kNIX/nt/b_panic.c \
     199        $(PATH_LIBC_SRC)/kNIX/nt/fhNtFile.c \
     200        $(PATH_LIBC_SRC)/kNIX/nt/NtStatus.c \
    189201
    190202
  • trunk/libc/src/kNIX/filehandles.c

    r2733 r2739  
    44 * LIBC File Handles.
    55 *
    6  * Copyright (c) 2003-2004 knut st. osmundsen <bird-srcspam@anduin.net>
     6 * Copyright (c) 2003-2006 knut st. osmundsen <bird-srcspam@anduin.net>
    77 *
    88 *
     
    2525 */
    2626
    27 /*******************************************************************************
    28 *   Defined Constants And Macros                                               *
    29 *******************************************************************************/
    30 /** Maximum number of file handles. */
    31 #define __LIBC_MAX_FHS      10000
    32 /** Number of file handles to increase the max value with. */
    33 #define __LIBC_INC_FHS      64
    34 
    3527
    3628/*******************************************************************************
    3729*   Header Files                                                               *
    3830*******************************************************************************/
     31#include "libc-alias.h"
    3932#define __LIBC_LOG_GROUP    __LIBC_LOG_GRP_INITTERM
    4033#ifdef __OS2__
     
    4740# include <klibc/nt/nt.h>
    4841#endif
    49 #include "libc-alias.h"
     42#include "kNIX.h"
    5043#include <malloc.h>
    5144#include <string.h>
    5245#include <sys/fcntl.h>
    5346#include <errno.h>
     47#include <klibc/io.h>
    5448#include <InnoTekLIBC/fork.h>
    5549#include <InnoTekLIBC/sharedpm.h>
    5650#include <InnoTekLIBC/tcpip.h>
    57 #include <emx/io.h>
    5851#include <emx/umalloc.h>
    59 //#include "syscalls.h"
    6052#include "b_fs.h"
    6153#include "b_dir.h"
    6254
    63 #include <InnoTekLIBC/backend.h>
    64 #include <InnoTekLIBC/logstrict.h>
     55#include <klibc/backend.h>
     56#include <klibc/logstrict.h>
    6557
    6658
     
    7870
    7971/** Array of preallocated handles - normal files only! */
    80 static LIBCFH               gaPreAllocated[40];
     72static __LIBC_FH            gaPreAllocated[40];
    8173/** Number of free handles in the preallocated array. */
    8274static unsigned             gcPreAllocatedAvail;
     75
     76#if !CFG_KNIX_FH_NATIVE_ALLOCATION
     77/** Bitmap used for keeping track of which filehandle has been allocated. */
     78static  uint8_t             gbmAllocations[(CFG_KNIX_MAX_FHS + 63) / 8];
     79#endif
    8380
    8481/** Indicator whether or not inherit flags and other stuff have been cleaned
    8582 * up after fork. */
    8683static int                  gfForkCleanupDone;
     84
     85/** Last used fake I-node number. */
     86ino_t                       __libc_back_gIno = 0;
    8787
    8888extern int _fmode_bin;
     
    9393*******************************************************************************/
    9494static int      fhMoreHandles(unsigned cMin);
    95 static int      fhAllocate(int fh, unsigned fFlags, int cb, __LIBC_PCFHOPS pOps, __LIBC_PFH *ppFH, int *pfh, int fOwnSem);
     95static int      fhAllocate(int cb, __LIBC_PCFHOPS pOps, uintptr_t hNative, int fh, unsigned fFlags, int fOwnSem, __LIBC_PFH *ppFH);
    9696static void     fhFreeHandle(__LIBC_PFH pFH);
    97 static __LIBC_PFH  fhGet(int fh);
     97static int      fhImportFile(uintptr_t hNative, int fh, __LIBC_PFH *ppFH);
    9898static int      fhForkParent1(__LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
    9999static int      fhForkChild1(__LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
     
    134134     * Figure out the size of the pointer array and initiatlize it.
    135135     */
     136#ifdef __OS2__
    136137    rc = DosSetRelMaxFH(&lDeltaFHs, &cMaxFHs);
    137138    if (rc)
     
    140141        cMaxFHs = 20;
    141142    }
    142     gcFHs = (cMaxFHs + 3) & ~3;     /* round up to nearest 4. */
     143#else
     144    gcFHs = CFG_KNIX_MAX_FHS;
     145#endif
     146    gcFHs = (cMaxFHs + 4) & ~3;     /* round up to nearest 4. */
    143147    gpapFHs = _hcalloc(gcFHs, sizeof(gpapFHs[0]));
    144148    if (!gpapFHs)
     
    147151    gcPreAllocatedAvail = sizeof(gaPreAllocated) / sizeof(gaPreAllocated[0]);
    148152
     153#ifdef __OS2__
    149154    /*
    150155     * Check if we inherited flags and stuff from parent.
     
    166171            cMaxFHs = 3;
    167172        for (i = 0; i < cMaxFHs; i++)
    168             fhGet(i);
     173        {
     174            __LIBC_PFH pFH;
     175            if (!fhImportFile(i, i, &pFH))
     176                /*fhPut(pFH)*/;
     177        }
    169178    }
    170179    else
     
    194203                    {
    195204                        __LIBC_PFH pFH;
    196                         if (fhAllocate(iFH, u.pStds->aHandles[i].fFlags, sizeof(__LIBC_FH), NULL, &pFH, NULL, 0))
     205                        if (fhAllocate(sizeof(__LIBC_FH), &__libc_back_gFileOps, iFH, iFH, u.pStds->aHandles[i].fFlags, 0, &pFH))
    197206                        {
    198207                            __libc_Back_panic(0, NULL, "Failed to allocated inherited file handle! iFH=%d\n", iFH);
     
    272281    }
    273282
     283#elif __NT__
     284    /*
     285     * Need to figure this one out later.
     286     */
     287
     288#else
     289# error
     290#endif
     291
    274292    return 0;
    275293}
    276294
    277 #if 0 // not used
     295
     296#if 0 /// @todo unload termination.
    278297/**
    279298 * Terminate the file handles.
     
    382401    if (rc)
    383402    {
    384         _sys_set_errno(rc);
    385403        free(pRet);
    386404        LIBCLOG_ERROR_RETURN_P(NULL);
     
    471489                        LIBCLOG_ERROR_RETURN_P(NULL);
    472490                    }
     491#ifdef __OS2__ /// @todo fixme
    473492                    u.pDirs->aHandles[i].fInUnixTree   = !!((__LIBC_PFHDIR)gpapFHs[iFH])->fInUnixTree;
    474493                    u.pDirs->aHandles[i].uCurEntry     = ((__LIBC_PFHDIR)gpapFHs[iFH])->uCurEntry;
     494#endif
    475495                    /* next */
    476496                    i++; iFH++;
     
    566586 *
    567587 * @returns 0 on success.
    568  * @returns OS/2 error on failure.
    569  * @param   fh  Filehandle to open the dummy device for.
    570  *              Use -1 if no special handle is requested.
    571  * @param   pfh Where to store the opened fake handle.
    572  */
    573 static int fhOpenDummy(int fh, int *pfh)
    574 {
     588 * @returns Negated errno on failure.
     589 * @param   pFH     The file handle structure to which fh member to set on success.
     590 * @param   fh      The file handle to reserve. If -1 the next free handle is reserved.
     591 */
     592static int fhReserveHandle(__LIBC_PFH pFH, int fh)
     593{
     594#if CFG_KNIX_FH_NATIVE_ALLOCATION
     595# ifdef __OS2__
    575596    int     rc;
    576597    ULONG   ulAction;
     
    582603     * If we're out of handle space, try increase it.
    583604     */
     605/** @todo inherit stuff isn't right here. I.e. O_NOINHERIT won't work. */
    584606    FS_SAVE_LOAD();
    585607    for (;;)
     
    605627            rc = DosDupHandle(hFile, &hDup);
    606628            if (!rc)
    607                 *pfh = hDup;
     629                pFH->fh = hDup;
    608630            DosClose(hFile);
    609631        }
    610632        else
    611             *pfh = hFile;
     633            fh = hFile;
     634
     635        /*
     636         * Make sure we've got enough table space allocated.
     637         * (This may happen when others mess with the max file handle number.)
     638         */
     639        if (!rc && fh >= gcFHs)
     640        {
     641            rc = fhMoreHandles(fh + 1);
     642            if (rc)
     643                DosClose(fh);
     644        }
     645
     646        /*
     647         * Finally, update the handle structure.
     648         */
     649        if (!rc)
     650            pFH->fh = fh;
    612651    }
    613652    FS_RESTORE();
     653    if (rc > 0)
     654        rc = -__libc_native2errno(rc);
    614655    return rc;
     656# endif /* __OS2__ */
     657
     658#else   /* !CFG_KNIX_FH_NATIVE_ALLOCATION */
     659
     660    if (fh == -1)
     661    {
     662        fh = __bit_scan_clear_forward(gbmAllocations, sizeof(gbmAllocations));
     663        if (fh < 0)
     664            return -EMFILE;
     665    }
     666    else if (fh >= 0)
     667    {
     668        if (fh >= CFG_KNIX_MAX_FHS)
     669            return -EMFILE;
     670    }
     671    else
     672    {
     673        LIBC_ASSERTM_FAILED("fh=%d\n", fh);
     674        return -EINVAL;
     675    }
     676    __atomic_bit_set(gbmAllocations, fh);
     677    pFH->fh = fh;
     678    return 0;
     679#endif  /* !CFG_KNIX_FH_NATIVE_ALLOCATION */
    615680}
    616681
     
    631696    pFH->fFlags     = 0;
    632697    pFH->iLookAhead = 0;
     698    pFH->fh         = -1;
     699    pFH->hNative    = 0xdeadbeef;
    633700    pFH->pOps       = NULL;
    634701    pFH->Dev        = 0;
     
    660727 *
    661728 * @returns 0 on success.
    662  * @returns OS/2 error code on failure.
     729 * @returns Negated errno on failure.
    663730 * @param   cMin    Minimum number for the new max handle count.
    664731 * @remark  Lock must be owned upon entry!
     
    666733static int fhMoreHandles(unsigned cMin)
    667734{
     735#if CFG_KNIX_FH_NATIVE_ALLOCATION
     736# ifdef __OS2__
    668737    int     rc;
    669738    ULONG   cNewMaxFHs = gcFHs;
     
    674743     * How many handles?
    675744     * Now, we must be somewhat sensibel about incrementing this number
    676      * into unreasonable values. If an application requires __LIBC_MAX_FHS+
     745     * into unreasonable values. If an application requires CFG_KNIX_MAX_FHS+
    677746     * files it must take steps to tell that to OS/2. If he has we'll receive
    678      * cMin > __LIBC_MAX_FHS, else keep __LIBC_MAX_FHS as a max limit for
     747     * cMin > CFG_KNIX_MAX_FHS, else keep CFG_KNIX_MAX_FHS as a max limit for
    679748     * auto increase.
    680749     */
     
    688757    if (cMin < cNewMaxFHs)
    689758    {   /* auto increment. */
    690         cMin = cNewMaxFHs + __LIBC_INC_FHS;
    691         if (cMin > __LIBC_MAX_FHS)
    692         {
    693             if (gcFHs >= __LIBC_MAX_FHS)
     759        cMin = cNewMaxFHs + CFG_KNIX_INC_FHS;
     760        if (cMin > CFG_KNIX_MAX_FHS)
     761        {
     762            if (gcFHs >= CFG_KNIX_MAX_FHS)
    694763            {
    695764                FS_RESTORE();
    696                 return ERROR_TOO_MANY_OPEN_FILES;
     765                return -EMFILE;
    697766            }
    698             cMin = __LIBC_MAX_FHS;
     767            cMin = CFG_KNIX_MAX_FHS;
    699768        }
    700769    }
     
    723792            gcFHs = cNewMaxFHs;
    724793        }
    725     }
    726 
     794        else
     795            rc = -ENOMEM;
     796    }
     797
     798    if (rc > 0)
     799        rc = -__libc_native2errno(rc);
    727800    return rc;
     801# endif /* __OS2__ */
     802
     803#else   /* !CFG_KNIX_FH_NATIVE_ALLOCATION */
     804
     805    /*
     806     * We've got a fixed number of entries.
     807     * Any ulimit restrictions are virtual (when implemented), the tables
     808     * allocated at init time will be sized to contain the max handle count.
     809     */
     810    if (!cMin)
     811    {
     812        /* increment */
     813        if (gcFHs >= CFG_KNIX_MAX_FHS)
     814            return -EMFILE;
     815        gcFHs = gcFHs + CFG_KNIX_INC_FHS < CFG_KNIX_MAX_FHS ? gcFHs + CFG_KNIX_INC_FHS : CFG_KNIX_MAX_FHS;
     816    }
     817    else
     818    {
     819        /* minimum fh. */
     820        if (cMin > CFG_KNIX_MAX_FHS)
     821            return -EMFILE;
     822        if (gcFHs < cMin)
     823            gcFHs = cMin;
     824    }
     825    return 0;
     826#endif  /* !CFG_KNIX_FH_NATIVE_ALLOCATION */
    728827}
    729828
     
    733832 *
    734833 * @returns 0 on success.
    735  * @returns OS/2 error code on failure.
     834 * @returns Negated errno on failure.
    736835 * @param   fh      Filehandle which must fit.
    737836 */
     
    750849
    751850    if (_fmutex_request(&gmtx, 0))
    752         return -1;
     851        return -EDOOFUS;
    753852
    754853    rc = fhMoreHandles(fh + 1);
     
    763862 *
    764863 * @returns 0 on success.
    765  * @returns -1 on failure.
     864 * @returns Negated errno on failure.
    766865 */
    767866int __libc_FHMoreHandles(void)
     
    769868    int rc;
    770869    if (_fmutex_request(&gmtx, 0))
    771         return -1;
     870        return -EDOOFUS;
    772871
    773872    rc = fhMoreHandles(0);
     
    778877
    779878
    780 
    781 
    782879/**
    783880 * Allocates a file handle.
    784881 *
    785882 * @returns 0 on success.
    786  * @returns OS/2 error code and errno set to the corresponding error number.
     883 * @returns Negated errno on failure.
     884 * @param   pOps    Value of the pOps field.
    787885 * @param   fh      Number of the filehandle to allocate.
    788886 *                  Will fail if the handle is in use.
    789887 *                  Use -1 for any handle.
     888 * @param   hNative The native file handle.
    790889 * @param   fFlags  Initial flags.
    791890 * @param   cb      Size of the file handle.
    792  *                  Must not be less than the mandatory size (sizeof(LIBCFH)).
    793  * @param   pOps    Value of the pOps field, NULL not allowed.
     891 *                  Must not be less than the mandatory size (sizeof(__LIBC_FH)).
    794892 * @param   ppFH    Where to store the allocated file handle struct pointer. (NULL allowed)
    795  * @param   pfh     Where to store the number of the filehandle allocated.
    796893 * @param   fOwnSem Set if we should not take or release the semaphore.
    797894 * @remark  The preallocated handles make this function somewhat big and messy.
    798895 */
    799 static int fhAllocate(int fh, unsigned fFlags, int cb, __LIBC_PCFHOPS pOps, __LIBC_PFH *ppFH, int *pfh, int fOwnSem)
    800 {
    801     __LIBC_PFH  pFH;
    802     int         rc;
    803     FS_VAR();
    804 
    805     /*
    806      * If we know we cannot use the preallocated handles it's prefered to
    807      * do the allocation outside the mutex.
    808      */
    809     pFH = NULL;
    810     if (cb > sizeof(LIBCFH) || !gcPreAllocatedAvail)
     896static int fhAllocate(int cb, __LIBC_PCFHOPS pOps, uintptr_t hNative, int fh, unsigned fFlags, int fOwnSem, __LIBC_PFH *ppFH)
     897{
     898    LIBC_ASSERT(cb >= sizeof(__LIBC_FH)); LIBC_ASSERT(pOps);
     899
     900    /*
     901     * If we know we cannot use the preallocated handles, we will
     902     * do the allocation without owning the lock.
     903     */
     904    __LIBC_PFH pFH = NULL;
     905    if (cb != sizeof(__LIBC_FH) || !gcPreAllocatedAvail)
    811906    {
    812907        pFH = _hmalloc(cb);
    813908        if (!pFH)
    814             return ERROR_NOT_ENOUGH_MEMORY;
    815     }
    816 
    817     /*
    818      * Now take the lock.
     909            return -ENOMEM;
     910    }
     911
     912    /*
     913     * Aquire the lock if necessary.
    819914     */
    820915    if (!fOwnSem && _fmutex_request(&gmtx, 0))
    821         return -1;
    822 
    823     /*
    824      * Now is the time to try use the pre allocated handles.
     916        return -EDOOFUS;
     917
     918    /*
     919     * Do the allocation if we wanted to use preallocated handles.
    825920     */
    826921    if (!pFH)
    827922    {
    828         if (cb == sizeof(LIBCFH) && gcPreAllocatedAvail)
     923        if (cb == sizeof(__LIBC_FH) && gcPreAllocatedAvail)
    829924        {
    830925            __LIBC_PFH pFHSearch;
     
    843938        /*
    844939         * If the pre allocated handle table for some reason was
    845          * full, we'll allocate the handle here.
     940         * exhausted, we'll allocate the handle here.
    846941         */
    847942        if (!pFH)
     
    849944    }
    850945
     946    int rc;
    851947    if (pFH)
    852948    {
     
    854950         * Initiate the handle data.
    855951         */
     952        pFH->fFlags     = fFlags;
    856953        pFH->fFlags     = fFlags;
    857954        if (fFlags & O_NOINHERIT)
    858955            fFlags |= FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT;
    859956        pFH->iLookAhead = -1;
     957        pFH->fh         = fh;
     958        pFH->hNative    = hNative;
    860959        pFH->pOps       = pOps;
    861         pFH->Inode      = ++_sys_ino;
     960        pFH->Inode      = ++__libc_back_gIno;
    862961        if (!pFH->Inode)
    863             pFH->Inode  = ++_sys_ino;
     962            pFH->Inode  = ++__libc_back_gIno;
    864963        pFH->Dev        = 0;
    865964        pFH->pFsInfo    = NULL;
     
    872971        {
    873972            /*
    874              * Non OS/2 filehandle.
    875              * Open dummy device to find a handle number.
     973             * Find and reserve the next kNIX handle number.
    876974             */
    877             LIBC_ASSERTM(pOps, "cannot open a non-standard handle without giving pOps!\n");
    878             rc = fhOpenDummy(-1, &fh);
     975            rc = fhReserveHandle(pFH, -1);
    879976            if (!rc)
    880977            {
     978#if CFG_KNIX_FH_NATIVE_ALLOCATION
    881979                /*
    882                  * Enough space in the handle table?
     980                 * Free any old filehandle which death we didn't catch
     981                 * and insert the new one.
    883982                 */
    884                 if (fh >= gcFHs)
    885                     rc = fhMoreHandles(fh + 1);
    886                 if (!rc)
    887                 {
    888                     /*
    889                      * Free any old filehandle which death we didn't catch
    890                      * and insert the new one.
    891                      */
    892                     if (gpapFHs[fh])
    893                         fhFreeHandle(gpapFHs[fh]);
    894                     gpapFHs[fh] = pFH;
    895                 }
    896                 else
    897                 {
    898                     /* failure: close dummy */
    899                     FS_SAVE_LOAD();
    900                     DosClose((HFILE)fh);
    901                     FS_RESTORE();
    902                     fh = -1;
    903                 }
     983                if (gpapFHs[pFH->fh])
     984                    fhFreeHandle(gpapFHs[pFH->fh]);
     985#else
     986                LIBC_ASSERT(!gpapFHs[pFH->fh]);
     987#endif
     988                gpapFHs[pFH->fh] = pFH;
    904989            }
    905990        }
     
    907992        {
    908993            /*
    909              * Specific handle request.
    910994             * Make sure there are enough file handles available.
    911995             */
     
    913997            if (fh >= gcFHs)
    914998                rc = fhMoreHandles(fh + 1);
    915 
    916999            if (!rc)
    9171000            {
    9181001                /*
    919                  * Send the close call to any non-OS/2 handle.
     1002                 * Close any existing handle (dup), except when the new one is identical to the one being replaced.
    9201003                 */
    921                 __LIBC_PFH  pFHOld = gpapFHs[fh];
     1004                __LIBC_PFH pFHOld = gpapFHs[fh];
    9221005                if (    pFHOld
    923                     &&  pFHOld->pOps
    924                     &&  pFHOld->pOps->pfnClose)
    925                     rc = pFHOld->pOps->pfnClose(pFHOld, fh);
     1006                    &&  (    pFHOld->hNative != pFH->hNative
     1007                         ||  pFHOld->pOps != pFH->pOps)
     1008                    &&  pFHOld->pOps->pfnClose
     1009                   )
     1010                {
     1011                    rc = pFHOld->pOps->pfnClose(pFHOld);
     1012                    if (rc == -EBADF)
     1013                        rc = 0;
     1014                }
    9261015                if (!rc)
    9271016                {
    928                     /*
    929                      * If not OS/2 filehandle, make a fake handle.
    930                      */
    931                     if (pOps)
    932                         rc = fhOpenDummy(fh, &fh);
     1017                    if (pFHOld)
     1018                        fhFreeHandle(pFHOld);
     1019                    rc = fhReserveHandle(pFH, fh);
    9331020                    if (!rc)
    9341021                    {
    935                         /*
    936                          * Free any old filehandle (replaced during dup2 or closed outside
    937                          * this libc) and insert the new one.
    938                          */
    939                         if (pFHOld)
    940                             fhFreeHandle(pFHOld);
     1022                        LIBC_ASSERT(pFH->fh == fh);
    9411023                        gpapFHs[fh] = pFH;
    9421024                    }
     
    9461028    }
    9471029    else
    948         rc = ERROR_NOT_ENOUGH_MEMORY;
     1030        rc = -ENOMEM;
    9491031
    9501032    /*
     
    9531035    if (rc)
    9541036    {
    955         _sys_set_errno(rc);
    9561037        if (pFH)
    9571038            fhFreeHandle(pFH);
    9581039        pFH = NULL;
    959         fh = -1;
    9601040    }
    9611041
     
    9651045    if (ppFH)
    9661046        *ppFH = pFH;
    967     if (pfh)
    968         *pfh = fh;
    9691047
    9701048    if (!fOwnSem)
     
    9771055 *
    9781056 * @returns 0 on success.
    979  * @returns OS/2 error code and errno set to the corresponding error number.
    980  * @param   fh      Number of the filehandle to allocate.
    981  *                  Will fail if the handle is in use.
    982  *                  Use -1 for any handle.
     1057 * @returns Negated errno on failure.
     1058 *
     1059 * @param   cb      Size of the file handle. Obviously, it can't be less that sizeof(__LIBC_FH).
     1060 * @param   pOps    The file handle operations.
     1061 * @param   hNative The natvie file handle.
     1062 * @param   fh      Number of the filehandle to allocate. Use -1 for any handle.
    9831063 * @param   fFlags  Initial flags.
    984  * @param   cb      Size of the file handle.
    985  *                  Must not be less than the mandatory size (sizeof(LIBCFH)).
    986  * @param   pOps    Value of the pOps field.
    9871064 * @param   ppFH    Where to store the allocated file handle struct pointer. (NULL allowed)
    988  * @param   pfh     Where to store the number of the filehandle allocated.
    989  * @remark  The preallocated handles make this function somewhat big and messy.
    990  */
    991 int __libc_FHAllocate(int fh, unsigned fFlags, int cb, __LIBC_PCFHOPS pOps, __LIBC_PFH *ppFH, int *pfh)
    992 {
    993     return fhAllocate(fh, fFlags, cb, pOps, ppFH, pfh, 0);
    994 }
    995 
    996 
    997 /**
    998  * Close (i.e. free) a file handle.
    999  *
    1000  * @returns 0 on success.
    1001  * @returns OS/2 error code on failure and errno set to corresponding error number.
    1002  * @param   fh      Filehandle to close.
    1003  */
    1004 int __libc_FHClose(int fh)
    1005 {
    1006     LIBCLOG_ENTER("fh=%d\n", fh);
    1007     __LIBC_PFH  pFH;
    1008     int         rc;
    1009     FS_VAR();
    1010 
     1065 */
     1066int __libc_FHAllocate(int cb, __LIBC_PCFHOPS pOps, uintptr_t hNative, int fh, unsigned fFlags, __LIBC_PFH *ppFH)
     1067{
     1068    return fhAllocate(cb, pOps, hNative, fh, fFlags, 0, ppFH);
     1069}
     1070
     1071
     1072/**
     1073 * Frees a file handle.
     1074 *
     1075 * The caller is responsible for any necessary closing of the handle and that the handle is
     1076 * locked (__libc_FHGet/FHAllocate).
     1077 *
     1078 * @param   pFH     The handle.
     1079 */
     1080void __libc_FHFree(__LIBC_PFH pFH)
     1081{
     1082    LIBCLOG_ENTER("pFH=%p:{.fh=%d}\n", pFH, pFH->fh);
    10111083    if (_fmutex_request(&gmtx, 0))
    1012         LIBCLOG_ERROR_RETURN(-1, "ret -1 - fh=%d is not opened according to our table!\n", fh);
    1013 
    1014     /*
    1015      * Validate input.
    1016      */
    1017     if (!fhGet(fh))
    1018     {
    1019         _fmutex_release(&gmtx);
    1020         errno = EBADF;
    1021         LIBCLOG_ERROR_RETURN(-1, "ret -1 - fh=%d is not opened according to our table!\n", fh);
    1022     }
    1023 
    1024     pFH = gpapFHs[fh];
    1025 
    1026     /*
    1027      * If this is an non OS/2 handle, let the subsystem clean it up first.
    1028      */
    1029     rc = 0;
    1030     if (pFH->pOps && pFH->pOps->pfnClose)
    1031         rc = pFH->pOps->pfnClose(pFH, fh);
    1032 
    1033     /*
    1034      * We should continue closing the OS/2 handle if the previuos step
    1035      * were successful or if the handle has become invalid.
    1036      */
    1037     if (    !rc
    1038         ||  rc == ERROR_INVALID_HANDLE
    1039         ||  rc == -EBADF
    1040         ||  rc == -ENOTSOCK)
    1041     {
    1042         int rc2;
    1043 
     1084        LIBCLOG_ERROR_RETURN_VOID();
     1085
     1086    if (    pFH->fh >= 0
     1087        &&  pFH->fh < gcFHs
     1088       )
     1089    {
     1090        LIBC_ASSERT(gpapFHs[pFH->fh] == pFH);
     1091
     1092#if CFG_KNIX_FH_NATIVE_ALLOCATION
     1093# ifdef __OS2__
    10441094        /*
    10451095         * Close the OS/2 handle and remove the handle from the array
    10461096         * making the space available to others.
    1047          * - This ain't the way which scales best, but it's the safe way.
    1048          */
    1049         FS_SAVE_LOAD();
    1050         rc2 = DosClose(fh);
     1097         */
     1098        FS_VAR_SAVE_LOAD();
     1099        rc2 = DosClose(pFH->fh);
    10511100        FS_RESTORE();
    1052         LIBC_ASSERTM(!rc2, "DosClose(%d) -> rc2=%d (rc=%d)\n", fh, rc2, rc);
    1053         if (!pFH->pOps)
    1054             rc = rc2;
    1055 
    1056         /*
    1057          * If we successfully freed the handle, or it had become invalid
    1058          * we will free it now.
    1059          */
    1060         if (    !rc2
    1061             ||  rc2 == ERROR_INVALID_HANDLE
    1062             ||  pFH->pOps)
    1063         {
    1064             gpapFHs[fh] = NULL;
    1065             fhFreeHandle(pFH);
    1066         }
    1067     }
     1101        LIBC_ASSERTM(!rc2, "DosClose(%d) -> rc2=%d (rc=%d)\n", pFH->fh, rc2, rc);
     1102
     1103        gpapFHs[pFH->fh] = NULL;
     1104        fhFreeHandle(pFH);
     1105# endif /* __OS2__ */
     1106
     1107#else  /* !CFG_KNIX_FH_NATIVE_ALLOCATION */
     1108
     1109        __atomic_bit_clear(gbmAllocations, pFH->fh);
     1110        gpapFHs[pFH->fh] = NULL;
     1111        fhFreeHandle(pFH);
     1112
     1113#endif /* !CFG_KNIX_FH_NATIVE_ALLOCATION */
     1114    }
     1115    else
     1116        LIBC_ASSERT(pFH->fh >= 0 && pFH->fh < gcFHs);
    10681117
    10691118    _fmutex_release(&gmtx);
    1070 
    1071     if (!rc)
    1072         LIBCLOG_RETURN_INT(0);
    1073     if (rc > 0)
    1074         _sys_set_errno(rc);
    1075     else
    1076         errno = -rc;
    1077     LIBCLOG_ERROR_RETURN_INT(rc);
    1078 }
    1079 
    1080 
    1081 /**
    1082  * Get the LIBC handle structure corresponding to a filehandle.
    1083  *
    1084  * @returns Pointer to handle structure on success.
    1085  * @returns NULL on failure.
    1086  * @param   fh  Handle to lookup.
     1119    LIBCLOG_RETURN_VOID();
     1120}
     1121
     1122
     1123/**
     1124 * Import a normal file handle.
     1125 *
     1126 * Caller must own the file handle mutex.
     1127 *
     1128 * @returns 0 on success.
     1129 * @returns Negated errno on failure.
     1130 *
     1131 * @param   hNative The native file handle.
     1132 * @param   fh      The kNIX file handle.
     1133 * @param   ppFH    Where to store the file handle structure. (Must be release with __libc_FHPut().)
     1134 *
    10871135 * @remark  Must own the mutex.
    1088  * @internal
    1089  */
    1090 static __LIBC_PFH fhGet(int fh)
    1091 {
    1092     __LIBC_PFH pFH = NULL;
     1136 */
     1137static int fhImportFile(uintptr_t hNative, int fh, __LIBC_PFH *ppFH)
     1138{
     1139#ifdef __OS2__
     1140    if (hNative != fh)
     1141        return -EINVAL;
    10931142
    10941143    /*
     
    11091158     * Validate file handle range.
    11101159     */
    1111     if (fh >= 0 && fh < gcFHs)
    1112     {
    1113         pFH = gpapFHs[fh];
    1114         if (!pFH)
    1115         {
    1116             /*
    1117              * Try import the handle.
    1118              */
    1119             ULONG       rc;
    1120             ULONG       fulType;
    1121             ULONG       fulDevFlags;
    1122             ULONG       fulMode;
    1123             unsigned    fLibc;
    1124             dev_t       Dev = 0;
    1125 
    1126             /*
    1127              * Is it in use and if so what kind of handle?
    1128              */
    1129             if (    (rc = DosQueryHType((HFILE)fh, &fulType, &fulDevFlags)) != NO_ERROR
    1130                 ||  (rc = DosQueryFHState((HFILE)fh, &fulMode)) != NO_ERROR)
    1131             {
    1132                 errno = EBADF;
    1133                 return NULL;
    1134             }
    1135 
    1136             /*
    1137              * Determin initial flags.
    1138              */
    1139             switch (fulType & 0xff)
    1140             {
    1141                 default: /* paranoia */
    1142                 case HANDTYPE_FILE:
    1143                     fLibc = F_FILE;
    1144                     break;
    1145                 case HANDTYPE_DEVICE:
    1146                     fLibc = F_DEV;
    1147                     /* @todo inherit O_NDELAY */
    1148                     if (!(fulDevFlags & 0xf))
    1149                         Dev = makedev('c', 0);
    1150                     else if (fulDevFlags & 1 /*KBD*/)
    1151                         Dev = makedev('c', 1);
    1152                     else if (fulDevFlags & 2 /*SCR*/)
    1153                         Dev = makedev('c', 2);
    1154                     else if (fulDevFlags & 4 /*NUL*/)
    1155                         Dev = makedev('c', 4);
    1156                     else /*if (fulDevFlags & 8 / *CLK* /)*/
    1157                         Dev = makedev('c', 8);
    1158                     break;
    1159                 case HANDTYPE_PIPE:
    1160                     fLibc = F_PIPE;
    1161                     Dev = makedev('p', 0);
    1162                     break;
    1163             }
    1164 
    1165             /*
    1166              * Read write flags.
    1167              */
    1168             switch (fulMode & (OPEN_ACCESS_READONLY | OPEN_ACCESS_WRITEONLY | OPEN_ACCESS_READWRITE))
    1169             {
    1170                 case OPEN_ACCESS_READONLY:      fLibc |= O_RDONLY; break;
    1171                 case OPEN_ACCESS_WRITEONLY:     fLibc |= O_WRONLY; break;
    1172                 default: /* paranoia */
    1173                 case OPEN_ACCESS_READWRITE:     fLibc |= O_RDWR; break;
    1174             }
    1175 
    1176             /*
    1177              * Inherit flags.
    1178              */
    1179             if (fulMode & OPEN_FLAGS_NOINHERIT)
    1180                 fLibc |= O_NOINHERIT | (FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT);
    1181 
    1182             /*
    1183              * Textflag.
    1184              */
    1185             if (!_fmode_bin)
    1186                 fLibc |= O_TEXT;
    1187 
    1188 
    1189             /*
    1190              * Allocate a new handle for this filehandle.
    1191              */
    1192             rc = fhAllocate(fh, fLibc, sizeof(LIBCFH), NULL, &pFH, NULL, 1);
    1193             if (!rc)
    1194                 pFH->Dev = Dev;
    1195             else
    1196                 pFH = NULL;
     1160    if (fh < 0 && fh >= gcFHs)
     1161        return -EBADF;
     1162
     1163    __LIBC_PFH pFH = gpapFHs[fh];
     1164    if (!pFH)
     1165    {
     1166        /*
     1167         * Try import the handle.
     1168         */
     1169        ULONG       rc;
     1170        ULONG       fulType;
     1171        ULONG       fulDevFlags;
     1172        ULONG       fulMode;
     1173        unsigned    fLibc;
     1174        dev_t       Dev = 0;
     1175
     1176        /*
     1177         * Is it in use and if so what kind of handle?
     1178         */
     1179        if (    (rc = DosQueryHType((HFILE)fh, &fulType, &fulDevFlags)) != NO_ERROR
     1180            ||  (rc = DosQueryFHState((HFILE)fh, &fulMode)) != NO_ERROR)
     1181            return -EBADF;
     1182
     1183        /*
     1184         * Determin initial flags.
     1185         */
     1186        switch (fulType & 0xff)
     1187        {
     1188            default: /* paranoia */
     1189            case HANDTYPE_FILE:
     1190                fLibc = F_FILE;
     1191                break;
     1192            case HANDTYPE_DEVICE:
     1193                fLibc = F_DEV;
     1194                /* @todo inherit O_NDELAY */
     1195                if (!(fulDevFlags & 0xf))
     1196                    Dev = makedev('c', 0);
     1197                else if (fulDevFlags & 1 /*KBD*/)
     1198                    Dev = makedev('c', 1);
     1199                else if (fulDevFlags & 2 /*SCR*/)
     1200                    Dev = makedev('c', 2);
     1201                else if (fulDevFlags & 4 /*NUL*/)
     1202                    Dev = makedev('c', 4);
     1203                else /*if (fulDevFlags & 8 / *CLK* /)*/
     1204                    Dev = makedev('c', 8);
     1205                break;
     1206            case HANDTYPE_PIPE:
     1207                fLibc = F_PIPE;
     1208                Dev = makedev('p', 0);
     1209                break;
    11971210        }
    1198     }
    1199     else /* out of range: can't possibly be open. */
    1200         errno = EBADF;
    1201 
    1202     return pFH;
    1203 }
    1204 
    1205 /**
    1206  * Get the LIBC handle structure corresponding to a filehandle.
    1207  *
    1208  * @returns Pointer to handle structure on success.
    1209  * @returns NULL on failure.
    1210  * @param   fh  Handle to lookup.
    1211  * @deprecated
    1212  */
    1213 __LIBC_PFH __libc_FH(int fh)
    1214 {
    1215     __LIBC_PFH pFH;
    1216 
    1217     /** @todo shared access */
    1218     if (_fmutex_request(&gmtx, 0))
    1219         return NULL;
    1220 
    1221     pFH = fhGet(fh);
     1211
     1212        /*
     1213         * Read write flags.
     1214         */
     1215        switch (fulMode & (OPEN_ACCESS_READONLY | OPEN_ACCESS_WRITEONLY | OPEN_ACCESS_READWRITE))
     1216        {
     1217            case OPEN_ACCESS_READONLY:      fLibc |= O_RDONLY; break;
     1218            case OPEN_ACCESS_WRITEONLY:     fLibc |= O_WRONLY; break;
     1219            default: /* paranoia */
     1220            case OPEN_ACCESS_READWRITE:     fLibc |= O_RDWR; break;
     1221        }
     1222
     1223        /*
     1224         * Inherit flags.
     1225         */
     1226        if (fulMode & OPEN_FLAGS_NOINHERIT)
     1227            fLibc |= O_NOINHERIT | (FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT);
     1228
     1229        /*
     1230         * Textflag.
     1231         */
     1232        if (!_fmode_bin)
     1233            fLibc |= O_TEXT;
     1234
     1235        /*
     1236         * Allocate a new handle for this filehandle.
     1237         */
     1238        rc = fhAllocate(sizeof(__LIBC_FH), &__libc_back_gFileOps, hNative, fh, fLibc, 1, &pFH);
     1239        if (rc)
     1240            return rc;
     1241        pFH->Dev = Dev;
     1242    }
     1243
     1244    *ppFH = pFH;
     1245    return 0;
     1246#else   /* !__OS2__ */
     1247    return -EBADF;
     1248#endif  /* !__OS2__ */
     1249}
     1250
     1251
     1252/**
     1253 * Import a normal file handle.
     1254 *
     1255 * @returns 0 on success.
     1256 * @returns Negated errno on failure.
     1257 *
     1258 * @param   hNative The native file handle.
     1259 * @param   fh      The kNIX file handle.
     1260 * @param   ppFH    Where to store the file handle structure. (Must be release with __libc_FHPut().)
     1261 */
     1262int __libc_FHImportFile(uintptr_t hNative, int fh, __LIBC_PFH *ppFH)
     1263{
     1264    LIBCLOG_ENTER("hNative=%p fh=%d ppFH=%p\n", hNative, fh, ppFH);
     1265    int rc = _fmutex_request(&gmtx, 0);
     1266    if (rc)
     1267        LIBCLOG_ERROR_RETURN_INT(-EDOOFUS);
     1268
     1269    rc = fhImportFile(hNative, fh, ppFH);
    12221270
    12231271    _fmutex_release(&gmtx);
    1224     return pFH;
    1225 }
    1226 
    1227 
    1228 /**
    1229  * Get the LIBC handle structure corresponding to a filehandle.
    1230  *
    1231  * @returns Pointer to handle structure on success.
     1272    if (!rc)
     1273        LIBCLOG_RETURN_MSG(rc, "ret %d *ppFH=%p\n", rc, *ppFH);
     1274    LIBCLOG_ERROR_RETURN_INT(rc);
     1275}
     1276
     1277
     1278/**
     1279 * Get the locked LIBC handle structure corresponding to a file handle.
     1280 *
     1281 * The caller must call __libc_FHPut() or __libc_FHFree() to release the file handler structure.
     1282 *
     1283 * @returns 0 on success and *ppFH pointing to the file handle structure.
    12321284 * @returns Negative error code (errno.h) on failure.
    12331285 * @param   fh      Handle to lookup.
    1234  * @param   ppFH    Where to store the filehandle pointer
    1235  */
    1236 int __libc_FHEx(int fh, __LIBC_PFH *ppFH)
    1237 {
    1238     __LIBC_PFH pFH;
    1239 
    1240     /** @todo shared access */
     1286 * @param   ppFH    Where to store the file handle pointer
     1287 */
     1288int __libc_FHGet(int fh, __LIBC_PFH *ppFH)
     1289{
    12411290    int rc = _fmutex_request(&gmtx, 0);
    12421291    if (rc)
    1243         return -__libc_native2errno(rc);
    1244 
    1245     /** @todo rewrite fhGet() to avoid this errno saving and restoring. */
    1246     int errno_saved = errno;
    1247     pFH = fhGet(fh);
    1248     rc = -errno;
    1249     errno = errno_saved;
     1292        return -EDOOFUS;
     1293
     1294#if CFG_KNIX_FH_NATIVE_ALLOCATION
     1295    /*
     1296     * Someone might have opened this externally after
     1297     * growing the filehandle range.
     1298     */
     1299    if (fh >= gcFHs && fh < 0x10000)
     1300    {
     1301# ifdef __OS2__
     1302        LONG    lDelta = 0;
     1303        ULONG   cCur = 0;
     1304        if (!DosSetRelMaxFH(&lDelta, &cCur))
     1305            cCur = gcFHs;
     1306        if (gcFHs != cCur)
     1307            fhMoreHandles(cCur);
     1308# else  /* !__OS2__ */
     1309        fhMoreHandles(fh + 1);
     1310# endif /* !__OS2__ */
     1311    }
     1312#endif  /* CFG_KNIX_FH_NATIVE_ALLOCATION */
     1313
     1314    /*
     1315     * Look it up in the file handle table.
     1316     * On platforms with native allocation we can try import the handle if we don't find it.
     1317     */
     1318    __LIBC_PFH pFH = NULL;
     1319    if (fh >= 0 && fh < gcFHs)
     1320    {
     1321        pFH = gpapFHs[fh];
     1322#if CFG_KNIX_FH_NATIVE_ALLOCATION
     1323        if (!pFH)
     1324            rc = fhImportFile(fh, fh, &pFH);
     1325#endif
     1326        if (!pFH)
     1327            rc = -EBADF;
     1328    }
     1329    else
     1330        rc = -EBADF;
    12501331
    12511332    _fmutex_release(&gmtx);
     1333    *ppFH = pFH;
     1334    return rc;
     1335}
     1336
     1337
     1338/**
     1339 * Releases a locked LIBC handle structure.
     1340 * The caller obtained the handle using __libc_FHGet() or __libc_FHAllocate().
     1341 *
     1342 * @param   pFH     Pointer to the handle structure. NULL is allowed.
     1343 */
     1344void __libc_FHPut(__LIBC_PFH pFH)
     1345{
    12521346    if (pFH)
    12531347    {
    1254         *ppFH = pFH;
    1255         return 0;
    1256     }
    1257     return rc;
     1348        /* we're not locking anything - yet. */
     1349        (void)pFH;
     1350    }
    12581351}
    12591352
     
    12651358 * the __LIBC_FH structure. It will not call any FH operators, since
    12661359 * it assumes that the caller takes care of such things.
     1360 *
     1361 * The caller must own the FH structure. This function will not call __libc_FHPut() for you.
    12671362 *
    12681363 * @returns 0 on success.
     
    12721367 * @param   fFlags  The new flags.
    12731368 */
    1274 int __libc_FHSetFlags(__LIBC_PFH pFH, int fh, unsigned fFlags)
    1275 {
    1276     LIBCLOG_ENTER("pFH=%p fh=%d fFlags=%#x\n", (void *)pFH, fh, fFlags);
    1277     int     rc;
    1278     ULONG   fulState;
    1279     FS_VAR();
     1369int __libc_FHSetFlags(__LIBC_PFH pFH, unsigned fFlags)
     1370{
     1371    LIBCLOG_ENTER("pFH=%p fFlags=%#x\n", (void *)pFH, fh, fFlags);
     1372
    12801373    LIBC_ASSERT(((fFlags & O_NOINHERIT) != 0) == ((fFlags & (FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT)) != 0));
    1281 
    1282     FS_SAVE_LOAD();
    1283     rc = DosQueryFHState(fh, &fulState);
     1374#if CFG_KNIX_FH_NATIVE_ALLOCATION
     1375# ifdef __OS2__
     1376    FS_VAR_SAVE_LOAD();
     1377    ULONG fulState;
     1378    int rc = DosQueryFHState(fh, &fulState);
    12841379    if (!rc)
    12851380    {
     
    13101405    rc = -__libc_native2errno(rc);
    13111406    LIBCLOG_ERROR_RETURN_INT(rc);
    1312 }
    1313 
    1314 
    1315 
     1407
     1408# else  /* !__OS2__ */
     1409#  error "Port me!"
     1410# endif /* !__OS2__ */
     1411#else   /* !CFG_KNIX_FH_NATIVE_ALLOCATION */
     1412
     1413    /*
     1414     * This API isn't so helpful here. At least not yet.
     1415     * Just make sure the duplicate flags match up and update atomically.
     1416     */
     1417    if (fFlags & (FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT))
     1418        fFlags |= O_NOINHERIT;
     1419    else
     1420        fFlags &= ~O_NOINHERIT;
     1421
     1422    __atomic_xchg(&pFH->fFlags, fFlags);
     1423    LIBCLOG_RETURN_INT(0);
     1424#endif  /* !CFG_KNIX_FH_NATIVE_ALLOCATION*/
     1425}
     1426
     1427
     1428#ifdef __OS2__
    13161429
    13171430#undef  __LIBC_LOG_GROUP
     
    16011714}
    16021715
     1716#endif /* __OS2__ */
     1717
  • trunk/libc/src/kNIX/heap.c

    r2738 r2739  
    1 /* sys/heap.c (emx+gcc) -- Copyright (c) 1996 by Eberhard Mattes */
    2 
    3 #include "libc-alias.h"
    4 #define INCL_DOSERRORS
    5 #define INCL_FSMACROS
    6 #define INCL_EXAPIS
    7 #include <os2emx.h>
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kNIX - sbrk/brk heap.
     5 *
     6 * Copyright (c) 1996 by Eberhard Mattes
     7 * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
     8 *
     9 *
     10 * This file is part of kLIBC.
     11 *
     12 * kLIBC is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU Lesser General Public License as published
     14 * by the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * kLIBC is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU Lesser General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU Lesser General Public License
     23 * along with kLIBC; if not, write to the Free Software
     24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     25 *
     26 */
     27
     28
     29/*******************************************************************************
     30*   Header Files                                                               *
     31*******************************************************************************/
     32#define  __LIBC_LOG_GROUP __LIBC_LOG_GRP_HEAP
     33#include "kNIX.h"
     34#ifdef __OS2__
     35# define INCL_DOSERRORS
     36# define INCL_FSMACROS
     37# define INCL_EXAPIS
     38# include <os2emx.h>
     39#endif
     40#ifdef __NT__
     41# include <klibc/nt/nt.h>
     42#endif
    843#include <errno.h>
    9 #include <sys/uflags.h>
    10 #include <emx/syscalls.h>
    11 #include "syscalls.h"
    12 #define  __LIBC_LOG_GROUP __LIBC_LOG_GRP_HEAP
    13 #include <InnoTekLIBC/logstrict.h>
    14 
    15 
    16 /* Allocate a memory object of SIZE bytes which is not located below
    17    MIN_ADDR.  Return the address of the memory object.  Return 0 on
    18    error. */
    19 
    20 static ULONG alloc_above (ULONG size, ULONG min_addr)
    21 {
    22   ULONG ret;
    23   void *p;
    24   FS_VAR();
    25 
    26   FS_SAVE_LOAD();
    27   if (DosAllocMemEx (&p, size, PAG_READ | PAG_WRITE | OBJ_FORK) != 0)
    28     {
    29       FS_RESTORE();
    30       return 0;
    31     }
    32   if ((ULONG)p > min_addr)
    33     {
    34       FS_RESTORE();
    35       return (ULONG)p;
    36     }
    37 
    38   /* The memory object is located below MIN_ADDR.  Recurse until we
    39      get an appropriate object or until we run out of memory. */
    40 
    41   ret = alloc_above (size, min_addr);
    42 
    43   /* We got a suitable object.  Free the bad one. */
    44 
    45   DosFreeMemEx (p);
    46   FS_RESTORE();
    47   return ret;
    48 }
    49 
    50 
    51 /* Expand the top heap object by INCR bytes.  INCR is a positive
    52    number.  Return the previous break address or 0 (error). */
    53 
    54 ULONG _sys_expand_heap_obj_by (ULONG incr)
    55 {
    56   LIBCLOG_ENTER("incr=%ld\n", incr);
    57   ULONG rc, old_brk, new_brk, addr, size, rest;
    58 
    59   old_brk = _sys_top_heap_obj->brk;
    60   new_brk = old_brk + incr;
    61 
    62   if (new_brk < _sys_top_heap_obj->base || new_brk > _sys_top_heap_obj->end)
    63     LIBCLOG_RETURN_ULONG(0UL);
    64 
    65   addr = old_brk;
    66   size = incr;
    67   if (addr & 0xfff)
    68     {
    69       rest = 0x1000 - (addr & 0xfff);
    70       if (rest >= size)
    71         size = 0;
    72       else
     44#include <klibc/backend.h>
     45#include <klibc/logstrict.h>
     46
     47
     48
     49/**
     50 * Wrapper around the OS api for freeing an object.
     51 */
     52static __inline__ void heapFreeObj(uintptr_t ObjPtr)
     53{
     54#ifdef __OS2__
     55    FS_VAR_SAVE_LOAD();
     56    int rc = DosFreeMemEx((void *)ObjPtr);
     57    LIBC_ASSERTM(!rc, ("ObjPtr=%p rc=%d\n", ObjPtr, rc);
     58    FS_RESTORE();
     59
     60#elif defined(__NT__)
     61    PVOID pv = (void *)ObjPtr;
     62    NTSTATUS rc = NtFreeVirtualMemory(NtCurrentProcess(),   /* ProcessHandle */
     63                                      &pv,                  /* BaseAddress */
     64                                      NULL,                 /* FreeSize */
     65                                      MEM_RELEASE);         /* FreeType */
     66    LIBC_ASSERTM(NT_SUCCESS(rc), "ObjPtr=%p rc=%x\n", ObjPtr, rc);
     67
     68#else
     69# error "Port me!"
     70#endif
     71}
     72
     73
     74/**
     75 * Allocate a memory object of SIZE bytes which is not located below
     76 * MIN_ADDR.
     77 *
     78 * @returns The address of the memory object.
     79 * @returns Return 0 on error.
     80 */
     81static uintptr_t heapAllocObjAbove(uintptr_t size, uintptr_t min_addr)
     82{
     83    void *pv = NULL;
     84#ifdef __OS2__
     85    FS_VAR_SAVE_LOAD();
     86    int rc = DosAllocMemEx(&p, size, PAG_READ | PAG_WRITE | OBJ_FORK);
     87    FS_RESTORE();
     88    if (rc)
     89        return 0;
     90
     91#elif defined(__NT__)
     92    ULONG cb = size;
     93    NTSTATUS rc = NtAllocateVirtualMemory(NtCurrentProcess(),   /* ProcessHandle */
     94                                          &pv,                  /* BaseAddress (In/Out) */
     95                                          0,                    /* ZeroBits */
     96                                          &cb,                  /* AllocationSize */
     97                                          MEM_RESERVE,          /* AllocationType */
     98                                          PAGE_READWRITE);      /* Protect */
     99    if (!NT_SUCCESS(rc))
     100        return 0;
     101
     102#else
     103# error "Port me!"
     104#endif
     105
     106    if ((uintptr_t)pv > min_addr)
     107        return (uintptr_t)pv;
     108
     109    /*
     110     * The memory object is located below MIN_ADDR.  Recurse until we
     111     * get an appropriate object or until we run out of memory.
     112     */
     113    uintptr_t ret = heapAllocObjAbove(size, min_addr);
     114
     115    /* We got a suitable object. Free the bad one. */
     116    heapFreeObj((uintptr_t)pv);
     117    return ret;
     118}
     119
     120
     121/**
     122 * Wrapper around the OS api for committing memory.
     123 */
     124static __inline__ int heapCommitObj(uintptr_t addr, uintptr_t size)
     125{
     126#ifdef __OS2__
     127    FS_VAR_SAVE_LOAD();
     128    rc = DosSetMem((void *)addr, size, PAG_DEFAULT | PAG_COMMIT);
     129    FS_RESTORE();
     130    return !rc ? 0 : -EINVAL;
     131
     132#elif defined(__NT__)
     133    ULONG cb = size;
     134    PVOID pv = (void *)addr;
     135    NTSTATUS rc = NtAllocateVirtualMemory(NtCurrentProcess(),   /* ProcessHandle */
     136                                          &pv,                  /* BaseAddress (In/Out) */
     137                                          0,                    /* ZeroBits */
     138                                          &cb,                  /* AllocationSize */
     139                                          MEM_COMMIT,           /* AllocationType */
     140                                          PAGE_READWRITE);      /* Protect */
     141    return NT_SUCCESS(rc) ? 0 : -EINVAL;
     142
     143#else
     144# error "Port me!"
     145#endif
     146}
     147
     148
     149/**
     150 * Wrapper around the OS api for decommitting memory.
     151 */
     152static __inline__ int heapDecommitObj(uintptr_t addr, uintptr_t size)
     153{
     154#ifdef __OS2__
     155    FS_VAR_SAVE_LOAD();
     156    rc = DosSetMem((void *)addr, size, PAG_DECOMMIT);
     157    FS_RESTORE();
     158    return !rc ? 0 : -EINVAL;
     159
     160#elif defined(__NT__)
     161    ULONG cb = size;
     162    PVOID pv = (void *)addr;
     163    NTSTATUS rc = NtFreeVirtualMemory(NtCurrentProcess(),   /* ProcessHandle */
     164                                      &pv,                  /* BaseAddress */
     165                                      &cb,                  /* FreeSize */
     166                                      MEM_DECOMMIT);        /* FreeType */
     167    return NT_SUCCESS(rc) ? 0 : -EINVAL;
     168
     169#else
     170# error "Port me!"
     171#endif
     172}
     173
     174
     175
     176/**
     177 * Expand the top heap object by INCR bytes. INCR is a positive number.
     178 * Return the previous break address or 0 (error).
     179 */
     180void *__libc_back_heapExpandObjBy(uintptr_t incr)
     181{
     182    LIBCLOG_ENTER("incr=%p\n", (void *)incr);
     183
     184    const uintptr_t old_brk = __libc_back_gpHeapTopObj->brk;
     185    const uintptr_t new_brk = old_brk + incr;
     186    if (    new_brk < __libc_back_gpHeapTopObj->base
     187        ||  new_brk > __libc_back_gpHeapTopObj->end)
     188        LIBCLOG_ERROR_RETURN_P(NULL);
     189
     190    uintptr_t addr = old_brk;
     191    uintptr_t size = incr;
     192    if (addr & 0xfff)
     193    {
     194        uintptr_t rest = 0x1000 - (addr & 0xfff);
     195        if (rest >= size)
     196            size = 0;
     197        else
    73198        {
    74           size -= rest;
    75           addr += rest;
     199            size -= rest;
     200            addr += rest;
    76201        }
    77202    }
    78   if (size != 0)
    79     {
    80       FS_VAR();
    81       FS_SAVE_LOAD();
    82       rc = DosSetMem ((void *)addr, size, PAG_DEFAULT | PAG_COMMIT);
    83       FS_RESTORE();
    84       if (rc != 0)
    85         LIBCLOG_RETURN_ULONG(0UL);
    86     }
    87   _sys_top_heap_obj->brk = new_brk;
    88   LIBCLOG_RETURN_ULONG(old_brk);
    89 }
    90 
    91 
    92 /* Shrink the top heap object by DECR bytes.  DECR is a positive
    93    number.  Return the previous break address or 0 (error). */
    94 
    95 ULONG _sys_shrink_heap_obj_by (ULONG decr)
    96 {
    97   LIBCLOG_ENTER("decr=%ld\n", decr);
    98   ULONG rc, old_brk, new_brk, addr, high;
    99 
    100   old_brk = _sys_top_heap_obj->brk;
    101   new_brk = old_brk - decr;
    102 
    103   if (new_brk < _sys_top_heap_obj->base || new_brk > _sys_top_heap_obj->end)
    104     LIBCLOG_RETURN_ULONG(0UL);
    105 
    106   addr = (new_brk + 0xfff) & ~0xfff;
    107   high = (_sys_top_heap_obj->brk + 0xfff) & ~0xfff;
    108   if (high > addr)
    109     {
    110       FS_VAR();
    111       FS_SAVE_LOAD();
    112       rc = DosSetMem ((void *)addr, high - addr, PAG_DECOMMIT);
    113       FS_RESTORE();
    114       if (rc != 0)
    115         LIBCLOG_RETURN_ULONG(0UL);
    116     }
    117   _sys_top_heap_obj->brk = new_brk;
    118   LIBCLOG_RETURN_ULONG(old_brk);
    119 }
    120 
    121 
    122 /* Expand the heap by INCR bytes.  INCR is a positive number.  Return
    123    the base address of the expansion or 0 (error). */
    124 
    125 ULONG _sys_expand_heap_by (ULONG incr, ULONG sbrk_model)
    126 {
    127   LIBCLOG_ENTER("incr=%ld sbrk_model=%ld\n", incr, sbrk_model);
    128   unsigned old_obj_count;
    129   ULONG base, size;
    130 
    131   old_obj_count = _sys_heap_obj_count;
    132 
    133   /* Allocate the first object if not yet done. */
    134 
    135   if (_sys_heap_obj_count == 0)
    136     {
    137       size = _sys_heap_size;
    138       if (incr > size)
    139         size = (incr + 0xffff) & ~0xffff;
    140       base = alloc_above (size, 0);
    141       if (base == 0)
     203    if (size != 0)
     204    {
     205        if (heapCommitObj(addr, size) != 0)
     206            LIBCLOG_ERROR_RETURN_P(NULL);
     207    }
     208    __libc_back_gpHeapTopObj->brk = new_brk;
     209    LIBCLOG_RETURN_P((void *)old_brk);
     210}
     211
     212
     213/**
     214 * Shrink the top heap object by DECR bytes. DECR is a positive number.
     215 * Return the previous break address or 0 (error).
     216 */
     217void *__libc_back_heapShrinkObjBy(uintptr_t decr)
     218{
     219    LIBCLOG_ENTER("decr=%p\n", (void *)decr);
     220
     221    const uintptr_t old_brk = __libc_back_gpHeapTopObj->brk;
     222    const uintptr_t new_brk = old_brk - decr;
     223    if (    new_brk < __libc_back_gpHeapTopObj->base
     224        ||  new_brk > __libc_back_gpHeapTopObj->end)
     225        LIBCLOG_ERROR_RETURN_P(NULL);
     226
     227    const uintptr_t addr = (new_brk + 0xfff) & ~(uintptr_t)0xfff;
     228    const uintptr_t high = (__libc_back_gpHeapTopObj->brk + 0xfff) & ~(uintptr_t)0xfff;
     229    if (high > addr)
     230    {
     231        if (heapDecommitObj(addr, high - addr) != 0)
     232            LIBCLOG_ERROR_RETURN_P(NULL);
     233    }
     234    __libc_back_gpHeapTopObj->brk = new_brk;
     235    LIBCLOG_RETURN_P((void *)old_brk);
     236}
     237
     238
     239/**
     240 * Expand the heap by INCR bytes. INCR is a positive number.
     241 * Return the base address of the expansion or 0 (error).
     242 */
     243void *__libc_back_heapExpandBy(uintptr_t incr, __LIBCSBRKMODEL enmSBrkModel)
     244{
     245    LIBCLOG_ENTER("incr=%p enmSBrkModel=%d\n", incr, enmSBrkModel);
     246    const unsigned old_obj_count = __libc_back_gcHeapObjs;
     247
     248    /*
     249     *Allocate the first object if not yet done.
     250     */
     251    if (__libc_back_gcHeapObjs == 0)
     252    {
     253        uintptr_t size = __libc_back_gcbHeap;
     254        if (incr > size)
     255            size = (incr + 0xffff) & ~(uintptr_t)0xffff;
     256        uintptr_t base = heapAllocObjAbove(size, 0);
     257        if (base == 0)
     258            LIBCLOG_ERROR_RETURN_P(NULL);
     259        __libc_back_gaHeapObjs[0].base = base;
     260        __libc_back_gaHeapObjs[0].brk = base;
     261        __libc_back_gaHeapObjs[0].end = base + size;
     262        __libc_back_gcHeapObjs = 1;
     263        __libc_back_gpHeapTopObj = &__libc_back_gaHeapObjs[0];
     264    }
     265
     266    /*
     267     * Now we have at least one heap object. Check for arithmetic
     268     * overflow.
     269     */
     270    if (__libc_back_gpHeapTopObj->brk + incr < __libc_back_gpHeapTopObj->base)
     271    {
     272        /*
     273         * Overflow. If we've just allocated the first heap object,
     274         * deallocate it again unless memory must be allocated contiguously.
     275         */
     276        if (    old_obj_count == 0
     277            &&  enmSBrkModel != __LIBC_SBRK_MODEL_CONTIGUOUS)
     278        {
     279            heapFreeObj(__libc_back_gaHeapObjs[0].base);
     280            __libc_back_gcHeapObjs = 0;
     281            __libc_back_gpHeapTopObj = NULL;
     282        }
     283        LIBCLOG_ERROR_RETURN_P(NULL);
     284    }
     285
     286    /*
     287     * Check whether we need another heap object. Allocate one if we
     288     * need one and are allowed to allocate one. This should not happen
     289     * if we just allocated the first one above.
     290     */
     291    if (__libc_back_gpHeapTopObj->brk + incr > __libc_back_gpHeapTopObj->end)
     292    {
     293        /*
     294         * We need another heap object. Fail if we are not allowed to
     295         * allocate non-contiguous memory or if we already have the
     296         * maximum number of heap objects.
     297         */
     298        if (    enmSBrkModel == __LIBC_SBRK_MODEL_CONTIGUOUS
     299            ||  __libc_back_gcHeapObjs >= CFG_KNIX_MAX_HEAP_OBJS)
     300            LIBCLOG_ERROR_RETURN_P(NULL);
     301
     302        /*
     303         * Allocate at least __libc_back_gcbHeap bytes. The new object must
     304         * be located above the currently top one.
     305         */
     306        uintptr_t size = __libc_back_gcbHeap;
     307        if (incr > size)
     308            size = (incr + 0xffff) & ~(uintptr_t)0xffff;
     309
     310        uintptr_t base;
     311        for (;;)
     312        {
     313            if (enmSBrkModel == __LIBC_SBRK_MODEL_ARBITRARY)
     314                base = heapAllocObjAbove(size, 0);
     315            else
     316                base = heapAllocObjAbove(size, __libc_back_gpHeapTopObj->end);
     317            if (base != 0)
     318                break;
     319
     320            /*
     321             * If we're out of virtual address space, halve the size and
     322             * try again until allocation succeeds. Of course, don't
     323             * attempt to allocate less than INCR bytes.
     324             */
     325            size /= 2;
     326            if (size < incr)
     327                LIBCLOG_ERROR_RETURN_P(NULL);
     328        }
     329
     330        __libc_back_gpHeapTopObj = &__libc_back_gaHeapObjs[__libc_back_gcHeapObjs++];
     331        __libc_back_gpHeapTopObj->base = base;
     332        __libc_back_gpHeapTopObj->brk = base;
     333        __libc_back_gpHeapTopObj->end = base + size;
     334    }
     335
     336    /*
     337     * Now __libc_back_gpHeapTopObj points to an object which has enough
     338     * space. Commit memory as required.  _sys_expand_heap_obj() returns
     339     * the top object's break address, which is the base address of the
     340     * expansion as an object might have been added.
     341     */
     342    void *pRet = __libc_back_heapExpandObjBy(incr);
     343    if (pRet)
     344        LIBCLOG_RETURN_P(pRet);
     345    LIBCLOG_ERROR_RETURN_P(pRet);
     346}
     347
     348
     349/**
     350 * Shrink the heap to the new break address NEW_BRK.
     351 * Return the previous break address or 0 (error).
     352 */
     353void *__libc_back_heapShrinkTo(uintptr_t new_brk)
     354{
     355    LIBCLOG_ENTER("new_brk=%ld\n", new_brk);
     356
     357    /*
     358     * Find the heap object containing the new break address.  Fail if
     359     * there is no such heap object.  Note that the new break address
     360     * must not be beyond the heap object current break address, that
     361     * is, we cannot shrink the heap (by deallocating objects) and grow
     362     * a heap object in one step.
     363     */
     364    unsigned iObj;
     365    for (iObj = 0; iObj < __libc_back_gcHeapObjs; ++iObj)
     366        if (    __libc_back_gaHeapObjs[iObj].base <= new_brk
     367            &&  __libc_back_gaHeapObjs[iObj].brk >= new_brk)
     368            break;
     369    if (iObj >= __libc_back_gcHeapObjs)
    142370        return 0;
    143       _sys_heap_objs[0].base = base;
    144       _sys_heap_objs[0].brk = base;
    145       _sys_heap_objs[0].end = base + size;
    146       _sys_heap_obj_count = 1;
    147       _sys_top_heap_obj = &_sys_heap_objs[0];
    148     }
    149 
    150   /* Now we have at least one heap object.  Check for arithmetic
    151      overflow. */
    152 
    153   if (_sys_top_heap_obj->brk + incr < _sys_top_heap_obj->base)
    154     {
    155       /* Overflow.  If we've just allocated the first heap object,
    156          deallocate it again unless memory must be allocated
    157          contiguously. */
    158 
    159       if (old_obj_count == 0 && sbrk_model != _UF_SBRK_CONTIGUOUS)
     371
     372    /* We have at least one heap object, OBJ, so this is safe. */
     373    void * const pvOldBrk = (void *)__libc_back_gpHeapTopObj->brk;
     374
     375    /*
     376     * Free objects which are between the new break address and the old
     377     * one. Fail if there are such objects and __LIBC_SBRK_MODEL_CONTIGUOUS is
     378     * selected.
     379     */
     380    if (iObj != __libc_back_gcHeapObjs - 1)
     381    {
     382        if (__libc_back_genmSBrkModel == __LIBC_SBRK_MODEL_CONTIGUOUS)
     383            LIBCLOG_ERROR_RETURN_P(NULL);
     384
     385        while (__libc_back_gcHeapObjs - 1 > iObj)
    160386        {
    161           FS_VAR();
    162           FS_SAVE_LOAD();
    163           DosFreeMemEx ((void *)_sys_heap_objs[0].base);
    164           FS_RESTORE();
    165           _sys_heap_obj_count = 0;
    166           _sys_top_heap_obj = NULL;
     387            __libc_back_gcHeapObjs -= 1;
     388            heapFreeObj(__libc_back_gaHeapObjs[__libc_back_gcHeapObjs].base);
     389            __libc_back_gaHeapObjs[__libc_back_gcHeapObjs].base = 0;
    167390        }
    168       LIBCLOG_RETURN_ULONG(0UL);  /* Failure */
    169     }
    170 
    171   /* Check whether we need another heap object.  Allocate one if we
    172      need one and are allowed to allocate one.  This should not happen
    173      if we just allocated the first one above. */
    174 
    175   if (_sys_top_heap_obj->brk + incr > _sys_top_heap_obj->end)
    176     {
    177       /* We need another heap object.  Fail if we are not allowed to
    178          allocate non-contiguous memory or if we already have the
    179          maximum number of heap objects. */
    180 
    181       if (sbrk_model == _UF_SBRK_CONTIGUOUS
    182           || _sys_heap_obj_count >= MAX_HEAP_OBJS)
    183         LIBCLOG_RETURN_ULONG(0UL);
    184 
    185       /* Allocate at least _sys_heap_size bytes.  The new object must
    186          be located above the currently top one. */
    187 
    188       size = _sys_heap_size;
    189       if (incr > size)
    190         size = (incr + 0xffff) & ~0xffff;
    191 
    192       for (;;)
     391        __libc_back_gpHeapTopObj = &__libc_back_gaHeapObjs[__libc_back_gcHeapObjs-1];
     392    }
     393
     394    if (new_brk == __libc_back_gpHeapTopObj->base)
     395    {
     396        /*
     397         * The top object is shrunk to zero bytes, deallocate it and bump NEW_BRK back
     398         * to the previous object. If __LIBC_SBRK_MODEL_CONTIGUOUS is selected and
     399         * the (only) object is shrunk to 0 bytes, it will be kept anyway to avoid
     400         * breaking programs which depend on the object keeping its address:
     401         *
     402         *      p = sbrk(1000);
     403         *      sbrk(-1000);
     404         *      assert(sbrk(1000) == p);
     405         *
     406         * The assertion should not fail. However, programs which select
     407         * __LIBC_SBRK_MODEL_MONOTONOUS or __LIBC_SBRK_MODEL_ARBITRARY should be
     408         * prepared for failure of the assertion. Consider the following code:
     409         *
     410         *      sbrk(1000);
     411         *      p = sbrk(0);
     412         *      sbrk(-1000);
     413         *      brk(p);
     414         *
     415         * Here, brk() may fail due to deallocation of the top object.
     416         */
     417        if (    iObj != 0
     418            ||  __libc_back_genmSBrkModel != __LIBC_SBRK_MODEL_CONTIGUOUS)
    193419        {
    194           if (sbrk_model == _UF_SBRK_ARBITRARY)
    195             base = alloc_above (size, 0);
    196           else
    197             base = alloc_above (size, _sys_top_heap_obj->end);
    198           if (base != 0)
    199             break;
    200 
    201           /* If we're out of virtual address space, halve the size and
    202              try again until allocation succeeds.  Of course, don't
    203              attempt to allocate less than INCR bytes. */
    204 
    205           size /= 2;
    206           if (size < incr)
    207             LIBCLOG_RETURN_ULONG(0UL);
    208         }
    209 
    210       _sys_top_heap_obj = &_sys_heap_objs[_sys_heap_obj_count++];
    211       _sys_top_heap_obj->base = base;
    212       _sys_top_heap_obj->brk = base;
    213       _sys_top_heap_obj->end = base + size;
    214     }
    215 
    216   /* Now _sys_top_heap_obj points to an object which has enough space.
    217      Commit memory as required.  _sys_expand_heap_obj() returns the
    218      top object's break address, which is the base address of the
    219      expansion as an object might have been added. */
    220 
    221   base = _sys_expand_heap_obj_by (incr);
    222   LIBCLOG_RETURN_ULONG(base);
    223 }
    224 
    225 
    226 /* Shrink the heap to the new break address NEW_BRK.  Return the
    227    previous break address or 0 (error). */
    228 
    229 ULONG _sys_shrink_heap_to (ULONG new_brk)
    230 {
    231   LIBCLOG_ENTER("new_brk=%ld\n", new_brk);
    232   unsigned obj;
    233   ULONG old_brk;
    234 
    235   /* Find the heap object containing the new break address.  Fail if
    236      there is no such heap object.  Note that the new break address
    237      must not be beyond the heap object current break address, that
    238      is, we cannot shrink the heap (by deallocating objects) and grow
    239      a heap object in one step. */
    240 
    241   for (obj = 0; obj < _sys_heap_obj_count; ++obj)
    242     if (_sys_heap_objs[obj].base <= new_brk
    243         && _sys_heap_objs[obj].brk >= new_brk)
    244       break;
    245 
    246   if (obj >= _sys_heap_obj_count)
    247     return 0;
    248 
    249   /* We have at least one heap object, OBJ, so this is safe. */
    250 
    251   old_brk = _sys_top_heap_obj->brk;
    252 
    253   /* Free objects which are between the new break address and the old
    254      one.  Fail if there are such objects and _UF_SBRK_CONTIGUOUS is
    255      selected. */
    256 
    257   if (obj != _sys_heap_obj_count - 1)
    258     {
    259       if ((_sys_uflags & _UF_SBRK_MODEL) == _UF_SBRK_CONTIGUOUS)
    260         LIBCLOG_RETURN_ULONG(0UL);
    261       while (_sys_heap_obj_count - 1 > obj)
    262         {
    263           FS_VAR();
    264           _sys_heap_obj_count -= 1;
    265           FS_SAVE_LOAD();
    266           DosFreeMemEx ((void *)_sys_heap_objs[_sys_heap_obj_count].base);
    267           FS_RESTORE();
    268           _sys_heap_objs[_sys_heap_obj_count].base = 0;
    269         }
    270       _sys_top_heap_obj = &_sys_heap_objs[_sys_heap_obj_count-1];
    271     }
    272 
    273   if (new_brk == _sys_top_heap_obj->base)
    274     {
    275       /* The top object is shrunk to zero bytes, deallocate it and
    276          bump NEW_BRK back to the previous object.  If
    277          _UF_SBRK_CONTIGUOUS is selected and the (only) object is
    278          shrunk to 0 bytes, it will be kept anyway to avoid breaking
    279          programs which depend on the object keeping its address:
    280 
    281             p = sbrk (1000);
    282             sbrk (-1000);
    283             assert (sbrk (1000) == p);
    284 
    285          The assertion should not fail.  However, programs which
    286          select _UF_SBRK_MONOTONOUS or _UF_SBRK_ARBITRARY should be
    287          prepared for failure of the assertion.  Consider the
    288          following code:
    289 
    290             sbrk (1000);
    291             p = sbrk (0);
    292             sbrk (-1000);
    293             brk (p);
    294 
    295          Here, brk() may fail due to deallocation of the top
    296          object. */
    297 
    298       if (obj != 0 || (_sys_uflags & _UF_SBRK_MODEL) != _UF_SBRK_CONTIGUOUS)
    299         {
    300           FS_VAR();
    301           _sys_heap_obj_count -= 1;
    302           FS_SAVE_LOAD();
    303           DosFreeMemEx ((void *)_sys_heap_objs[_sys_heap_obj_count].base);
    304           FS_RESTORE();
    305           _sys_heap_objs[_sys_heap_obj_count].base = 0;
    306 
    307           if (_sys_heap_obj_count == 0)
    308             _sys_top_heap_obj = NULL;
    309           else
     420            __libc_back_gcHeapObjs -= 1;
     421            heapFreeObj(__libc_back_gaHeapObjs[__libc_back_gcHeapObjs].base);
     422            __libc_back_gaHeapObjs[__libc_back_gcHeapObjs].base = 0;
     423
     424            if (__libc_back_gcHeapObjs == 0)
     425                __libc_back_gpHeapTopObj = NULL;
     426            else
    310427            {
    311               _sys_top_heap_obj = &_sys_heap_objs[_sys_heap_obj_count-1];
    312               new_brk = _sys_top_heap_obj->brk;
     428                __libc_back_gpHeapTopObj = &__libc_back_gaHeapObjs[__libc_back_gcHeapObjs-1];
     429                new_brk = __libc_back_gpHeapTopObj->brk;
    313430            }
    314431        }
    315432    }
    316433
    317   /* Now decommit unused pages of the top heap object, if there is
    318      one. */
    319 
    320   if (_sys_heap_obj_count > 0
    321       && _sys_shrink_heap_obj_by (_sys_top_heap_obj->brk - new_brk) == 0)
    322       LIBCLOG_RETURN_ULONG(0UL);
    323   LIBCLOG_RETURN_ULONG(old_brk);
    324 }
    325 
    326 
    327 /* Shrink the heap by DECR bytes.  DECR is a positive number.  Return
    328    the previous break address or 0 (error). */
    329 
    330 ULONG _sys_shrink_heap_by (ULONG decr, ULONG sbrk_model)
    331 {
    332   LIBCLOG_ENTER("decr=%ld sbrk_model=%ld\n", decr, sbrk_model);
    333   ULONG ulRet;
    334   if (_sys_heap_obj_count == 0)
    335     LIBCLOG_RETURN_ULONG(0UL);
    336   if (_sys_top_heap_obj->brk - decr < _sys_top_heap_obj->base)
    337     LIBCLOG_RETURN_ULONG(0UL);
    338   ulRet = _sys_shrink_heap_to (_sys_top_heap_obj->brk - decr);
    339   LIBCLOG_RETURN_ULONG(ulRet);
    340 }
     434    /*
     435     * Now decommit unused pages of the top heap object, if there is one.
     436     */
     437    if (    __libc_back_gcHeapObjs > 0
     438        &&  __libc_back_heapShrinkObjBy(__libc_back_gpHeapTopObj->brk - new_brk) == 0)
     439        LIBCLOG_RETURN_P(NULL);
     440    LIBCLOG_RETURN_P(pvOldBrk);
     441}
     442
     443
     444/**
     445 * Shrink the heap by DECR bytes. DECR is a positive number.
     446 * Return the previous break address or 0 (error).
     447 */
     448void *__libc_back_heapShrinkBy(uintptr_t decr, __LIBCSBRKMODEL enmSBrkModel)
     449{
     450    LIBCLOG_ENTER("decr=%ld enmSBrkModel=%d\n", decr, enmSBrkModel);
     451    if (    __libc_back_gcHeapObjs != 0
     452        &&  __libc_back_gpHeapTopObj->brk - decr >= __libc_back_gpHeapTopObj->base)
     453    {
     454        void *pvRet = __libc_back_heapShrinkTo(__libc_back_gpHeapTopObj->brk - decr);
     455        LIBCLOG_RETURN_P(pvRet);
     456    }
     457    LIBCLOG_RETURN_P(NULL);
     458}
     459
  • trunk/libc/src/kNIX/heapdump.c

    r2738 r2739  
    11/* sys/heapdump.c (emx+gcc) -- Copyright (c) 1996 by Eberhard Mattes */
    22
    3 #include "libc-alias.h"
    4 #include "syscalls.h"
     3#include "kNIX.h"
    54#include <stdio.h>
    65
     
    1211
    1312  fprintf (f, "base     brk      end\n");
    14   for (i = 0; i < _sys_heap_obj_count; ++i)
     13  for (i = 0; i < __libc_back_gcHeapObjs; ++i)
    1514    fprintf (f, "%.8lx %.8lx %.8lx%s\n",
    16              _sys_heap_objs[i].base,
    17              _sys_heap_objs[i].brk,
    18              _sys_heap_objs[i].end,
    19              _sys_top_heap_obj == &_sys_heap_objs[i] ? " top" : "");
     15             __libc_back_gaHeapObjs[i].base,
     16             __libc_back_gaHeapObjs[i].brk,
     17             __libc_back_gaHeapObjs[i].end,
     18             __libc_back_gpHeapTopObj == &__libc_back_gaHeapObjs[i] ? " top" : "");
    2019}
     20
  • trunk/libc/src/kNIX/nt/Makefile.kmk

    r2732 r2739  
    1 # $Id: $
    2 ## @file
    3 #
    4 # kBuild Sub-Makefile for kLIBC - src/libc/sys.
    5 #
    6 # Copyright (c) 2006 knut st. osmundsen <bird@anduin.net>
    7 #
    8 #
    9 # This file is part of kLIBC.
    10 #
    11 # kLIBC is free software; you can redistribute it and/or modify
    12 # it under the terms of the GNU General Public License as published by
    13 # the Free Software Foundation; either version 2 of the License, or
    14 # (at your option) any later version.
    15 #
    16 # kLIBC is distributed in the hope that it will be useful,
    17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    19 # GNU General Public License for more details.
    20 #
    21 # You should have received a copy of the GNU General Public License
    22 # along with kLIBC; if not, write to the Free Software
    23 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 #
    25 #
     1# Forward to the parent makefile.
     2DEPTH = ../../../..
     3include $(PATH_KBUILD)/up.kmk
    264
    27 # include common stuff.
    28 DEPTH ?= ../../..
    29 SUB_DEPTH = ../..
    30 include $(PATH_KBUILD)/subheader.kmk
    31 ifeq ($(filter-out win32 win64,$(BUILD_TARGET)),)
    32 
    33 LIBRARIES += kNIX.nt
    34 
    35 kNIX.nt_TEMPLATE = libcsub
    36 kNIX.nt_SOURCES = \
    37     $(PATH_LIBC_SRC)/kNIX.nt/b_panic.c \
    38 
    39 kNIX.nt_SOURCES_later = \
    40     $(PATH_LIBC_SRC)/kNIX.nt/brk.c \
    41     $(PATH_LIBC_SRC)/kNIX.nt/b_dir.c \
    42     $(PATH_LIBC_SRC)/kNIX.nt/b_fsDirChangeRoot.c \
    43     $(PATH_LIBC_SRC)/kNIX.nt/b_fsDirCreate.c \
    44     $(PATH_LIBC_SRC)/kNIX.nt/b_fsDirCurrentGet.c \
    45     $(PATH_LIBC_SRC)/kNIX.nt/b_fsDirCurrentSet.c \
    46     $(PATH_LIBC_SRC)/kNIX.nt/b_fsDirCurrentSetFH.c \
    47     $(PATH_LIBC_SRC)/kNIX.nt/b_fsDirRemove.c \
    48     $(PATH_LIBC_SRC)/kNIX.nt/b_fsDriveDefaultGet.c \
    49     $(PATH_LIBC_SRC)/kNIX.nt/b_fsDriveDefaultSet.c \
    50     $(PATH_LIBC_SRC)/kNIX.nt/b_fsFileModeSet.c \
    51     $(PATH_LIBC_SRC)/kNIX.nt/b_fsFileModeSetFH.c \
    52     $(PATH_LIBC_SRC)/kNIX.nt/b_fsFileStat.c \
    53     $(PATH_LIBC_SRC)/kNIX.nt/b_fsFileStatFH.c \
    54     $(PATH_LIBC_SRC)/kNIX.nt/b_fsFileTimesSet.c \
    55     $(PATH_LIBC_SRC)/kNIX.nt/b_fsFileTimesSetFH.c \
    56     $(PATH_LIBC_SRC)/kNIX.nt/b_fsNativeFileModeSet.c \
    57     $(PATH_LIBC_SRC)/kNIX.nt/b_fsNativeFileStat.c \
    58     $(PATH_LIBC_SRC)/kNIX.nt/b_fsNativeFileTimesSet.c \
    59     $(PATH_LIBC_SRC)/kNIX.nt/b_fsPathResolve.c \
    60     $(PATH_LIBC_SRC)/kNIX.nt/b_fsRename.c \
    61     $(PATH_LIBC_SRC)/kNIX.nt/b_fsStat.c \
    62     $(PATH_LIBC_SRC)/kNIX.nt/b_fsSymlinkCreate.c \
    63     $(PATH_LIBC_SRC)/kNIX.nt/b_fsSymlinkModeSet.c \
    64     $(PATH_LIBC_SRC)/kNIX.nt/b_fsSymlinkRead.c \
    65     $(PATH_LIBC_SRC)/kNIX.nt/b_fsSymlinkStat.c \
    66     $(PATH_LIBC_SRC)/kNIX.nt/b_fsSymlinkTimesSet.c \
    67     $(PATH_LIBC_SRC)/kNIX.nt/b_fsSync.c \
    68     $(PATH_LIBC_SRC)/kNIX.nt/b_fsUnlink.c \
    69     $(PATH_LIBC_SRC)/kNIX.nt/b_ioDirGetEntries.c \
    70     $(PATH_LIBC_SRC)/kNIX.nt/b_ioFHToPath.c \
    71     $(PATH_LIBC_SRC)/kNIX.nt/b_ioFileControl.c \
    72     $(PATH_LIBC_SRC)/kNIX.nt/b_ioFileOpen.c \
    73     $(PATH_LIBC_SRC)/kNIX.nt/b_ioFileSizeSet.c \
    74     $(PATH_LIBC_SRC)/kNIX.nt/b_ioSeek.c \
    75     $(PATH_LIBC_SRC)/kNIX.nt/b_ldrClose.c \
    76     $(PATH_LIBC_SRC)/kNIX.nt/b_ldrOpen.c \
    77     $(PATH_LIBC_SRC)/kNIX.nt/b_ldrSymbol.c \
    78     $(PATH_LIBC_SRC)/kNIX.nt/b_miscLoadAvg.c \
    79     $(PATH_LIBC_SRC)/kNIX.nt/b_mmanProtect.c \
    80     $(PATH_LIBC_SRC)/kNIX.nt/b_nativeSymlinkCreate.c \
    81     $(PATH_LIBC_SRC)/kNIX.nt/b_processCredentials.c \
    82     $(PATH_LIBC_SRC)/kNIX.nt/b_processGetPriority.c \
    83     $(PATH_LIBC_SRC)/kNIX.nt/b_processSetPriority.c \
    84     $(PATH_LIBC_SRC)/kNIX.nt/b_processWait.c \
    85     $(PATH_LIBC_SRC)/kNIX.nt/b_signalInterrupt.c \
    86     $(PATH_LIBC_SRC)/kNIX.nt/b_signalMask.c \
    87     $(PATH_LIBC_SRC)/kNIX.nt/b_signalPending.c \
    88     $(PATH_LIBC_SRC)/kNIX.nt/b_signalQueue.c \
    89     $(PATH_LIBC_SRC)/kNIX.nt/b_signalSendPid.c \
    90     $(PATH_LIBC_SRC)/kNIX.nt/b_signalStack.c \
    91     $(PATH_LIBC_SRC)/kNIX.nt/b_signalSuspend.c \
    92     $(PATH_LIBC_SRC)/kNIX.nt/b_signalTimer.c \
    93     $(PATH_LIBC_SRC)/kNIX.nt/b_signalWait.c \
    94     $(PATH_LIBC_SRC)/kNIX.nt/b_threadCleanup.c \
    95     $(PATH_LIBC_SRC)/kNIX.nt/b_threadEnd.c \
    96     $(PATH_LIBC_SRC)/kNIX.nt/b_threadInit.c \
    97     $(PATH_LIBC_SRC)/kNIX.nt/b_threadSleep.c \
    98     $(PATH_LIBC_SRC)/kNIX.nt/b_threadStartup.c \
    99     $(PATH_LIBC_SRC)/kNIX.nt/b_time.c \
    100     $(PATH_LIBC_SRC)/kNIX.nt/b_timeHighResNano.c \
    101 
    102 #kNIX.nt_SOURCES.x86 = \
    103 #    $(PATH_LIBC_SRC)/kNIX.nt/386/__init_environ.s \
    104 
    105 #$(PATH_LIBC_SRC)/kNIX.nt/heapsize.c_DEFS = HEAPSIZE=0x2000000
    106 
    107 # configure the variants. */
    108 $(call LIBC_CONFIG_VARIANT_LIBS,kNIX.nt)
    109 
    110 
    111 endif # BUILD_TARGET == win32 || win64
    112 # generate rules
    113 include $(PATH_KBUILD)/subfooter.kmk
    114 
  • trunk/libc/src/kNIX/os2/__close.c

    r2732 r2739  
    1 /* sys/close.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes
    2                          -- Copyright (c) 2003 by Knut St. Osmunden */
     1/* dead */
    32
    4 #include "libc-alias.h"
    5 #include <emx/io.h>
    6 #include <emx/syscalls.h>
    7 
    8 int __close(int fh)
    9 {
    10     if (!__libc_FHClose(fh))
    11         return -0;
    12     return -1;
    13 }
  • trunk/libc/src/kNIX/os2/__dup.c

    r2732 r2739  
    5757        {
    5858            PLIBCFH pFHNew;
    59             rc = __libc_FHAllocate(hNew, pFH->fFlags, sizeof(LIBCFH), NULL, &pFHNew, NULL);
     59            rc = __libc_FHAllocate(sizeof(__LIBC_FH), &__libc_back_gFileOps, hNew, hNew, pFH->fFlags, &pFHNew);
    6060            if (!rc)
    6161            {
     
    7373                 */
    7474                pFHNew->fFlags &= ~((FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT) | O_NOINHERIT);
    75                 LIBC_ASSERT(!__libc_FHSetFlags(pFHNew, hNew, pFHNew->fFlags));
     75                LIBC_ASSERT(!__libc_FHSetFlags(pFHNew, pFHNew->fFlags));
     76                __libc_FHPut(pFHNew);
    7677            }
    7778            else
  • trunk/libc/src/kNIX/os2/__dup2.c

    r2732 r2739  
    6262    if (rc)
    6363    {
    64         _sys_set_errno(rc);
     64        _sys_set_errno(-rc);
    6565        return -1;
    6666    }
     
    7171     */
    7272    pFHNew = __libc_FH(fhNew);
    73     if (pFHNew && pFHNew->pOps)
     73    if (    pFHNew
     74        &&  pFHNew->pOps != &__libc_back_gFileOps)
    7475    {
    7576        rc = __libc_FHClose(fhNew);
     
    9091        if (!rc)
    9192        {
    92             PLIBCFH pFHNew;
    93             rc = __libc_FHAllocate(hNew, pFH->fFlags, sizeof(LIBCFH), NULL, &pFHNew, NULL);
     93            __LIBC_PFH pFHNew;
     94            rc = __libc_FHAllocate(sizeof(__LIBC_FH), &__libc_back_gFileOps, hNew, hNew, pFH->fFlags, &pFHNew);
    9495            if (!rc)
    9596            {
     
    107108                 */
    108109                pFHNew->fFlags &= ~((FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT) | O_NOINHERIT);
    109                 LIBC_ASSERT(!__libc_FHSetFlags(pFHNew, hNew, pFHNew->fFlags));
     110                LIBC_ASSERT(!__libc_FHSetFlags(pFHNew, pFHNew->fFlags));
    110111            }
    111112            else
  • trunk/libc/src/kNIX/os2/__initdll.c

    r2732 r2739  
    151151     * Initialize the heap semaphores.
    152152     */
    153     if (_fmutex_create2(&_sys_heap_fmutex, 0, "LIBC SYS Heap Mutex") != 0)
    154         return -1;
    155     if (_fmutex_create2(&_sys_gmtxHimem,   0, "LIBC SYS Highmem Mutex") != 0)
     153    if (_fmutex_create2(&__libc_back_gmtxHeap, 0, "LIBC SYS Heap Mutex") != 0)
     154        return -1;
     155    if (_fmutex_create2(&__libc_back_gmtxHighHeap,   0, "LIBC SYS Highmem Mutex") != 0)
    156156        return -1;
    157157    if (_fmutex_create2(&__libc_gmtxExec,  0, "LIBC SYS Exec Mutex") != 0)
  • trunk/libc/src/kNIX/os2/__pipe.c

    r2732 r2739  
    3939         * Register the handle.
    4040         */
    41         rc = __libc_FHAllocate((HFILE)two_handles[0], F_PIPE | O_RDONLY, sizeof(LIBCFH), NULL, ppFHRead, NULL);
     41        rc = __libc_FHAllocate(sizeof(__LIBC_FH), &__libc_back_gFileOps, (HFILE)two_handles[0], (HFILE)two_handles[0], F_PIPE | O_RDONLY, ppFHRead);
    4242        if (!rc)
    43             rc = __libc_FHAllocate((HFILE)two_handles[1], F_PIPE | O_WRONLY, sizeof(LIBCFH), NULL, ppFHWrite, NULL);
     43            rc = __libc_FHAllocate(sizeof(__LIBC_FH), &__libc_back_gFileOps, (HFILE)two_handles[1], (HFILE)two_handles[0], F_PIPE | O_WRONLY, ppFHWrite);
    4444        if (rc)
    4545        {
  • trunk/libc/src/kNIX/os2/__ulimit.c

    r2732 r2739  
    1414      /* Note: As this is the limit for brk(), not for sbrk(), we
    1515         don't return 512M. */
    16       return _sys_top_heap_obj != NULL ? _sys_top_heap_obj->end : 0;
     16      return __libc_back_gpHeapTopObj != NULL ? __libc_back_gpHeapTopObj->end : 0;
    1717
    1818    case UL_OBJREST:
    19       return (_sys_top_heap_obj != NULL
    20               ? _sys_top_heap_obj->end - _sys_top_heap_obj->brk : 0);
     19      return (__libc_back_gpHeapTopObj != NULL
     20              ? __libc_back_gpHeapTopObj->end - __libc_back_gpHeapTopObj->brk : 0);
    2121
    2222    default:
  • trunk/libc/src/kNIX/os2/b_dir.c

    r2732 r2739  
    392392            {
    393393                __LIBC_PFH pFH;
    394                 rc = __libc_FHAllocate(*pfh, fLibc, sizeof(__LIBC_FHDIR), &gDirOps, &pFH, pfh);
     394                rc = __libc_FHAllocate(sizeof(__LIBC_FHDIR), &gDirOps, Tmp.hDir, *pfh, fLibc, &pFH);
    395395                if (!rc)
    396396                {
  • trunk/libc/src/kNIX/os2/b_ioFileControl.c

    r2732 r2739  
    5656/**
    5757 * File Control.
    58  * 
     58 *
    5959 * Deals with file descriptor flags, file descriptor duplication and locking.
    60  * 
     60 *
    6161 * @returns 0 on success and *piRet set.
    6262 * @returns Negated errno on failure and *piRet set to -1.
     
    108108/**
    109109 * File Control operation - OS/2 standard handle.
    110  * 
     110 *
    111111 * @returns 0 on success.
    112112 * @returns OS/2 error code or negated errno on failure.
    113  * 
     113 *
    114114 * @param   pFH         Pointer to the handle structure to operate on.
    115115 * @param   fh          It's associated filehandle.
     
    144144            unsigned fFlags = pFH->fFlags & ~__LIBC_FH_SETFL_MASK;
    145145            fFlags |= ((int)iArg & __LIBC_FH_SETFL_MASK);
    146             int rc = __libc_FHSetFlags(pFH, fh, fFlags);
     146            int rc = __libc_FHSetFlags(pFH, fFlags);
    147147            LIBCLOG_MIX0_RETURN_INT(rc);
    148148        }
     
    255255     * Update the flags.
    256256     */
    257     int rc = __libc_FHSetFlags(pFH, fh, fFlags);
     257    int rc = __libc_FHSetFlags(pFH, fFlags);
    258258    LIBCLOG_MIX0_RETURN_INT(rc);
    259259}
     
    262262/**
    263263 * Handle locking requests.
    264  * 
     264 *
    265265 * @returns 0 on success.
    266266 * @returns OS/2 error code or negated errno on failure.
     
    273273    LIBCLOG_ENTER("fh=%d iRequest=%d pFlock=%p\n", fh, iRequest, (void *)pFlock);
    274274
    275     /* 
     275    /*
    276276     * Check input.
    277277     */
     
    282282        LIBCLOG_ERROR_RETURN_INT(-EINVAL);
    283283
    284     /* 
    285      * Check fh & get filesize. 
     284    /*
     285     * Check fh & get filesize.
    286286     */
    287287    union
     
    371371            FS_RESTORE();
    372372        }
    373         /* 
     373        /*
    374374         * There is/was a bug in the large API which make it fail on non JFS
    375          * disks with ERROR_INVALID_PARAMETER. We need to work around this. 
     375         * disks with ERROR_INVALID_PARAMETER. We need to work around this.
    376376         */
    377377        if (rc == ERROR_INVALID_PARAMETER)
  • trunk/libc/src/kNIX/os2/b_ioFileOpen.c

    r2732 r2739  
    372372             */
    373373            __LIBC_PFH pFH;
    374             rc = __libc_FHAllocate(hFile, fLibc, sizeof(LIBCFH), NULL, &pFH, NULL);
     374            rc = __libc_FHAllocate(sizeof(__LIBC_FH), &__libc_back_gFileOps, hFile, hFile, fLibc, &pFH);
    375375            if (__predict_true(!rc))
    376376            {
     
    380380                pFH->pszNativePath  = _hstrdup(szNativePath);
    381381
     382                LIBCLOG_MSG("pFH=%p hFile=%#lx fLibc=%#x fulType=%#lx ulAction=%lu Dev=%#x Inode=%#llx\n",
     383                            (void *)pFH, hFile, fLibc, fulType, ulAction, Dev, Inode);
    382384                if (ppFH)
    383385                    *ppFH = pFH;
     386                else
     387                    __libc_FHPut(pFH);
    384388                FS_RESTORE();
    385                 LIBCLOG_MSG("pFH=%p hFile=%#lx fLibc=%#x fulType=%#lx ulAction=%lu Dev=%#x Inode=%#llx\n",
    386                             (void *)pFH, hFile, fLibc, fulType, ulAction, Dev, Inode);
    387389            }
    388390        }
  • trunk/libc/src/kNIX/os2/brk.c

    r2732 r2739  
    1414  ULONG base;
    1515
    16   if (_fmutex_request (&_sys_heap_fmutex, _FMR_IGNINT) != 0)
     16  if (_fmutex_request (&__libc_back_gmtxHeap, _FMR_IGNINT) != 0)
    1717    return -1;
    1818
    19   if (_sys_heap_obj_count == 0)
     19  if (__libc_back_gcHeapObjs == 0)
    2020    base = 0;
    21   else if ((ULONG)brkp >= _sys_top_heap_obj->brk
    22            && (ULONG)brkp <= _sys_top_heap_obj->end)
    23     base = _sys_expand_heap_obj_by ((ULONG)brkp - _sys_top_heap_obj->brk);
    24   else if ((ULONG)brkp >= _sys_top_heap_obj->base
    25            && (ULONG)brkp < _sys_top_heap_obj->brk)
    26     base = _sys_shrink_heap_obj_by (_sys_top_heap_obj->brk - (ULONG)brkp);
     21  else if ((ULONG)brkp >= __libc_back_gpHeapTopObj->brk
     22           && (ULONG)brkp <= __libc_back_gpHeapTopObj->end)
     23    base = __libc_back_heapExpandObjBy ((ULONG)brkp - __libc_back_gpHeapTopObj->brk);
     24  else if ((ULONG)brkp >= __libc_back_gpHeapTopObj->base
     25           && (ULONG)brkp < __libc_back_gpHeapTopObj->brk)
     26    base = __libc_back_heapShrinkObjBy (__libc_back_gpHeapTopObj->brk - (ULONG)brkp);
    2727  else
    28     base = _sys_shrink_heap_to ((ULONG)brkp);
     28    base = __libc_back_heapShrinkTo ((ULONG)brkp);
    2929
    30   if (_fmutex_release (&_sys_heap_fmutex) != 0)
     30  if (_fmutex_release (&__libc_back_gmtxHeap) != 0)
    3131    return -1;
    3232
  • trunk/libc/src/kNIX/os2/heaphigh.c

    r2732 r2739  
    139139     * Take semaphore.
    140140     */
    141     if (_fmutex_request(&_sys_gmtxHimem, _FMR_IGNINT))
     141    if (_fmutex_request(&__libc_back_gmtxHighHeap, _FMR_IGNINT))
    142142        LIBCLOG_RETURN_P(NULL);
    143143
     
    182182    {
    183183        LIBC_ASSERTM_FAILED("Failed to allocate more chunks. rc=%d\n", rc);
    184         _fmutex_release(&_sys_gmtxHimem);
     184        _fmutex_release(&__libc_back_gmtxHighHeap);
    185185        LIBCLOG_ERROR_RETURN_P(NULL);
    186186    }
     
    191191        LIBC_ASSERTM_FAILED("DosSetMem(%p, 0x1000,) -> rc=%d\n", pv, rc);
    192192        DosFreeMemEx(pv);
    193         _fmutex_release(&_sys_gmtxHimem);
     193        _fmutex_release(&__libc_back_gmtxHighHeap);
    194194        LIBCLOG_ERROR_RETURN_P(NULL);
    195195    }
     
    280280        {
    281281            himemFreeChunk(pChunk);
    282             _fmutex_release(&_sys_gmtxHimem);
     282            _fmutex_release(&__libc_back_gmtxHighHeap);
    283283        }
    284284    }
     
    288288         * Check if we have a chunk we can expand to satisfy the request.
    289289         */
    290         if (_fmutex_request(&_sys_gmtxHimem, _FMR_IGNINT))
     290        if (_fmutex_request(&__libc_back_gmtxHighHeap, _FMR_IGNINT))
    291291            LIBCLOG_RETURN_P(NULL);
    292292        cbCommit = *pcb;
     
    325325                    pChunk->cbUncommitted -= cbCommit;
    326326                    gpHimemHint = pChunk->cbUncommitted ? pChunk : gpHimemHead;
    327                     _fmutex_release(&_sys_gmtxHimem);
     327                    _fmutex_release(&__libc_back_gmtxHighHeap);
    328328
    329329                    /* return pv and commit size. The heap takes care of joining
     
    338338
    339339        /* Out of luck, allocate a new chunk. */
    340         _fmutex_release(&_sys_gmtxHimem);
     340        _fmutex_release(&__libc_back_gmtxHighHeap);
    341341    }
    342342
     
    391391
    392392            /* release and return. */
    393             _fmutex_release(&_sys_gmtxHimem);
     393            _fmutex_release(&__libc_back_gmtxHighHeap);
    394394            *pcb = cbCommit;
    395395            *pfClean = _BLOCK_CLEAN;
     
    428428     * Take semaphore.
    429429     */
    430     if (_fmutex_request(&_sys_gmtxHimem, _FMR_IGNINT) != 0)
     430    if (_fmutex_request(&__libc_back_gmtxHighHeap, _FMR_IGNINT) != 0)
    431431        return;
    432432
     
    458458                    LIBC_ASSERTM_FAILED("Bad high heap release!! pv=%p cb=%#x off=%#x offEnd=%#x; chunk pv=%p cb=%#x cbUncomitted=%#x\n",
    459459                                        pv, cb, off, offEnd, pChunk->pv, pChunk->cb, pChunk->cbUncommitted);
    460                     _fmutex_release(&_sys_gmtxHimem);
     460                    _fmutex_release(&__libc_back_gmtxHighHeap);
    461461                    LIBCLOG_ERROR_RETURN_VOID();
    462462                }
     
    479479
    480480                    /* we're done. */
    481                     _fmutex_release(&_sys_gmtxHimem);
     481                    _fmutex_release(&__libc_back_gmtxHighHeap);
    482482                    LIBCLOG_RETURN_VOID();
    483483                }
     
    509509    } while (cb && pChunk);
    510510
    511     _fmutex_release(&_sys_gmtxHimem);
     511    _fmutex_release(&__libc_back_gmtxHighHeap);
    512512    LIBCLOG_RETURN_VOID();
    513513}
  • trunk/libc/src/kNIX/os2/sbrk.c

    r2732 r2739  
    1 /* sys/sbrk.c (emx+gcc) -- Copyright (c) 1992-1996 by Eberhard Mattes */
    2 
    3 #include "libc-alias.h"
    4 #include <os2emx.h>
    5 #include <errno.h>
    6 #include <sys/builtin.h>
    7 #include <sys/fmutex.h>
    8 #include <sys/uflags.h>
    9 #include <sys/types.h>
    10 #include <stdlib.h>
    11 #include <emx/syscalls.h>
    12 #include "syscalls.h"
    13 
    14 void *_STD(sbrk) (intptr_t incr)
    15 {
    16   ULONG base;
    17 
    18   if (_fmutex_request (&_sys_heap_fmutex, _FMR_IGNINT) != 0)
    19     return (void *)-1;
    20 
    21   if (incr >= 0)
    22     base = _sys_expand_heap_by (incr, _sys_uflags & _UF_SBRK_MODEL);
    23   else
    24     base = _sys_shrink_heap_by (-incr, _sys_uflags & _UF_SBRK_MODEL);
    25 
    26   if (_fmutex_release (&_sys_heap_fmutex) != 0)
    27     return (void *)-1;
    28 
    29   if (base == 0)
    30     {
    31       errno = ENOMEM;
    32       return (void *)-1;
    33     }
    34   return (void *)base;
    35 }
     1/* dead */
  • trunk/libc/src/kNIX/os2/syscalls.h

    r2732 r2739  
    3838/* Maximum number of heap objects (16 = 512 / 32). */
    3939
    40 #define MAX_HEAP_OBJS   16
    41 
    42 /* This structure describes one heap object. */
    43 
    44 struct heap_obj
    45 {
    46   ULONG base;                   /* Base address */
    47   ULONG end;                    /* End address */
    48   ULONG brk;                    /* Address of first unused byte */
    49 };
     40#define CFG_KNIX_MAX_HEAP_OBJS   16
    5041
    5142EXTERN unsigned _sys_uflags INIT (0);
     
    6556EXTERN unsigned long    _sys_gcbVirtualAddressLimit;
    6657
    67 /* The top heap object.  This points into _sys_heap_objs[] or is NULL.
    68    While this variable is NULL, no memory has been allocated. */
    69 
    70 EXTERN struct heap_obj *_sys_top_heap_obj;
    71 
    72 /* This array holds information on all the heap objects.  The heap
    73    objects are managed in LIFO fashion. */
    74 
    75 EXTERN struct heap_obj  _sys_heap_objs[MAX_HEAP_OBJS];
    76 
    77 /* This is the number of heap objects. */
    78 
    79 EXTERN unsigned         _sys_heap_obj_count;
    80 
    81 /* This variable can be initialized by the application to control the
    82    size of the heap object(s). */
    83 
    84 extern unsigned         _sys_heap_size;
    8558
    8659
     
    9770
    9871void _sys_get_clock (unsigned long *ms);
    99 
    100 /** @group Heap stuff.
    101  * @{ */
    102 ULONG _sys_expand_heap_obj_by (ULONG incr);
    103 ULONG _sys_expand_heap_by (ULONG incr, ULONG sbrk_model);
    104 ULONG _sys_shrink_heap_to (ULONG new_brk);
    105 ULONG _sys_shrink_heap_by (ULONG decr, ULONG sbrk_model);
    106 ULONG _sys_shrink_heap_obj_by (ULONG decr);
    107 #ifdef _SYS_FMUTEX_H
    108 /** This mutex semaphore protects the heap. */
    109 EXTERN _fmutex          _sys_heap_fmutex;
    110 /** Mutex semaphore protecting the list of high memory big blocks. */
    111 EXTERN _fmutex          _sys_gmtxHimem;
    112 #endif
    113 /** @} */
    114 
    11572
    11673/** @group Init Functions
  • trunk/libc/src/kNIX/os2/tcpipver.c

    r2732 r2739  
    423423                {
    424424                    rc = __libc_Back_ioFileControlStandard(pFH, fh, iRequest, iArg, prc);
    425                     if (rc) 
     425                    if (rc)
    426426                    {
    427427                        /* undo change on failure. */
     
    501501                else
    502502                    fFlags &= ~O_NONBLOCK;
    503                 rc = __libc_FHSetFlags(pFH, fh, fFlags);
     503                rc = __libc_FHSetFlags(pFH, fFlags);
    504504            }
    505505            break;
     
    854854    LIBCLOG_ENTER("iSocket=%d\n", iSocket);
    855855    PLIBCFH         pFHLibc;
    856     int rc = __libc_FHAllocate(fh, fFlags, sizeof(LIBCSOCKETFH), &gSocketOps, &pFHLibc, pfh);
     856    int rc = __libc_FHAllocate(sizeof(LIBCSOCKETFH), &gSocketOps, iSocket, fh, fFlags, &pFHLibc);
    857857    if (!rc)
    858858    {
     859        if (pfh)
     860            *pfh = pFHLibc->fh;
     861
    859862        /*
    860863         * Init the handle.
    861864         */
    862         PLIBCSOCKETFH   pFH = (PLIBCSOCKETFH)pFHLibc;
     865        PLIBCSOCKETFH pFH = (PLIBCSOCKETFH)pFHLibc;
    863866        pFH->iSocket = iSocket;
    864867
     
    892895        if (ppFHSocket)
    893896            *ppFHSocket = pFH;
     897        else
     898            __libc_FHPut(pFHLibc);
    894899        LIBCLOG_RETURN_INT(0);
    895900    }
  • trunk/libc/src/libc/app/stdio.c

    r2672 r2739  
    22                     -- Copyright (c) 2003-2004 by knut st. osmundsen */
    33
     4#define __LIBC_LOG_GROUP  __LIBC_LOG_GRP_STREAM
    45#include "libc-alias.h"
    5 #include <sys/builtin.h>        /* For <sys/fmutex.h> */
    66#include <sys/fmutex.h>
    77#include <stdio.h>
    88#include <string.h>
    99#include <stdlib.h>
    10 #include <emx/io.h>
     10#include <unistd.h>
     11#include <klibc/io.h>
     12#include <klibc/backend.h>
     13#include <klibc/logstrict.h>
    1114#include <emx/startup.h>
    12 #include <emx/syscalls.h>
    13 #define __LIBC_LOG_GROUP  __LIBC_LOG_GRP_STREAM
    14 #include <InnoTekLIBC/logstrict.h>
    1515
    1616
     
    9191    for (i = 0; i < 3; i++)
    9292    {
    93         PLIBCFH pFH = __libc_FH(i);
    94         if (!pFH)
     93        __LIBC_PFH pFH;
     94        int rc = __libc_FHGet(i, &pFH);
     95        if (rc)
     96        {
    9597            LIBCLOG_MSG("No open file for %d\n", i);
     98            pFH = NULL;
     99        }
    96100
    97101        /*
     
    137141                break;
    138142        }
     143        __libc_FHPut(pFH);
    139144    } /* for standard handles. */
    140145    LIBCLOG_RETURN_VOID();
     
    169174{
    170175    static const char szMsg[] = "\r\nLIBC fatal error - streams: ";
    171     __write(2, szMsg, sizeof(szMsg) - 1);
    172     __write(2, pszMsg, strlen(pszMsg));
     176    size_t cbWritten;
     177    __libc_Back_ioWrite(STDERR_FILENO, szMsg, sizeof(szMsg) - 1, &cbWritten);
     178    __libc_Back_ioWrite(STDERR_FILENO, pszMsg, strlen(pszMsg), &cbWritten);
    173179    if (f->__uVersion != _FILE_STDIO_VERSION)
    174180    {
    175181        static const char szMsg2[] = " (stream version mismatch (too))";
    176         __write(2, szMsg2, sizeof(szMsg2) - 1);
     182        __libc_Back_ioWrite(STDERR_FILENO, szMsg2, sizeof(szMsg2) - 1, &cbWritten);
    177183    }
    178     __write(2, "\r\n", 2);
     184    __libc_Back_ioWrite(STDERR_FILENO, "\r\n", 2, &cbWritten);
    179185    abort();
    180186    return 0;
  • trunk/libc/src/libc/io/_fbuf.c

    r1454 r2739  
    55#include <stdio.h>
    66#include <stdlib.h>
    7 #include <emx/io.h>
     7#include <klibc/io.h>
    88#include <emx/umalloc.h>
    99
     
    1616  else
    1717    {
    18       PLIBCFH   pFH = __libc_FH(stream->_handle);
    19       if (pFH && (   (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_DEV
    20                   || (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_SOCKET))
     18      unsigned fFlags = __libc_FHGetFlags(stream->_handle);
     19      if (    fFlags
     20          &&  (   (fFlags & __LIBC_FH_TYPEMASK) == F_DEV
     21               || (fFlags & __LIBC_FH_TYPEMASK) == F_SOCKET))
    2122        stream->_buffer = _lmalloc(BUFSIZ);
    2223      else
  • trunk/libc/src/libc/io/_flushst.c

    r871 r2739  
    66#include <fcntl.h>
    77#include <errno.h>
    8 #include <emx/io.h>
     8#include <klibc/io.h>
    99
    1010int _flushstream (FILE *stream, int c)
     
    4949          else                  /* New or flushed buffer */
    5050            {
    51               PLIBCFH   pFH = __libc_FH(fh);
    5251              w = 0;
    53               if (pFH && (pFH->fFlags & O_APPEND))
     52              if (__libc_FHGetFlags(fh) & O_APPEND)
    5453                lseek (fh, 0, SEEK_END);
    5554            }
  • trunk/libc/src/libc/io/_isterm.c

    r1454 r2739  
    44#include <io.h>
    55#include <errno.h>
    6 #include <emx/io.h>
    7 #include <emx/syscalls.h>
     6#include <klibc/io.h>
    87
    98int _isterm(int handle)
    109{
    11     PLIBCFH pFH;
     10    /** @todo this needs attention, it's now identical to isatty(). I'm not entirely sure if that's the idea... */
     11    /*
     12     * Get filehandle and inspect the flags.
     13     */
     14    __LIBC_PFH pFH;
     15    int rc = __libc_FHGet(handle, &pFH);
     16    if (!rc)
     17    {
     18        /*
     19         * If it's a device we assume it is a terminal...
     20         * (Hope that's correct interpretation of the __ioctl1() call...)
     21         */
     22        rc = (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_DEV;
     23        __libc_FHPut(pFH);
     24    }
     25    else
     26    {
     27        errno = -rc;
     28        rc = 0;
     29    }
     30    return rc;
     31}
    1232
    13     /*
    14      * Get filehandle.
    15      */
    16     pFH = __libc_FH(handle);
    17     if (!pFH)
    18     {
    19         errno = EBADF;
    20         return 0;
    21     }
    22 
    23     /*
    24      * Is it a atty?
    25      */
    26     if (!isatty(handle))
    27         return 0;
    28 
    29     /*
    30      * If it's a device we assume is a terminal...
    31      * (Hope that's correct interpretation of the __ioctl1() call...)
    32      */
    33     return (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_DEV;
    34 }
  • trunk/libc/src/libc/io/_output.c

    r2160 r2739  
    373373  char buf[9];
    374374
    375   _ltoa (n, buf, 16);
     375  ltoa (n, buf, 16);
    376376  return cvt_hex (v, buf, x, n == 0);
    377377}
     
    382382  char buf[17];
    383383
    384   _ulltoa (n, buf, 16);
     384  ulltoa (n, buf, 16);
    385385  return cvt_hex (v, buf, x, n == 0);
    386386}
     
    405405  char buf[12];
    406406
    407   _ltoa (n, buf, 8);
     407  ltoa (n, buf, 8);
    408408  return cvt_oct (v, buf, n == 0);
    409409}
     
    414414  char buf[23];
    415415
    416   _ulltoa (n, buf, 8);
     416  ulltoa (n, buf, 8);
    417417  return cvt_oct (v, buf, n == 0);
    418418}
     
    423423  char buf[11];
    424424
    425   _ultoa (n, buf, 10);
     425  ultoa (n, buf, 10);
    426426  return cvt_integer (v, NULL, buf, n == 0, is_signed, is_neg);
    427427}
     
    433433  char buf[21];
    434434
    435   _ulltoa (n, buf, 10);
     435  ulltoa (n, buf, 10);
    436436  return cvt_integer (v, NULL, buf, n == 0, is_signed, is_neg);
    437437}
  • trunk/libc/src/libc/io/_vsopen.c

    r2316 r2739  
    100100     */
    101101    int     saved_errno = errno;
    102     PLIBCFH pFH;
     102    __LIBC_PFH pFH;
    103103    int     fd = __libc_Back_ioFileOpen(pszName, fLibc, fShare, cbInitial, Mode, &pFH);
    104104    if (fd == -EACCES && fCtrlZKludge)
     
    140140        {
    141141            char chDummy = 127;
    142             if (    __read(fd, &chDummy, 1) == 1
     142            size_t cbRead;
     143            int rc = __libc_Back_ioRead(fd, &chDummy, 1, &cbRead);
     144            if (    !rc
     145                &&  cbRead == 1
    143146                &&  chDummy == 0x1a)
    144147            {
     
    155158
    156159    /*
    157      * Reopen the file in write-only Mode if Ctrl-Z hack applied.
     160     * Reopen the file in write-only mode if Ctrl-Z hack applied.
    158161     */
    159162    if (fCtrlZKludge)
     
    186189
    187190    errno = saved_errno;
     191    __libc_FHPut(pFH);
    188192    LIBCLOG_RETURN_INT(fd);
    189193}
  • trunk/libc/src/libc/io/close.c

    r871 r2739  
    1 /* close.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes
    2                      -- Copyright (c) 2003 by Knut St. Osmunden */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * kLIBC - close().
     5 *
     6 * Copyright (c) 2006 knut st. osmundsen <bird-srcspam@anduin.net>
     7 *
     8 *
     9 * This file is part of kLIBC.
     10 *
     11 * kLIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * kLIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with kLIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
    326
     27#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_IO
    428#include "libc-alias.h"
     29#include <unistd.h>
    530#include <io.h>
    6 #include <emx/io.h>
     31#include <errno.h>
     32#include <klibc/io.h>
     33#include <klibc/backend.h>
     34#include <klibc/logstrict.h>
    735
     36
     37/**
     38 * Closes the specified handle.
     39 * @returns 0 on success, -1 and errno on failure.
     40 * @param   fh      The file handle to close.
     41 */
    842int _STD(close)(int fh)
    943{
    10     int rc;
    11     rc = __libc_FHClose(fh);
     44    LIBCLOG_ENTER("fh=%d\n", fh);
     45    int rc = __libc_Back_ioClose(fh);
    1246    if (!rc)
    13         return 0;
    14     /* (it sets errno) */
    15     return -1;
     47        LIBCLOG_RETURN_INT(0);
     48    errno = -rc;
     49    LIBCLOG_ERROR_RETURN_INT(-1);
    1650}
     51
  • trunk/libc/src/libc/io/eof.c

    r871 r2739  
    11/* eof.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
    22
     3#define __LIBC_LOG_GROUP  __LIBC_LOG_GRP_IO
    34#include "libc-alias.h"
    45#include <io.h>
    56#include <errno.h>
    6 #include <emx/io.h>
     7#include <klibc/io.h>
     8#include <klibc/logstrict.h>
    79
    8 int _STD(eof) (int handle)
     10int _STD(eof)(int fh)
    911{
    10   PLIBCFH   pFH;
    11   off_t cur, len;
     12    LIBCLOG_ENTER("fh=%d\n", fh);
    1213
    13   /*
    14    * Get filehandle.
    15    */
    16   pFH = __libc_FH(handle);
    17   if (!pFH)
    18   {
    19       errno = EBADF;
    20       return -1;
    21   }
    22   if (pFH->fFlags & F_EOF)          /* Ctrl-Z reached */
    23     return 1;
    24   cur = tell (handle);
    25   if (cur < 0)
    26     return -1;
    27   len = filelength (handle);
    28   if (len < 0)
    29     return -1;
    30   return cur == len;
     14    /*
     15     * Get filehandle.
     16     */
     17    __LIBC_PFH pFH;
     18    int rc = __libc_FHGet(fh, &pFH);
     19    if (rc)
     20    {
     21        errno = -rc;
     22        LIBCLOG_ERROR_RETURN_INT(-1);
     23    }
     24
     25    /*
     26     * Examin the handle state and then compare file position with file length.
     27     */
     28    if (pFH->fFlags & F_EOF)          /* Ctrl-Z reached */
     29        rc = 1;
     30    else
     31    {
     32        off_t cur = tell(fh);
     33        if (cur < 0)
     34            rc = -1;
     35        else
     36        {
     37            off_t len = filelength(fh);
     38            if (len < 0)
     39                rc = -1;
     40            else
     41                rc = cur == len;
     42        }
     43    }
     44    __libc_FHPut(pFH);
     45    LIBCLOG_RETURN_INT(rc);
    3146}
     47
  • trunk/libc/src/libc/io/fchown.c

    r2254 r2739  
    3030*   Header Files                                                               *
    3131*******************************************************************************/
     32#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_IO
    3233#include "libc-alias.h"
    3334#include <unistd.h>
    34 #include <emx/io.h>
    35 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_IO
    36 #include <InnoTekLIBC/logstrict.h>
     35#include <errno.h>
     36#include <klibc/io.h>
     37#include <klibc/logstrict.h>
    3738
    3839
     
    4142 * Change the owner and group over a file.
    4243 *
    43  * This is stub. It only validates the filehandle and returns without changing anything.
     44 * This is a stub. It only validates the filehandle and returns without changing anything.
    4445 *
    4546 * @returns 0 on success.
     
    4950 * @param   group   Group id.
    5051 */
    51 int      _STD(fchown)(int fh, uid_t owner, gid_t group)
     52int _STD(fchown)(int fh, uid_t owner, gid_t group)
    5253{
    5354    LIBCLOG_ENTER("fh=%d owner=%d group=%d\n", fh, owner, group);
    54     __LIBC_PFH  pFH = __libc_FH(fh);
    55     if (pFH)
     55    __LIBC_PFH pFH;
     56    int rc = __libc_FHGet(fh, &pFH);
     57    if (!rc)
     58    {
     59        __libc_FHPut(pFH);
    5660        LIBCLOG_RETURN_INT(0);
     61    }
     62    errno = -rc;
    5763    LIBCLOG_ERROR_RETURN_INT(-1);
    5864}
    5965
    60 
  • trunk/libc/src/libc/io/fseek.c

    r2090 r2739  
    88#include <io.h>
    99#include <errno.h>
    10 #include <emx/io.h>
     10#include <klibc/io.h>
    1111
    1212int _fseek_unlocked (FILE *stream, off_t offset, int origin)
     
    1414  off_t     cur_pos;
    1515  int       fflush_result;
    16   PLIBCFH   pFH;
    1716
    1817  if (!(stream->_flags & _IOOPEN) || origin < 0 || origin > 2
     
    3635    {
    3736      off_t file_pos, end_pos, buf_pos;
    38       int text_mode, n;
     37      int n;
    3938
    4039      file_pos = tell (stream->_handle);
     
    5554          origin = SEEK_SET;
    5655        }
    57       text_mode = (   (pFH = __libc_FH (stream->_handle)) != NULL
    58                    && (pFH->fFlags & F_CRLF));
     56
     57      const unsigned text_mode = __libc_FHGetFlags (stream->_handle) & F_CRLF;
    5958      n = stream->_ptr - stream->_buffer;
    6059      if (text_mode)
     
    193192  return fseeko (stream, (off_t)offset, origin);
    194193}
     194
  • trunk/libc/src/libc/io/ftell.c

    r2090 r2739  
    1010#include <limits.h>
    1111#include <errno.h>
    12 #include <emx/io.h>
     12#include <klibc/io.h>
    1313
    1414off_t _ftello_unlocked (FILE *stream)
    1515{
    1616  off_t     pos;
    17   PLIBCFH   pFH;
    1817
    1918  if (stream->_flags & _IOSPECIAL)
     
    3130          pos += stream->_ptr - stream->_buffer;
    3231          if (!(stream->_flags & _IOSPECIAL)
    33               && (pFH = __libc_FH (stream->_handle)) != NULL
    34               && (pFH->fFlags & O_TEXT))
     32              && (__libc_FHGetFlags (stream->_handle) & O_TEXT))
    3533            {
    3634              const char *p;
     
    5957      if (!(stream->_flags & _IOSPECIAL)
    6058          && stream->_ungetc_count == 0
    61           && (pFH = __libc_FH (stream->_handle)) != NULL
    62           && (pFH->fFlags & F_CRLF))
     59          && (__libc_FHGetFlags (stream->_handle) & F_CRLF))
    6360        {
    6461          const char *p;
  • trunk/libc/src/libc/io/ioctl.c

    r871 r2739  
    99#include <sys/termio.h>
    1010#include <sys/ioctl.h>
    11 #include <emx/io.h>
     11#include <klibc/io.h>
    1212#include <emx/syscalls.h>
    1313
     
    2121{
    2222    va_list     va;
    23     PLIBCFH     pFH;
    24     int         rc, saved_errno, arg, *int_ptr;
     23    int         saved_errno, arg, *int_ptr;
    2524    const struct termio *tp;
    2625
     
    2827     * Get filehandle.
    2928     */
    30     pFH = __libc_FH(handle);
    31     if (!pFH)
     29    __LIBC_PFH pFH;
     30    int rc = __libc_FHGet(handle, &pFH);
     31    if (rc)
    3232    {
    33         errno = EBADF;
     33        errno = -rc;
    3434        return -1;
    3535    }
     
    3939     */
    4040    saved_errno = errno; errno = 0;
    41     va_start (va, request);
     41    va_start(va, request);
    4242    arg = va_arg(va, int);
    43     va_end (va);
     43    va_end(va);
    4444    rc = __ioctl2(handle, request, arg);
    4545
     
    4747     * On success do small touches of our own.
    4848     */
    49     /** @todo fFlags can be handled by the syscall just as well as here..*/
     49    /** @todo fFlags should be handled by the backend! */
    5050    if (rc >= 0 && errno == 0)
    5151    {
     
    9393    if (errno == 0)
    9494        errno = saved_errno;
     95    __libc_FHPut(pFH);
    9596    return rc;
    9697}
  • trunk/libc/src/libc/io/isatty.c

    r1454 r2739  
    55#include <io.h>
    66#include <errno.h>
    7 #include <emx/io.h>
     7#include <klibc/io.h>
    88
    99int _STD(isatty)(int handle)
    1010{
    11     PLIBCFH pFH;
     11    /*
     12     * Get filehandle and inspect the flags.
     13     */
     14    __LIBC_PFH pFH;
     15    int rc = __libc_FHGet(handle, &pFH);
     16    if (!rc)
     17    {
     18        rc = (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_DEV;
     19        __libc_FHPut(pFH);
     20    }
     21    else
     22    {
     23        errno = -rc;
     24        rc = 0;
     25    }
     26    return rc;
     27}
    1228
    13     /*
    14      * Get filehandle.
    15      */
    16     pFH = __libc_FH(handle);
    17     if (!pFH)
    18     {
    19         errno = EBADF;
    20         return 0;
    21     }
    22 
    23     return (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_DEV;
    24 }
  • trunk/libc/src/libc/io/lseek.c

    r1519 r2739  
    44#include <io.h>
    55#include <errno.h>
    6 #include <emx/io.h>
    7 #include <InnoTekLIBC/backend.h>
     6#include <klibc/io.h>
     7#include <klibc/backend.h>
    88
    99off_t _STD(lseek) (int handle, off_t offset, int origin)
    1010{
    11     PLIBCFH pFH;
    12     off_t   n;
    13 
    1411    /*
    1512     * Get filehandle.
    1613     */
    17     pFH = __libc_FH(handle);
    18     if (!pFH)
    19       return -1;
     14    __LIBC_PFH pFH;
     15    int rc = __libc_FHGet(handle, &pFH);
     16    if (rc)
     17    {
     18        errno = -rc;
     19        return -1;
     20    }
    2021
     22    /*
     23     * If we've got a read-ahead byte or Ctrl-Z, adjust SEEK_CUR seeks.
     24     */
    2125    if (    origin == SEEK_CUR
    2226        && (    pFH->iLookAhead >= 0
    2327            || (pFH->fFlags & F_EOF)) )
    2428        --offset;
    25     n = __libc_Back_ioSeek(handle, offset, origin);
     29
     30    /*
     31     * Do the seek.
     32     */
     33    off_t n = __libc_Back_ioSeek(handle, offset, origin);
    2634    if (n >= 0)
    2735    {
    2836        pFH->fFlags &= ~F_EOF;          /* Clear Ctrl-Z flag */
    2937        pFH->iLookAhead = -1;           /* Clear lookahead */
     38        __libc_FHPut(pFH);
    3039        return n;
    3140    }
     
    3342    return -1;
    3443}
     44
  • trunk/libc/src/libc/io/pc_setmode.c

    r2229 r2739  
    66#include <fcntl.h>
    77#include <errno.h>
    8 #include <emx/io.h>
     8#include <klibc/io.h>
    99
    1010int _STD(setmode)(int handle, int mode)
    1111{
    12     PLIBCFH pFH;
    13     int     old_mode;
    14 
    1512    /*
    1613     * Get filehandle.
    1714     */
    18     pFH = __libc_FH(handle);
    19     if (!pFH)
     15    __LIBC_PFH pFH;
     16    int rc = __libc_FHGet(handle, &pFH);
     17    if (rc)
    2018    {
    21         errno = EBADF;
     19        errno = -rc;
    2220        return -1;
    2321    }
     
    2624     * O_BINARY isn't normally stored in the fFlags member.
    2725     */
    28     old_mode = (pFH->fFlags & O_TEXT) ? O_TEXT : O_BINARY;
     26    unsigned old_mode = (pFH->fFlags & O_TEXT) ? O_TEXT : O_BINARY;
    2927    if (mode == O_BINARY)
    3028        pFH->fFlags &= ~O_TEXT;
     
    3230        pFH->fFlags = (pFH->fFlags & ~O_BINARY) | O_TEXT; /* paranoia */
    3331    else
    34     {
     32    {   __libc_FHPut(pFH);
    3533        errno = EINVAL;
    3634        return -1;
    3735    }
     36
     37    __libc_FHPut(pFH);
    3838    return old_mode;
    3939}
  • trunk/libc/src/libc/io/pipe.c

    r871 r2739  
    55#include <fcntl.h>
    66#include <errno.h>
    7 #include <emx/io.h>
     7#include <klibc/io.h>
    88#include <emx/syscalls.h>
    99
     
    1515int _STD(pipe)(int *two_handles)
    1616{
    17     PLIBCFH pFHRead, pFHWrite;
     17    __LIBC_PFH pFHRead, pFHWrite;
    1818
    1919    if (__pipe(two_handles, _pipe_size != 0 ? _pipe_size : 8192, &pFHRead, &pFHWrite) != 0)
     
    2626        pFHWrite->fFlags |= O_TEXT;
    2727    }
     28    __libc_FHPut(pFHRead);
     29    __libc_FHPut(pFHWrite);
    2830
    2931    return 0;
  • trunk/libc/src/libc/io/read.c

    r1454 r2739  
    11/* read.c (emx+gcc) -- Copyright (c) 1990-1999 by Eberhard Mattes */
    22
     3#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_IO
    34#include "libc-alias.h"
    45#include <string.h>
     6#include <signal.h>
    57#include <io.h>
    68#include <fcntl.h>
    79#include <errno.h>
     10#include <limits.h>
    811#include <sys/builtin.h>
    9 #include <emx/io.h>
    10 #include <emx/syscalls.h>
     12#include <klibc/io.h>
     13#include <klibc/backend.h>
     14#include <klibc/logstrict.h>
     15
     16static ssize_t read_lookahead(int fh, void *pvBuf, size_t cbToRead, __LIBC_PFH pFH);
     17
     18
     19/**
     20 * Do post read processing of the buffer to convert \\r\\n -> \\n.
     21 *
     22 * In one odd case, we will read ahead to figure out if a \\r is followed by a \\n or not.
     23 *
     24 * @returns The cbRead value correcte for the conversions.
     25 * @returns -1 and errno = EAGAIN if we cannot read the byte following a \\r (cbRead == 1).
     26 *
     27 * @param   fh          The file handle in question.
     28 * @param   pbDst       The buffer with the data we've just read.
     29 * @param   cbRead      The number of bytes in the buffer.
     30 * @param   pFH         The file handle structure.
     31 */
     32static ssize_t read_text(int fh, char *pbDst, ssize_t cbRead, __LIBC_PFH pFH)
     33{
     34    /* special processing for text mode */
     35    if (    (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_FILE
     36        &&  pbDst[cbRead - 1] == 0x1a
     37        &&  eof(fh))
     38    {
     39        /* remove last Ctrl-Z in text files */
     40        cbRead--;
     41        pFH->fFlags |= F_EOF;
     42        if (cbRead == 0)
     43            return 0;
     44    }
     45    if (__predict_false(cbRead == 1 && pbDst[0] == '\r'))
     46    {
     47        /*
     48         * This is the tricky case as we are not allowed to decrement cbRead by one
     49         * as 0 indicates end of file. We have to use look ahead.
     50         */
     51        char c;
     52        int saved_errno = errno;
     53        ssize_t j = read_lookahead(fh, &c, 1, pFH); /* look ahead */
     54        if (j == -1 && errno == EAGAIN)
     55        {
     56            LIBCLOG_MSG2("fh=%d iLookAhead=\\r\n", fh);
     57            pFH->iLookAhead = '\r';
     58            return -1;
     59        }
     60        if (j == 1)
     61        {
     62            if (c == '\n')                          /* CR/LF ? */
     63            {
     64                pbDst[0] = '\n';                    /* yes -> replace with LF */
     65                pFH->fFlags |= F_CRLF;
     66                LIBCLOG_MSG2("fh=%d looked ahead: '\\n'", fh);
     67            }
     68            else
     69            {
     70                pFH->iLookAhead = (unsigned char)c; /* no -> save the 2nd char */
     71                LIBCLOG_MSG2("fh=%d iLookAhead=%#04x\n", fh, (unsigned char)c);
     72            }
     73        }
     74        else
     75            LIBCLOG_MSG2("fh=%d looked ahead: errno=%d!", errno);
     76        errno = saved_errno;                        /* hide error */
     77    }
     78    else
     79    {
     80        /*
     81         * Translate each CR/LF pair to a newline character. Set F_CRLF if at
     82         * lest one such translation has been  performed. Set the file's
     83         * look-ahead to CR if the buffer ends with CR.
     84         */
     85        size_t cbNewSize;
     86        if (_crlf(pbDst, cbRead, &cbNewSize))
     87        {
     88            /* Buffer ends with CR: Set look ahead and adjust `cbRead' for F_CRLF logic. */
     89            pFH->iLookAhead = '\r';
     90            cbRead--;
     91        }
     92        if (cbNewSize != cbRead)
     93            pFH->fFlags |= F_CRLF;
     94        cbRead = cbNewSize;
     95    }
     96    return cbRead;
     97}
     98
    1199
    12100/* Read NBYTE characters, use lookahead, if available. This is simple
    13101   unless O_NDELAY is in effect. */
    14102
    15 static int read_lookahead (int handle, void *buf, size_t nbyte, PLIBCFH pFH)
     103static ssize_t read_lookahead(int fh, void *pvBuf, size_t cbToRead, __LIBC_PFH pFH)
    16104{
    17   int i, n, la, saved_errno;
    18   char *dst;
     105    int la;
     106    size_t i = 0;
     107    char *pbDst = (char *)pbDst;
     108    if (    cbToRead > 0
     109        &&  (la = __lxchg(&pFH->iLookAhead, -1)) != -1)
     110    {
     111        *pbDst++ = (char)la;
     112        i++;
     113        cbToRead--;
     114    }
    19115
    20   i = 0; dst = buf; saved_errno = errno;
    21   if (nbyte > 0 && (la = __lxchg (&pFH->iLookAhead, -1)) != -1)
    22     {
    23       *dst = (char)la;
    24       ++i; --nbyte;
    25     }
    26   n = __read (handle, dst+i, nbyte);
    27   if (n == -1)
    28     {
    29       if (errno == EAGAIN && i > 0)           /* lookahead and O_NDELAY */
    30         {
    31           errno = saved_errno;                /* hide EAGAIN */
    32           return i;                           /* and be successful */
    33         }
    34       return -1;
    35     }
    36   return i + n;
     116    size_t cbRead;
     117    int rc = __libc_Back_ioRead(fh, pbDst, cbToRead, &cbRead);
     118    if (__predict_true(!rc))
     119        return i + cbRead;
     120
     121    if (rc == -EAGAIN && i > 0)                 /* lookahead and O_NDELAY */
     122        return i;
     123    errno = -rc;
     124    return -1;
    37125}
    38126
    39127
    40 ssize_t _STD(read) (int handle, void *buf, size_t nbyte)
     128ssize_t _STD(read)(int fh, void *pvBuf, size_t cbToRead)
    41129{
    42   int       n;
    43   PLIBCFH   pFH;
    44   size_t    j, k;
    45   char     *dst, c;
     130    LIBCLOG_ENTER("fh=%d pvBuf=%p cbToRead=%zu\n", fh, pvBuf, cbToRead);
    46131
    47   /*
    48    * Get filehandle.
    49    */
    50   pFH = __libc_FH(handle);
    51   if (!pFH)
     132    /*
     133     * Get filehandle.
     134     */
     135    __LIBC_PFH  pFH;
     136    int rc = __libc_FHGet(fh, &pFH);
     137    if (rc)
    52138    {
    53       errno = EBADF;
    54       return -1;
     139        errno = -rc;
     140        LIBCLOG_ERROR_RETURN_INT(-1);
    55141    }
    56142
    57   pFH->fFlags &= ~F_CRLF;           /* No CR/LF pair translated to newline */
    58   if (nbyte > 0 && (pFH->fFlags & F_EOF))
    59     return 0;
    60   dst = buf;
    61   n = read_lookahead (handle, dst, nbyte, pFH);
    62   if (n == -1)
    63     return -1;
    64   if ((pFH->fFlags & O_TEXT) && !(pFH->fFlags & F_TERMIO) && n > 0)
     143    /* No CR/LF pair translated to newline */
     144    pFH->fFlags &= ~F_CRLF;
     145
     146    /*
     147     * End-of-file?
     148     */
     149    if (    cbToRead > 0
     150        &&  (pFH->fFlags & F_EOF))
    65151    {
    66       /* special processing for text mode */
    67       if (  (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_FILE
    68           && dst[n-1] == 0x1a
    69           && eof (handle))
     152        __libc_FHPut(pFH);
     153        LIBCLOG_RETURN_INT(0);
     154    }
     155
     156    /*
     157     * Perform the read.
     158     */
     159    ssize_t cbRead = read_lookahead(fh, pvBuf, cbToRead, pFH);
     160    if (__predict_false(cbRead == -1))
     161    {
     162        __libc_FHPut(pFH);
     163        LIBCLOG_ERROR_RETURN_INT(-1);
     164    }
     165
     166    /*
     167     * Need to do \r\n -> \n translation?
     168     */
     169    if (    (pFH->fFlags & O_TEXT)
     170        &&  !(pFH->fFlags & F_TERMIO)
     171        &&  cbRead > 0)
     172    {
     173        cbRead = read_text(fh, (char *)pvBuf, cbRead, pFH);
     174        if (cbRead < 0)
    70175        {
    71           /* remove last Ctrl-Z in text files */
    72           --n;
    73           pFH->fFlags |= F_EOF;
    74           if (n == 0)
    75             return 0;
    76         }
    77       if (n == 1 && dst[0] == '\r')
    78         {
    79           /* This is the tricky case as we are not allowed to
    80              decrement n by one as 0 indicates end of file. We have to
    81              use look ahead. */
    82 
    83           int saved_errno = errno;
    84           j = read_lookahead (handle, &c, 1, pFH); /* look ahead */
    85           if (j == -1 && errno == EAGAIN)
    86             {
    87               pFH->iLookAhead = '\r';
    88               return -1;
    89             }
    90           errno = saved_errno;                /* hide error */
    91           if (j == 1 && c == '\n')            /* CR/LF ? */
    92             {
    93               dst[0] = '\n';                  /* yes -> replace with LF */
    94               pFH->fFlags |= F_CRLF;
    95             }
    96           else
    97             pFH->iLookAhead = (unsigned char)c; /* no -> save the 2nd char */
    98         }
    99       else
    100         {
    101           /* Translate each CR/LF pair to a newline character.  Set
    102              F_CRLF if at lest one such translation has been
    103              performed.  Set the file's look-ahead to CR if the buffer
    104              ends with CR. */
    105 
    106           if (_crlf (dst, n, &k))
    107             {
    108               /* Buffer ends with CR: Set look ahead and adjust `n'
    109                  for F_CRLF logic. */
    110 
    111               pFH->iLookAhead = '\r';
    112               --n;
    113             }
    114           if (k != n)
    115             pFH->fFlags |= F_CRLF;
    116           n = k;
     176            __libc_FHPut(pFH);
     177            LIBCLOG_ERROR_RETURN_INT(cbRead);
    117178        }
    118179    }
    119   return n;
     180    __libc_FHPut(pFH);
     181    LIBCLOG_RETURN_INT(cbRead);
    120182}
     183
  • trunk/libc/src/libc/io/tell.c

    r1519 r2739  
    44#include <io.h>
    55#include <errno.h>
    6 #include <emx/io.h>
    7 #include <InnoTekLIBC/backend.h>
     6#include <klibc/io.h>
     7#include <klibc/backend.h>
    88
    99off_t _STD(tell)(int handle)
    1010{
    11     PLIBCFH pFH;
    12     off_t   n;
     11    /*
     12     * Get filehandle.
     13     */
     14    __LIBC_PFH pFH;
     15    int rc = __libc_FHGet(handle, &pFH);
     16    if (rc)
     17    {
     18        errno = -rc;
     19        return -1;
     20    }
    1321
    14     pFH = __libc_FH(handle);
    15     if (!pFH)
    16         return -1;
    17     n = __libc_Back_ioSeek(handle, 0L, SEEK_CUR);
     22    off_t n = __libc_Back_ioSeek(handle, 0L, SEEK_CUR);
    1823    if (n >= 0)
    1924    {
    20         if (pFH->iLookAhead >= 0 || (pFH->fFlags & F_EOF))
     25        if (    pFH->iLookAhead >= 0
     26            ||  (pFH->fFlags & F_EOF))
    2127            --n;
     28        __libc_FHPut(pFH);
    2229        return n;
    2330    }
     31    __libc_FHPut(pFH);
    2432    errno = -n;
    2533    return -1;
    2634}
     35
  • trunk/libc/src/libc/io/write.c

    r1519 r2739  
    11/* write.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
    22
     3#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_IO
    34#include "libc-alias.h"
    45#include <string.h>
     
    78#include <fcntl.h>
    89#include <errno.h>
    9 #include <emx/io.h>
    10 #include <emx/syscalls.h>
    11 #include <InnoTekLIBC/backend.h>
     10#include <limits.h>
     11#include <klibc/io.h>
     12#include <klibc/backend.h>
     13#include <klibc/logstrict.h>
    1214
    1315#define CTRL_Z 0x1a
    1416
    15 #define BEGIN do {
    16 #define END   } while (0)
    17 
    18 /* Write the current buffer, for write_text(). */
    19 
    20 #define WRTBUF                                                  \
    21   BEGIN                                                         \
    22     n = __write (handle, buf, buf_cnt);                         \
    23     if (n < 0) return -1;                                       \
    24     out_cnt += n;                                               \
    25     if (n != buf_cnt) goto partial;                             \
    26     buf_cnt = 0; lf_cnt_1 = lf_cnt; buf_pos = i;                \
    27   END
     17/**
     18 * Write the current buffer, for write_text().
     19 */
     20#define WRTBUF                                                      \
     21    do {                                                            \
     22        int rc = __libc_Back_ioWrite (fh, buf, buf_cnt, &n);        \
     23        if (rc < 0)                                                 \
     24        {                                                           \
     25            errno = -rc;                                            \
     26            return -1;                                              \
     27        }                                                           \
     28        out_cnt += n;                                               \
     29        if (n != buf_cnt)                                           \
     30            goto l_partial;                                         \
     31        buf_cnt = 0; lf_cnt_1 = lf_cnt; buf_pos = i;                \
     32    } while (0)
    2833
    2934/* Write to a text-mode file.  Partial writes are possible.  `buf' is
     
    3641   Return -1 on error. */
    3742
    38 static int write_text (int handle, const char *src, size_t nbyte, PLIBCFH pFH)
     43static ssize_t write_text(int fh, const char *src, size_t nbyte, __LIBC_PFH pFH)
    3944{
    40   int out_cnt, lf_cnt, lf_cnt_1, buf_cnt, n;
    41   size_t i, buf_pos;
    42   char buf[2*512];
    43   char splitp;
    44 
    45   out_cnt = lf_cnt = lf_cnt_1 = buf_cnt = 0;
    46   buf_pos = 0; i = 0;
    47   if (pFH->fFlags & F_WRCRPEND)
    48     {
    49       if (*src == '\n')
    50         {
    51           /* Handle the first newline specially: Don't prepend a '\r'
    52              character. */
    53 
    54           buf[buf_cnt++] = src[i++];
    55         }
    56       else
    57         {
    58           /* This is the case where our algorithm fails: The
    59              application does not try to continue writing with a
    60              newline.  There will be an unexpected '\r' left in the
    61              pipe. */
    62 
    63           pFH->fFlags &= ~F_WRCRPEND;
    64         }
    65     }
    66   while (i < nbyte)
    67     {
    68       if (src[i] == '\n')
    69         {
    70           /* Don't split '\r' and '\n' between two __write() calls as
    71              we cannot remove the '\r' from a pipe in case the second
    72              __write() fails. */
    73 
    74          if (buf_cnt >= sizeof (buf) - 1) WRTBUF;
    75           buf[buf_cnt++] = '\r';
    76           ++lf_cnt;
    77         }
    78       if (buf_cnt >= sizeof (buf)) WRTBUF;
    79       buf[buf_cnt++] = src[i++];
    80     }
    81   if (buf_cnt != 0) WRTBUF;
    82   pFH->fFlags &= ~F_WRCRPEND;
    83   return out_cnt - lf_cnt;
    84 
    85 partial:
    86 
    87   /* Not all bytes have been written. */
    88 
    89   if (n == 0)
     45    ssize_t out_cnt, lf_cnt, lf_cnt_1, buf_cnt;
     46    size_t i, buf_pos, n;
     47    char buf[2*512];
     48    char splitp;
     49
     50    out_cnt = lf_cnt = lf_cnt_1 = buf_cnt = 0;
     51    buf_pos = 0; i = 0;
     52    if (pFH->fFlags & F_WRCRPEND)
     53    {
     54        if (*src == '\n')
     55        {
     56            /* Handle the first newline specially: Don't prepend a '\r'
     57               character. */
     58
     59            buf[buf_cnt++] = src[i++];
     60        }
     61        else
     62        {
     63            /* This is the case where our algorithm fails: The
     64               application does not try to continue writing with a
     65               newline.  There will be an unexpected '\r' left in the
     66               pipe. */
     67
     68            pFH->fFlags &= ~F_WRCRPEND;
     69        }
     70    }
     71
     72    while (i < nbyte)
     73    {
     74        if (src[i] == '\n')
     75        {
     76            /* Don't split '\r' and '\n' between two __write() calls as
     77               we cannot remove the '\r' from a pipe in case the second
     78               __write() fails. */
     79
     80            if (buf_cnt >= sizeof(buf) - 1)
     81                WRTBUF;
     82            buf[buf_cnt++] = '\r';
     83            ++lf_cnt;
     84        }
     85        if (buf_cnt >= sizeof(buf))
     86            WRTBUF;
     87        buf[buf_cnt++] = src[i++];
     88    }
     89    if (buf_cnt != 0)
     90        WRTBUF;
     91    pFH->fFlags &= ~F_WRCRPEND;
     92    return out_cnt - lf_cnt;
     93
     94l_partial:
     95
     96    /* Not all bytes have been written. */
     97    LIBCLOG_MSG("Partial read n=%zu out_cnt=%zd lf_cnt1=%zd\n", n, out_cnt, lf_cnt_1);
     98
     99    if (n == 0)
     100        return out_cnt - lf_cnt_1;
     101
     102    /* Adjust the return value for newline conversion: Add to `lf_cnt_1'
     103       the number of '\r' characters written.
     104
     105       If the '\r', but not the '\n', of an expanded newline has been
     106       written, processing depends on the fh type.  For files, we
     107       remove the '\r' by changing the size of the file.  For pipes (and
     108       devices), we exclude the newline from the count and set a flag to
     109       let the next write() omit the '\r' if the first character to be
     110       written is a newline. */
     111
     112    buf_cnt = 0; splitp = 0;
     113    for (i = buf_pos; buf_cnt < n; ++i)
     114    {
     115        /* Check for '\r' in `buf' to fh the case of an initial '\n'
     116           with suppressed '\r'. */
     117
     118        if (src[i] == '\n' && buf[buf_cnt] == '\r')
     119        {
     120            ++buf_cnt;
     121            if (buf_cnt == n)
     122                splitp = 1;
     123            if (buf_cnt <= n)
     124                ++lf_cnt_1;
     125        }
     126        ++buf_cnt;
     127    }
     128
     129    if (splitp)
     130    {
     131        if ((pFH->fFlags & __LIBC_FH_TYPEMASK) != F_FILE)
     132            pFH->fFlags |= F_WRCRPEND;
     133        else
     134        {
     135            off_t pos = __libc_Back_ioSeek(fh, -1, SEEK_CUR);
     136            if (pos >= 0)
     137                __libc_Back_ioFileSizeSet(fh, pos, 0);
     138        }
     139    }
     140    else
     141        pFH->fFlags &= ~F_WRCRPEND;
    90142    return out_cnt - lf_cnt_1;
    91 
    92   /* Adjust the return value for newline conversion: Add to `lf_cnt_1'
    93      the number of '\r' characters written.
    94 
    95      If the '\r', but not the '\n', of an expanded newline has been
    96      written, processing depends on the handle type.  For files, we
    97      remove the '\r' by changing the size of the file.  For pipes (and
    98      devices), we exclude the newline from the count and set a flag to
    99      let the next write() omit the '\r' if the first character to be
    100      written is a newline. */
    101 
    102   buf_cnt = 0; splitp = 0;
    103   for (i = buf_pos; buf_cnt < n; ++i)
    104     {
    105       /* Check for '\r' in `buf' to handle the case of an initial '\n'
    106          with suppressed '\r'. */
    107 
    108       if (src[i] == '\n' && buf[buf_cnt] == '\r')
    109         {
    110           ++buf_cnt;
    111           if (buf_cnt == n)
    112             splitp = 1;
    113           if (buf_cnt <= n)
    114             ++lf_cnt_1;
    115         }
    116       ++buf_cnt;
    117     }
    118 
    119   if (splitp)
    120     {
    121       if ((pFH->fFlags & __LIBC_FH_TYPEMASK) != F_FILE)
    122         pFH->fFlags |= F_WRCRPEND;
    123       else
    124         {
    125           off_t pos = __libc_Back_ioSeek (handle, -1, SEEK_CUR);
    126           if (pos >= 0)
    127             __libc_Back_ioFileSizeSet (handle, pos, 0);
    128         }
    129     }
    130   else
    131     pFH->fFlags &= ~F_WRCRPEND;
    132   return out_cnt - lf_cnt_1;
    133143}
    134144
    135145
    136 int _STD(write) (int handle, const void *buf, size_t nbyte)
     146ssize_t _STD(write)(int fh, const void *pvBuf, size_t cbToWrite)
    137147{
    138   PLIBCFH   pFH;
    139   int       n;
    140   const char *src;
    141 
    142   /*
    143    * Get filehandle
    144    */
    145   pFH = __libc_FH(handle);
    146   if (!pFH)
    147       return -1;
    148 
    149   if ((pFH->fFlags & (__LIBC_FH_TYPEMASK | O_APPEND)) == (O_APPEND | F_FILE))
    150     __libc_Back_ioSeek (handle, 0, SEEK_END);
    151   if (nbyte == 0)                 /* Avoid truncation of file */
    152     return 0;
    153   src = buf;
    154   if (    (pFH->fFlags & O_TEXT)
    155        && (   (pFH->fFlags & F_WRCRPEND)
    156            || memchr (src, '\n', nbyte) != NULL))
    157     n = write_text (handle, src, nbyte, pFH);
    158   else
    159     n = __write (handle, src, nbyte);
    160 
    161   if (n < 0)
    162     {
    163       if (errno == EPIPE)
    164         {
    165           raise (SIGPIPE);
    166           errno = EPIPE;
    167         }
    168       return -1;
    169     }
    170   if (n == 0)
    171     {
    172       /* Ctrl-Z cannot be written to certain devices (printer) unless
    173          they have been switched to binary mode.  Don't return an
    174          error if writing failed due to a Ctrl-Z at the start of the
    175          data to be written. */
    176 
    177       if (   (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_DEV
    178           && *src == CTRL_Z)
    179         return 0;
    180 
    181       /* For devices and pipes with O_NONBLOCK set, set errno to
    182          EAGAIN. */
    183 
    184       if (   (pFH->fFlags & O_NONBLOCK)
    185           && (   (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_DEV
    186               || (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_SOCKET /* ???? */
    187               || (pFH->fFlags & __LIBC_FH_TYPEMASK) == F_PIPE) )
    188         {
    189           errno = EAGAIN;
    190           return -1;
    191         }
    192 
    193       /* Set errno to ENOSPC in all remaining cases (disk full while
    194          writing to a disk file). */
    195 
    196       errno = ENOSPC;
    197       return -1;
    198     }
    199   return n;
     148    LIBCLOG_ENTER("fh=%d pvBuf=%p cbToWrite=%zu\n", fh, pvBuf, cbToWrite);
     149
     150    /*
     151     * Check for overflows (implementation defined).
     152     */
     153    if (cbToWrite > SSIZE_MAX)
     154    {
     155        errno = E2BIG;
     156        LIBCLOG_ERROR_RETURN_UINT(-1);
     157    }
     158
     159    /*
     160     * Get filehandle
     161     */
     162    __LIBC_PFH pFH;
     163    int rc = __libc_FHGet(fh, &pFH);
     164    if (rc)
     165    {
     166        errno = -rc;
     167        LIBCLOG_ERROR_RETURN_UINT(-1);
     168    }
     169
     170    /*
     171     * Perform the write operation.
     172     */
     173    ssize_t cbWritten;
     174    if (    (pFH->fFlags & O_TEXT)
     175        &&  (   (pFH->fFlags & F_WRCRPEND)
     176             || memchr(pvBuf, '\n', cbToWrite) != NULL))
     177        cbWritten = write_text(fh, pvBuf, cbToWrite, pFH);
     178    else
     179    {
     180        size_t cbWritten2;
     181        rc = __libc_Back_ioWrite(fh, pvBuf, cbToWrite, &cbWritten2);
     182        if (!rc)
     183            cbWritten = cbWritten2;
     184        else
     185        {
     186            errno = -rc;
     187            cbWritten = -1;
     188        }
     189    }
     190
     191    /*
     192     * Success.
     193     */
     194    __libc_FHPut(pFH);
     195    if (__predict_true(cbWritten > 0))
     196        LIBCLOG_RETURN_INT(cbWritten);
     197    if (errno == EPIPE)
     198    {
     199/** @todo this probably belongs in the backend. */
     200        raise(SIGPIPE);
     201        errno = EPIPE;
     202    }
     203    LIBCLOG_ERROR_RETURN_INT(-1);
    200204}
     205
  • trunk/libc/src/libc/locale/Makefile.kmk

    r2729 r2739  
    5757    $(PATH_LIBC_SRC)/libc/locale/os2/__to_ucs.c \
    5858
    59 libc_libc_locale_SOURCES.win32 = \
     59libc_libc_locale_SOURCES.nt = \
    6060    $(PATH_LIBC_SRC)/libc/locale/generic/locale_ctype-generic.c \
    6161    $(PATH_LIBC_SRC)/libc/locale/generic/setlocale-generic.c \
  • trunk/libc/src/libc/malloc/Makefile.kmk

    r2702 r2739  
    3434libc_libc_malloc_TEMPLATE = libcsub
    3535libc_libc_malloc_SOURCES = \
     36    $(PATH_LIBC_SRC)/libc/malloc/brk.c \
    3637    $(PATH_LIBC_SRC)/libc/malloc/calloc.c \
    3738    $(PATH_LIBC_SRC)/libc/malloc/defalloc.c \
     
    5960    $(PATH_LIBC_SRC)/libc/malloc/posix_memalign.c \
    6061    $(PATH_LIBC_SRC)/libc/malloc/realloc.c \
     62    $(PATH_LIBC_SRC)/libc/malloc/sbrk.c \
    6163    $(PATH_LIBC_SRC)/libc/malloc/tcalloc.c \
    6264    $(PATH_LIBC_SRC)/libc/malloc/tfree.c \
  • trunk/libc/src/libc/malloc/_linitheap.c

    r2254 r2739  
    2929*******************************************************************************/
    3030#include "libc-alias.h"
     31#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_HEAP
    3132#include <stdlib.h>
    3233#include <emx/umalloc.h>
    3334#include <sys/smutex.h>
    34 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_HEAP
    35 #include <InnoTekLIBC/logstrict.h>
     35#include <klibc/backend.h>
     36#include <klibc/logstrict.h>
    3637
    3738
     
    7475     * Initialize the sbrk model and allocate the initial heap block.
    7576     */
    76     _uflags(_UF_SBRK_MODEL, _UF_SBRK_ARBITRARY);
     77    __libc_Back_mmanSBrkSetModel(__LIBC_SBRK_MODEL_ARBITRARY);
    7778    pvInitial = sbrk(_INITIAL_DEFAULT_HEAP_SIZE);
    7879    if (pvInitial == (void *)-1)
  • trunk/libc/src/libc/misc/Makefile.kmk

    r2717 r2739  
    147147    $(PATH_LIBC_SRC)/libc/misc/_getdrive.c \
    148148    $(PATH_LIBC_SRC)/libc/misc/_realrealpath.c \
     149    $(PATH_LIBC_SRC)/libc/misc/_uflags.c \
    149150
    150151libc_libc_misc_SOURCES.x86 = \
  • trunk/libc/src/libc/process/Makefile.kmk

    r2730 r2739  
    120120    $(PATH_LIBC_SRC)/libc/process/os2/fmutex-os2.c \
    121121
    122 libc_libc_process_SOURCES.win32 = \
     122libc_libc_process_SOURCES.nt = \
    123123    $(PATH_LIBC_SRC)/libc/process/nt/fmutex-nt.c \
    124124    $(PATH_LIBC_SRC)/libc/process/nt/smutex-nt.c \
     125    $(PATH_LIBC_SRC)/libc/process/nt/_errno-nt.c \
    125126
    126 libc_libc_process_SOURCES.win64 = $(libc_libc_process_SOURCES.win32)
     127$(PATH_LIBC_SRC)/libc/process/nt/_errno-nt.c_CFLAGS = -fomit-frame-pointer -O3
    127128
    128129# configure the variants. */
  • trunk/libc/src/libc/process/fmutex2.c

    r2719 r2739  
    11/* fmutex2.c (emx+gcc) -- Copyright (c) 1996 by Eberhard Mattes */
    22
     3#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_MUTEX
    34#include "libc-alias.h"
    4 #include <stdlib.h>
    5 #include <string.h>
    6 #include <sys/builtin.h>
    75#include <sys/fmutex.h>
    8 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_MUTEX
    9 #include <InnoTekLIBC/logstrict.h>
     6#include <klibc/logstrict.h>
     7#include <klibc/backend.h>
    108
    119
  • trunk/libc/src/libc/process/psignal.c

    r2254 r2739  
    7575     * Write message.
    7676     */
     77    size_t cbWritten;
    7778    if (pszMsg && *pszMsg)
    7879    {
    79         __write(STDERR_FILENO, pszMsg, strlen(pszMsg));
    80         __write(STDERR_FILENO, ": ", sizeof(": ") - 1);
     80        __libc_Back_ioWrite(STDERR_FILENO, pszMsg, strlen(pszMsg), &cbWritten);
     81        __libc_Back_ioWrite(STDERR_FILENO, ": ", sizeof(": ") - 1, &cbWritten);
    8182    }
    82     __write(STDERR_FILENO, pszSignal, strlen(pszSignal));
    83     __write(STDERR_FILENO, "\n", sizeof("\n") - 1);
     83    __libc_Back_ioWrite(STDERR_FILENO, pszSignal, strlen(pszSignal), &cbWritten);
     84    __libc_Back_ioWrite(STDERR_FILENO, "\n", sizeof("\n") - 1, &cbWritten);
    8485
    8586    LIBCLOG_RETURN_VOID();
  • trunk/libc/src/libc/process/thread_internals.c

    r2254 r2739  
    2828*   Header Files                                                               *
    2929*******************************************************************************/
     30#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_THREAD
    3031#include "libc-alias.h"
    3132#undef NDEBUG
    32 #include <386/builtin.h>
     33#include <sys/builtin.h>
    3334#include <assert.h>
    3435#include <string.h>
     
    3940#include <emx/umalloc.h>
    4041#include <emx/syscalls.h>
    41 #include <InnoTekLIBC/thread.h>
    42 #include <InnoTekLIBC/backend.h>
    43 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_THREAD
    44 #include <InnoTekLIBC/logstrict.h>
     42#include <klibc/thread.h>
     43#include <klibc/backend.h>
     44#include <klibc/logstrict.h>
    4545
    4646
     
    7272
    7373
     74/**
     75 * Internal wrapper for the various OS interfaces for
     76 * setting the thread pointer.
     77 *
     78 * @param   pThrd   The new thread pointer.
     79 */
     80static inline void threadSetPtr(__LIBC_PTHREAD pThrd)
     81{
     82#ifdef __OS2__
     83    *__libc_gpTLS = pThrd;
     84#elif defined(__NT__)
     85    fibSetLibcThread(pThrd);
     86#else
     87# error "Port me!"
     88#endif
     89}
     90
    7491
    7592/**
     
    100117     */
    101118    assert(!pThrd->pNext && !pThrd->tid);
    102     *__libc_gpTLS = pThrd;
     119    threadSetPtr(pThrd);
    103120
    104121    /*
     
    164181{
    165182    LIBCLOG_ENTER("\n");
    166     if (!*__libc_gpTLS)
    167     {
    168         __LIBC_PTHREAD  pThrd;
     183    if (!__libc_threadCurrentNoAuto())
     184    {
    169185        /*
    170186         * Setup a temporary thread block on the stack so _hmalloc()
    171187         * can't end up calling us recursivly if something goes wrong.
    172188         */
    173         __LIBC_THREAD   Thrd;
     189        __LIBC_THREAD Thrd;
    174190        threadInit(&Thrd, NULL);
    175         *__libc_gpTLS   = &Thrd;
    176 
     191        threadSetPtr(&Thrd);
     192
     193        __LIBC_PTHREAD pThrd;
    177194        if (!__lxchg(&gfPreAllocThrd, 1))
    178195            pThrd = &gPreAllocThrd;
     
    188205    }
    189206
    190     LIBCLOG_RETURN_P(*__libc_gpTLS);
     207    LIBCLOG_RETURN_P(__libc_threadCurrentNoAuto());
    191208}
    192209
     
    302319         * Clear the TLS if it's for the current thread.
    303320         */
    304         if (*__libc_gpTLS == pThrd)
    305             *__libc_gpTLS = NULL;
     321        if (__libc_threadCurrentNoAuto() == pThrd)
     322            threadSetPtr(NULL);
    306323
    307324        /*
  • trunk/libc/src/libc/process/tls.c

    r2260 r2739  
    2828*   Header Files                                                               *
    2929*******************************************************************************/
     30#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_THREAD
     31#include <errno.h>
    3032#include <sys/builtin.h>
    31 #include <errno.h>
    3233#include <sys/limits.h>
    3334#include <sys/smutex.h>
    34 #include <InnoTekLIBC/thread.h>
    35 #define __LIBC_LOG_GROUP __LIBC_LOG_GRP_THREAD
    36 #include <InnoTekLIBC/logstrict.h>
     35#include <klibc/thread.h>
     36#include <klibc/logstrict.h>
    3737
    3838
     
    114114                    for (uBit = 0; uBit < ENTRY_BITS; uBit++)
    115115                    {
    116                         if (!__atomic_set_bit(pu, uBit))
     116                        if (!__atomic_bit_test_and_set(pu, uBit))
    117117                        {
    118118                            int iBitRet = (pu - &gauBitmap[0]) * ENTRY_BITS + uBit;
     
    144144    if (    iIndex < 0
    145145        ||  iIndex >= __LIBC_TLS_MAX
    146         ||  !__atomic_test_bit(&gauBitmap[0], iIndex)
     146        ||  !__bit_test(&gauBitmap[0], iIndex)
    147147            )
    148148    {
     
    156156    gapfnDestructors[iIndex] = NULL;
    157157    /* @todo do serialized NULLing of all threads! */
    158     __atomic_clear_bit(&gauBitmap[0], iIndex);
     158    __atomic_bit_clear(&gauBitmap[0], iIndex);
    159159
    160160    /*
     
    175175    if (    iIndex < 0
    176176        ||  iIndex >= __LIBC_TLS_MAX
    177         ||  !__atomic_test_bit(&gauBitmap[0], iIndex)
     177        ||  !__bit_test(&gauBitmap[0], iIndex)
    178178            )
    179179    {
     
    197197    if (    iIndex < 0
    198198        ||  iIndex >= __LIBC_TLS_MAX
    199         ||  !__atomic_test_bit(&gauBitmap[0], iIndex)
     199        ||  !__bit_test(&gauBitmap[0], iIndex)
    200200            )
    201201    {
     
    224224    if (    iIndex < 0
    225225        ||  iIndex >= __LIBC_TLS_MAX
    226         ||  !__atomic_test_bit(&gauBitmap[0], iIndex)
     226        ||  !__bit_test(&gauBitmap[0], iIndex)
    227227            )
    228228    {
     
    299299                        void (*pfnDestructor)(void *, int, unsigned);
    300300                        void  *pvValue;
    301                         if (    __atomic_test_bit(&gauBitmap[0], k)
     301                        if (    __bit_test(&gauBitmap[0], k)
    302302                            &&  k < __LIBC_TLS_MAX
    303303                            &&  (pvValue = pThrd->apvTLS[k]) != NULL
     
    330330    if (    iIndex < 0
    331331        ||  iIndex >= __LIBC_TLS_MAX
    332         ||  !__atomic_test_bit(&gauBitmap[0], iIndex)
     332        ||  !__bit_test(&gauBitmap[0], iIndex)
    333333            )
    334334    {
  • trunk/libc/src/libsocket/soclose.c

    r1772 r2739  
    4040{
    4141    LIBCLOG_ENTER("socket=%d\n", socket);
    42     PLIBCSOCKETFH   pFHSocket = __libc_TcpipFH(socket);
     42    PLIBCSOCKETFH pFHSocket = __libc_TcpipFH(socket);
    4343    if (pFHSocket)
    4444    {
    45         if (!__libc_FHClose(socket))
     45        int rc = __libc_FHClose(socket)
     46        if (!rc)
    4647            LIBCLOG_RETURN_INT(0);
    4748        /* Convert EBADF to ENOTSOCK (although this normally won't happen). */
    48         if (errno == EBADF)
    49             errno = ENOTSOCK;
    50         __libc_TcpipSetSocketErrno();
     49        if (rc == -EBADF)
     50            rc = -ENOTSOCK;
     51        __libc_TcpipSetErrno(-rc);
    5152    }
    5253
Note: See TracChangeset for help on using the changeset viewer.