Minor fixes to input checking, error reporting in daemon commands.

--- src/daemon.c
+++ src/daemon.c
@@ -158,6 +158,7 @@
 CMD(up)
 {
   *output = co_tree16_create();
+  CHECK(co_list_length(params) == 2, "Incorrect parameters.");
   unsigned char mac[6];
   memset(mac, '\0', sizeof(mac));
   char address[16];
@@ -220,7 +221,7 @@
   return 1;
 error:
   co_iface_remove(ifname);
-  co_tree_insert(*output, ifname, iflen, co_str8_create("fail", sizeof("fail"), 0));
+  co_tree_insert(*output, "error", sizeof("error"), co_str8_create("Failed to bring up interface.", sizeof("Failed to bring up interface."), 0));
   return 0;
 }

@@ -234,7 +235,7 @@
   co_tree_insert(*output, ifname, iflen, co_str8_create("down", sizeof("down"), 0));
   return 1;
 error:
-  co_tree_insert(*output, ifname, iflen, co_str8_create("fail", sizeof("fail"), 0));
+  co_tree_insert(*output, "error", sizeof("error"), co_str8_create("Failed to bring down interface.", sizeof("Failed to bring down interface."), 0));
   return 0;
 }

@@ -246,12 +247,14 @@
   char *ifname = NULL;
   size_t iflen = co_obj_data(&ifname, co_list_element(params, 0));
   CHECK(iflen > 0, "Incorrect parameters.");
-  char *profile_name = NULL;
-  CHECK((profile_name = co_iface_profile(ifname)), "Interface state is inactive.");
-  co_tree_insert(*output, "status", sizeof("status"), co_str8_create(profile_name, strlen(profile_name)+1, 0));
-  return 1;
-error:
-  co_tree_insert(*output, "status", sizeof("status"), co_str8_create("down", sizeof("down"), 0));
+  char *profile_name = profile_name = co_iface_profile(ifname);
+  if(profile_name == NULL)
+    co_tree_insert(*output, "status", sizeof("status"), co_str8_create("down", sizeof("down"), 0));
+  else
+    co_tree_insert(*output, "status", sizeof("status"), co_str8_create(profile_name, strlen(profile_name)+1, 0));
+  return 1;
+error:
+  co_tree_insert(*output, "error", sizeof("error"), co_str8_create("Failed to get status.", sizeof("Failed to get status."), 0));
   return 0;
 }


createLatencyReport(), fix mount option name.

--- src/latency.c
+++ src/latency.c
@@ -391,7 +391,7 @@
         }

         if (advise_data_writeback) {
-            report = sdscat(report,"- Mounting ext3/4 filesystems with mode=writeback can provide a performance boost compared to mode=ordered, however this mode of operation provides less guarantees, and sometimes it can happen that after a hard crash the AOF file will have an half-written command at the end and will require to be repaired before Redis restarts.\n");
+            report = sdscat(report,"- Mounting ext3/4 filesystems with data=writeback can provide a performance boost compared to data=ordered, however this mode of operation provides less guarantees, and sometimes it can happen that after a hard crash the AOF file will have an half-written command at the end and will require to be repaired before Redis restarts.\n");
         }

         if (advise_disk_contention) {


Defrag: don't crash when a module value is encountered.

--- src/defrag.c
+++ src/defrag.c
@@ -406,6 +406,9 @@
         } else {
             serverPanic("Unknown hash encoding");
         }
+    } else if (ob->type == OBJ_MODULE) {
+        /* Currently defragmenting modules private data types
+         * is not supported. */
     } else {
         serverPanic("Unknown object type");
     }


Delete demo01.c

Delete demo01.c

