comparison src/channel.c @ 8859:03250bc0c63a v7.4.1717

commit https://github.com/vim/vim/commit/0e4c1de5560c7f8b4cae539ec8cff0949daba3fc Author: Bram Moolenaar <Bram@vim.org> Date: Thu Apr 7 21:40:38 2016 +0200 patch 7.4.1717 Problem: Leaking memory when opening a channel fails. Solution: Unreference partials in job options.
author Christian Brabandt <cb@256bit.org>
date Thu, 07 Apr 2016 21:45:05 +0200
parents 176647a751d7
children e1b84109506a
comparison
equal deleted inserted replaced
8858:593b17f02b78 8859:03250bc0c63a
856 char_u *address; 856 char_u *address;
857 char_u *p; 857 char_u *p;
858 char *rest; 858 char *rest;
859 int port; 859 int port;
860 jobopt_T opt; 860 jobopt_T opt;
861 channel_T *channel; 861 channel_T *channel = NULL;
862 862
863 address = get_tv_string(&argvars[0]); 863 address = get_tv_string(&argvars[0]);
864 if (argvars[1].v_type != VAR_UNKNOWN 864 if (argvars[1].v_type != VAR_UNKNOWN
865 && (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL)) 865 && (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL))
866 { 866 {
888 clear_job_options(&opt); 888 clear_job_options(&opt);
889 opt.jo_mode = MODE_JSON; 889 opt.jo_mode = MODE_JSON;
890 opt.jo_timeout = 2000; 890 opt.jo_timeout = 2000;
891 if (get_job_options(&argvars[1], &opt, 891 if (get_job_options(&argvars[1], &opt,
892 JO_MODE_ALL + JO_CB_ALL + JO_WAITTIME + JO_TIMEOUT_ALL) == FAIL) 892 JO_MODE_ALL + JO_CB_ALL + JO_WAITTIME + JO_TIMEOUT_ALL) == FAIL)
893 return NULL; 893 goto theend;
894 if (opt.jo_timeout < 0) 894 if (opt.jo_timeout < 0)
895 { 895 {
896 EMSG(_(e_invarg)); 896 EMSG(_(e_invarg));
897 return NULL; 897 goto theend;
898 } 898 }
899 899
900 channel = channel_open((char *)address, port, opt.jo_waittime, NULL); 900 channel = channel_open((char *)address, port, opt.jo_waittime, NULL);
901 if (channel != NULL) 901 if (channel != NULL)
902 { 902 {
903 opt.jo_set = JO_ALL; 903 opt.jo_set = JO_ALL;
904 channel_set_options(channel, &opt); 904 channel_set_options(channel, &opt);
905 } 905 }
906 theend:
907 free_job_options(&opt);
906 return channel; 908 return channel;
907 } 909 }
908 910
909 static void 911 static void
910 may_close_part(sock_T *fd) 912 may_close_part(sock_T *fd)
2895 rettv->vval.v_string = NULL; 2897 rettv->vval.v_string = NULL;
2896 2898
2897 clear_job_options(&opt); 2899 clear_job_options(&opt);
2898 if (get_job_options(&argvars[1], &opt, JO_TIMEOUT + JO_PART + JO_ID) 2900 if (get_job_options(&argvars[1], &opt, JO_TIMEOUT + JO_PART + JO_ID)
2899 == FAIL) 2901 == FAIL)
2900 return; 2902 goto theend;
2901 2903
2902 channel = get_channel_arg(&argvars[0], TRUE); 2904 channel = get_channel_arg(&argvars[0], TRUE);
2903 if (channel != NULL) 2905 if (channel != NULL)
2904 { 2906 {
2905 if (opt.jo_set & JO_PART) 2907 if (opt.jo_set & JO_PART)
2928 rettv->v_type = VAR_SPECIAL; 2930 rettv->v_type = VAR_SPECIAL;
2929 rettv->vval.v_number = VVAL_NONE; 2931 rettv->vval.v_number = VVAL_NONE;
2930 } 2932 }
2931 } 2933 }
2932 } 2934 }
2935
2936 theend:
2937 free_job_options(&opt);
2933 } 2938 }
2934 2939
2935 # if defined(WIN32) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) \ 2940 # if defined(WIN32) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) \
2936 || defined(PROTO) 2941 || defined(PROTO)
2937 /* 2942 /*
3054 int *part_read) 3059 int *part_read)
3055 { 3060 {
3056 channel_T *channel; 3061 channel_T *channel;
3057 int part_send; 3062 int part_send;
3058 3063
3064 clear_job_options(opt);
3059 channel = get_channel_arg(&argvars[0], TRUE); 3065 channel = get_channel_arg(&argvars[0], TRUE);
3060 if (channel == NULL) 3066 if (channel == NULL)
3061 return NULL; 3067 return NULL;
3062 part_send = channel_part_send(channel); 3068 part_send = channel_part_send(channel);
3063 *part_read = channel_part_read(channel); 3069 *part_read = channel_part_read(channel);
3064 3070
3065 clear_job_options(opt);
3066 if (get_job_options(&argvars[2], opt, JO_CALLBACK + JO_TIMEOUT) == FAIL) 3071 if (get_job_options(&argvars[2], opt, JO_CALLBACK + JO_TIMEOUT) == FAIL)
3067 return NULL; 3072 return NULL;
3068 3073
3069 /* Set the callback. An empty callback means no callback and not reading 3074 /* Set the callback. An empty callback means no callback and not reading
3070 * the response. With "ch_evalexpr()" and "ch_evalraw()" a callback is not 3075 * the response. With "ch_evalexpr()" and "ch_evalraw()" a callback is not
3143 *rettv = list->lv_last->li_tv; 3148 *rettv = list->lv_last->li_tv;
3144 list->lv_last->li_tv.v_type = VAR_NUMBER; 3149 list->lv_last->li_tv.v_type = VAR_NUMBER;
3145 free_tv(listtv); 3150 free_tv(listtv);
3146 } 3151 }
3147 } 3152 }
3153 free_job_options(&opt);
3148 } 3154 }
3149 3155
3150 /* 3156 /*
3151 * common for "ch_evalraw()" and "ch_sendraw()" 3157 * common for "ch_evalraw()" and "ch_sendraw()"
3152 */ 3158 */
3173 timeout = opt.jo_timeout; 3179 timeout = opt.jo_timeout;
3174 else 3180 else
3175 timeout = channel_get_timeout(channel, part_read); 3181 timeout = channel_get_timeout(channel, part_read);
3176 rettv->vval.v_string = channel_read_block(channel, part_read, timeout); 3182 rettv->vval.v_string = channel_read_block(channel, part_read, timeout);
3177 } 3183 }
3184 free_job_options(&opt);
3178 } 3185 }
3179 3186
3180 # if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO) 3187 # if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO)
3181 /* 3188 /*
3182 * Add open channels to the poll struct. 3189 * Add open channels to the poll struct.
3543 return FAIL; 3550 return FAIL;
3544 } 3551 }
3545 return OK; 3552 return OK;
3546 } 3553 }
3547 3554
3555 /*
3556 * Clear a jobopt_T before using it.
3557 */
3548 void 3558 void
3549 clear_job_options(jobopt_T *opt) 3559 clear_job_options(jobopt_T *opt)
3550 { 3560 {
3551 vim_memset(opt, 0, sizeof(jobopt_T)); 3561 vim_memset(opt, 0, sizeof(jobopt_T));
3562 }
3563
3564 /*
3565 * Free any members of a jobopt_T.
3566 */
3567 void
3568 free_job_options(jobopt_T *opt)
3569 {
3570 if (opt->jo_partial != NULL)
3571 partial_unref(opt->jo_partial);
3572 if (opt->jo_out_partial != NULL)
3573 partial_unref(opt->jo_out_partial);
3574 if (opt->jo_err_partial != NULL)
3575 partial_unref(opt->jo_err_partial);
3576 if (opt->jo_close_partial != NULL)
3577 partial_unref(opt->jo_close_partial);
3552 } 3578 }
3553 3579
3554 /* 3580 /*
3555 * Get the PART_ number from the first character of an option name. 3581 * Get the PART_ number from the first character of an option name.
3556 */ 3582 */
4051 job = job_alloc(); 4077 job = job_alloc();
4052 if (job == NULL) 4078 if (job == NULL)
4053 return NULL; 4079 return NULL;
4054 4080
4055 job->jv_status = JOB_FAILED; 4081 job->jv_status = JOB_FAILED;
4082 #ifndef USE_ARGV
4083 ga_init2(&ga, (int)sizeof(char*), 20);
4084 #endif
4056 4085
4057 /* Default mode is NL. */ 4086 /* Default mode is NL. */
4058 clear_job_options(&opt); 4087 clear_job_options(&opt);
4059 opt.jo_mode = MODE_NL; 4088 opt.jo_mode = MODE_NL;
4060 if (get_job_options(&argvars[1], &opt, 4089 if (get_job_options(&argvars[1], &opt,
4061 JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL + JO_STOPONEXIT 4090 JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL + JO_STOPONEXIT
4062 + JO_EXIT_CB + JO_OUT_IO + JO_BLOCK_WRITE) == FAIL) 4091 + JO_EXIT_CB + JO_OUT_IO + JO_BLOCK_WRITE) == FAIL)
4063 return job; 4092 goto theend;
4064 4093
4065 /* Check that when io is "file" that there is a file name. */ 4094 /* Check that when io is "file" that there is a file name. */
4066 for (part = PART_OUT; part <= PART_IN; ++part) 4095 for (part = PART_OUT; part <= PART_IN; ++part)
4067 if ((opt.jo_set & (JO_OUT_IO << (part - PART_OUT))) 4096 if ((opt.jo_set & (JO_OUT_IO << (part - PART_OUT)))
4068 && opt.jo_io[part] == JIO_FILE 4097 && opt.jo_io[part] == JIO_FILE
4069 && (!(opt.jo_set & (JO_OUT_NAME << (part - PART_OUT))) 4098 && (!(opt.jo_set & (JO_OUT_NAME << (part - PART_OUT)))
4070 || *opt.jo_io_name[part] == NUL)) 4099 || *opt.jo_io_name[part] == NUL))
4071 { 4100 {
4072 EMSG(_("E920: _io file requires _name to be set")); 4101 EMSG(_("E920: _io file requires _name to be set"));
4073 return job; 4102 goto theend;
4074 } 4103 }
4075 4104
4076 if ((opt.jo_set & JO_IN_IO) && opt.jo_io[PART_IN] == JIO_BUFFER) 4105 if ((opt.jo_set & JO_IN_IO) && opt.jo_io[PART_IN] == JIO_BUFFER)
4077 { 4106 {
4078 buf_T *buf = NULL; 4107 buf_T *buf = NULL;
4089 EMSG(_("E915: in_io buffer requires in_buf or in_name to be set")); 4118 EMSG(_("E915: in_io buffer requires in_buf or in_name to be set"));
4090 } 4119 }
4091 else 4120 else
4092 buf = buflist_find_by_name(opt.jo_io_name[PART_IN], FALSE); 4121 buf = buflist_find_by_name(opt.jo_io_name[PART_IN], FALSE);
4093 if (buf == NULL) 4122 if (buf == NULL)
4094 return job; 4123 goto theend;
4095 if (buf->b_ml.ml_mfp == NULL) 4124 if (buf->b_ml.ml_mfp == NULL)
4096 { 4125 {
4097 char_u numbuf[NUMBUFLEN]; 4126 char_u numbuf[NUMBUFLEN];
4098 char_u *s; 4127 char_u *s;
4099 4128
4103 s = numbuf; 4132 s = numbuf;
4104 } 4133 }
4105 else 4134 else
4106 s = opt.jo_io_name[PART_IN]; 4135 s = opt.jo_io_name[PART_IN];
4107 EMSG2(_("E918: buffer must be loaded: %s"), s); 4136 EMSG2(_("E918: buffer must be loaded: %s"), s);
4108 return job; 4137 goto theend;
4109 } 4138 }
4110 job->jv_in_buf = buf; 4139 job->jv_in_buf = buf;
4111 } 4140 }
4112 4141
4113 job_set_options(job, &opt); 4142 job_set_options(job, &opt);
4114
4115 #ifndef USE_ARGV
4116 ga_init2(&ga, (int)sizeof(char*), 20);
4117 #endif
4118 4143
4119 if (argvars[0].v_type == VAR_STRING) 4144 if (argvars[0].v_type == VAR_STRING)
4120 { 4145 {
4121 /* Command is a string. */ 4146 /* Command is a string. */
4122 cmd = argvars[0].vval.v_string; 4147 cmd = argvars[0].vval.v_string;
4123 if (cmd == NULL || *cmd == NUL) 4148 if (cmd == NULL || *cmd == NUL)
4124 { 4149 {
4125 EMSG(_(e_invarg)); 4150 EMSG(_(e_invarg));
4126 return job; 4151 goto theend;
4127 } 4152 }
4128 #ifdef USE_ARGV 4153 #ifdef USE_ARGV
4129 if (mch_parse_cmd(cmd, FALSE, &argv, &argc) == FAIL) 4154 if (mch_parse_cmd(cmd, FALSE, &argv, &argc) == FAIL)
4130 return job; 4155 goto theend;
4131 argv[argc] = NULL; 4156 argv[argc] = NULL;
4132 #endif 4157 #endif
4133 } 4158 }
4134 else if (argvars[0].v_type != VAR_LIST 4159 else if (argvars[0].v_type != VAR_LIST
4135 || argvars[0].vval.v_list == NULL 4160 || argvars[0].vval.v_list == NULL
4136 || argvars[0].vval.v_list->lv_len < 1) 4161 || argvars[0].vval.v_list->lv_len < 1)
4137 { 4162 {
4138 EMSG(_(e_invarg)); 4163 EMSG(_(e_invarg));
4139 return job; 4164 goto theend;
4140 } 4165 }
4141 else 4166 else
4142 { 4167 {
4143 list_T *l = argvars[0].vval.v_list; 4168 list_T *l = argvars[0].vval.v_list;
4144 listitem_T *li; 4169 listitem_T *li;
4146 4171
4147 #ifdef USE_ARGV 4172 #ifdef USE_ARGV
4148 /* Pass argv[] to mch_call_shell(). */ 4173 /* Pass argv[] to mch_call_shell(). */
4149 argv = (char **)alloc(sizeof(char *) * (l->lv_len + 1)); 4174 argv = (char **)alloc(sizeof(char *) * (l->lv_len + 1));
4150 if (argv == NULL) 4175 if (argv == NULL)
4151 return job; 4176 goto theend;
4152 #endif 4177 #endif
4153 for (li = l->lv_first; li != NULL; li = li->li_next) 4178 for (li = l->lv_first; li != NULL; li = li->li_next)
4154 { 4179 {
4155 s = get_tv_string_chk(&li->li_tv); 4180 s = get_tv_string_chk(&li->li_tv);
4156 if (s == NULL) 4181 if (s == NULL)
4220 #ifdef USE_ARGV 4245 #ifdef USE_ARGV
4221 vim_free(argv); 4246 vim_free(argv);
4222 #else 4247 #else
4223 vim_free(ga.ga_data); 4248 vim_free(ga.ga_data);
4224 #endif 4249 #endif
4250 free_job_options(&opt);
4225 return job; 4251 return job;
4226 } 4252 }
4227 4253
4228 /* 4254 /*
4229 * Get the status of "job" and invoke the exit callback when needed. 4255 * Get the status of "job" and invoke the exit callback when needed.