Changeset 39caad0
- Timestamp:
- Mar 15, 2016, 10:39:46 PM (9 years ago)
- Branches:
- master, release-1.10
- Children:
- 4ced41e
- Parents:
- 0f5af62 (diff), e8db357 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
filterproc.c
r7155955 re8db357 1 1 #include "filterproc.h" 2 2 #include <sys/wait.h> 3 #include < fcntl.h>3 #include <string.h> 4 4 #include <glib.h> 5 #include <poll.h>6 #include <string.h>7 #include <unistd.h>8 5 9 /* Even in case of error, send_receive is responsible for closing wfd 10 * (to EOF the child) and rfd (for consistency). */ 11 static int send_receive(int rfd, int wfd, const char *out, char **in) 6 struct filter_data { 7 const char **in; 8 const char *in_end; 9 GString *out_str; 10 GMainLoop *loop; 11 int err; 12 }; 13 14 static gboolean filter_stdin(GIOChannel *channel, GIOCondition condition, gpointer data_) 12 15 { 13 GString *str = g_string_new(""); 14 char buf[1024]; 15 nfds_t nfds; 16 int err = 0; 17 struct pollfd fds[2]; 16 struct filter_data *data = data_; 17 gboolean done = condition & (G_IO_ERR | G_IO_HUP); 18 18 19 fcntl(rfd, F_SETFL, O_NONBLOCK | fcntl(rfd, F_GETFL)); 20 fcntl(wfd, F_SETFL, O_NONBLOCK | fcntl(wfd, F_GETFL)); 21 22 fds[0].fd = rfd; 23 fds[0].events = POLLIN; 24 fds[1].fd = wfd; 25 fds[1].events = POLLOUT; 26 27 if(!out || !*out) { 28 /* Nothing to write. Close our end so the child doesn't hang waiting. */ 29 close(wfd); wfd = -1; 30 out = NULL; 19 if (condition & G_IO_OUT) { 20 gsize n; 21 GIOStatus ret = g_io_channel_write_chars(channel, *data->in, data->in_end - *data->in, &n, NULL); 22 *data->in += n; 23 if (ret == G_IO_STATUS_ERROR) 24 data->err = 1; 25 if (ret == G_IO_STATUS_ERROR || *data->in == data->in_end) 26 done = TRUE; 31 27 } 32 28 33 while(1) { 34 if(out && *out) { 35 nfds = 2; 36 } else { 37 nfds = 1; 38 } 39 err = poll(fds, nfds, -1); 40 if(err < 0) { 41 break; 42 } 43 if(out && *out) { 44 if(fds[1].revents & POLLOUT) { 45 err = write(wfd, out, strlen(out)); 46 if(err > 0) { 47 out += err; 48 } 49 if(err < 0) { 50 out = NULL; 51 } 52 } 53 if(!out || !*out || fds[1].revents & (POLLERR | POLLHUP)) { 54 close(wfd); wfd = -1; 55 out = NULL; 56 } 57 } 58 if(fds[0].revents & POLLIN) { 59 err = read(rfd, buf, sizeof(buf)); 60 if(err <= 0) { 61 break; 62 } 63 g_string_append_len(str, buf, err); 64 } else if(fds[0].revents & (POLLHUP | POLLERR)) { 65 err = 0; 66 break; 29 if (condition & G_IO_ERR) 30 data->err = 1; 31 32 if (done) 33 g_io_channel_shutdown(channel, TRUE, NULL); 34 return !done; 35 } 36 37 static gboolean filter_stdout(GIOChannel *channel, GIOCondition condition, gpointer data_) 38 { 39 struct filter_data *data = data_; 40 gboolean done = condition & (G_IO_ERR | G_IO_HUP); 41 42 if (condition & (G_IO_IN | G_IO_HUP)) { 43 gchar *buf; 44 gsize n; 45 GIOStatus ret = g_io_channel_read_to_end(channel, &buf, &n, NULL); 46 g_string_append_len(data->out_str, buf, n); 47 g_free(buf); 48 if (ret == G_IO_STATUS_ERROR) { 49 data->err = 1; 50 done = TRUE; 67 51 } 68 52 } 69 53 70 if (wfd >= 0) close(wfd); 71 close(rfd); 72 *in = g_string_free(str, err < 0); 73 return err; 54 if (condition & G_IO_ERR) 55 data->err = 1; 56 57 if (done) { 58 g_io_channel_shutdown(channel, TRUE, NULL); 59 g_main_loop_quit(data->loop); 60 } 61 return !done; 74 62 } 75 63 76 64 int call_filter(const char *const *argv, const char *in, char **out, int *status) 77 65 { 78 int err;79 66 GPid child_pid; 80 67 int child_stdin, child_stdout; … … 89 76 } 90 77 91 err = send_receive(child_stdout, child_stdin, in, out); 92 if (err == 0) { 93 waitpid(child_pid, status, 0); 94 } 95 return err; 78 if (in == NULL) in = ""; 79 GMainContext *context = g_main_context_new(); 80 struct filter_data data = {&in, in + strlen(in), g_string_new(""), g_main_loop_new(context, FALSE), 0}; 81 82 GIOChannel *channel = g_io_channel_unix_new(child_stdin); 83 g_io_channel_set_encoding(channel, NULL, NULL); 84 g_io_channel_set_flags(channel, g_io_channel_get_flags(channel) | G_IO_FLAG_NONBLOCK, NULL); 85 GSource *source = g_io_create_watch(channel, G_IO_OUT | G_IO_ERR | G_IO_HUP); 86 g_io_channel_unref(channel); 87 g_source_set_callback(source, (GSourceFunc)filter_stdin, &data, NULL); 88 g_source_attach(source, context); 89 g_source_unref(source); 90 91 channel = g_io_channel_unix_new(child_stdout); 92 g_io_channel_set_encoding(channel, NULL, NULL); 93 g_io_channel_set_flags(channel, g_io_channel_get_flags(channel) | G_IO_FLAG_NONBLOCK, NULL); 94 source = g_io_create_watch(channel, G_IO_IN | G_IO_ERR | G_IO_HUP); 95 g_io_channel_unref(channel); 96 g_source_set_callback(source, (GSourceFunc)filter_stdout, &data, NULL); 97 g_source_attach(source, context); 98 g_source_unref(source); 99 100 g_main_loop_run(data.loop); 101 102 g_main_loop_unref(data.loop); 103 g_main_context_unref(context); 104 105 waitpid(child_pid, status, 0); 106 g_spawn_close_pid(child_pid); 107 *out = g_string_free(data.out_str, data.err); 108 return data.err; 96 109 } -
.travis.yml
r48c09d4 rbecd617 1 1 language: perl 2 sudo: false 2 3 compiler: 3 4 - clang … … 9 10 - "5.16" 10 11 - "5.18" 11 - "5.19" 12 install: 13 - sudo apt-get update -q 14 # we actually want debhelper >= 7, libperl-dev >= 5.10.1-8, libzephyr-dev >= 3.0~beta 15 - sudo apt-get install -q autoconf autotools-dev debhelper dh-autoreconf libglib2.0-dev libkrb5-dev libncurses5-dev libncursesw5-dev libssl-dev libzephyr-dev pkg-config zip 12 - "5.20" 13 addons: 14 apt: 15 # we actually want debhelper >= 7, libperl-dev >= 5.10.1-8, libzephyr-dev >= 3.0~beta 16 packages: 17 - autoconf 18 - autotools-dev 19 - debhelper 20 - dh-autoreconf 21 - libglib2.0-dev 22 - libkrb5-dev 23 - libncurses5-dev 24 - libncursesw5-dev 25 - libssl-dev 26 - libzephyr-dev 27 - pkg-config 28 - zip 16 29 # perl things 17 30 # In lp:~barnowl/barnowl/packaging, we use apt-get. Here, we use cpanm. 18 31 # - sudo apt-get install libanyevent-perl libclass-accessor-perl libextutils-depends-perl libglib-perl libmodule-install-perl libnet-twitter-lite-perl libpar-perl libperl-dev 19 - cpanm AnyEvent Class::Accessor ExtUtils::Depends Glib Module::Install Net::Twitter::Lite PAR 20 script: "./autogen.sh && ./configure && make distcheck"32 # It's taken care of by the default install script 33 script: ./autogen.sh && ./configure && make distcheck -
commands.c
rca1fb26a r8fcd3e7 548 548 "optional color arguments are used they specifies the colors that\n" 549 549 "messages matching this filter should be displayed in.\n\n" 550 "SEE ALSO: view, viewclass, viewuser\n"),550 "SEE ALSO: smartfilter, smartnarrow, view, viewclass, viewuser\n"), 551 551 552 552 OWLCMD_ARGS("colorview", owl_command_colorview, OWL_CTX_INTERACTIVE, … … 585 585 "filter expression that will be dynamically created by BarnOwl and then\n" 586 586 "applied as the view's filter\n" 587 "SEE ALSO: filter, viewclass, viewuser\n"),587 "SEE ALSO: filter, smartfilter, smartnarrow, viewclass, viewuser\n"), 588 588 589 589 OWLCMD_ARGS("smartnarrow", owl_command_smartnarrow, OWL_CTX_INTERACTIVE, … … 599 599 " then narrow to the class and instance.\n" 600 600 "If '-r' or '--related' is specified, behave as though the\n" 601 " 'narrow-related' variable was inverted."), 601 " 'narrow-related' variable was inverted.\n\n" 602 "SEE ALSO: filter, smartfilter, view, viewclass, viewuser\n"), 602 603 603 604 OWLCMD_ARGS("smartfilter", owl_command_smartfilter, OWL_CTX_INTERACTIVE, … … 610 611 "If the curmsg is a class message, the filter is that class.\n" 611 612 "If the curmsg is a class message and '-i' is specified\n" 612 " the filter is to that class and instance.\n"), 613 " the filter is to that class and instance.\n\n" 614 "SEE ALSO: filter, smartnarrow, view, viewclass, viewuser\n"), 613 615 614 616 OWLCMD_ARGS("viewclass", owl_command_viewclass, OWL_CTX_INTERACTIVE, … … 618 620 "matching the specified class and switch the current view\n" 619 621 "to it.\n\n" 620 "SEE ALSO: filter, view, viewuser\n"),622 "SEE ALSO: filter, smartfilter, smartnarrow, view, viewuser\n"), 621 623 OWLCMD_ALIAS("vc", "viewclass"), 622 624 … … 627 629 "matching the specified user and switch the current\n" 628 630 "view to it.\n\n" 629 "SEE ALSO: filter, view, viewclass\n"),631 "SEE ALSO: filter, smartfilter, smartnarrow, view, viewclass\n"), 630 632 OWLCMD_ALIAS("vu", "viewuser"), 631 633 OWLCMD_ALIAS("viewperson", "viewuser"), -
perl/modules/IRC/lib/BarnOwl/Module/IRC.pm
r926c721 rd4f33f1 562 562 "[" . $conn->alias . "] Reconnect cancelled"); 563 563 $conn->cancel_reconnect; 564 delete $ircnets{$conn->alias}; 565 } elsif (exists $ircnets{$conn->alias}) { # inconsistent state; no socket, but not yet deleted 566 BarnOwl::admin_message('IRC', 567 "[" . $conn->alias . "] Attempt to disconnect from a socketless connection; deleting it"); 564 568 delete $ircnets{$conn->alias}; 565 569 } -
perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm
rbe43554 r4379288 437 437 } 438 438 439 sub rejoin_channels { 440 my $self = shift; 441 my @channels = @_; 442 # As reported in https://barnowl.mit.edu/ticket/274, if we reconnect to 443 # too many at once, the server rejects us. Empirically, this is about 444 # 20-26, so we set the cap at 15, then delay further joins for 5 seconds. 445 my $MAX_RECONNECT_CHANNELS = 15; 446 my $DELAY = 5; 447 foreach my $c (@channels[ 0 .. $MAX_RECONNECT_CHANNELS ]) { 448 $self->conn->send_msg(join => $c); 449 } 450 if ($MAX_RECONNECT_CHANNELS < $#channels) { 451 my $remaining = $#channels - $MAX_RECONNECT_CHANNELS; 452 my $cur_alias = $self->alias; 453 BarnOwl::admin_message('IRC', "[$cur_alias] Delaying $remaining autorejoins for $DELAY seconds"); 454 # if we don't assign the timer to anything, then it gets garbage 455 # collected, and never runs 456 $self->{autoconnect_channels_delay_timer} = BarnOwl::Timer->new({ 457 name => "IRC rejoin overflow timer ($remaining remaining)", 458 after => $DELAY, 459 cb => sub { 460 rejoin_channels($self, @channels[ $MAX_RECONNECT_CHANNELS .. $#channels ]); 461 } 462 }); 463 } 464 } 465 466 439 467 sub connected { 440 468 my $self = shift; … … 443 471 $self->cancel_reconnect; 444 472 if ($self->autoconnect_channels) { 445 for my $c (@{$self->autoconnect_channels}) { 446 $self->conn->send_msg(join => $c); 447 } 473 rejoin_channels($self, @{$self->autoconnect_channels}); 448 474 } 449 475 $self->conn->enable_ping(60, sub { -
zephyr.c
r18380fd rff58239 1311 1311 { 1312 1312 int n = strcspn(in, "./"); 1313 char *realm = strchrnul(in, '@'); 1313 const char *realm = strchr(in, '@'); 1314 if (realm == NULL) 1315 realm = in + strlen(in); 1314 1316 1315 1317 if (in + n >= realm ||
Note: See TracChangeset
for help on using the changeset viewer.