--- src/demo01.c
+++ src/demo01.c
@@ -1,176 +0,0 @@
-#include "demo01.h"
-#include "library.h"
-#include "d3d12.h"
-
-
-#if 0
-static struct
-{
-    u32 BackBufferResolution[2];
-    u32 BackBufferIndex;
-    u32 FrameIndex;
-    u32 DescriptorSize;
-    u32 RTVDescriptorSize;
-    D3D12_CPU_DESCRIPTOR_HANDLE RTVHeapStart;
-    D3D12_CPU_DESCRIPTOR_HANDLE DSVHeapStart;
-    ID3D12Device *Device;
-    ID3D12CommandQueue *CmdQueue;
-    ID3D12CommandAllocator *CmdAlloc[2];
-    ID3D12GraphicsCommandList *CmdList;
-    ID3D12Resource *SwapBuffers[4];
-    ID3D12Resource *DepthStencilImage;
-    IDXGIFactory4 *GiFactory;
-    IDXGISwapChain3 *SwapChain;
-    ID3D12DescriptorHeap *RTVHeap;
-    ID3D12DescriptorHeap *DSVHeap;
-    u64 CPUCompletedFrames;
-    ID3D12Fence *FrameFence;
-    void *FrameFenceEvent;
-    i64 Frequency;
-    i64 StartCounter;
-    void *Window;
-    double FrameTime;
-    float FrameDeltaTime;
-} G;
-
-static i32 InitializeD3D12(void)
-{
-    // depth-stencil image, view and heap
-    {
-        D3D12_DESCRIPTOR_HEAP_DESC HeapDesc =
-        {
-            .NumDescriptors = 1,.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV,.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE
-        };
-        VHR(ID3D12Device_CreateDescriptorHeap(G.Device, &HeapDesc, &IID_ID3D12DescriptorHeap, &G.DSVHeap));
-        ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(G.DSVHeap, &G.DSVHeapStart);
-
-        D3D12_CLEAR_VALUE ClearValue =
-        {
-            .Format = DXGI_FORMAT_D32_FLOAT,.DepthStencil.Depth = 1.0f,.DepthStencil.Stencil = 0
-        };
-        D3D12_HEAP_PROPERTIES HeapProps =
-        {
-            .Type = D3D12_HEAP_TYPE_DEFAULT
-        };
-        D3D12_RESOURCE_DESC ImageDesc =
-        {
-            .Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D,.Width = G.BackBufferResolution[0],.Height = G.BackBufferResolution[1],
-            .DepthOrArraySize = 1,.MipLevels = 1,.Format = DXGI_FORMAT_D32_FLOAT,.SampleDesc.Count = 1,
-            .Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN,.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL
-        };
-        VHR(ID3D12Device_CreateCommittedResource(G.Device, &HeapProps, D3D12_HEAP_FLAG_NONE, &ImageDesc,
-            D3D12_RESOURCE_STATE_DEPTH_WRITE, &ClearValue, &IID_ID3D12Resource, &G.DepthStencilImage));
-
-        D3D12_DEPTH_STENCIL_VIEW_DESC ViewDesc =
-        {
-            .Format = DXGI_FORMAT_D32_FLOAT,.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D,.Flags = D3D12_DSV_FLAG_NONE
-        };
-        ID3D12Device_CreateDepthStencilView(G.Device, G.DepthStencilImage, &ViewDesc, G.DSVHeapStart);
-    }
-
-
-    return 1;
-}
-
-static void Update(void)
-{
-
-}
-#endif
-
-static u32 s_descriptor_size;
-static u32 s_descriptor_size_rtv;
-static ID3D12Device *s_d3d;
-static ID3D12GraphicsCommandList *s_cmdlist;
-static ID3D12CommandQueue *s_cmdqueue;
-static ID3D12CommandAllocator *s_cmdalloc[2];
-static D3D12_CPU_DESCRIPTOR_HANDLE s_rtv_heap_start;
-static ID3D12DescriptorHeap *s_rtv_heap;
-static ID3D12Resource *s_swap_buffers[4];
-
-void demo_update(double frame_time, float frame_delta_time)
-{
-    (void)frame_time; (void)frame_delta_time;
-}
-
-void demo_draw(u32 frame_index)
-{
-    (void)frame_index;
-    /*
-    D3D12_VIEWPORT viewport = {
-        .TopLeftX = 0.0f, .TopLeftY = 0.0f, .Width = (float)k_win_width, .Height = (float)k_win_height,
-        .MinDepth = 0.0f, .MaxDepth = 1.0f
-    };
-    D3D12_RECT scissor = { .left = 0, .top = 0, .right = k_win_width, .bottom = k_win_height };
-
-    ID3D12CommandAllocator *cmdalloc = s_cmdalloc[frame_index];
-    ID3D12CommandAllocator_Reset(cmdalloc);
-
-    ID3D12GraphicsCommandList_Reset(s_cmdlist, cmdalloc, NULL);
-    ID3D12GraphicsCommandList_RSSetViewports(s_cmdlist, 1, &viewport);
-    ID3D12GraphicsCommandList_RSSetScissorRects(s_cmdlist, 1, &scissor);
-
-    D3D12_RESOURCE_BARRIER Barrier =
-    {
-        .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,.Transition.pResource = G.SwapBuffers[G.BackBufferIndex],
-        .Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT,.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET
-    };
-    ID3D12GraphicsCommandList_ResourceBarrier(CmdList, 1, &Barrier);
-
-    D3D12_CPU_DESCRIPTOR_HANDLE RTVHandle = G.RTVHeapStart;
-    RTVHandle.ptr += G.BackBufferIndex *G.RTVDescriptorSize;
-
-    ID3D12GraphicsCommandList_OMSetRenderTargets(CmdList, 1, &RTVHandle, 0, &G.DSVHeapStart);
-
-    const float ClearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };
-    ID3D12GraphicsCommandList_ClearRenderTargetView(CmdList, RTVHandle, ClearColor, 0, NULL);
-    ID3D12GraphicsCommandList_ClearDepthStencilView(CmdList, G.DSVHeapStart, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, NULL);
-
-    Barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
-    Barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
-    ID3D12GraphicsCommandList_ResourceBarrier(CmdList, 1, &Barrier);
-
-    ID3D12GraphicsCommandList_Close(CmdList);
-
-    ID3D12CommandQueue_ExecuteCommandLists(G.CmdQueue, 1, (ID3D12CommandList **)&CmdList);
-    */
-}
-
-void demo_init(IDXGISwapChain3 *swapchain, ID3D12Device *d3d, ID3D12CommandQueue *cmdqueue)
-{
-    (void)swapchain;
-    s_d3d = d3d;
-    s_cmdqueue = cmdqueue;
-
-    for (u32 i = 0; i < 2; ++i)
-        VHR(ID3D12Device_CreateCommandAllocator(s_d3d, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator,
-                                                &s_cmdalloc[i]));
-
-    s_descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(s_d3d, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
-    s_descriptor_size_rtv = ID3D12Device_GetDescriptorHandleIncrementSize(s_d3d, D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
-
-    /* rtv descriptor heap */ {
-        D3D12_DESCRIPTOR_HEAP_DESC heap_desc = {
-            .NumDescriptors = 4, .Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV
-        };
-        VHR(ID3D12Device_CreateDescriptorHeap(s_d3d, &heap_desc, &IID_ID3D12DescriptorHeap, &s_rtv_heap));
-        ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(s_rtv_heap, &s_rtv_heap_start);
-
-        D3D12_CPU_DESCRIPTOR_HANDLE handle = s_rtv_heap_start;
-
-        for (u32 i = 0; i < 4; ++i) {
-            VHR(IDXGISwapChain3_GetBuffer(swapchain, i, &IID_ID3D12Resource, &s_swap_buffers[i]));
-
-            ID3D12Device_CreateRenderTargetView(s_d3d, s_swap_buffers[i], NULL, handle);
-            handle.ptr += s_descriptor_size_rtv;
-        }
-    }
-
-    VHR(ID3D12Device_CreateCommandList(s_d3d, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, s_cmdalloc[0], NULL,
-                                       &IID_ID3D12GraphicsCommandList, &s_cmdlist));
-    ID3D12GraphicsCommandList_Close(s_cmdlist);
-}
-
-void demo_shutdown(void)
-{
-}


Fix createStringForKey failure on Mac OS for non-Latin languages

--- src/keycode.c
+++ src/keycode.c
@@ -134,7 +134,7 @@

 CFStringRef createStringForKey(CGKeyCode keyCode)
 {
-	TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+	TISInputSourceRef currentKeyboard = TISCopyCurrentASCIICapableKeyboardInputSource();
 	CFDataRef layoutData =
 		TISGetInputSourceProperty(currentKeyboard,
 		                          kTISPropertyUnicodeKeyLayoutData);


- iwkv

- iwkv

--- src/kv/iwkv.c
+++ src/kv/iwkv.c
@@ -819,7 +819,7 @@
   IWFS_FSM *fsm = &db->iwkv->fsm;
   uint32_t first_sblkn;
   bool dec_worker = true;
-
+
   kh_del(DBS, db->iwkv->dbs, db->id);
   rc = fsm->acquire_mmap(fsm, 0, &mm, 0);
   RCRET(rc);
@@ -1147,10 +1147,10 @@
   kb->db = lx->db;
   kb->addr = addr;
   kb->zidx = -1;
-
+
   *blkp = 0;
   rp = mm + addr;
-
+
   IW_READBV(rp, kb->szpow, kb->szpow);
   IW_READSV(rp, sv, kb->idxsz);
   if (IW_UNLIKELY(kb->idxsz > 2 * 4 * KVBLK_IDXNUM)) {
@@ -1394,7 +1394,7 @@
   off_t psz = (key->size + uval->size) + IW_VNUMSIZE(key->size); // required size
   bool compacted = false;
   *oidx = -1;
-
+
   if (kb->zidx < 0) {
     return _IWKV_ERROR_KVBLOCK_FULL;
   }
@@ -1426,7 +1426,7 @@
     }
     return IWKV_ERROR_MAXKVSZ;
   }
-
+
 start:
   msz = (1ULL << kb->szpow) - KVBLK_HDRSZ - kb->idxsz - kb->maxoff;
   noff = kb->maxoff + psz;
@@ -1487,7 +1487,7 @@
   wp += key->size;
   memcpy(wp, uval->data, uval->size);
   fsm->release_mmap(fsm);
-
+
 finish:
   if (uval != val) {
     _kv_val_dispose(uval);
@@ -1514,7 +1514,7 @@
   IWFS_FSM *fsm = &db->iwkv->fsm;
   iwrc rc = fsm->acquire_mmap(fsm, 0, &mm, 0);
   RCRET(rc);
-
+
   // DUP
   if (!internal && (db->dbflg & IWDB_DUP_FLAGS)) {
     if (((db->dbflg & IWDB_DUP_UINT32_VALS) && val->size != 4) ||
@@ -1539,7 +1539,7 @@
     uint8_t vbuf[8];
     uint32_t avail = len - (4 /* num items */ + sz * val->size);
     _num2lebuf(vbuf, val->data, val->size);
-
+
     if (opflags & IWKV_DUP_REMOVE) {
       if (!sz || !iwarr_sorted_remove(wp, sz, val->size, vbuf,  val->size > 4 ? _u8cmp : _u4cmp)) {
         rc = IWKV_ERROR_NOTFOUND;
@@ -1554,7 +1554,7 @@
         kb->flags |= KVBLK_DURTY;
       }
       goto finish;
-
+
     } else if (avail >= val->size) { // we have enough room to store the given number
       if (iwarr_sorted_insert(wp, sz, val->size, vbuf,
                               val->size > 4 ? _u8cmp : _u4cmp, true) == -1) {
@@ -1592,7 +1592,7 @@
     }
   }
   // !DUP
-
+
   wp = mm + kb->addr + (1ULL << kb->szpow) - kvp->off;
   sp = wp;
   IW_READVNUMBUF(wp, len, sz);
@@ -1639,7 +1639,7 @@
       }
     }
   }
-
+
 finish:
   if (uval != val) {
     _kv_val_dispose(uval);
@@ -1678,8 +1678,9 @@
   iwrc rc = 0;
   SBLK *sblk = *sblkp;
   if (!(sblk->flags & SBLK_DB)) {
+    assert(sblk->flags & SBLK_WLOCKED);
+    uint8_t kvb_szpow;
     IWFS_FSM *fsm = &lx->db->iwkv->fsm;
-    uint8_t kvb_szpow;
     off_t kvb_addr = BLK2ADDR(sblk->kvblkn),
           sblk_addr = sblk->addr;
     if (!sblk->kvblk) {
@@ -1837,6 +1838,7 @@
     return rc;
   }
   sblk->flags |= SBLK_WLOCKED;
+  // Now re-read `SBLK`
   if (IW_UNLIKELY(sblk->addr == lx->db->addr)) {
     // [magic:u4,dbflg:u1,dbid:u4,next_db_blk:u4,p0:u4,n0-n29:u4]:u137
     uint8_t *rp = mm + sblk->addr + DOFF_N0_U4;
@@ -1900,6 +1902,7 @@

 IW_INLINE void _sblk_sync_mm(SBLK *sblk, uint8_t *mm) {
   if (sblk->flags & SBLK_DURTY) {
+    assert(sblk->flags & SBLK_WLOCKED);
     uint32_t lv;
     sblk->flags &= ~SBLK_DURTY;
     if (IW_UNLIKELY(sblk->flags & SBLK_DB)) {
@@ -1908,9 +1911,8 @@
         assert(sblk->addr == sblk->db->addr);
         wp += DOFF_N0_U4;
         // [magic:u4,dbflg:u1,dbid:u4,next_db_blk:u4,p0:u4,n0-n29:u4]:u137
-        for (int i = 0; i < SLEVELS; ++i) {
+        for (int i = 0; i < SLEVELS && sblk->n[i]; ++i) {
           IW_WRITELV(wp, lv, sblk->n[i]);
-          if (!sblk->n[i]) break;
         }
       } else { // Database tail
         wp += DOFF_P0_U4;
@@ -1938,6 +1940,7 @@
     }
   }
   if (sblk->kvblk && (sblk->kvblk->flags & KVBLK_DURTY)) {
+    assert(sblk->flags & SBLK_WLOCKED);
     _kvblk_sync_mm(sblk->kvblk, mm);
   }
 }
@@ -1947,6 +1950,23 @@
     _sblk_sync_mm(*sblkp, mm);
   }
   _sblk_release(lx, sblkp);
+}
+
+IW_INLINE iwrc _sblk_sync_and_release(IWLCTX *lx, SBLK **sblkp) {
+  assert(sblkp && *sblkp);
+  SBLK *sblk = *sblkp;
+  if ((sblk->flags & SBLK_DURTY) || (sblk->kvblk && (sblk->kvblk->flags & KVBLK_DURTY))) {
+    uint8_t *mm;
+    IWFS_FSM *fsm = &lx->db->iwkv->fsm;
+    iwrc rc = fsm->acquire_mmap(fsm, 0, &mm, 0);
+    RCRET(rc);
+    _sblk_sync_mm(*sblkp, mm);
+    _sblk_release(lx, sblkp);
+    return fsm->release_mmap(fsm);
+  } else {
+    _sblk_release(lx, sblkp);
+    return 0;
+  }
 }

 static int _sblk_find_pi_mm(SBLK *sblk,
@@ -1992,10 +2012,10 @@
   return idx;
 }

-static int _sblk_insert_pi(SBLK *sblk,
-                           int8_t nidx,
-                           const IWKV_val *key,
-                           const uint8_t *mm) {
+static int _sblk_insert_pi_mm(SBLK *sblk,
+                              int8_t nidx,
+                              const IWKV_val *key,
+                              const uint8_t *mm) {
   assert(sblk->kvblk);
   uint8_t *k;
   uint32_t kl;
@@ -2057,7 +2077,7 @@
   if (sblk->pnum - idx > 0) {
     memmove(sblk->pi + idx + 1, sblk->pi + idx, sblk->pnum - idx);
   }
-  if (idx == 0) {
+  if (idx == 0) { // the lowest key inserted
     rc = fsm->acquire_mmap(fsm, 0, &mm, 0);
     RCRET(rc);
     uint8_t lkl = MIN(SBLK_LKLEN, key->size);
@@ -2097,7 +2117,7 @@
   RCRET(rc);
   rc = fsm->acquire_mmap(fsm, 0, &mm, 0);
   RCRET(rc);
-  if (_sblk_insert_pi(sblk, kvidx, key, mm) == 0) { // the lowest key inserted
+  if (_sblk_insert_pi_mm(sblk, kvidx, key, mm) == 0) { // the lowest key inserted
     uint8_t lkl = MIN(SBLK_LKLEN, key->size);
     _mm_set_u1(mm, sblk->addr + SOFF_LKL_U1, lkl);
     memcpy(mm + sblk->addr + SOFF_LK_U61, key->data, lkl);
@@ -2131,7 +2151,7 @@

 IW_INLINE iwrc _sblk_rmkv(SBLK *sblk,
                           uint8_t idx) {
-
+
   assert(sblk && sblk->kvblk);
   KVBLK *kvblk = sblk->kvblk;
   IWFS_FSM *fsm = &sblk->db->iwkv->fsm;
@@ -2144,11 +2164,11 @@
   if (idx < sblk->pnum && sblk->pnum > 0) {
     memmove(sblk->pi + idx, sblk->pi + idx + 1, sblk->pnum - idx);
   }
-  if (idx == 0) {
+  if (idx == 0) { // Lowest key removed
     uint8_t *mm;
     rc = fsm->acquire_mmap(fsm, 0, &mm, 0);
     RCRET(rc);
-    // Lowest key removed, replace it with the next key or reset
+    // Replace key with the next one or reset
     if (sblk->pnum > 0) {
       uint32_t klen;
       uint8_t *kbuf, lkl;
@@ -2196,7 +2216,7 @@
   if (IW_UNLIKELY(sblk->pnum < 1 || (sblk->flags & SBLK_DB))) { // empty block
     *res = 0;
     return IWKV_ERROR_CORRUPTED;
-  } else if (sblk->flags & SBLK_FULL_LKEY) {
+  } else if ((sblk->flags & SBLK_FULL_LKEY) || key->size < sblk->lkl) {
     *res = _cmp_key(dbflg, sblk->lk, sblk->lkl, key->data, key->size);
   } else {
     uint32_t kl;
@@ -2272,11 +2292,6 @@
   assert(!lx->lower);
   iwrc rc = _sblk_at(lx, lx->db->addr, 0, &lx->lower);
   RCRET(rc);
-  if (lx->nlvl > lx->lower->lvl) { // todo review?
-    memset(&lx->lower->n[lx->lower->lvl + 1], 0, lx->nlvl - lx->lower->lvl);
-    lx->lower->lvl = lx->nlvl;
-    lx->lower->flags |= SBLK_DURTY;
-  }
   for (int lvl = lx->lower->lvl; lvl >= 0;) {
     lx->lvl = lvl;
     rc = _lx_roll_forward(lx);
@@ -2340,12 +2355,10 @@
   iwrc rc;
   SBLK *nb;
   blkn_t nblk;
-  uint8_t *mm;
   uint8_t kvbpow = 0;
-  IWFS_FSM *fsm = &lx->db->iwkv->fsm;
   register int pivot = (KVBLK_IDXNUM / 2) + 1; // 32
   assert(sblk->flags & SBLK_WLOCKED);
-
+
   if (idx < sblk->pnum) {
     // Partial split required
     // Compute space required for the new sblk which stores kv pairs after pivot `idx`
@@ -2370,7 +2383,9 @@
     // Do the partial split
     // Move kv pairs into new `nb`
     IWKV_val key, val;
+    IWFS_FSM *fsm = &lx->db->iwkv->fsm;
     for (int i = pivot, end = sblk->pnum; i < end; ++i) {
+      uint8_t *mm;
       rc = fsm->acquire_mmap(fsm, 0, &mm, 0);
       RCBREAK(rc);
       rc = _kvblk_getkv(sblk->kvblk, mm, sblk->pi[i], &key, &val);
@@ -2452,7 +2467,7 @@
   uint8_t *mm = 0;
   SBLK *sblk = lx->lower;
   IWFS_FSM *fsm = &lx->db->iwkv->fsm;
-
+
   if (lx->nlvl < 0) {
     rc = _sblk_write_upgrade(lx, sblk);
     RCRET(rc);
@@ -2460,7 +2475,7 @@
     rc = _lx_lock_chute(lx);
     RCRET(rc);
   }
-
+
   rc = fsm->acquire_mmap(fsm, 0, &mm, 0);
   RCRET(rc);
   idx = _sblk_find_pi_mm(sblk, lx->key, mm, &found);
@@ -2469,7 +2484,7 @@
     return IWKV_ERROR_KEY_EXISTS;
   }
   fsm->release_mmap(fsm);
-
+
   if (!found && sblk->pnum >= KVBLK_IDXNUM) {
     if (lx->nlvl < 0 && idx == sblk->pnum && lx->upper && lx->upper->pnum < KVBLK_IDXNUM) {
       rc = _sblk_write_upgrade(lx, lx->upper);
@@ -2555,7 +2570,7 @@
   SBLK *sblk;
   uint8_t *mm = 0;
   IWFS_FSM *fsm = &lx->db->iwkv->fsm;
-
+
   rc = _lx_find_bounds(lx);
   RCRET(rc);
   sblk = dbwlocked ? lx->upper : lx->lower;
@@ -2564,7 +2579,7 @@
     rc = _sblk_write_upgrade(lx, sblk);
     RCGO(rc, finish);
   }
-
+
   rc = fsm->acquire_mmap(fsm, 0, &mm, 0);
   RCGO(rc, finish);
   rc = _sblk_loadkvblk_mm(lx, sblk, mm);
@@ -2576,7 +2591,7 @@
   }
   fsm->release_mmap(fsm);
   mm = 0;
-
+
   if (sblk->pnum <= 1) {
     if (!dbwlocked) {
       int8_t nlvl = sblk->lvl;
@@ -2595,11 +2610,11 @@
       goto finish;
     }
   }
-
+
   // Remove KV
   rc = _sblk_rmkv(sblk, idx);
   RCGO(rc, finish);
-
+
   if (lx->upper->pnum < 1) {
     assert(dbwlocked && lx->upper->addr == lx->upper_addr);
     for (int i = 0; i <= lx->nlvl; ++i) {
@@ -2624,7 +2639,7 @@
     // Now destroy KV block
     rc = _sblk_destroy(lx, &lx->upper);
   }
-
+
 finish:
   if (mm) {
     fsm->release_mmap(fsm);
@@ -2666,16 +2681,14 @@
 }

 IW_INLINE iwrc _cursor_to_lr(IWKV_cursor cur, IWKV_cursor_op op) {
+  iwrc rc = 0;
   IWDB db = cur->lx.db;
+  IWLCTX *lx = &cur->lx;
   blkn_t dblk = ADDR2BLK(db->addr);
-  IWFS_FSM *fsm = &db->iwkv->fsm;
-  IWLCTX *lx = &cur->lx;
-  uint8_t *mm = 0;
-  iwrc rc = fsm->acquire_mmap(fsm, 0, &mm, 0);
-  RCGO(rc, finish);
   if (op < IWKV_CURSOR_NEXT) { // IWKV_CURSOR_BEFORE_FIRST | IWKV_CURSOR_AFTER_LAST
     if (cur->cn) {
-      _sblk_sync_and_release_mm(lx, &cur->cn, mm);
+      rc = _sblk_sync_and_release(lx, &cur->cn);
+      RCRET(rc);
     }
     if (op == IWKV_CURSOR_BEFORE_FIRST) {
       cur->dbaddr = db->addr;
@@ -2684,7 +2697,6 @@
       cur->dbaddr = -1; // Negative as sign of dbtail
       cur->cnpos = 0;
     }
-    fsm->release_mmap(fsm);
     return 0;
   }
 start:
@@ -2692,7 +2704,7 @@
     blkn_t n = 0;
     if (!cur->cn) {
       if (cur->dbaddr) {
-        rc = _sblk_at(lx, (cur->dbaddr < 0 ? 0 : cur->dbaddr), mm, 0, &cur->cn);
+        rc = _sblk_at(lx, (cur->dbaddr < 0 ? 0 : cur->dbaddr), 0, &cur->cn);
         cur->dbaddr = 0;
         RCGO(rc, finish);
       } else {
@@ -2707,8 +2719,8 @@
           rc = IWKV_ERROR_NOTFOUND;
           goto finish;
         }
-        _sblk_sync_and_release_mm(lx, &cur->cn, mm);
-        rc = _sblk_at_mm(lx, BLK2ADDR(n), mm, 0, &cur->cn);
+        _sblk_sync_and_release(lx, &cur->cn);
+        rc = _sblk_at(lx, BLK2ADDR(n), 0, &cur->cn);
         RCGO(rc, finish);
         cur->cnpos = 0;
         if (IW_UNLIKELY(!cur->cn->pnum)) {
@@ -2728,8 +2740,8 @@
           rc = IWKV_ERROR_NOTFOUND;
           goto finish;
         }
-        _sblk_sync_and_release_mm(lx, &cur->cn, mm);
-        rc = _sblk_at_mm(lx, BLK2ADDR(n), mm, 0, &cur->cn);
+        _sblk_sync_and_release(lx, &cur->cn);
+        rc = _sblk_at(lx, BLK2ADDR(n), 0, &cur->cn);
         RCGO(rc, finish);
         if (IW_LIKELY(cur->cn->pnum)) {
           cur->cnpos = cur->cn->pnum - 1;
@@ -2760,9 +2772,6 @@
 finish:
   if (rc && rc != IWKV_ERROR_NOTFOUND && cur->cn) {
     _sblk_release(lx, &cur->cn);
-  }
-  if (mm) {
-    IWRC(fsm->release_mmap(fsm), rc);
   }
   return rc;
 }
@@ -2874,7 +2883,7 @@
   iwkv->dbs = kh_init(DBS);
   rc = fsm->state(fsm, &fsmstate);
   RCGO(rc, finish);
-
+
   if (fsmstate.exfile.file.ostatus & IWFS_OPEN_NEW) {
     // Write magic number
     lv = IWKV_MAGIC;
@@ -3244,48 +3253,42 @@
   }
   IWDB db = cur->lx.db;
   API_DB_RLOCK(db, rci);
-  uint8_t *mm = 0, *kbuf;
+  uint8_t *kbuf;
   uint32_t klen;
   int8_t idx = cur->cn->pi[cur->cnpos];
-  IWFS_FSM *fsm = &db->iwkv->fsm;
-  rc = fsm->acquire_mmap(fsm, 0, &mm, 0);
-  RCGO(rc, finish);
-  if (!cur->cn->kvblk) {
-    rc = _sblk_loadkvblk_mm(&cur->lx, cur->cn, mm);
-    RCGO(rc, finish);
-  }
+
   if (!(cur->cn->flags & SBLK_WLOCKED)) {
-    IWKV_val key;
-    rc = _kvblk_getkey(cur->cn->kvblk, mm, idx, &key);
-    RCGO(rc, finish);
-    rc = _sblk_write_upgrade_mm(&cur->lx, cur->cn, mm);
-    RCGO(rc, finish);
-    if (cur->cnpos >= cur->cn->pnum) {
-      _kv_val_dispose(&key);
-      rc = IWKV_ERROR_CURSOR_SEEK_AGAIN;
-      goto finish;
-    }
-    idx = cur->cn->pi[cur->cnpos];
-    _kvblk_peek_key(cur->cn->kvblk, idx, mm, &kbuf, &klen);
-    if (klen != key.size) {
-      _kv_val_dispose(&key);
-      rc = IWKV_ERROR_CURSOR_SEEK_AGAIN;
-      goto finish;
-    }
-    if (memcmp(kbuf, key.data, klen)) {
-      _kv_val_dispose(&key);
-      rc = IWKV_ERROR_CURSOR_SEEK_AGAIN;
-      goto finish;
-    }
-    _kv_val_dispose(&key);
-  }
-  mm = 0;
-  fsm->release_mmap(fsm);
+// !!!! todo
+//    IWKV_val key;
+//    uint8_t *mm;
+//    IWFS_FSM *fsm = &db->iwkv->fsm;
+//    rc = _sblk_write_upgrade(&cur->lx, cur->cn);
+//    RCGO(rc, finish);
+//    if (cur->cnpos >= cur->cn->pnum || !cur->cn->pnum) {
+//      rc = IWKV_ERROR_CURSOR_SEEK_AGAIN;
+//      goto finish;
+//    }
+//
+//    rc = _kvblk_getkey(cur->cn->kvblk, mm, idx, &key);
+//    RCGO(rc, finish);
+//
+//    idx = cur->cn->pi[cur->cnpos];
+//    _kvblk_peek_key(cur->cn->kvblk, idx, mm, &kbuf, &klen);
+//    if (klen != key.size) {
+//      _kv_val_dispose(&key);
+//      rc = IWKV_ERROR_CURSOR_SEEK_AGAIN;
+//      goto finish;
+//    }
+//    if (memcmp(kbuf, key.data, klen)) {
+//      _kv_val_dispose(&key);
+//      rc = IWKV_ERROR_CURSOR_SEEK_AGAIN;
+//      goto finish;
+//    }
+//    _kv_val_dispose(&key);
+  }
   rc = _sblk_updatekv(cur->cn, cur->cnpos, 0, val, opflags);
+
 finish:
-  if (mm) {
-    fsm->release_mmap(fsm);
-  }
   API_DB_UNLOCK(cur->lx.db, rci, rc);
   return rc;
 }
@@ -3509,7 +3512,7 @@
   blkn_t blkn = ADDR2BLK(kb->addr);
   fprintf(f, "\n === KVBLK[%u] maxoff=%u, zidx=%d, idxsz=%d, szpow=%u, flg=%x, db=%d\n",
           blkn, kb->maxoff, kb->zidx, kb->idxsz, kb->szpow, kb->flags, kb->db->id);
-
+
   iwrc rc = fsm->probe_mmap(fsm, 0, &mm, 0);
   if (rc) {
     iwlog_ecode_error3(rc);
@@ -3558,8 +3561,8 @@
           sb->pnum, sb->flags, sb->kvblk->zidx,
           sb->p0,
           sb->kvblk->db->id);
-
-
+
+
   if (sb->db->dbflg & IWDB_UINT64_KEYS) {
     uint64_t k;
     memcpy(&k, lkbuf, sizeof(k));
@@ -3573,7 +3576,7 @@
   } else {
     fprintf(f, "\n === SBLK[%u] szpow=%d, lkl=%d, lk=%s\n", blkn, sb->kvblk->szpow, lkl, lkbuf);
   }
-
+
   for (int i = 0, j = 0; i < sb->pnum; ++i, ++j) {
     if (j == 3) {
       fputc('\n', f);


eet: remove uneeded Evas.h.

eet: remove uneeded Evas.h.

SVN revision: 58950

--- src/lib/Eet.h
+++ src/lib/Eet.h
@@ -1879,7 +1879,6 @@
  *
  * @code
  * #include <Eet.h>
- * #include <Evas.h>
  *
  * typedef struct _blah2
  * {


core/device: Don't disconnect if attios not set

Currently there is no way for external applications to claim ownership
on a GATT connection and as profiles move away from attio.h it doesn't
make much sense to immediately disconnect if no attio callbacks have
been set after probing the profiles (as this will always immediately
disconnect the device). This patch removes this logic from btd_device.

--- src/device.c
+++ src/device.c
@@ -3642,9 +3642,6 @@

 	device_probe_profiles(device, req->profiles_added);

-	if (device->attios == NULL && device->attios_offline == NULL)
-		attio_cleanup(device);
-
 	device_svc_resolved(device, device->bdaddr_type, 0);

 	store_services(device);
@@ -5069,11 +5066,6 @@

 	g_free(attio);

-	if (device->attios != NULL || device->attios_offline != NULL)
-		return TRUE;
-
-	attio_cleanup(device);
-
 	return TRUE;
 }


- iwkv

- iwkv

--- src/kv/iwkv.c
+++ src/kv/iwkv.c
@@ -129,14 +129,14 @@
 }

 static int _kvblk_sort_kv(const void *v1, const void *v2) {
-  uint32_t o1 = ((KVP*) v1)->off > 0 ? ((KVP*) v1)->off : -1UL;
-  uint32_t o2 = ((KVP*) v2)->off > 0 ? ((KVP*) v1)->off : -1UL;
+  uint32_t o1 = ((KVP *) v1)->off > 0 ? ((KVP *) v1)->off : -1UL;
+  uint32_t o2 = ((KVP *) v2)->off > 0 ? ((KVP *) v1)->off : -1UL;
   return o1 > o2 ? 1 : o1 < o2 ? -1 : 0;
 }

 static iwrc _kvblk_compact(KVBLK *kb) {
   iwrc rc = 0;
-  uint8_t *mm;
+  uint8_t *mm, i;
   size_t sp;
   IWFS_FSM *fsm = &kb->iwkv->fsm;
   off_t coff = _kvblk_compacted_offset(kb);
@@ -149,6 +149,15 @@

   // todo

+  for (i = 0; i < KVBLK_IDXNUM; ++i) {
+    if (!kb->pidx[i].len)  {
+      kb->zidx = i;
+      break;
+    }
+  }
+  if (i == KVBLK_IDXNUM) {
+    kb->zidx = -1;
+  }
   _kvblk_sync(kb, mm);
   IWRC(fsm->release_mmap(fsm), rc);
   return rc;
@@ -225,6 +234,7 @@
   for (i = kb->zidx + 1; i < KVBLK_IDXNUM; ++i) {
     if (!kb->pidx[i].len) {
       kb->zidx = i;
+      break;
     }
   }
   if (i == KVBLK_IDXNUM) {


Add multi-bit bypassing of CABAC.

Add multi-bit bypassing of CABAC.


Fix possible memleak which could happen if bt_search_service fails.

--- src/device.c
+++ src/device.c
@@ -956,71 +956,10 @@
 	g_free(str);
 }

-static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
-{
-	struct browse_req *req = user_data;
+static void browse_req_free(struct browse_req *req)
+{
 	struct btd_device *device = req->device;
-	DBusMessage *reply;
-
-	if (err < 0) {
-		error("%s: error updating services: %s (%d)",
-				device->path, strerror(-err), -err);
-		goto proceed;
-	}
-
-	update_services(req, recs);
-
-	if (!req->uuids_added && !req->uuids_removed) {
-		debug("%s: No service update", device->path);
-		goto proceed;
-	}
-
-	/* Probe matching drivers for services added */
-	if (req->uuids_added)
-		device_probe_drivers(device, req->uuids_added, req->records);
-
-	/* Remove drivers for services removed */
-	if (req->uuids_removed)
-		device_remove_drivers(device, req->uuids_removed, req->records);
-
-	/* Propagate services changes */
-	services_changed(req);
-
-proceed:
-	/* Store the device's profiles in the filesystem */
-	store(device);
-
-	if (req->msg) {
-		if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
-						"DiscoverServices")) {
-			discover_device_reply(req, req->records);
-			goto cleanup;
-		}
-
-		g_dbus_emit_signal(req->conn, dbus_message_get_path(req->msg),
-				ADAPTER_INTERFACE, "DeviceCreated",
-				DBUS_TYPE_OBJECT_PATH, &device->path,
-				DBUS_TYPE_INVALID);
-	}
-
-	/* Update device list */
-	adapter_update_devices(device->adapter);
-
-	if (!req->msg)
-		goto cleanup;
-
-	/* Reply create device request */
-	reply = dbus_message_new_method_return(req->msg);
-	if (!reply)
-		goto cleanup;
-
-	dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,
-							DBUS_TYPE_INVALID);
-
-	dbus_connection_send(req->conn, reply, NULL);
-	dbus_message_unref(reply);
-
-cleanup:
+
 	device->discov_active = 0;

 	if (device->discov_requestor) {
@@ -1039,7 +978,74 @@
 	if (req->records)
 		sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
 	g_free(req);
-
+}
+
+static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
+{
+	struct browse_req *req = user_data;
+	struct btd_device *device = req->device;
+	DBusMessage *reply;
+
+	if (err < 0) {
+		error("%s: error updating services: %s (%d)",
+				device->path, strerror(-err), -err);
+		goto proceed;
+	}
+
+	update_services(req, recs);
+
+	if (!req->uuids_added && !req->uuids_removed) {
+		debug("%s: No service update", device->path);
+		goto proceed;
+	}
+
+	/* Probe matching drivers for services added */
+	if (req->uuids_added)
+		device_probe_drivers(device, req->uuids_added, req->records);
+
+	/* Remove drivers for services removed */
+	if (req->uuids_removed)
+		device_remove_drivers(device, req->uuids_removed, req->records);
+
+	/* Propagate services changes */
+	services_changed(req);
+
+proceed:
+	/* Store the device's profiles in the filesystem */
+	store(device);
+
+	if (req->msg) {
+		if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
+						"DiscoverServices")) {
+			discover_device_reply(req, req->records);
+			goto cleanup;
+		}
+
+		g_dbus_emit_signal(req->conn, dbus_message_get_path(req->msg),
+				ADAPTER_INTERFACE, "DeviceCreated",
+				DBUS_TYPE_OBJECT_PATH, &device->path,
+				DBUS_TYPE_INVALID);
+	}
+
+	/* Update device list */
+	adapter_update_devices(device->adapter);
+
+	if (!req->msg)
+		goto cleanup;
+
+	/* Reply create device request */
+	reply = dbus_message_new_method_return(req->msg);
+	if (!reply)
+		goto cleanup;
+
+	dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path,
+							DBUS_TYPE_INVALID);
+
+	dbus_connection_send(req->conn, reply, NULL);
+	dbus_message_unref(reply);
+
+cleanup:
+	browse_req_free(req);
 }

 static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
@@ -1139,6 +1145,7 @@
 	bdaddr_t src;
 	uuid_t uuid;
 	bt_callback_t cb;
+	int err;

 	if (device->discov_active)
 		return -EBUSY;
@@ -1173,8 +1180,12 @@
 						device, NULL);
 	}

-	return bt_search_service(&src, &device->bdaddr,
-					&uuid, cb, req, NULL);
+	err = bt_search_service(&src, &device->bdaddr,
+				&uuid, cb, req, NULL);
+	if (err < 0)
+		browse_req_free(req);
+
+	return err;
 }

 struct btd_adapter *device_get_adapter(struct btd_device *device)


Poprawka obrazków w HTML-u (Bartłomiej Zimoń)

--- src/libgadu.c
+++ src/libgadu.c
@@ -1312,8 +1312,8 @@
 {
 	const char span_fmt[] = "";
 	const int span_len = 75;
-	const char img_fmt[] = "";
-	const int img_len = 28;
+	const char img_fmt[] = "";
+	const int img_len = 29;
 	int char_pos = 0;
 	int format_idx = 3;
 	unsigned char old_attr = 0;


device: Use new storage for device trust

As set_trust() changes value in device structure and write to
storage is deferred, property set could not return failure.

--- src/device.c
+++ src/device.c
@@ -226,6 +226,9 @@
 		g_key_file_set_string(key_file, "General", "Alias",
 					device->alias);

+	g_key_file_set_boolean(key_file, "General", "Trusted",
+				device->trusted);
+
 	ba2str(adapter_get_address(device->adapter), adapter_addr);
 	ba2str(&device->bdaddr, device_addr);
 	snprintf(filename, PATH_MAX, INFO_PATH, adapter_addr, device_addr);
@@ -713,22 +716,13 @@
 static void set_trust(GDBusPendingPropertySet id, gboolean value, void *data)
 {
 	struct btd_device *device = data;
-	struct btd_adapter *adapter = device->adapter;
-	char srcaddr[18], dstaddr[18];
-	int err;

 	if (device->trusted == value)
 		return g_dbus_pending_property_success(id);

-	ba2str(adapter_get_address(adapter), srcaddr);
-	ba2str(&device->bdaddr, dstaddr);
-
-	err = write_trust(srcaddr, dstaddr, device->bdaddr_type, value);
-	if (err < 0)
-		return g_dbus_pending_property_error(id,
-				ERROR_INTERFACE ".Failed", strerror(-err));
-
 	device->trusted = value;
+
+	store_device_info(device);

 	g_dbus_emit_property_changed(btd_get_dbus_connection(),
 				device->path, DEVICE_INTERFACE, "Trusted");
@@ -1753,6 +1747,10 @@
 	device->alias = g_key_file_get_string(key_file, "General", "Alias",
 						NULL);

+	/* Load trust */
+	device->trusted = g_key_file_get_boolean(key_file, "General",
+							"Trusted", NULL);
+
 	if (store_needed)
 		store_device_info(device);

@@ -1796,8 +1794,6 @@
 	ba2str(src, srcaddr);

 	load_info(device, srcaddr, address);
-
-	device->trusted = read_trust(src, address, device->bdaddr_type);

 	if (read_blocked(src, &device->bdaddr, device->bdaddr_type))
 		device_block(device, FALSE);


Poprawka konwersji do HTML (matiolszewski).

--- src/libgadu.c
+++ src/libgadu.c
@@ -1494,7 +1494,7 @@

 			format_idx += 3;

-			if ((attr & (GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR)) != 0) {
+			if ((attr & (GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR)) != 0 || (attr == 0 && old_attr != 0)) {
 				if (char_pos != 0) {
 					if ((old_attr & GG_FONT_UNDERLINE) != 0)
 						gg_append(dst, &len, "", 4);
@@ -1505,7 +1505,8 @@
 					if ((old_attr & GG_FONT_BOLD) != 0)
 						gg_append(dst, &len, "", 4);

-					gg_append(dst, &len, "", 7);
+					if (src[i] != 0)
+						gg_append(dst, &len, "", 7);
 				}

 				if (((attr & GG_FONT_COLOR) != 0) && (format_idx + 3 <= format_len)) {
@@ -1515,9 +1516,11 @@
 					color = (unsigned char*) "\x00\x00\x00";
 				}

-				if (dst != NULL)
-					sprintf(&dst[len], span_fmt, color[0], color[1], color[2]);
-				len += span_len;
+				if (src[i] != 0) {
+					if (dst != NULL)
+						sprintf(&dst[len], span_fmt, color[0], color[1], color[2]);
+					len += span_len;
+				}
 			} else if (char_pos == 0 && src[0] != 0) {
 				if (dst != NULL)
 					sprintf(&dst[len], span_fmt, 0, 0, 0);


Check for duplicate records when discovering services

--- src/device.c
+++ src/device.c
@@ -787,12 +787,18 @@

 		if (sdp_get_service_classes(rec, &svcclass) < 0)
 			continue;
-		store_record(src, dst, rec);

 		/* Extract the first element and skip the remainning */
 		uuid_str = bt_uuid2string(svcclass->data);
 		if (!uuid_str)
 			continue;
+
+		/* Check for duplicates */
+		if (g_slist_find_custom(req->uuids_added, uuid_str,
+						(GCompareFunc) strcmp))
+			continue;
+
+		store_record(src, dst, rec);

 		/* Copy record */
 		if (sdp_gen_record_pdu(rec, &pdu) == 0) {


dhcpcd: Rename function for prior now it no longer inits

--- src/dhcpcd.c
+++ src/dhcpcd.c
@@ -1154,7 +1154,7 @@
 #endif

 static void
-dhcpcd_initprestartinterface(void *arg)
+dhcpcd_runprestartinterface(void *arg)
 {
 	struct interface *ifp = arg;

@@ -1227,7 +1227,7 @@
 		if (ifp->active) {
 			dhcpcd_initstate(ifp, 0);
 			eloop_timeout_add_sec(ctx->eloop, 0,
-			    dhcpcd_initprestartinterface, ifp);
+			    dhcpcd_runprestartinterface, ifp);
 		}
 	}
 	free(ifaces);


docs: fix double articles bug

docs: fix double articles bug

Delete the extra article 'the'.

Signed-off-by: Wang Yufei <29d8b7da2f1f99924c75ef99c490e51ba28217ef@huawei.com>
Signed-off-by: Eric Blake <a9da18479c871fe903d9590822cfe2629c6a4d11@redhat.com>

--- src/libvirt.c
+++ src/libvirt.c
@@ -16526,7 +16526,7 @@
  * Otherwise, creates a new secret with an automatically chosen UUID, and
  * initializes its attributes from xml.
  *
- * Returns a the secret on success, NULL on failure.
+ * Returns a secret on success, NULL on failure.
  */
 virSecretPtr
 virSecretDefineXML(virConnectPtr conn, const char *xml, unsigned int flags)


Fix -B and -E, these options are supported only once


whitespace

whitespace

--- src/luabins.c
+++ src/luabins.c
@@ -55,9 +55,9 @@
 /* luabins Lua module API */
 static const struct luaL_reg R[] =
 {
-	{ "save", l_save },
-	{ "load", l_load },
-	{ NULL, NULL }
+  { "save", l_save },
+  { "load", l_load },
+  { NULL, NULL }
 };

 #ifdef __cplusplus


vm: Fix incorrect comment about registers having types.

It's been a long time since values have included types.

--- src/lily_vm.c
+++ src/lily_vm.c
@@ -431,17 +431,10 @@
  *                |___/
  */

-/** Lily is a register-based vm. This means that each call has a block of values
-    that belong to it. Upon a call's entry, the types of the registers are set,
-    and values are put into the registers. Each register has a type that it will
-    retain through the lifetime of the call.
-
-    This section deals with operations concerning registers. One area that is
-    moderately difficult is handling generics. Lily does not create specialized
-    concretely-typed functions in place of generic ones, but instead checks for
-    soundness and defers things to vm-time. The vm is then tasked with changing
-    a register with a seed type of, say, A, into whatever it should be for the
-    given invocation. **/
+/** This section handles growing registers and also copying register values over
+    for calls. This is also where pushing functions are, which push new values
+    onto the stack and increase the top pointer. Those functions are called
+    from outside the vm. **/

 static void vm_error(lily_vm_state *, uint8_t, const char *);


develop merge fix

develop merge fix

--- src/dnssec.c
+++ src/dnssec.c
@@ -835,7 +835,7 @@
 	q_rrset.pkt_len  = pkt_len;
 	q_rrset.sections = SECTION_ANSWER;

-	for (anti_loop = MAX_CNAMES; anti_loop; anti_loop--) {
+	for (anti_loop = MAX_CNAME_REFERRALS; anti_loop; anti_loop--) {
 		if (!(rr = _getdns_rrtype_iter_init(&rr_spc, &q_rrset)))
 			break;
 		if (!(rdf = _getdns_rdf_iter_init(&rdf_spc, &rr->rr_i)))


Use %m instead of strerror() when available

Use %m under HAVE_M_FORMAT instead of strerror()

Signed-off-by: Rachid Koucha <55b470430ab0f78cdba904b886a7b6e0a92ea649@gmail.com>

--- src/lxc/log.h
+++ src/lxc/log.h
@@ -416,53 +416,94 @@
 	LXC_FATAL(&locinfo, format, ##__VA_ARGS__);			\
 } while (0)

+#if HAVE_M_FORMAT
+#define SYSTRACE(format, ...)                              \
+		TRACE("%m - " format, ##__VA_ARGS__);
+#else
 #define SYSTRACE(format, ...)                              \
 	do {                                               \
 		lxc_log_strerror_r;                        \
 		TRACE("%s - " format, ptr, ##__VA_ARGS__); \
 	} while (0)
-
+#endif
+
+#if HAVE_M_FORMAT
+#define SYSDEBUG(format, ...)                              \
+                DEBUG("%m - " format, ##__VA_ARGS__)
+#else
 #define SYSDEBUG(format, ...)                              \
 	do {                                               \
 		lxc_log_strerror_r;                        \
 		DEBUG("%s - " format, ptr, ##__VA_ARGS__); \
 	} while (0)
-
+#endif
+
+
+#if HAVE_M_FORMAT
+#define SYSINFO(format, ...)                              \
+                INFO("%m - " format, ##__VA_ARGS__)
+#else
 #define SYSINFO(format, ...)                              \
 	do {                                              \
 		lxc_log_strerror_r;                       \
 		INFO("%s - " format, ptr, ##__VA_ARGS__); \
 	} while (0)
-
+#endif
+
+#if HAVE_M_FORMAT
+#define SYSNOTICE(format, ...)                              \
+		NOTICE("%m - " format, ##__VA_ARGS__)
+#else
 #define SYSNOTICE(format, ...)                              \
 	do {                                                \
 		lxc_log_strerror_r;                         \
 		NOTICE("%s - " format, ptr, ##__VA_ARGS__); \
 	} while (0)
-
+#endif
+
+#if HAVE_M_FORMAT
+#define SYSWARN(format, ...)                              \
+		WARN("%m - " format, ##__VA_ARGS__)
+#else
 #define SYSWARN(format, ...)                              \
 	do {                                              \
 		lxc_log_strerror_r;                       \
 		WARN("%s - " format, ptr, ##__VA_ARGS__); \
 	} while (0)
-
+#endif
+
+#if HAVE_M_FORMAT
+#define SYSERROR(format, ...)                              \
+		ERROR("%m - " format, ##__VA_ARGS__)
+#else
 #define SYSERROR(format, ...)                              \
 	do {                                               \
 		lxc_log_strerror_r;                        \
 		ERROR("%s - " format, ptr, ##__VA_ARGS__); \
 	} while (0)
-
+#endif
+
+#if HAVE_M_FORMAT
+#define CMD_SYSERROR(format, ...)                                    \
+		fprintf(stderr, "%m - " format, ##__VA_ARGS__)
+#else
 #define CMD_SYSERROR(format, ...)                                    \
 	do {                                                         \
 		lxc_log_strerror_r;                                  \
 		fprintf(stderr, "%s - " format, ptr, ##__VA_ARGS__); \
 	} while (0)
-
+#endif
+
+#if HAVE_M_FORMAT
+#define CMD_SYSINFO(format, ...)                            \
+		printf("%m - " format, ##__VA_ARGS__)
+#else
 #define CMD_SYSINFO(format, ...)                            \
 	do {                                                \
 		lxc_log_strerror_r;                         \
 		printf("%s - " format, ptr, ##__VA_ARGS__); \
 	} while (0)
+#endif

 extern int lxc_log_fd;


driver: Don't leak saved error in virGetConnectGeneric()

Recently, a new code was added to virGetConnectGeneric() that
saves the original error into a variable so that it's not lost in
virConnectClose() called under the 'error' label.

However, the error saving code uses virSaveLastError() +
virSetError() combo which leaks the memory allocated for the
error copy. Using virErrorPreserveLast() + virErrorRestore() does
the same job without the memleak.

Signed-off-by: Michal Privoznik <83d82aaba2eed257f4814b0c239c260c4caaadf0@redhat.com>
Reviewed-by: Ján Tomko <4cab11cfb98d3c937327354a78eb07dbb6ee2bc6@redhat.com>

--- src/driver.c
+++ src/driver.c
@@ -138,7 +138,7 @@
 virGetConnectGeneric(virThreadLocal *threadPtr, const char *name)
 {
     virConnectPtr conn;
-    virErrorPtr saved;
+    virErrorPtr orig_err;

     if (virConnectCacheInitialize() < 0)
         return NULL;
@@ -178,9 +178,9 @@
     return conn;

  error:
-    saved = virSaveLastError();
+    virErrorPreserveLast(&orig_err);
     virConnectClose(conn);
-    virSetError(saved);
+    virErrorRestore(&orig_err);
     return NULL;
 }


log: account for Android's Bionic's strerror_r()

Signed-off-by: Christian Brauner <48455ab3070520a2d174545c7239d6d0fabd9a83@ubuntu.com>

--- src/lxc/log.h
+++ src/lxc/log.h
@@ -295,7 +295,7 @@
 /*
  * Helper macro to define errno string.
  */
-#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE)
+#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE) || IS_BIONIC
 #define lxc_log_strerror_r                                               \
 	char errno_buf[MAXPATHLEN / 2] = {"Failed to get errno string"}; \
 	char *ptr = errno_buf;                                           \


Dead code removal

Dead code removal

Remove some #if 0 code.

Signed-off-by: Jeremy Huddleston <db3cec0cba09acb9cf8fd8bd399a3b27498cf883@apple.com>
Reviewed-by: Jamey Sharp <167c1dcbbc9c320e8e02a0c15c886204b4e658a4@minilop.net>

--- src/driver.c
+++ src/driver.c
@@ -485,63 +485,6 @@
     pScrn->modes->prev->next = pScrn->modes;

     return ret;
-
-#if 0
-    /* Use xf86ValidateModes */
-    ClockRangePtr clockRanges;
-    int rc;
-
-    pScrn->videoRam = 1024*128; /* kByte */
-    pScrn->progClock = TRUE;
-    clockRanges = (ClockRangePtr)xnfcalloc(sizeof(ClockRange), 1);
-    clockRanges->next = NULL;
-    clockRanges->ClockMulFactor = 1;
-    clockRanges->minClock = 1;
-    clockRanges->maxClock = 3000000;
-    clockRanges->clockIndex = 1;
-    clockRanges->interlaceAllowed = TRUE;
-    clockRanges->doubleScanAllowed = TRUE;
-    rc = xf86ValidateModes(pScrn,                    /* scrp        */
-                          pScrn->monitor->Modes,    /* availModes  */
-                          pScrn->display->modes,    /* modeNames   */
-                          clockRanges,              /* cockRanges  */
-                          NULL,                     /* linePitches (opt) */
-                          256,                      /* minPitch    (opt) */
-                          2048,                     /* maxPitch    (opt) */
-                          (8*pScrn->bitsPerPixel),  /* pitchInc    */
-                          0,                        /* minHeight   (opt) */
-                          0,                        /* maxHeight   (opt) */
-                          pScrn->display->virtualX, /* virualX     (opt) */
-                          pScrn->display->virtualY, /* virtualY    (opt) */
-                          pScrn->videoRam * 1024,   /* apertureSize */
-                          LOOKUP_BEST_REFRESH       /* strategy */);
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "pScrn->modePool: 0x%x\n",
-               pScrn->modePool);
-
-    int rounds = 0;
-    for (mode = pScrn->modes;
-         (mode != pScrn->modes) && (rounds == 1);
-         mode = mode->next) {
-        rounds = 1;
-        NestedValidMode(pScrn->scrnIndex, mode, FALSE, 0);
-
-    }
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "pScrn->virtualX: %d\n",
-               pScrn->virtualX);
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "pScrn->virtualY: %d\n",
-               pScrn->virtualY);
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "pScrn->displayWidth: %d\n",
-               pScrn->displayWidth);
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "pScrn->virtualFrom: %d\n",
-               pScrn->virtualFrom);
-    if (rc < 1) {
-        return rc;
-    } else {
-        xf86PruneDriverModes(pScrn);
-        return rc;
-    }
-#endif
 }

 Bool


fix race condition in monitorWait

fix race condition in monitorWait

We don't want to check Thread::waiting until we have re-acquired the
monitor, since another thread might notify us between releasing
Thread::lock and acquiring the monitor.

--- src/machine.h
+++ src/machine.h
@@ -2508,7 +2508,6 @@

   bool interrupted;
   unsigned depth;
-  bool stillWaiting;

   PROTECT(t, monitor);

@@ -2524,13 +2523,11 @@
     ENTER(t, Thread::IdleState);

     interrupted = t->lock->wait(t->systemThread, time);
-
-    stillWaiting = t->waiting;
   }

   monitorAcquire(t, monitor);

-  if (stillWaiting) {
+  if (t->waiting) {
     monitorRemoveWait(t, monitor);
   }


Wrapping words and graphemes by default

Wrapping words and graphemes by default

--- src/editor.c
+++ src/editor.c
@@ -149,6 +149,9 @@
 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget),
 			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 	editor->view = gtk_text_view_new();
+	/* FIXME make it an option */
+	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(editor->view),
+			GTK_WRAP_WORD_CHAR);
 	desc = pango_font_description_new();
 	pango_font_description_set_family(desc, "monospace");
 	gtk_widget_modify_font(editor->view, desc);


Fix bugs found in testing

Fix bugs found in testing


core: Fix forcing close socket

core: Fix forcing close socket

This patch fixes the following warning when the cloud service
closes the connection. The current approach was forcing to close
the cloud (protocol) socket, even when HUP signal has been received.
(knotd:6016): GLib-WARNING **: Invalid file descriptor

--- src/manager.c
+++ src/manager.c
@@ -56,8 +56,9 @@
  * device context: 'drivers' and file descriptors
  */
 struct session {
-	unsigned int radio_id;	/* Radio event source */
+	unsigned int node_id;	/* Radio event source */
 	unsigned int proto_id;	/* TCP/backend event source */
+	GIOChannel *node_io;	/* Radio GIOChannel reference */
 	GIOChannel *proto_io;	/* Protocol GIOChannel reference */
 	struct node_ops *ops;
 };
@@ -168,8 +169,11 @@
 	ssize_t recvbytes, sentbytes, olen;
 	int sock, proto_sock, err;

-	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
+	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+		/* Mark as removed */
+		session->node_id = 0;
 		return FALSE;
+	}

 	sock = g_io_channel_unix_get_fd(io);

@@ -177,7 +181,7 @@
 	if (recvbytes < 0) {
 		err = errno;
 		LOG_ERROR("readv(): %s(%d)\n", strerror(err), err);
-		return FALSE;
+		return TRUE;
 	}

 	proto_sock = g_io_channel_unix_get_fd(session->proto_io);
@@ -206,21 +210,21 @@
 {

 	struct session *session = user_data;
-	int sock;
-
-	/* Mark as removed */
-	session->radio_id = 0;
-
-	/*
-	 * When the protocol connection (backend) is dropped
-	 * call signoff & unref the GIOChannel.
-	 */
-	sock = g_io_channel_unix_get_fd(session->proto_io);
-	proto_ops[proto_index]->close(sock);
-	g_io_channel_unref(session->proto_io);
-
-	if (session->proto_id)
+	GIOChannel *proto_io;
+
+	proto_io = session->proto_io;
+
+	if (session->proto_id) {
+		/* Trigger proto destroy callback */
 		g_source_remove(session->proto_id);
+
+		/* Mark for shutdown */
+		g_io_channel_shutdown(proto_io, FALSE, NULL);
+	}
+
+	/* Release last reference and shutdown */
+	g_io_channel_unref(proto_io);
+	LOG_INFO("proto_io unref(%p)\n", proto_io);

 	g_free(session);
 }
@@ -228,7 +232,13 @@
 static gboolean proto_io_watch(GIOChannel *io, GIOCondition cond,
 					       gpointer user_data)
 {
-	/* Return FALSE to remove protocol GIOChannel reference */
+	struct session *session = user_data;
+
+	/*
+	 * Mark protocol watch as removed. Return
+	 * FALSE to remove GIOChannel watch.
+	 */
+	session->proto_id = 0;

 	return FALSE;
 }
@@ -236,19 +246,26 @@
 static void proto_io_destroy(gpointer user_data)
 {
 	struct session *session = user_data;
+	GIOChannel *node_io;

 	/*
-	 * Remove Unix socket GIOChannel watch when protocol
-	 * socket disconnects. Removing the watch triggers
-	 * channe unref and consequently disconnection of
-	 * the Unix socket
+	 * Assign to a temporary reference: 'session' might be
+	 * freed by node destroy callback (triggered by source
+	 * remove).
 	 */
-
-	/* Mark protocol watch as removed */
-	session->proto_id = 0;
-
-	if (session->radio_id)
-	    g_source_remove(session->radio_id);
+	node_io = session->node_io;
+
+	if (session->node_id) {
+		/* Trigger node destroy callback */
+		g_source_remove(session->node_id);
+
+		/* Mark for shutdown */
+		g_io_channel_shutdown(node_io, TRUE, NULL);
+	}
+
+	/* Release last reference and shutdown */
+	g_io_channel_unref(node_io);
+	LOG_INFO("node_io unref(%p)\n", node_io);
 }

 static gboolean accept_cb(GIOChannel *io, GIOCondition cond,
@@ -265,7 +282,6 @@

 	srv_sock = g_io_channel_unix_get_fd(io);

-	LOG_INFO("%p accept()\n", ops);
 	sockfd = ops->accept(srv_sock);
 	if (sockfd < 0) {
 		LOG_ERROR("%p accept(): %s(%d)\n", ops,
@@ -274,23 +290,19 @@
 	}

 	node_io = g_io_channel_unix_new(sockfd);
-	g_io_channel_set_close_on_unref(node_io, TRUE);

 	proto_sock = proto_ops[proto_index]->connect();
 	proto_io = g_io_channel_unix_new(proto_sock);
-	g_io_channel_set_close_on_unref(proto_io, TRUE);

 	session = g_new0(struct session, 1);
 	/* Watch for unix socket disconnection */
 	watch_cond = G_IO_HUP | G_IO_NVAL | G_IO_ERR | G_IO_IN;
-	session->radio_id = g_io_add_watch_full(node_io,
+	session->node_id = g_io_add_watch_full(node_io,
 				G_PRIORITY_DEFAULT, watch_cond,
 				node_io_watch, session,
 				node_io_destroy);

-	/* Keep only one ref: GIOChannel watch */
-	g_io_channel_unref(node_io);
-
+	session->node_io = node_io;
 	/* Watch for TCP socket disconnection */
 	watch_cond = G_IO_HUP | G_IO_NVAL | G_IO_ERR;
 	session->proto_id = g_io_add_watch_full(proto_io,
@@ -303,6 +315,8 @@

 	/* TODO: Create refcount */
 	session->ops = ops;
+
+	LOG_INFO("node:%p proto:%p\n", node_io, proto_io);

 	return TRUE;
 }


gw: Add Meshblu registration response consistency

This patch extends the registration response parsing function returning
the status of JSON parsing (UUID & token).

--- src/manager.c
+++ src/manager.c
@@ -161,26 +161,28 @@
 	return 0;
 }

-static void parse_device_info(const char *json_str, struct session *session)
+static int parse_device_info(const char *json_str, struct session *session)
 {
 	json_object *jobj,*json_uuid, *json_token;
 	const char *uuid, *token;

 	jobj = json_tokener_parse(json_str);
 	if (jobj == NULL)
-		return;
+		return -EINVAL;

 	if (!json_object_object_get_ex(jobj, "uuid", &json_uuid))
-		return;
+		return -EINVAL;

 	if (!json_object_object_get_ex(jobj, "token", &json_token))
-		return;
+		return -EINVAL;

 	uuid = json_object_get_string(json_uuid);
 	token = json_object_get_string(json_token);

 	session->uuid = g_strdup(uuid);
 	session->token = g_strdup(token);
+
+	return 0;
 }

 static gboolean node_io_watch(GIOChannel *io, GIOCondition cond,
@@ -190,7 +192,7 @@
 	struct node_ops *ops = session->ops;
 	uint8_t dgram[128];
 	const knot_header *hdr = (const knot_header *) dgram;
-	struct json_buffer jbuf = { .data = NULL, .size = 0 };
+	struct json_buffer jbuf;
 	ssize_t nbytes;
 	int sock, proto_sock, err = 0;

@@ -211,9 +213,15 @@
 	proto_sock = g_io_channel_unix_get_fd(session->proto_io);
 	switch (hdr->opcode) {
 	case KNOT_OP_REGISTER:
+		memset(&jbuf, 0, sizeof(jbuf));
 		err = proto_ops[proto_index]->signup(proto_sock,
 						owner->uuid, &jbuf);
-		printf("%s: %s\n", __PRETTY_FUNCTION__, jbuf.data);
+		if (err < 0) {
+			printf("manager signup: %s(%d)\n",
+						strerror(-err), -err);
+			return FALSE;
+		}
+
 		parse_device_info(jbuf.data, session);
 		free(jbuf.data);
 		break;


Faster node name resolution (two seconds)

--- src/manager.h
+++ src/manager.h
@@ -44,11 +44,9 @@

 #define STATE_BAD        -1
 #define STATE_READY       0
-#define STATE_WAITING___  1
-#define STATE_WAITING__   2
-#define STATE_WAITING_    3
-#define STATE_WAITING     4
-#define STATE_RESET       5
+#define STATE_WAITING_    1
+#define STATE_WAITING     2
+#define STATE_RESET       3

 typedef struct opts_s {


- Whoops, fixed compilation issue on mob_dead.

git-svn-id: c1e39603916b71782cde5facdf0b79eff05c1414@7210 54d463be-8e91-2dee-dedb-b68131a5f0ec

--- src/map/mob.c
+++ src/map/mob.c
@@ -2083,7 +2083,7 @@
 			log_mvpdrop(mvp_sd, md->class_, log_mvp);
 	}

-	if (flag&2 && !sd && md->class_ == MOBID_EMPERIUM)
+	if (type&2 && !sd && md->class_ == MOBID_EMPERIUM)
 	  	//Emperium destroyed by script. Discard mvp character. [Skotlex]
 		mvp_sd = NULL;


fixed int writing

fixed int writing

--- src/map/int.c
+++ src/map/int.c
@@ -79,8 +79,8 @@

 		if (arg->need_alloc)
 			*(arg->output) = malloc(sizeof(intmax_t));
-		**((intmax_t**)arg->output) = signed_int;
-		printf("  Value: %lld\n", **((intmax_t**)arg->output));
+		*((intmax_t*)arg->output) = signed_int;
+		printf("  Value: %lld\n", *((intmax_t*)arg->output));
 	}

 	/* if (is_signed) { */


处理log_level名称

--- src/ez_log.c
+++ src/ez_log.c
@@ -30,18 +30,18 @@
 static struct logger logger;

 static struct logLevelInfo LOG_LEVEL_INFO[] = {
-	{.name = "LOG_EMERG",.level = LOG_EMERG},
-	{.name = "LOG_ALERT",.level = LOG_ALERT},
-	{.name = "LOG_CRIT",.level = LOG_CRIT},
-	{.name = "LOG_ERR",.level = LOG_ERR},
-	{.name = "LOG_WARN",.level = LOG_WARN},
-	{.name = "LOG_NOTICE",.level = LOG_NOTICE},
-	{.name = "LOG_INFO",.level = LOG_INFO},
-	{.name = "LOG_DEBUG",.level = LOG_DEBUG},
-	{.name = "LOG_VERB",.level = LOG_VERB},
-	{.name = "LOG_VVERB",.level = LOG_VVERB},
-	{.name = "LOG_VVVERB",.level = LOG_VVVERB},
-	{.name = "LOG_PVERB",.level = LOG_PVERB},
+	{.name = "EMERG",.level = LOG_EMERG},
+	{.name = "ALERT",.level = LOG_ALERT},
+	{.name = "CRIT",.level = LOG_CRIT},
+	{.name = "ERR",.level = LOG_ERR},
+	{.name = "WARN",.level = LOG_WARN},
+	{.name = "NOTICE",.level = LOG_NOTICE},
+	{.name = "INFO",.level = LOG_INFO},
+	{.name = "DEBUG",.level = LOG_DEBUG},
+	{.name = "VERB",.level = LOG_VERB},
+	{.name = "VVERB",.level = LOG_VVERB},
+	{.name = "VVVERB",.level = LOG_VVVERB},
+	{.name = "PVERB",.level = LOG_PVERB},
 	{.name = NULL}
 };

@@ -158,7 +158,7 @@

 	len +=
 	    ez_scnprintf(buf + len, size - len,
-			 "%04d-%02d-%02d %02d:%02d:%02d.%03d [%10s] %s:%d ",
+			 "%04d-%02d-%02d %02d:%02d:%02d.%03d [%6s] %s:%d ",
 			 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
 			 tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(tv.tv_usec / 1000),
 			 get_log_level_name(log_level), file, line);


- Cleaned up unused variables in npc.c

- Cleaned up unused variables in npc.c

git-svn-id: c1e39603916b71782cde5facdf0b79eff05c1414@6383 54d463be-8e91-2dee-dedb-b68131a5f0ec

--- src/map/npc.c
+++ src/map/npc.c
@@ -50,7 +50,7 @@
 static int npc_delay_mob=0;
 static int npc_cache_mob=0;
 char *current_file = NULL;
-int dummy_npc_id=0;
+//int dummy_npc_id=0;
 int npc_get_new_npc_id(void){ return npc_id++; }

 static struct dbt *ev_db;
@@ -2793,7 +2793,7 @@
 	add_timer_func_list(npc_timerevent,"npc_timerevent");

 	// Init dummy NPC
-	dummy_npc_id = npc_get_new_npc_id();
+	//dummy_npc_id = npc_get_new_npc_id();

 	return 0;
 }


fixed bug where updating expression string would cause switch to linear mode

--- src/mapping.c
+++ src/mapping.c
@@ -512,7 +512,8 @@
     }

     // TO DO: test if range has actually changed
-    if (m->props.range.known == MAPPING_RANGE_KNOWN) {
+    if (m->props.range.known == MAPPING_RANGE_KNOWN
+        && m->props.mode == SC_LINEAR) {
         mapper_mapping_set_linear_range(m, sig, &m->props.range);
     }

@@ -545,6 +546,7 @@
     case -1:
         /* No mode type specified; if mode not yet set, see if
          we know the range and choose between linear or direct mapping. */
+            printf("MAPPING MODE: %i\n", m->props.mode);
             if (m->props.mode == SC_UNDEFINED) {
                 if (range_known == MAPPING_RANGE_KNOWN) {
                     /* We have enough information for a linear mapping. */


Fixed bug with official npc idle timer thing, bugreport:5343

git-svn-id: c1e39603916b71782cde5facdf0b79eff05c1414@15598 54d463be-8e91-2dee-dedb-b68131a5f0ec

--- src/map/npc.c
+++ src/map/npc.c
@@ -214,9 +214,10 @@
  **/
 int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data) {
 	struct map_session_data* sd = NULL;
-	if( (sd = map_id2sd(id)) == NULL || !sd->npc_id )
+	if( (sd = map_id2sd(id)) == NULL || !sd->npc_id ) {
+		if( sd ) sd->npc_idle_timer = INVALID_TIMER;
 		return 0;//Not logged in anymore OR no longer attached to a npc
-
+	}
 	if( DIFF_TICK(tick,sd->npc_idle_tick) > (SECURE_NPCTIMEOUT*1000) ) {
 		/**
 		 * If we still have the NPC script attached, tell it to stop.
@@ -227,6 +228,7 @@
 		 * This guy's been idle for longer than allowed, close him.
 		 **/
 		clif_scriptclose(sd,sd->npc_id);
+		sd->npc_idle_timer = INVALID_TIMER;
 	} else //Create a new instance of ourselves to continue
 		sd->npc_idle_timer = add_timer(gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
 	return 0;


Update Foursquare2.h

Update Foursquare2.h

--- Foursquare2/Foursquare2.h
+++ Foursquare2/Foursquare2.h
@@ -111,7 +111,7 @@
  Returns the dispatch queue in which request callbacks are called.
  */

-+ (dispatch_queue_T)callbackQueue;
++ (dispatch_queue_t)callbackQueue;

 /**
  Setup Foursqare2 with clientId, secret and callbackURL.


Allow 'nil' as valid argument for type='any'.

--- src/marshal.c
+++ src/marshal.c
@@ -933,6 +933,9 @@
       if (g_type_info_is_pointer (ti))
 	{
 	  /* Check and marshal according to real Lua type. */
+	  if (lua_isnoneornil (L, narg))
+	    /* nil -> NULL. */
+	    val->v_pointer = NULL;
 	  if (lua_type (L, narg) == LUA_TSTRING)
 	    /* Use string directly. */
 	    val->v_pointer = (gpointer) lua_tostring (L, narg);


Fix handling of filenames, use proper conversion routines on them

--- src/marshal.c
+++ src/marshal.c
@@ -841,14 +841,27 @@
 	break;
       }

-      /* We have no distinction between filename and utf8, Lua does
-	 not enforce any encoding on the strings. */
     case GI_TYPE_TAG_UTF8:
     case GI_TYPE_TAG_FILENAME:
       {
 	const gchar *str = (optional && lua_isnoneornil (L, narg)
 			    ? NULL : luaL_checkstring (L, narg));
-	if (transfer == GI_TRANSFER_EVERYTHING)
+	if (tag == GI_TYPE_TAG_FILENAME)
+	  {
+	    /* Convert from UTF-8 to filename encoding. */
+	    if (str)
+	      {
+		str = g_filename_from_utf8 (str, -1, NULL, NULL, NULL);
+		if (transfer != GI_TRANSFER_EVERYTHING)
+		  {
+		    /* Create temporary object on the stack which will
+		       destroy the allocated temporary filename. */
+		    *lgi_guard_create (L, g_free) = (gpointer) str;
+		    nret = 1;
+		  }
+	      }
+	  }
+	else if (transfer == GI_TRANSFER_EVERYTHING)
 	  str = g_strdup (str);
 	if (use_pointer)
 	  val->v_pointer = (gchar *)str;
@@ -1252,7 +1265,14 @@
     case GI_TYPE_TAG_FILENAME:
       {
 	gchar *str = use_pointer ? val->v_pointer : val->v_string;
-	lua_pushstring (L, str);
+	if (tag == GI_TYPE_TAG_FILENAME && str != NULL)
+	  {
+	    gchar *utf8 = g_filename_to_utf8 (str, -1, NULL, NULL, NULL);
+	    lua_pushstring (L, utf8);
+	    g_free (utf8);
+	  }
+	else
+	  lua_pushstring (L, str);
 	if (transfer == GI_TRANSFER_EVERYTHING)
 	  g_free (str);
 	break;


[LWP] Modification Thread Unix

[LWP] Modification Thread Unix

--- Generics/LWP/UnixThread.h
+++ Generics/LWP/UnixThread.h
@@ -40,7 +40,7 @@

   virtual void launch(void)
   {
-    this->id_ = pthread_create(&this->t_, 0, &Thread::threadProc, 0);
+    this->id_ = pthread_create(&this->t_, 0, &Thread::threadProc, this);
   }

   virtual void join(void)


minor tweaks to remove warnings

minor tweaks to remove warnings

--- src/maxmind.c
+++ src/maxmind.c
@@ -24,11 +24,12 @@
     fprintf(stdout, "-s : if set will silence output. otherwise this program writes to stdout.\n\n");
 }

+
 char * MMDB_PATH = NULL;
 int verbose = 1;

 int main(int argc, char **argv) {
-    int c, errno = 0;
+    int c = 0;
     const char *testip = "4.4.4.4";
     while ((c = getopt(argc, argv, "hm:st:?")) != -1) {
         switch (c) {
@@ -76,7 +77,7 @@
     const char *country_lookup[] = {"country", "iso_code", NULL};
     const char *expected = "US";

-    char *actual = geo_lookup(&mmdb_handle, testip, country_lookup);
+    const char *actual = geo_lookup(&mmdb_handle, testip, country_lookup);
     if (strncmp(actual, expected, 2)) {
         if (verbose) {
             fprintf(stderr, "Invalid mamxind db file. Bad actual for %s - should be 'US' but was '%s'\n", testip, actual);


Fix pasto, accessing Object GValue by BOXED api.

--- src/marshal.c
+++ src/marshal.c
@@ -890,7 +890,7 @@
     case G_TYPE_OBJECT:
       {
 	vals = lgi_compound_get (L, narg, &type, &obj, FALSE);
-	g_value_set_boxed (val, obj);
+	g_value_set_object (val, obj);
 	lua_pop (L, vals);
 	return;
       }


Fix regression with rsa_sha2_verify #758 (#763)

Fixes comparison with the result value coming from `mbedtls_rsa_pkcs1_verify`. Success is 0, not 1.

--- src/mbedtls.c
+++ src/mbedtls.c
@@ -541,7 +541,7 @@
 #endif
     free(hash);

-    return (ret == 1) ? 0 : -1;
+    return (ret == 0) ? 0 : -1;
 }

 int


Fix for valgrind to output Invalid read.

--- src/getset.c
+++ src/getset.c
@@ -519,7 +519,7 @@
 				ValueString(val) = (unsigned char *)xmalloc(size);
 			}
 			memclear(ValueString(val),ValueStringSize(val));
-			memcpy(ValueString(val),str,size - 1);
+			strncpy(ValueString(val),str,size - 1);
 			if		(  codeset  !=  NULL  ) {
 				cd = iconv_open("utf8",codeset);
 				while	(TRUE) {


Define new Diffie-Hellman context for mbedTLS


another 32 bit optimization for sysx_time_gmtime()

--- src/gmtime.c
+++ src/gmtime.c
@@ -19,9 +19,9 @@
 // ---------- macros -------------------------------------------
 */

-static const uint64_t SECONDS_TO_1970 = LIBCORE_d64C(62135596800);
-
-static const uint64_t SECONDS_IN_GREG = LIBCORE_d64C(12622780800);
+static const unsigned DAYS_TO_1970 = 719162;
+
+static const unsigned DAYS_IN_GREG = 146097;

 static const unsigned SECONDS_PER_DAY = 24 * 60 * 60;

@@ -178,22 +178,20 @@
 LIBCORE__STDCALL(xbrokentime *)
 sysx_time_gmtime(time_t tm32, xbrokentime *tmrec)
 {
-    int64_t tm64;
     int tm_greg, days, year, secs;

     unsigned int leap;

-    tm64 = tm32 + SECONDS_TO_1970;
-    tm_greg = (int) (tm64 / SECONDS_IN_GREG);
-    tm64 %= SECONDS_IN_GREG;
-
-    if (tm64 < 0) {
+    secs = (int)(tm32 % (time_t)SECONDS_PER_DAY);
+    days = (int)(tm32 / (time_t)SECONDS_PER_DAY);
+    days += DAYS_TO_1970;
+    tm_greg = days / DAYS_IN_GREG;
+    days %= DAYS_IN_GREG;
+
+    if (days < 0) {
         tm_greg--;
-        tm64 += SECONDS_IN_GREG;
+        days += DAYS_IN_GREG;
     }
-
-    days = (int) (tm64 / SECONDS_PER_DAY);
-    secs = (int) (tm64 % SECONDS_PER_DAY);

     tmrec->tm_wday = (days + 1) % 7;


branches/zip: rec_get_nth_field_offs_old(): Replace if (!cond) ut_error; tests with ut_a(cond).

--- rem/rem0rec.c
+++ rem/rem0rec.c
@@ -695,19 +695,9 @@
 	ulint	os;
 	ulint	next_os;

-	ut_ad(rec && len);
-	ut_ad(n < rec_get_n_fields_old(rec));
-
-	if (UNIV_UNLIKELY(n > REC_MAX_N_FIELDS)) {
-		fprintf(stderr, "Error: trying to access field %lu in rec\n",
-			(ulong) n);
-		ut_error;
-	}
-
-	if (UNIV_UNLIKELY(rec == NULL)) {
-		fputs("Error: rec is NULL pointer\n", stderr);
-		ut_error;
-	}
+	ut_ad(len);
+	ut_a(rec);
+	ut_a(n < rec_get_n_fields_old(rec));

 	if (rec_get_1byte_offs_flag(rec)) {
 		os = rec_1_get_field_start_offs(rec, n);


Remove two unused variables.

Remove two unused variables.

--- src/mdl/mdl.c
+++ src/mdl/mdl.c
@@ -1,4 +1,4 @@
-/* $Id: mdl.c,v 1.37 2016/06/27 20:07:31 je Exp $ */
+/* $Id: mdl.c,v 1.38 2016/06/30 19:31:19 je Exp $ */

 /*
  * Copyright (c) 2015, 2016 Juha Erkkil <je@turnipsi.no-ip.org>
@@ -266,9 +266,6 @@
 {
 	struct imsg imsg;
 	ssize_t nr;
-	int seq_socket;
-
-	seq_socket = -1;

 	if ((nr = imsg_read(&server_conn->ibuf)) == -1 || nr == 0) {
 		warnx("error in reading from server / imsg_read");
@@ -524,7 +521,7 @@
     enum sequencer_event event)
 {
 	struct imsg imsg;
-	ssize_t nr, datalen;
+	ssize_t nr;
 	int found;

 	found = 0;
@@ -547,8 +544,6 @@
 		}
 		if (nr == 0)
 			continue;
-
-		datalen = imsg.hdr.len - IMSG_HEADER_SIZE;

 		if (imsg.hdr.type == event)
 			found = 1;


add ipv6 checking

add ipv6 checking

--- src/hndlrs.c
+++ src/hndlrs.c
@@ -1283,7 +1283,8 @@
 		if(continue_checks
 			&& gMtaHostIpChk
 			&& strcmp(priv->helo,priv->iphostname) != 0
-			&& !dns_hostname_ip_match(priv->presstate,priv->helo,ntohl(satosin(priv->pip)->sin_addr.s_addr))
+			// TODO - ipv6
+			&& priv->pip->sa_family == AF_INET && !dns_hostname_ip_match(priv->presstate,priv->helo,ntohl(satosin(priv->pip)->sin_addr.s_addr))
 			)
 		{
 			mlfi_setreply(ctx,550,"5.7.1","Rejecting due to security policy - Helo hostname/ip mismatch, Please see: %s#hostnameipmismatch",gPolicyUrl);
@@ -1321,21 +1322,31 @@

 		// Policy enforcement
 		// Validate the sndr return path
-		if(continue_checks
-			&& gSmtpSndrChk
-			&& ntohl(satosin(priv->pip)->sin_addr.s_addr) != INADDR_LOOPBACK
-			&& strcasecmp("<>",priv->sndr) != 0
-			)
-		{
-			char *mbox = NULL;
-			char *dom = NULL;
-
-			mlfi_regex_mboxsplit(priv->sndr,&mbox,&dom);
-
-			rs = mlfi_sndrchk(ctx,mbox,dom);
-			continue_checks = (rs == SMFIS_CONTINUE);
-			free(mbox);
-			free(dom);
+		if(continue_checks && gSmtpSndrChk)
+		{	int isLoopBack = 0;
+
+			switch(priv->pip->sa_family)
+			{
+				case AF_INET:
+					isLoopBack = (ntohl(satosin(priv->pip)->sin_addr.s_addr) == INADDR_LOOPBACK);
+					break;
+				case AF_INET6:
+					isLoopBack = IN6_ARE_ADDR_EQUAL( &((struct sockaddr_in6 *)priv->pip)->sin6_addr, &in6addr_loopback);
+					break;
+			}
+
+			if(!isLoopBack && strcasecmp("<>",priv->sndr) != 0)
+			{
+				char *mbox = NULL;
+				char *dom = NULL;
+
+				mlfi_regex_mboxsplit(priv->sndr,&mbox,&dom);
+
+				rs = mlfi_sndrchk(ctx,mbox,dom);
+				continue_checks = (rs == SMFIS_CONTINUE);
+				free(mbox);
+				free(dom);
+			}
 		}

 #ifdef SUPPORT_GEOIP


Added real(floating-point) numbers

Added real(floating-point) numbers

--- src/miniscm.c
+++ src/miniscm.c
@@ -68,6 +68,7 @@

 #include <string.h>
 #include <stdlib.h>
+#include <float.h>
 #define prompt "> "
 #define InitFile "init.scm"
 #ifdef _WIN32
@@ -77,6 +78,7 @@
 /* cell structure */
 struct cell {
 	unsigned short _flag;
+	unsigned char  _isfixnum;
 	union {
 		struct {
 			char   *_svalue;
@@ -84,6 +86,7 @@
 		} _string;
 		struct {
 			long    _ivalue;
+			long    _rvalue;
 		} _number;
 		struct {
 			struct cell *_car;
@@ -126,6 +129,10 @@

 #define is_number(p)    (type(p)&T_NUMBER)
 #define ivalue(p)       ((p)->_object._number._ivalue)
+#define rvalue(p)       (*(double *)&(p)->_object._number._ivalue)
+#define nvalue(p)       ((p)->_isfixnum ? ivalue(p) : rvalue(p))
+#define set_num_integer(p)   ((p)->_isfixnum = 1)
+#define set_num_real(p)      ((p)->_isfixnum = 0)

 #define is_pair(p)      (type(p)&T_PAIR)
 #define car(p)          ((p)->_object._cons._car)
@@ -192,6 +199,8 @@
 pointer F = &_F;		/* special cell representing #f */
 pointer oblist = &_NIL;	/* pointer to symbol table */
 pointer global_env;		/* pointer to global environment */
+struct cell _ZERO;		/* special cell representing integer 0 */
+struct cell _ONE;		/* special cell representing integer 1 */

 /* global pointers to special symbols */
 pointer LAMBDA;			/* pointer to syntax lambda */
@@ -401,14 +410,30 @@
 	return x;
 }

-/* get number atom */
-pointer mk_number(register long num)
+pointer mk_integer(register long num)
 {
 	register pointer x = get_cell(&NIL, &NIL);

 	type(x) = (T_NUMBER | T_ATOM);
 	ivalue(x) = num;
+	set_num_integer(x);
 	return x;
+}
+
+pointer mk_real(register double num)
+{
+	register pointer x = get_cell(&NIL, &NIL);
+
+	type(x) = (T_NUMBER | T_ATOM);
+	rvalue(x) = num;
+	set_num_real(x);
+	return x;
+}
+
+/* get number atom */
+pointer mk_number(struct cell *v)
+{
+	return v->_isfixnum ? mk_integer(ivalue(v)) : mk_real(rvalue(v));
 }

 /* allocate name to string area */
@@ -494,17 +519,55 @@
 /* make symbol or number atom from string */
 pointer mk_atom(char *q)
 {
-	char    c, *p;
+	char c, *p;
+	int has_dec_point = 0;
+	int has_fp_exp = 0;

 	p = q;
-	if (!isdigit(c = *p++)) {
-		if ((c != '+' && c != '-') || !isdigit(*p))
+	c = *p++;
+	if ((c == '+') || (c == '-')) {
+		c = *p++;
+		if (c == '.') {
+			has_dec_point = 1;
+			c = *p++;
+		}
+		if (!isdigit(c)) {
 			return mk_symbol(q);
-	}
-	for ( ; (c = *p) != 0; ++p)
-		if (!isdigit(c))
+		}
+	} else if (c == '.') {
+		has_dec_point = 1;
+		c = *p++;
+		if (!isdigit(c)) {
 			return mk_symbol(q);
-	return mk_number(atol(q));
+		}
+	} else if (!isdigit(c)) {
+		return mk_symbol(q);
+	}
+
+	for ( ; (c = *p) != 0; ++p) {
+		if (!isdigit(c)) {
+			if (c == '.') {
+				if (!has_dec_point) {
+					has_dec_point = 1;
+					continue;
+				}
+			} else if ((c == 'e') || (c == 'E')) {
+				if (!has_fp_exp) {
+					has_fp_exp = 1;
+					has_dec_point = 1;
+					p++;
+					if ((*p == '-') || (*p == '+') || isdigit(*p)) {
+					continue;
+					}
+				}
+			}
+			return mk_symbol(q);
+		}
+	}
+	if (has_dec_point) {
+		return mk_real(atof(q));
+	}
+	return mk_integer(atol(q));
 }

 /* make constant */
@@ -520,14 +583,14 @@
 	else if (*name == 'o') {/* #o (octal) */
 		sprintf(tmp, "0%s", &name[1]);
 		sscanf(tmp, "%lo", &x);
-		return mk_number(x);
+		return mk_integer(x);
 	} else if (*name == 'd') {	/* #d (decimal) */
 		sscanf(&name[1], "%ld", &x);
-		return mk_number(x);
+		return mk_integer(x);
 	} else if (*name == 'x') {	/* #x (hex) */
 		sprintf(tmp, "0x%s", &name[1]);
 		sscanf(tmp, "%lx", &x);
-		return mk_number(x);
+		return mk_integer(x);
 	} else
 		return NIL;
 }
@@ -952,7 +1015,17 @@
 		p = "#f";
 	else if (is_number(l)) {
 		p = strbuff;
-		sprintf(p, "%ld", ivalue(l));
+		if (l->_isfixnum) {
+			sprintf(p, "%ld", ivalue(l));
+		} else {
+			sprintf(p, "%.10g", rvalue(l));
+			f = strcspn(p, ".e");
+			if (p[f] == 0) {
+				p[f] = '.';
+				p[f+1] = '0';
+				p[f+2] = 0;
+			}
+		}
 	} else if (is_string(l)) {
 		if (!f)
 			p = strvalue(l);
@@ -1129,7 +1202,7 @@
 		p = cons(dump_code(d), p);
 		p = cons(dump_envir(d), p);
 		args = cons(dump_args(d), p);
-		p = mk_number((long)dump_op(d));
+		p = mk_integer((long)dump_op(d));
 		p = cons(p, args);
 	}
 	pop_sink();
@@ -1142,7 +1215,7 @@
 	dump = cons((c), dump),                    \
 	dump = cons(envir, dump),                  \
 	dump = cons((b), dump),                    \
-	x = mk_number((long)(a)),                  \
+	x = mk_integer((long)(a)),                 \
 	dump = cons(x, dump))

 #define s_return(a) BEGIN                      \
@@ -1281,7 +1354,7 @@
 	int print_flag;
 	pointer value;
 	pointer x, y;
-	register long v;
+	struct cell v;
 	long w;

 LOOP:
@@ -1822,39 +1895,104 @@
 		s_goto(OP_APPLY);

 	case OP_ADD:		/* + */
-		for (x = args, v = 0; x != NIL; x = cdr(x))
-			v += ivalue(car(x));
-		s_return(mk_number(v));
+		for (x = args, v = _ZERO; x != NIL; x = cdr(x)) {
+			if (v._isfixnum) {
+				if (car(x)->_isfixnum) {
+					ivalue(&v) += ivalue(car(x));
+				} else {
+					rvalue(&v) = ivalue(&v) + rvalue(car(x));
+					set_num_real(&v);
+				}
+			} else {
+				rvalue(&v) += nvalue(car(x));
+			}
+		}
+		s_return(mk_number(&v));

 	case OP_SUB:		/* - */
-		for (x = cdr(args), v = ivalue(car(args)); x != NIL; x = cdr(x))
-			v -= ivalue(car(x));
-		s_return(mk_number(v));
+		if (cdr(args) == NIL) {
+			v = _ZERO;
+			x = args;
+		} else {
+			v = *car(args);
+			x = cdr(args);
+		}
+		for ( ; x != NIL; x = cdr(x)) {
+			if (v._isfixnum) {
+				if (car(x)->_isfixnum) {
+					ivalue(&v) -= ivalue(car(x));
+				} else {
+					rvalue(&v) = ivalue(&v) - rvalue(car(x));
+					set_num_real(&v);
+				}
+			} else {
+				rvalue(&v) -= nvalue(car(x));
+			}
+		}
+		s_return(mk_number(&v));

 	case OP_MUL:		/* * */
-		for (x = args, v = 1; x != NIL; x = cdr(x))
-			v *= ivalue(car(x));
-		s_return(mk_number(v));
+		for (x = args, v = _ONE; x != NIL; x = cdr(x)) {
+			if (v._isfixnum) {
+				if (car(x)->_isfixnum) {
+					ivalue(&v) *= ivalue(car(x));
+				} else {
+					rvalue(&v) = ivalue(&v) * rvalue(car(x));
+					set_num_real(&v);
+				}
+			} else {
+				rvalue(&v) *= nvalue(car(x));
+			}
+		}
+		s_return(mk_number(&v));

 	case OP_DIV:		/* / */
-		for (x = cdr(args), v = ivalue(car(args)); x != NIL; x = cdr(x)) {
-			if (ivalue(car(x)) != 0)
-				v /= ivalue(car(x));
-			else {
+		if (cdr(args) == NIL) {
+			v = _ONE;
+			x = args;
+		} else {
+			v = *car(args);
+			x = cdr(args);
+		}
+		for ( ; x != NIL; x = cdr(x)) {
+			double d = nvalue(car(x));
+			if (-DBL_MIN < d && d < DBL_MIN) {
 				Error_0("Divided by zero");
 			}
-		}
-		s_return(mk_number(v));
+			if (v._isfixnum) {
+				if (car(x)->_isfixnum && ivalue(&v) % ivalue(car(x)) == 0) {
+					ivalue(&v) /= ivalue(car(x));
+				} else {
+					rvalue(&v) = ivalue(&v) / d;
+					set_num_real(&v);
+				}
+			} else {
+				rvalue(&v) /= d;
+			}
+		}
+		s_return(mk_number(&v));

 	case OP_REM:		/* remainder */
-		for (x = cdr(args), v = ivalue(car(args)); x != NIL; x = cdr(x)) {
-			if (ivalue(car(x)) != 0)
-				v %= ivalue(car(x));
-			else {
-				Error_0("Divided by zero");
+		if (args == NIL || cdr(args) == NIL) {
+			Error_0("Needs 2 arguments");
+		}
+		v = *car(args);
+		x = cdr(args);
+		w = car(x)->_isfixnum ? ivalue(car(x)) : (long)rvalue(car(x));
+		if (w == 0) {
+			Error_0("Divided by zero");
+		}
+		if (v._isfixnum) {
+			if (car(x)->_isfixnum) {
+				ivalue(&v) %= ivalue(car(x));
+			} else {
+				rvalue(&v) = ivalue(&v) % w;
+				set_num_real(&v);
 			}
-		}
-		s_return(mk_number(v));
+		} else {
+			rvalue(&v) = (long)rvalue(&v) % w;
+		}
+		s_return(mk_number(&v));

 	case OP_CAR:		/* car */
 		if (is_pair(car(args))) {
@@ -1897,21 +2035,21 @@
 	case OP_NULL:		/* null? */
 		s_retbool(car(args) == NIL);
 	case OP_ZEROP:		/* zero? */
-		s_retbool(ivalue(car(args)) == 0);
+		s_retbool(nvalue(car(args)) == 0);
 	case OP_POSP:		/* positive? */
-		s_retbool(ivalue(car(args)) > 0);
+		s_retbool(nvalue(car(args)) > 0);
 	case OP_NEGP:		/* negative? */
-		s_retbool(ivalue(car(args)) < 0);
+		s_retbool(nvalue(car(args)) < 0);
 	case OP_NEQ:		/* = */
-		s_retbool(ivalue(car(args)) == ivalue(cadr(args)));
+		s_retbool(nvalue(car(args)) == nvalue(cadr(args)));
 	case OP_LESS:		/* < */
-		s_retbool(ivalue(car(args)) < ivalue(cadr(args)));
+		s_retbool(nvalue(car(args)) < nvalue(cadr(args)));
 	case OP_GRE:		/* > */
-		s_retbool(ivalue(car(args)) > ivalue(cadr(args)));
+		s_retbool(nvalue(car(args)) > nvalue(cadr(args)));
 	case OP_LEQ:		/* <= */
-		s_retbool(ivalue(car(args)) <= ivalue(cadr(args)));
+		s_retbool(nvalue(car(args)) <= nvalue(cadr(args)));
 	case OP_GEQ:		/* >= */
-		s_retbool(ivalue(car(args)) >= ivalue(cadr(args)));
+		s_retbool(nvalue(car(args)) >= nvalue(cadr(args)));
 	case OP_SYMBOL:	/* symbol? */
 		s_retbool(is_symbol(car(args)));
 	case OP_NUMBER:	/* number? */
@@ -2171,9 +2309,9 @@
 		}

 	case OP_LIST_LENGTH:	/* list-length */	/* a.k */
-		for (x = car(args), v = 0; is_pair(x); x = cdr(x))
-			++v;
-		s_return(mk_number(v));
+		for (x = car(args), w = 0; is_pair(x); x = cdr(x))
+			++w;
+		s_return(mk_integer(w));

 	case OP_ASSQ:		/* assq */	/* a.k */
 		x = car(args);
@@ -2200,7 +2338,7 @@
 OP_P0_WIDTH:
 		if (!is_pair(args)) {
 			w += printatom(args, print_flag);
-			s_return(mk_number(w));
+			s_return(mk_integer(w));
 		} else if (car(args) == QUOTE
 			   && ok_abbrev(cdr(args))) {
 			++w;
@@ -2238,7 +2376,7 @@
 			if (args != NIL)
 				w += 3 + printatom(args, print_flag);
 			++w;
-			s_return(mk_number(w));
+			s_return(mk_integer(w));
 		}

 	case OP_GET_CLOSURE:	/* get-closure-code */	/* a.k */
@@ -2300,6 +2438,7 @@
 	y = get_cell(&x, &NIL);
 	type(y) = (T_PROC | T_ATOM);
 	ivalue(y) = (long) op;
+	set_num_integer(y);
 	x = cons(x, y);
 	car(global_env) = cons(x, car(global_env));
 }
@@ -2326,6 +2465,12 @@
 	/* init else */
 	x = cons(mk_symbol("else"), T);
 	car(global_env) = cons(x, car(global_env));
+	type(&_ZERO) = T_NUMBER;
+	set_num_integer(&_ZERO);
+	ivalue(&_ZERO) = 0;
+	type(&_ONE) = T_NUMBER;
+	set_num_integer(&_ONE);
+	ivalue(&_ONE) = 1;
 }


HG: disable eager bulk when sending to self

--- src/mercury.c
+++ src/mercury.c
@@ -605,7 +605,8 @@
 #endif

     /* Attempt to use eager bulk transfers when appropriate */
-    if (HG_HANDLE_CLASS(&hg_handle->handle)->bulk_eager)
+    if (HG_HANDLE_CLASS(&hg_handle->handle)->bulk_eager &&
+        !HG_Core_addr_is_self(hg_handle->handle.core_handle->info.addr))
         proc_flags |= HG_PROC_BULK_EAGER;

     hg_proc_set_flags(proc, proc_flags);
@@ -665,7 +666,8 @@
 #endif

         /* Attempt to use eager bulk transfers when appropriate */
-        if (HG_HANDLE_CLASS(&hg_handle->handle)->bulk_eager)
+        if (HG_HANDLE_CLASS(&hg_handle->handle)->bulk_eager &&
+            !HG_Core_addr_is_self(hg_handle->handle.core_handle->info.addr))
             proc_flags |= HG_PROC_BULK_EAGER;

         hg_proc_set_flags(proc, proc_flags);


This file has been replaced by src/depend/disklib/mntopts.h

--- src/mntopts.h
+++ src/mntopts.h
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1994
- *      The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)mntopts.h	8.7 (Berkeley) 3/29/95
- */
-
-#ifdef linux
-#define MNT_RDONLY      0x00000001      /* read only filesystem */
-#define MNT_SYNCHRONOUS 0x00000002      /* file system written synchronously */
-#define MNT_NOEXEC      0x00000004      /* can't exec from filesystem */
-#define MNT_NOSUID      0x00000008      /* don't honor setuid bits on fs */
-#define MNT_NODEV       0x00000010      /* don't interpret special files */
-#define MNT_UNION       0x00000020      /* union with underlying filesystem */
-#define MNT_ASYNC       0x00000040      /* file system written asynchronously */
-
-#define FS_OPTTIME 0       /* minimize allocation time */
-#define MINFREE         5
-#define DEFAULTOPT      FS_OPTTIME
-#define BBSIZE          8192
-#define SBSIZE          8192
-
-#define MINBSIZE        4096
-#define FS_OPTSPACE        1       /* minimize disk fragmentation */
-#endif
-
-struct mntopt {
-	const char *m_option;	/* option name */
-	int m_inverse;		/* if a negative option, eg "dev" */
-	int m_flag;		/* bit to set, eg. MNT_RDONLY */
-	int m_altloc;		/* 1 => set bit in altflags */
-};
-
-/* User-visible MNT_ flags. */
-#define MOPT_ASYNC		{ "async",	0, MNT_ASYNC, 0 }
-#define MOPT_NODEV		{ "dev",	1, MNT_NODEV, 0 }
-#define MOPT_NOEXEC		{ "exec",	1, MNT_NOEXEC, 0 }
-#define MOPT_NOSUID		{ "suid",	1, MNT_NOSUID, 0 }
-#define MOPT_RDONLY		{ "rdonly",	0, MNT_RDONLY, 0 }
-#define MOPT_SYNC		{ "sync",	0, MNT_SYNCHRONOUS, 0 }
-#define MOPT_UNION		{ "union",	0, MNT_UNION, 0 }
-#define MOPT_USERQUOTA		{ "userquota",	0, 0, 0 }
-#define MOPT_GROUPQUOTA		{ "groupquota",	0, 0, 0 }
-#define MOPT_BROWSE		{ "browse",	1, MNT_DONTBROWSE, 0 }
-#define MOPT_AUTOMOUNTED	{ "automounted",0, MNT_AUTOMOUNTED, 0 }
-
-/* Control flags. */
-#define MOPT_FORCE		{ "force",	0, MNT_FORCE, 0 }
-#define MOPT_UPDATE		{ "update",	0, MNT_UPDATE, 0 }
-#define MOPT_RO			{ "ro",		0, MNT_RDONLY, 0 }
-#define MOPT_RW			{ "rw",		1, MNT_RDONLY, 0 }
-
-/* This is parsed by mount(8), but is ignored by specific mount_*(8)s. */
-#define MOPT_AUTO		{ "auto",	0, 0, 0 }
-
-#define MOPT_FSTAB_COMPAT						\
-	MOPT_RO,							\
-	MOPT_RW,							\
-	MOPT_AUTO
-
-/* Standard options which all mounts can understand. */
-#define MOPT_STDOPTS							\
-	MOPT_USERQUOTA,							\
-	MOPT_GROUPQUOTA,						\
-	MOPT_FSTAB_COMPAT,						\
-	MOPT_NODEV,							\
-	MOPT_NOEXEC,							\
-	MOPT_NOSUID,							\
-	MOPT_RDONLY,							\
-	MOPT_UNION,							\
-        MOPT_BROWSE,							\
-        MOPT_AUTOMOUNTED
-
-void getmntopts __P((const char *, const struct mntopt *, int *, int *));
-void checkpath __P((const char *, char resolved_path[]));
-void rmslashes __P((char *, char *));
-extern int getmnt_silent;


[mod_cgi] asynchronous send of request body to CGI

Like other dynamic handler in prior commit,
mod_cgi can read response before sending req body

mod_cgi no longer blocks sending request body to CGI

--- src/mod_cgi.c
+++ src/mod_cgi.c
@@ -72,7 +72,9 @@
 typedef struct {
 	pid_t pid;
 	int fd;
+	int fdtocgi;
 	int fde_ndx; /* index into the fd-event buffer */
+	int fde_ndx_tocgi; /* index into the fd-event buffer */

 	connection *remote_conn;  /* dumb pointer */
 	plugin_data *plugin_data; /* dumb pointer */
@@ -89,6 +91,7 @@
 	hctx->response = buffer_init();
 	hctx->response_header = buffer_init();
 	hctx->fd = -1;
+	hctx->fdtocgi = -1;

 	return hctx;
 }
@@ -519,6 +522,17 @@
 	return FDEVENT_HANDLED_NOT_FINISHED;
 }

+static void cgi_connection_close_fdtocgi(server *srv, handler_ctx *hctx) {
+	/*(closes only hctx->fdtocgi)*/
+	fdevent_event_del(srv->ev, &(hctx->fde_ndx_tocgi), hctx->fdtocgi);
+	fdevent_unregister(srv->ev, hctx->fdtocgi);
+
+	if (close(hctx->fdtocgi)) {
+		log_error_write(srv, __FILE__, __LINE__, "sds", "cgi stdin close failed ", hctx->fdtocgi, strerror(errno));
+	}
+	hctx->fdtocgi = -1;
+}
+
 static void cgi_connection_close(server *srv, handler_ctx *hctx) {
 	int status;
 	pid_t pid;
@@ -541,16 +555,16 @@
 		if (close(hctx->fd)) {
 			log_error_write(srv, __FILE__, __LINE__, "sds", "cgi close failed ", hctx->fd, strerror(errno));
 		}
-
-		hctx->fd = -1;
-		hctx->fde_ndx = -1;
+	}
+
+	if (hctx->fdtocgi != -1) {
+		cgi_connection_close_fdtocgi(srv, hctx); /*(closes only hctx->fdtocgi)*/
 	}

 	pid = hctx->pid;

 	con->plugin_ctx[p->id] = NULL;

-	/* is this a good idea ? */
 	cgi_handler_ctx_free(hctx);

 	/* if waitpid hasn't been called by response.c yet, do it here */
@@ -631,6 +645,43 @@
 }

+static int cgi_write_request(server *srv, handler_ctx *hctx, int fd);
+
+
+static handler_t cgi_handle_fdevent_send (server *srv, void *ctx, int revents) {
+	handler_ctx *hctx = ctx;
+	connection  *con  = hctx->remote_conn;
+
+	/*(joblist only actually necessary here in mod_cgi fdevent send if returning HANDLER_ERROR)*/
+	joblist_append(srv, con);
+
+	if (revents & FDEVENT_OUT) {
+		if (0 != cgi_write_request(srv, hctx, hctx->fdtocgi)) {
+			cgi_connection_close(srv, hctx);
+			return HANDLER_ERROR;
+		}
+		/* more request body to be sent to CGI */
+	}
+
+	if (revents & FDEVENT_HUP) {
+		/* skip sending remaining data to CGI */
+		chunkqueue *cq = con->request_content_queue;
+		chunkqueue_mark_written(cq, chunkqueue_length(cq));
+
+		cgi_connection_close_fdtocgi(srv, hctx); /*(closes only hctx->fdtocgi)*/
+	} else if (revents & FDEVENT_ERR) {
+		/* kill all connections to the cgi process */
+#if 1
+		log_error_write(srv, __FILE__, __LINE__, "s", "cgi-FDEVENT_ERR");
+#endif
+		cgi_connection_close(srv, hctx);
+		return HANDLER_ERROR;
+	}
+
+	return HANDLER_FINISHED;
+}
+
+
 static handler_t cgi_handle_fdevent(server *srv, void *ctx, int revents) {
 	handler_ctx *hctx = ctx;
 	connection  *con  = hctx->remote_conn;
@@ -724,7 +775,7 @@
  *
  * Also always use mmap; the files are "trusted", as we created them.
  */
-static int cgi_write_file_chunk_mmap(server *srv, connection *con, int fd, chunkqueue *cq) {
+static ssize_t cgi_write_file_chunk_mmap(server *srv, connection *con, int fd, chunkqueue *cq) {
 	chunk* const c = cq->first;
 	off_t offset, toSend, file_end;
 	ssize_t r;
@@ -791,6 +842,89 @@

 	if (r >= 0) {
 		chunkqueue_mark_written(cq, r);
+	}
+
+	return r;
+}
+
+static int cgi_write_request(server *srv, handler_ctx *hctx, int fd) {
+	connection *con = hctx->remote_conn;
+	chunkqueue *cq = con->request_content_queue;
+	chunk *c;
+
+	/* old comment: windows doesn't support select() on pipes - wouldn't be easy to fix for all platforms.
+	 * solution: if this is still a problem on windows, then substitute
+	 * socketpair() for pipe() and closesocket() for close() on windows.
+	 */
+
+	for (c = cq->first; c; c = cq->first) {
+		ssize_t r = -1;
+
+		switch(c->type) {
+		case FILE_CHUNK:
+			r = cgi_write_file_chunk_mmap(srv, con, fd, cq);
+			break;
+
+		case MEM_CHUNK:
+			if ((r = write(fd, c->mem->ptr + c->offset, buffer_string_length(c->mem) - c->offset)) < 0) {
+				switch(errno) {
+				case EAGAIN:
+				case EINTR:
+					/* ignore and try again */
+					r = 0;
+					break;
+				case EPIPE:
+				case ECONNRESET:
+					/* connection closed */
+					r = -2;
+					break;
+				default:
+					/* fatal error */
+					log_error_write(srv, __FILE__, __LINE__, "ss", "write failed due to: ", strerror(errno));
+					r = -1;
+					break;
+				}
+			} else if (r > 0) {
+				chunkqueue_mark_written(cq, r);
+			}
+			break;
+		}
+
+		if (0 == r) break; /*(might block)*/
+
+		switch (r) {
+		case -1:
+			/* fatal error */
+			return -1;
+		case -2:
+			/* connection reset */
+			log_error_write(srv, __FILE__, __LINE__, "s", "failed to send post data to cgi, connection closed by CGI");
+			/* skip all remaining data */
+			chunkqueue_mark_written(cq, chunkqueue_length(cq));
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (chunkqueue_is_empty(cq)) {
+		/* sent all request body input */
+		/* close connection to the cgi-script */
+		if (-1 == hctx->fdtocgi) { /*(entire request body sent in initial send to pipe buffer)*/
+			if (close(fd)) {
+				log_error_write(srv, __FILE__, __LINE__, "sds", "cgi stdin close failed ", fd, strerror(errno));
+			}
+		} else {
+			cgi_connection_close_fdtocgi(srv, hctx); /*(closes only hctx->fdtocgi)*/
+		}
+	} else {
+		/* more request body remains to be sent to CGI so register for fdevents */
+		if (-1 == hctx->fdtocgi) { /*(not registered yet)*/
+			hctx->fdtocgi = fd;
+			hctx->fde_ndx_tocgi = -1;
+			fdevent_register(srv->ev, hctx->fdtocgi, cgi_handle_fdevent_send, hctx);
+			fdevent_event_set(srv->ev, &(hctx->fde_ndx_tocgi), hctx->fdtocgi, FDEVENT_OUT);
+		}
 	}

 	return 0;
@@ -1099,81 +1233,29 @@
 		close(from_cgi_fds[1]);
 		close(to_cgi_fds[0]);

-		if (con->request.content_length) {
-			chunkqueue *cq = con->request_content_queue;
-			chunk *c;
-
-			assert(chunkqueue_length(cq) == (off_t)con->request.content_length);
-
-			/* NOTE: yes, this is synchronous sending of CGI post data;
-			 * if you need something asynchronous (recommended with large
-			 * request bodies), use mod_fastcgi + fcgi-cgi.
-			 *
-			 * Also: windows doesn't support select() on pipes - wouldn't be
-			 * easy to fix for all platforms.
-			 */
-
-			/* there is content to send */
-			for (c = cq->first; c; c = cq->first) {
-				int r = -1;
-
-				switch(c->type) {
-				case FILE_CHUNK:
-					r = cgi_write_file_chunk_mmap(srv, con, to_cgi_fds[1], cq);
-					break;
-
-				case MEM_CHUNK:
-					if ((r = write(to_cgi_fds[1], c->mem->ptr + c->offset, buffer_string_length(c->mem) - c->offset)) < 0) {
-						switch(errno) {
-						case EAGAIN:
-						case EINTR:
-							/* ignore and try again */
-							r = 0;
-							break;
-						case EPIPE:
-						case ECONNRESET:
-							/* connection closed */
-							r = -2;
-							break;
-						default:
-							/* fatal error */
-							log_error_write(srv, __FILE__, __LINE__, "ss", "write failed due to: ", strerror(errno));
-							r = -1;
-							break;
-						}
-					} else if (r > 0) {
-						chunkqueue_mark_written(cq, r);
-					}
-					break;
-				}
-
-				switch (r) {
-				case -1:
-					/* fatal error */
-					close(from_cgi_fds[0]);
-					close(to_cgi_fds[1]);
-					kill(pid, SIGTERM);
-					cgi_pid_add(srv, p, pid);
-					return -1;
-				case -2:
-					/* connection reset */
-					log_error_write(srv, __FILE__, __LINE__, "s", "failed to send post data to cgi, connection closed by CGI");
-					/* skip all remaining data */
-					chunkqueue_mark_written(cq, chunkqueue_length(cq));
-					break;
-				default:
-					break;
-				}
-			}
-		}
-
-		close(to_cgi_fds[1]);
-
-		/* register PID and wait for them asyncronously */
+		/* register PID and wait for them asynchronously */

 		hctx->pid = pid;
 		hctx->fd = from_cgi_fds[0];
 		hctx->fde_ndx = -1;
+
+		if (0 == con->request.content_length) {
+			close(to_cgi_fds[1]);
+		} else {
+			/* there is content to send */
+			if (-1 == fdevent_fcntl_set(srv->ev, to_cgi_fds[1])) {
+				log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno));
+				close(to_cgi_fds[1]);
+				cgi_connection_close(srv, hctx);
+				return -1;
+			}
+
+			if (0 != cgi_write_request(srv, hctx, to_cgi_fds[1])) {
+				close(to_cgi_fds[1]);
+				cgi_connection_close(srv, hctx);
+				return -1;
+			}
+		}

 		fdevent_register(srv->ev, hctx->fd, cgi_handle_fdevent, hctx);
 		fdevent_event_set(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_IN);


[mod_cgi] remove direct calls to network_backend*

--- src/mod_cgi.c
+++ src/mod_cgi.c
@@ -8,7 +8,6 @@
 #include "joblist.h"
 #include "response.h"
 #include "http_chunk.h"
-#include "network_backends.h"

 #include "plugin.h"

@@ -868,6 +867,17 @@
 	return 0;
 }

+/*(improved from network_write_mmap.c)*/
+static off_t mmap_align_offset(off_t start) {
+    static off_t pagemask = 0;
+    if (0 == pagemask) {
+        long pagesize = sysconf(_SC_PAGESIZE);
+        if (-1 == pagesize) pagesize = 4096;
+        pagemask = ~((off_t)pagesize - 1); /* pagesize always power-of-2 */
+    }
+    return (start & pagemask);
+}
+
 /* returns: 0: continue, -1: fatal error, -2: connection reset */
 /* similar to network_write_file_chunk_mmap, but doesn't use send on windows (because we're on pipes),
  * also mmaps and sends complete chunk instead of only small parts - the files
@@ -895,7 +905,14 @@
 		return 0;
 	}

-	if (0 != network_open_file_chunk(srv, con, cq)) return -1;
+	/*(simplified from network_write_no_mmap.c:network_open_file_chunk())*/
+	UNUSED(con);
+	if (-1 == c->file.fd) {
+		if (-1 == (c->file.fd = fdevent_open_cloexec(c->file.name->ptr, O_RDONLY, 0))) {
+			log_error_write(srv, __FILE__, __LINE__, "ssb", "open failed:", strerror(errno), c->file.name);
+			return -1;
+		}
+	}

 	/* (re)mmap the buffer if range is not covered completely */
 	if (MAP_FAILED == c->file.mmap.start


[mod_cgi] fix out of sockets error for POST to CGI (fixes #2771)

(thx asifgoldpk)

x-ref:
  "With mod_cgi I am getting sockets disabled, out-of-fds error"
  https://redmine.lighttpd.net/issues/2771

--- src/mod_cgi.c
+++ src/mod_cgi.c
@@ -1028,6 +1028,7 @@
 		/* sent all request body input */
 		/* close connection to the cgi-script */
 		if (-1 == hctx->fdtocgi) { /*(received request body sent in initial send to pipe buffer)*/
+			--srv->cur_fds;
 			if (close(fd)) {
 				log_error_write(srv, __FILE__, __LINE__, "sds", "cgi stdin close failed ", fd, strerror(errno));
 			}


Fix strcmps in parse_format.

Fix strcmps in parse_format.

--- src/imgcat.c
+++ src/imgcat.c
@@ -131,11 +131,11 @@
 }

 static Format parse_format(const char *arg) {
-    if (strncmp(arg, "256", 4)) {
+    if (strncmp(arg, "256", 4) == 0) {
         return F_256_COLOR;
-    } else if (strncmp(arg, "8", 2) || strncmp(arg, "ansi", 5)) {
+    } else if ((strncmp(arg, "8", 2) == 0) || (strncmp(arg, "ansi", 5) == 0)) {
         return F_8_COLOR;
-    } else if (strncmp(arg, "rgb", 4)) {
+    } else if (strncmp(arg, "rgb", 4) == 0) {
         return F_UNSET;
     }
     return F_UNSET;


support jpeg file on stdin if 'src' parameter is '-'

--- src/imgmin.c
+++ src/imgmin.c
@@ -181,14 +181,14 @@
     return tmp;
 }

-static void filecopy(const char *src, const char *dst, const off_t bytes)
+static void filecopy(const char *src, const char *dst, const size_t bytes)
 {
     int rd = open(src, O_RDONLY);
     int wr = open(dst, O_WRONLY | O_CREAT, 0644);
 #ifdef IMGMIN_USE_MMAP
     /* in-kernel copying, more efficient */
-    void *mm = mmap(NULL, (size_t)bytes, PROT_READ | MAP_SHARED, 0, rd, 0);
-    if (write(wr, mm, (size_t)bytes) != (ssize_t)bytes)
+    void *mm = mmap(NULL, bytes, PROT_READ | MAP_SHARED, 0, rd, 0);
+    if ((size_t)write(wr, mm, bytes) != bytes)
         perror("write");
 #else
     /* userspace copying, less efficient */
@@ -200,19 +200,36 @@
     close(rd);
 }

-static void doit(const char *src, const char *dst, const off_t oldsize,
+static void doit(const char *src, const char *dst, size_t oldsize,
                  const struct imgmin_options *opt)
 {
     MagickWand *mw, *tmp;
     MagickBooleanType status;
-    double ks = oldsize / 1024.;
+    double ks;

     MagickWandGenesis();
     mw = NewMagickWand();

-    status = MagickReadImage(mw, src);
-    if (status == MagickFalse)
-        ThrowWandException(mw);
+    if (0 == strcmp("-", src))
+    {
+        /* load image from stdin */
+        # define BIGBUF (16 * 1024 * 1024)
+        char *blob = malloc(BIGBUF);
+        oldsize = read(STDIN_FILENO, blob, BIGBUF);
+        if (BIGBUF == oldsize)
+        {
+            fprintf(stderr, "Image too large for hardcoded imgmin stdin buffer\n");
+            exit(1);
+        }
+        MagickReadImageBlob(mw, blob, oldsize);
+    } else {
+        /* load image from disk */
+        status = MagickReadImage(mw, src);
+        if (status == MagickFalse)
+            ThrowWandException(mw);
+    }
+
+    ks = oldsize / 1024.;

     fprintf(stderr,
         "Before quality:%lu colors:%lu size:%5.1fkB type:%s ",
@@ -238,11 +255,11 @@
     /* sanity check: fall back to original image if results are larger */
     {
         struct stat st;
-        off_t newsize;
+        size_t newsize;

         st.st_size = oldsize + 1; /* ensure newsize > oldsize if stat() fails for any reason */
         stat(dst, &st);
-        newsize = st.st_size;
+        newsize = (size_t)st.st_size;

         if (newsize > oldsize)
         {
@@ -335,6 +352,7 @@
     const char *src;
     const char *dst;
     struct imgmin_options opt;
+    size_t oldsize = 0;
     int argc_off = parse_opts(argc, argv, &opt);
     if (argc_off + 2 > argc)
     {
@@ -344,15 +362,17 @@
     src = argv[argc_off];
     dst = argv[argc_off+1];

-    {
+    if (0 != strcmp("-", src)){
         struct stat st;
         if (-1 == stat(src, &st))
         {
             perror("does not exist");
             exit(1);
         }
-        doit(src, dst, st.st_size, &opt);
-    }
+        oldsize = (size_t)st.st_size;
+    }
+
+    doit(src, dst, oldsize, &opt);

     return 0;
 }