comparison src/channel.c @ 9087:d4606ae170aa v7.4.1828

commit https://github.com/vim/vim/commit/e0f76d00979c972329f6c371463a20da61ccad65 Author: Bram Moolenaar <Bram@vim.org> Date: Mon May 9 20:38:53 2016 +0200 patch 7.4.1828 Problem: May try to access buffer that's already freed. Solution: When freeing a buffer remove it from any channel.
author Christian Brabandt <cb@256bit.org>
date Mon, 09 May 2016 20:45:08 +0200
parents d362e6df1deb
children 6bc0a492e8ba
comparison
equal deleted inserted replaced
9086:75f46a491f61 9087:d4606ae170aa
1066 } 1066 }
1067 } 1067 }
1068 1068
1069 /* 1069 /*
1070 * Find a buffer matching "name" or create a new one. 1070 * Find a buffer matching "name" or create a new one.
1071 * Returns NULL if there is something very wrong (error already reported).
1071 */ 1072 */
1072 static buf_T * 1073 static buf_T *
1073 find_buffer(char_u *name, int err) 1074 find_buffer(char_u *name, int err)
1074 { 1075 {
1075 buf_T *buf = NULL; 1076 buf_T *buf = NULL;
1079 buf = buflist_findname(name); 1080 buf = buflist_findname(name);
1080 if (buf == NULL) 1081 if (buf == NULL)
1081 { 1082 {
1082 buf = buflist_new(name == NULL || *name == NUL ? NULL : name, 1083 buf = buflist_new(name == NULL || *name == NUL ? NULL : name,
1083 NULL, (linenr_T)0, BLN_LISTED); 1084 NULL, (linenr_T)0, BLN_LISTED);
1085 if (buf == NULL)
1086 return NULL;
1084 buf_copy_options(buf, BCO_ENTER); 1087 buf_copy_options(buf, BCO_ENTER);
1085 curbuf = buf; 1088 curbuf = buf;
1086 #ifdef FEAT_QUICKFIX 1089 #ifdef FEAT_QUICKFIX
1087 set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL); 1090 set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
1088 set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL); 1091 set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL);
1185 ++(*pp)->pt_refcount; 1188 ++(*pp)->pt_refcount;
1186 } 1189 }
1187 1190
1188 if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER) 1191 if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER)
1189 { 1192 {
1193 buf_T *buf;
1194
1190 /* writing output to a buffer. Default mode is NL. */ 1195 /* writing output to a buffer. Default mode is NL. */
1191 if (!(opt->jo_set & JO_OUT_MODE)) 1196 if (!(opt->jo_set & JO_OUT_MODE))
1192 channel->ch_part[PART_OUT].ch_mode = MODE_NL; 1197 channel->ch_part[PART_OUT].ch_mode = MODE_NL;
1193 if (opt->jo_set & JO_OUT_BUF) 1198 if (opt->jo_set & JO_OUT_BUF)
1194 channel->ch_part[PART_OUT].ch_buffer = 1199 {
1195 buflist_findnr(opt->jo_io_buf[PART_OUT]); 1200 buf = buflist_findnr(opt->jo_io_buf[PART_OUT]);
1201 if (buf == NULL)
1202 EMSGN(_(e_nobufnr), (long)opt->jo_io_buf[PART_OUT]);
1203 }
1196 else 1204 else
1197 channel->ch_part[PART_OUT].ch_buffer = 1205 {
1198 find_buffer(opt->jo_io_name[PART_OUT], FALSE); 1206 buf = find_buffer(opt->jo_io_name[PART_OUT], FALSE);
1199 ch_logs(channel, "writing out to buffer '%s'", 1207 }
1200 (char *)channel->ch_part[PART_OUT].ch_buffer->b_ffname); 1208 if (buf != NULL)
1209 {
1210 ch_logs(channel, "writing out to buffer '%s'",
1211 (char *)buf->b_ffname);
1212 channel->ch_part[PART_OUT].ch_buffer = buf;
1213 }
1201 } 1214 }
1202 1215
1203 if ((opt->jo_set & JO_ERR_IO) && (opt->jo_io[PART_ERR] == JIO_BUFFER 1216 if ((opt->jo_set & JO_ERR_IO) && (opt->jo_io[PART_ERR] == JIO_BUFFER
1204 || (opt->jo_io[PART_ERR] == JIO_OUT && (opt->jo_set & JO_OUT_IO) 1217 || (opt->jo_io[PART_ERR] == JIO_OUT && (opt->jo_set & JO_OUT_IO)
1205 && opt->jo_io[PART_OUT] == JIO_BUFFER))) 1218 && opt->jo_io[PART_OUT] == JIO_BUFFER)))
1206 { 1219 {
1220 buf_T *buf;
1221
1207 /* writing err to a buffer. Default mode is NL. */ 1222 /* writing err to a buffer. Default mode is NL. */
1208 if (!(opt->jo_set & JO_ERR_MODE)) 1223 if (!(opt->jo_set & JO_ERR_MODE))
1209 channel->ch_part[PART_ERR].ch_mode = MODE_NL; 1224 channel->ch_part[PART_ERR].ch_mode = MODE_NL;
1210 if (opt->jo_io[PART_ERR] == JIO_OUT) 1225 if (opt->jo_io[PART_ERR] == JIO_OUT)
1211 channel->ch_part[PART_ERR].ch_buffer = 1226 buf = channel->ch_part[PART_OUT].ch_buffer;
1212 channel->ch_part[PART_OUT].ch_buffer;
1213 else if (opt->jo_set & JO_ERR_BUF) 1227 else if (opt->jo_set & JO_ERR_BUF)
1214 channel->ch_part[PART_ERR].ch_buffer = 1228 {
1215 buflist_findnr(opt->jo_io_buf[PART_ERR]); 1229 buf = buflist_findnr(opt->jo_io_buf[PART_ERR]);
1230 if (buf == NULL)
1231 EMSGN(_(e_nobufnr), (long)opt->jo_io_buf[PART_ERR]);
1232 }
1216 else 1233 else
1217 channel->ch_part[PART_ERR].ch_buffer = 1234 buf = find_buffer(opt->jo_io_name[PART_ERR], TRUE);
1218 find_buffer(opt->jo_io_name[PART_ERR], TRUE); 1235 if (buf != NULL)
1219 ch_logs(channel, "writing err to buffer '%s'", 1236 {
1220 (char *)channel->ch_part[PART_ERR].ch_buffer->b_ffname); 1237 ch_logs(channel, "writing err to buffer '%s'",
1238 (char *)buf->b_ffname);
1239 channel->ch_part[PART_ERR].ch_buffer = buf;
1240 }
1221 } 1241 }
1222 1242
1223 channel->ch_part[PART_OUT].ch_io = opt->jo_io[PART_OUT]; 1243 channel->ch_part[PART_OUT].ch_io = opt->jo_io[PART_OUT];
1224 channel->ch_part[PART_ERR].ch_io = opt->jo_io[PART_ERR]; 1244 channel->ch_part[PART_ERR].ch_io = opt->jo_io[PART_ERR];
1225 channel->ch_part[PART_IN].ch_io = opt->jo_io[PART_IN]; 1245 channel->ch_part[PART_IN].ch_io = opt->jo_io[PART_IN];
1383 ch_log(channel, "Finished writing all lines to channel"); 1403 ch_log(channel, "Finished writing all lines to channel");
1384 } 1404 }
1385 else 1405 else
1386 ch_logn(channel, "Still %d more lines to write", 1406 ch_logn(channel, "Still %d more lines to write",
1387 buf->b_ml.ml_line_count - lnum + 1); 1407 buf->b_ml.ml_line_count - lnum + 1);
1408 }
1409
1410 /*
1411 * Handle buffer "buf" beeing freed, remove it from any channels.
1412 */
1413 void
1414 channel_buffer_free(buf_T *buf)
1415 {
1416 channel_T *channel;
1417 int part;
1418
1419 for (channel = first_channel; channel != NULL; channel = channel->ch_next)
1420 for (part = PART_SOCK; part <= PART_IN; ++part)
1421 {
1422 chanpart_T *ch_part = &channel->ch_part[part];
1423
1424 if (ch_part->ch_buffer == buf)
1425 ch_part->ch_buffer = NULL;
1426 }
1388 } 1427 }
1389 1428
1390 /* 1429 /*
1391 * Write any lines waiting to be written to a channel. 1430 * Write any lines waiting to be written to a channel.
1392 */ 1431 */