]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 7.4.1855 v7.4.1855
authorBram Moolenaar <Bram@vim.org>
Sat, 28 May 2016 20:22:34 +0000 (22:22 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 28 May 2016 20:22:34 +0000 (22:22 +0200)
Problem:    Valgrind reports memory leak for job that is not freed.
Solution:   Free all jobs on exit.  Add test for failing job.

src/channel.c
src/misc2.c
src/proto/channel.pro
src/testdir/test_partial.vim
src/version.c

index 94681ee89809e9ddab177274f3d698875e5bf39c..2cc46fecb704e52e441b74e4d31bcf87226f81ef 100644 (file)
@@ -1285,6 +1285,7 @@ write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
     int            len = (int)STRLEN(line);
     char_u  *p;
 
+    /* Need to make a copy to be able to append a NL. */
     if ((p = alloc(len + 2)) == NULL)
        return;
     STRCPY(p, line);
@@ -2888,7 +2889,7 @@ channel_close_now(channel_T *channel)
 /*
  * Read from channel "channel" for as long as there is something to read.
  * "part" is PART_SOCK, PART_OUT or PART_ERR.
- * The data is put in the read queue.
+ * The data is put in the read queue.  No callbacks are invoked here.
  */
     static void
 channel_read(channel_T *channel, int part, char *func)
@@ -4184,6 +4185,15 @@ job_free(job_T *job)
     }
 }
 
+#if defined(EXITFREE) || defined(PROTO)
+    void
+job_free_all(void)
+{
+    while (first_job != NULL)
+       job_free(first_job);
+}
+#endif
+
 /*
  * Return TRUE if the job should not be freed yet.  Do not free the job when
  * it has not ended yet and there is a "stoponexit" flag, an exit callback
index a0cce07f66080519a47acafe3ba2d4edbcd4c0b6..b4e94795f193ec1cefb3215b7ce4e169bb6fd247 100644 (file)
@@ -1126,9 +1126,6 @@ free_all_mem(void)
 # endif
 # ifdef FEAT_DIFF
     diff_clear(curtab);
-# endif
-# ifdef FEAT_JOB_CHANNEL
-    channel_free_all();
 # endif
     clear_sb_text();         /* free any scrollback text */
 
@@ -1221,6 +1218,10 @@ free_all_mem(void)
 # ifdef FEAT_EVAL
     eval_clear();
 # endif
+# ifdef FEAT_JOB_CHANNEL
+    channel_free_all();
+    job_free_all();
+# endif
 
     free_termoptions();
 
index 5dc512181f1b2e197001f96864457d5849ba4d9b..60b68f013352d27e428a8de9600f6ec980464dbb 100644 (file)
@@ -50,6 +50,7 @@ void clear_job_options(jobopt_T *opt);
 void free_job_options(jobopt_T *opt);
 int get_job_options(typval_T *tv, jobopt_T *opt, int supported);
 channel_T *get_channel_arg(typval_T *tv, int check_open, int reading, int part);
+void job_free_all(void);
 int set_ref_in_job(int copyID);
 void job_unref(job_T *job);
 int free_unused_jobs_contents(int copyID, int mask);
index af6ca6db25904046a60b0741d6345c44b54e7632..f33aab3a1aada13c569eb8d97a38a3d5d3fba64e 100644 (file)
@@ -250,6 +250,20 @@ func Test_cycle_partial_job()
   endif
 endfunc
 
+func Test_job_start_fails()
+  if has('job')
+    let job = job_start('axdfxsdf')
+    for i in range(100)
+      if job_status(job) == 'dead'
+       break
+      endif
+      sleep 10m
+    endfor
+    call assert_equal('dead', job_status(job))
+    unlet job
+  endif
+endfunc
+
 func Test_ref_job_partial_dict()
   if has('job')
     let g:ref_job = job_start('echo')
index 2ec25c0b5e78aeec2e034fcc3cce8f01466d0400..e68c4ec05f502803bceab4c94b8bf67ccfe75a92 100644 (file)
@@ -753,6 +753,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1855,
 /**/
     1854,
 /**/