Changeset 7655e08
- Timestamp:
- May 3, 2011, 5:23:55 PM (13 years ago)
- Parents:
- 4fd211f (diff), f578d18 (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
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile.am
rce35060 rfafb842 45 45 aim.c buddy.c buddylist.c style.c errqueue.c \ 46 46 zbuddylist.c popexec.c select.c wcwidth.c \ 47 glib_compat.c mainpanel.c msgwin.c sepbar.c editcontext.c 47 glib_compat.c mainpanel.c msgwin.c sepbar.c editcontext.c signal.c 48 48 49 49 NORMAL_SRCS = filterproc.c window.c windowcb.c -
aim.c
r3472845 r0af5f9d 446 446 } 447 447 448 int owl_aim_process_events(void) 449 { 450 aim_session_t *aimsess; 448 int owl_aim_process_events(aim_session_t *aimsess) 449 { 451 450 aim_conn_t *waitingconn = NULL; 452 451 struct timeval tv; … … 454 453 struct owlfaim_priv *priv; 455 454 456 aimsess=owl_global_get_aimsess(&g);457 455 priv = aimsess->aux_data; 458 456 … … 1795 1793 } 1796 1794 1797 void owl_process_aim(void) 1798 { 1799 if (owl_global_is_doaimevents(&g)) { 1800 owl_aim_process_events(); 1801 } 1802 } 1795 typedef struct _owl_aim_event_source { /*noproto*/ 1796 GSource source; 1797 aim_session_t *sess; 1798 GPtrArray *fds; 1799 } owl_aim_event_source; 1800 1801 static void truncate_pollfd_list(owl_aim_event_source *event_source, int len) 1802 { 1803 GPollFD *fd; 1804 int i; 1805 if (len < event_source->fds->len) 1806 owl_function_debugmsg("Truncating AIM PollFDs to %d, was %d", len, event_source->fds->len); 1807 for (i = len; i < event_source->fds->len; i++) { 1808 fd = event_source->fds->pdata[i]; 1809 g_source_remove_poll(&event_source->source, fd); 1810 g_free(fd); 1811 } 1812 g_ptr_array_remove_range(event_source->fds, len, event_source->fds->len - len); 1813 } 1814 1815 static gboolean owl_aim_event_source_prepare(GSource *source, int *timeout) 1816 { 1817 owl_aim_event_source *event_source = (owl_aim_event_source*)source; 1818 aim_conn_t *cur; 1819 GPollFD *fd; 1820 int i; 1821 1822 /* AIM HACK: 1823 * 1824 * The problem - I'm not sure where to hook into the owl/faim 1825 * interface to keep track of when the AIM socket(s) open and 1826 * close. In particular, the bosconn thing throws me off. So, 1827 * rather than register particular dispatchers for AIM, I look up 1828 * the relevant FDs and add them to select's watch lists, then 1829 * check for them individually before moving on to the other 1830 * dispatchers. --asedeno 1831 */ 1832 i = 0; 1833 for (cur = event_source->sess->connlist; cur; cur = cur->next) { 1834 if (cur->fd != -1) { 1835 /* Add new GPollFDs as necessary. */ 1836 if (i == event_source->fds->len) { 1837 fd = g_new0(GPollFD, 1); 1838 g_ptr_array_add(event_source->fds, fd); 1839 g_source_add_poll(source, fd); 1840 owl_function_debugmsg("Allocated new AIM PollFD, len = %d", event_source->fds->len); 1841 } 1842 fd = event_source->fds->pdata[i]; 1843 fd->fd = cur->fd; 1844 fd->events |= G_IO_IN | G_IO_HUP | G_IO_ERR; 1845 if (cur->status & AIM_CONN_STATUS_INPROGRESS) { 1846 /* Yes, we're checking writable sockets here. Without it, AIM 1847 login is really slow. */ 1848 fd->events |= G_IO_OUT; 1849 } 1850 i++; 1851 } 1852 } 1853 /* If the number of GPollFDs went down, clean up. */ 1854 truncate_pollfd_list(event_source, i); 1855 1856 *timeout = -1; 1857 return FALSE; 1858 } 1859 1860 static gboolean owl_aim_event_source_check(GSource *source) 1861 { 1862 owl_aim_event_source *event_source = (owl_aim_event_source*)source; 1863 int i; 1864 1865 for (i = 0; i < event_source->fds->len; i++) { 1866 GPollFD *fd = event_source->fds->pdata[i]; 1867 if (fd->revents & fd->events) 1868 return TRUE; 1869 } 1870 return FALSE; 1871 } 1872 1873 static gboolean owl_aim_event_source_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) 1874 { 1875 owl_aim_event_source *event_source = (owl_aim_event_source*)source; 1876 owl_aim_process_events(event_source->sess); 1877 return TRUE; 1878 } 1879 1880 static void owl_aim_event_source_finalize(GSource *source) 1881 { 1882 owl_aim_event_source *event_source = (owl_aim_event_source*)source; 1883 truncate_pollfd_list(event_source, 0); 1884 g_ptr_array_free(event_source->fds, TRUE); 1885 } 1886 1887 static GSourceFuncs aim_event_funcs = { 1888 owl_aim_event_source_prepare, 1889 owl_aim_event_source_check, 1890 owl_aim_event_source_dispatch, 1891 owl_aim_event_source_finalize, 1892 }; 1893 1894 GSource *owl_aim_event_source_new(aim_session_t *sess) 1895 { 1896 GSource *source; 1897 owl_aim_event_source *event_source; 1898 1899 source = g_source_new(&aim_event_funcs, sizeof(owl_aim_event_source)); 1900 event_source = (owl_aim_event_source *)source; 1901 event_source->sess = sess; 1902 /* TODO: When we depend on glib 2.22+, use g_ptr_array_new_with_free_func. */ 1903 event_source->fds = g_ptr_array_new(); 1904 return source; 1905 } -
configure.ac
r4479497 re9b037f 115 115 116 116 dnl Add CFLAGS and LIBS for glib-2.0 117 PKG_CHECK_MODULES(GLIB,[glib-2.0 gobject-2.0 ])117 PKG_CHECK_MODULES(GLIB,[glib-2.0 gobject-2.0 gthread-2.0]) 118 118 119 119 AC_MSG_NOTICE([Adding glib-2.0 CFLAGS ${GLIB_CFLAGS}]) -
filterproc.c
rd564c3d rb9c7424 17 17 int err = 0; 18 18 struct pollfd fds[2]; 19 struct sigaction sig = {.sa_handler = SIG_IGN}, old;20 19 21 20 fcntl(rfd, F_SETFL, O_NONBLOCK | fcntl(rfd, F_GETFL)); … … 27 26 fds[1].events = POLLOUT; 28 27 29 sigaction(SIGPIPE, &sig, &old);30 31 28 while(1) { 32 29 if(out && *out) { … … 67 64 68 65 *in = g_string_free(str, err < 0); 69 sigaction(SIGPIPE, &old, NULL);70 66 return err; 71 67 } -
functions.c
r4fd211f r7655e08 2995 2995 i--; 2996 2996 } 2997 owl_function_mask_sigint(NULL); 2998 if(owl_global_is_interrupted(&g)) { 2999 owl_global_unset_interrupted(&g); 3000 owl_function_unmask_sigint(NULL); 2997 if (owl_global_take_interrupt(&g)) { 3001 2998 owl_function_makemsg("Search interrupted!"); 3002 2999 owl_mainwin_redisplay(owl_global_get_mainwin(&g)); 3003 3000 return; 3004 3001 } 3005 owl_function_unmask_sigint(NULL);3006 3002 } 3007 3003 owl_mainwin_redisplay(owl_global_get_mainwin(&g)); … … 3086 3082 ret=ZLocateUser(zstr(user), &numlocs, ZAUTH); 3087 3083 3088 owl_function_mask_sigint(NULL); 3089 if(owl_global_is_interrupted(&g)) { 3084 if (owl_global_take_interrupt(&g)) { 3090 3085 interrupted = 1; 3091 owl_global_unset_interrupted(&g);3092 owl_function_unmask_sigint(NULL);3093 3086 owl_function_makemsg("Interrupted!"); 3094 3087 break; 3095 3088 } 3096 3097 owl_function_unmask_sigint(NULL);3098 3089 3099 3090 if (ret!=ZERR_NONE) { … … 3500 3491 } 3501 3492 3502 void owl_function_mask_sigint(sigset_t *oldmask) {3503 sigset_t intr;3504 3505 sigemptyset(&intr);3506 sigaddset(&intr, SIGINT);3507 sigprocmask(SIG_BLOCK, &intr, oldmask);3508 }3509 3510 void owl_function_unmask_sigint(sigset_t *oldmask) {3511 sigset_t intr;3512 3513 sigemptyset(&intr);3514 sigaddset(&intr, SIGINT);3515 sigprocmask(SIG_UNBLOCK, &intr, oldmask);3516 }3517 3518 3493 void _owl_function_mark_message(const owl_message *m) 3519 3494 { -
global.c
r47e0a6a rf578d18 16 16 17 17 g_type_init(); 18 g_thread_init(NULL); 19 20 owl_select_init(); 18 21 19 22 g->lines=LINES; … … 99 102 100 103 owl_errqueue_init(&(g->errqueue)); 101 g->got_err_signal=0;102 104 103 105 owl_zbuddylist_create(&(g->zbuddies)); … … 108 110 owl_message_init_fmtext_cache(); 109 111 owl_list_create(&(g->io_dispatch_list)); 110 owl_list_create(&(g->psa_list));111 112 g->timerlist = NULL; 112 g->interrupted = FALSE;113 113 g->kill_buffer = NULL; 114 115 g->interrupt_count = 0; 116 g->interrupt_lock = g_mutex_new(); 114 117 } 115 118 … … 348 351 349 352 void owl_global_set_resize_pending(owl_global *g) { 350 g->resizepending =1;353 g->resizepending = true; 351 354 } 352 355 … … 448 451 /* resize the screen. If lines or cols is 0 use the terminal size */ 449 452 if (!g->resizepending) return; 450 g->resizepending = 0;453 g->resizepending = false; 451 454 452 455 owl_global_get_terminal_size(&g->lines, &g->cols); … … 693 696 } 694 697 695 int owl_global_is_doaimevents(const owl_global *g) 696 { 697 if (g->aim_doprocessing) return(1); 698 return(0); 698 bool owl_global_is_doaimevents(const owl_global *g) 699 { 700 return g->aim_event_source != NULL; 699 701 } 700 702 701 703 void owl_global_set_doaimevents(owl_global *g) 702 704 { 703 g->aim_doprocessing=1; 705 if (g->aim_event_source) 706 return; 707 g->aim_event_source = owl_aim_event_source_new(owl_global_get_aimsess(g)); 708 g_source_attach(g->aim_event_source, NULL); 704 709 } 705 710 706 711 void owl_global_set_no_doaimevents(owl_global *g) 707 712 { 708 g->aim_doprocessing=0; 713 if (!g->aim_event_source) 714 return; 715 g_source_destroy(g->aim_event_source); 716 g_source_unref(g->aim_event_source); 717 g->aim_event_source = NULL; 709 718 } 710 719 … … 824 833 } 825 834 826 void owl_global_set_errsignal(owl_global *g, int signum, siginfo_t *siginfo)827 {828 g->got_err_signal = signum;829 if (siginfo) {830 g->err_signal_info = *siginfo;831 } else {832 siginfo_t si;833 memset(&si, 0, sizeof(si));834 g->err_signal_info = si;835 }836 }837 838 int owl_global_get_errsignal_and_clear(owl_global *g, siginfo_t *siginfo)839 {840 int signum;841 if (siginfo && g->got_err_signal) {842 *siginfo = g->err_signal_info;843 }844 signum = g->got_err_signal;845 g->got_err_signal = 0;846 return signum;847 }848 849 850 835 owl_zbuddylist *owl_global_get_zephyr_buddylist(owl_global *g) 851 836 { … … 878 863 } 879 864 880 owl_list *owl_global_get_psa_list(owl_global *g)881 {882 return &(g->psa_list);883 }884 885 865 GList **owl_global_get_timerlist(owl_global *g) 886 866 { 887 867 return &(g->timerlist); 888 }889 890 int owl_global_is_interrupted(const owl_global *g) {891 return g->interrupted;892 }893 894 void owl_global_set_interrupted(owl_global *g) {895 g->interrupted = 1;896 }897 898 void owl_global_unset_interrupted(owl_global *g) {899 g->interrupted = 0;900 868 } 901 869 … … 965 933 g->kill_buffer = g_strndup(kill, len); 966 934 } 935 936 void owl_global_add_interrupt(owl_global *g) { 937 /* TODO: This can almost certainly be done with atomic 938 * operations. Whatever. */ 939 g_mutex_lock(g->interrupt_lock); 940 g->interrupt_count++; 941 g_mutex_unlock(g->interrupt_lock); 942 } 943 944 bool owl_global_take_interrupt(owl_global *g) { 945 bool ans = false; 946 g_mutex_lock(g->interrupt_lock); 947 if (g->interrupt_count > 0) { 948 ans = true; 949 g->interrupt_count--; 950 } 951 g_mutex_unlock(g->interrupt_lock); 952 return ans; 953 } -
owl.c
ra2a8833 r7655e08 160 160 * was ignored due to user settings or otherwise. 161 161 */ 162 int owl_process_message(owl_message *m) {162 static int owl_process_message(owl_message *m) { 163 163 const owl_filter *f; 164 164 /* if this message it on the puntlist, nuke it and continue */ … … 245 245 } 246 246 247 static gboolean owl_process_messages_prepare(GSource *source, int *timeout) { 248 *timeout = -1; 249 return owl_global_messagequeue_pending(&g); 250 } 251 252 static gboolean owl_process_messages_check(GSource *source) { 253 return owl_global_messagequeue_pending(&g); 254 } 255 247 256 /* 248 257 * Process any new messages we have waiting in the message queue. 249 * Returns 1 if any messages were added to the message list, and 0 otherwise.250 258 */ 251 int owl_process_messages(owl_ps_action *d, void *p) 252 { 259 static gboolean owl_process_messages_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { 253 260 int newmsgs=0; 254 261 int followlast = owl_global_should_followlast(&g); … … 274 281 owl_mainwin_redisplay(owl_global_get_mainwin(&g)); 275 282 } 276 return newmsgs; 283 return TRUE; 284 } 285 286 static GSourceFuncs owl_process_messages_funcs = { 287 owl_process_messages_prepare, 288 owl_process_messages_check, 289 owl_process_messages_dispatch, 290 NULL 291 }; 292 293 void owl_process_input_char(owl_input j) 294 { 295 int ret; 296 297 owl_global_set_lastinputtime(&g, time(NULL)); 298 ret = owl_keyhandler_process(owl_global_get_keyhandler(&g), j); 299 if (ret!=0 && ret!=1) { 300 owl_function_makemsg("Unable to handle keypress"); 301 } 277 302 } 278 303 … … 334 359 } 335 360 336 void sig_handler(int sig, siginfo_t *si, void *data) 337 { 338 if (sig==SIGWINCH) { 339 /* we can't inturrupt a malloc here, so it just sets a flag 340 * schedulding a resize for later 341 */ 361 static void sig_handler_main_thread(void *data) { 362 int sig = GPOINTER_TO_INT(data); 363 364 owl_function_debugmsg("Got signal %d", sig); 365 if (sig == SIGWINCH) { 342 366 owl_function_resize(); 343 } else if (sig==SIGPIPE || sig==SIGCHLD) { 344 /* Set a flag and some info that we got the sigpipe 345 * so we can record that we got it and why... */ 346 owl_global_set_errsignal(&g, sig, si); 347 } else if (sig==SIGTERM || sig==SIGHUP) { 367 } else if (sig == SIGTERM || sig == SIGHUP) { 348 368 owl_function_quit(); 349 } 350 } 351 352 void sigint_handler(int sig, siginfo_t *si, void *data) 353 { 354 owl_global_set_interrupted(&g); 355 } 356 357 static int owl_errsignal_pre_select_action(owl_ps_action *a, void *data) 358 { 359 siginfo_t si; 360 int signum; 361 if ((signum = owl_global_get_errsignal_and_clear(&g, &si)) > 0) { 362 owl_function_error("Got unexpected signal: %d %s (code: %d band: %ld errno: %d)", 363 signum, signum==SIGPIPE?"SIGPIPE":"SIG????", 364 si.si_code, si.si_band, si.si_errno); 365 } 366 return 0; 367 } 369 } else if (sig == SIGINT && owl_global_take_interrupt(&g)) { 370 owl_input in; 371 in.ch = in.uch = owl_global_get_startup_tio(&g)->c_cc[VINTR]; 372 owl_process_input_char(in); 373 } 374 } 375 376 static void sig_handler(const siginfo_t *siginfo, void *data) { 377 /* If it was an interrupt, set a flag so we can handle it earlier if 378 * needbe. sig_handler_main_thread will check the flag to make sure 379 * no one else took it. */ 380 if (siginfo->si_signo == SIGINT) { 381 owl_global_add_interrupt(&g); 382 } 383 /* Send a message to the main thread. */ 384 owl_select_post_task(sig_handler_main_thread, 385 GINT_TO_POINTER(siginfo->si_signo), NULL); 386 } 387 388 #define CHECK_RESULT(s, syscall) \ 389 G_STMT_START { \ 390 if ((syscall) != 0) { \ 391 perror((s)); \ 392 exit(1); \ 393 } \ 394 } G_STMT_END 368 395 369 396 void owl_register_signal_handlers(void) { 370 struct sigaction sigact; 371 372 /* signal handler */ 373 /*sigact.sa_handler=sig_handler;*/ 374 sigact.sa_sigaction=sig_handler; 375 sigemptyset(&sigact.sa_mask); 376 sigact.sa_flags=SA_SIGINFO; 377 sigaction(SIGWINCH, &sigact, NULL); 378 sigaction(SIGALRM, &sigact, NULL); 379 sigaction(SIGPIPE, &sigact, NULL); 380 sigaction(SIGTERM, &sigact, NULL); 381 sigaction(SIGHUP, &sigact, NULL); 382 383 sigact.sa_sigaction=sigint_handler; 384 sigaction(SIGINT, &sigact, NULL); 397 struct sigaction sig_ignore = { .sa_handler = SIG_IGN }; 398 struct sigaction sig_default = { .sa_handler = SIG_DFL }; 399 sigset_t sigset; 400 int ret, i; 401 const int signals[] = { SIGABRT, SIGBUS, SIGCHLD, SIGFPE, SIGHUP, SIGILL, 402 SIGINT, SIGQUIT, SIGSEGV, SIGTERM, SIGWINCH }; 403 404 /* Sanitize our signals; the mask and dispositions from our parent 405 * aren't really useful. Signal list taken from equivalent code in 406 * Chromium. */ 407 CHECK_RESULT("sigemptyset", sigemptyset(&sigset)); 408 if ((ret = pthread_sigmask(SIG_SETMASK, &sigset, NULL)) != 0) { 409 errno = ret; 410 perror("pthread_sigmask"); 411 } 412 for (i = 0; i < G_N_ELEMENTS(signals); i++) { 413 CHECK_RESULT("sigaction", sigaction(signals[i], &sig_default, NULL)); 414 } 415 416 /* Turn off SIGPIPE; we check the return value of write. */ 417 CHECK_RESULT("sigaction", sigaction(SIGPIPE, &sig_ignore, NULL)); 418 419 /* Register some signals with the signal thread. */ 420 CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGWINCH)); 421 CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGTERM)); 422 CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGHUP)); 423 CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGINT)); 424 owl_signal_init(&sigset, sig_handler, NULL); 385 425 } 386 426 … … 436 476 #endif /* OWL_STDERR_REDIR */ 437 477 438 static int owl_refresh_pre_select_action(owl_ps_action *a, void *data)439 {440 owl_colorpair_mgr *cpmgr;441 442 /* if a resize has been scheduled, deal with it */443 owl_global_check_resize(&g);444 /* update the terminal if we need to */445 owl_window_redraw_scheduled();446 /* On colorpair shortage, reset and redraw /everything/. NOTE: if447 * the current screen uses too many colorpairs, this draws448 * everything twice. But this is unlikely; COLOR_PAIRS is 64 with449 * 8+1 colors, and 256^2 with 256+1 colors. (+1 for default.) */450 cpmgr = owl_global_get_colorpair_mgr(&g);451 if (cpmgr->overflow) {452 owl_function_debugmsg("colorpairs: color shortage; reset pairs and redraw. COLOR_PAIRS = %d", COLOR_PAIRS);453 owl_fmtext_reset_colorpairs(cpmgr);454 owl_function_full_redisplay();455 owl_window_redraw_scheduled();456 }457 return 0;458 }459 460 461 478 int main(int argc, char **argv, char **env) 462 479 { … … 467 484 const char *dir; 468 485 owl_options opts; 486 GSource *source; 469 487 470 488 if (!GLIB_CHECK_VERSION (2, 12, 0)) … … 481 499 g.load_initial_subs = opts.load_initial_subs; 482 500 483 owl_register_signal_handlers();484 501 owl_start_curses(); 485 502 … … 492 509 g_strfreev(argv_copy); 493 510 owl_global_set_haveaim(&g); 511 512 owl_register_signal_handlers(); 494 513 495 514 /* register STDIN dispatch; throw away return, we won't need it */ … … 584 603 owl_global_push_context(&g, OWL_CTX_INTERACTIVE|OWL_CTX_RECV, NULL, "recv", NULL); 585 604 586 owl_select_add_pre_select_action(owl_refresh_pre_select_action, NULL, NULL); 587 owl_select_add_pre_select_action(owl_process_messages, NULL, NULL); 588 owl_select_add_pre_select_action(owl_errsignal_pre_select_action, NULL, NULL); 605 source = owl_window_redraw_source_new(); 606 g_source_attach(source, NULL); 607 g_source_unref(source); 608 609 source = g_source_new(&owl_process_messages_funcs, sizeof(GSource)); 610 g_source_attach(source, NULL); 611 g_source_unref(source); 589 612 590 613 owl_function_debugmsg("startup: entering main loop"); … … 593 616 /* Shut down everything. */ 594 617 owl_zephyr_shutdown(); 618 owl_signal_shutdown(); 595 619 owl_shutdown_curses(); 596 620 return 0; -
owl.h
r283ff1e rf578d18 550 550 void (*destroy)(const struct _owl_io_dispatch *); /* Destructor */ 551 551 void *data; 552 GPollFD pollfd; 552 553 } owl_io_dispatch; 553 554 typedef struct _owl_ps_action {555 int needs_gc;556 int (*callback)(struct _owl_ps_action *, void *);557 void (*destroy)(struct _owl_ps_action *);558 void *data;559 } owl_ps_action;560 554 561 555 typedef struct _owl_popexec { … … 566 560 const owl_io_dispatch *dispatch; 567 561 } owl_popexec; 568 569 typedef struct _OwlGlobalNotifier OwlGlobalNotifier;570 562 571 563 typedef struct _owl_global { … … 593 585 gulong typwin_erase_id; 594 586 int rightshift; 595 volatile sig_atomic_tresizepending;587 bool resizepending; 596 588 char *homedir; 597 589 char *confdir; … … 618 610 aim_conn_t bosconn; 619 611 int aim_loggedin; /* true if currently logged into AIM */ 620 int aim_doprocessing; /* true if we should process AIM events (like pending login)*/612 GSource *aim_event_source; /* where we get our AIM events from */ 621 613 char *aim_screenname; /* currently logged in AIM screen name */ 622 614 char *aim_screenname_for_filters; /* currently logged in AIM screen name */ … … 628 620 int haveaim; 629 621 int ignoreaimlogin; 630 volatile sig_atomic_t got_err_signal; /* 1 if we got an unexpected signal */631 volatile siginfo_t err_signal_info;632 622 owl_zbuddylist zbuddies; 633 623 GList *zaldlist; … … 635 625 struct termios startup_tio; 636 626 owl_list io_dispatch_list; 637 owl_list psa_list;638 627 GList *timerlist; 639 628 owl_timer *aim_nop_timer; 640 629 int load_initial_subs; 641 volatile sig_atomic_t interrupted;642 630 FILE *debug_file; 643 631 char *kill_buffer; 632 int interrupt_count; 633 GMutex *interrupt_lock; 644 634 } owl_global; 645 635 -
select.c
rd4927a7 r111850c 1 1 #include "owl.h" 2 2 3 static GMainLoop *loop = NULL; 4 static GMainContext *context; 3 5 static int dispatch_active = 0; 4 static int psa_active = 0; 5 static int loop_active = 0; 6 7 int _owl_select_timer_cmp(const owl_timer *t1, const owl_timer *t2) { 6 7 static GSource *owl_timer_source; 8 static GSource *owl_io_dispatch_source; 9 10 static int _owl_select_timer_cmp(const owl_timer *t1, const owl_timer *t2); 11 static void owl_select_io_dispatch_gc(void); 12 13 static gboolean owl_timer_prepare(GSource *source, int *timeout) { 14 GList **timers = owl_global_get_timerlist(&g); 15 GTimeVal now; 16 17 /* TODO: In the far /far/ future, g_source_get_time is what the cool 18 * kids use to get system monotonic time. */ 19 g_source_get_current_time(source, &now); 20 21 /* FIXME: bother with millisecond accuracy now that we can? */ 22 if (*timers) { 23 owl_timer *t = (*timers)->data; 24 *timeout = t->time - now.tv_sec; 25 if (*timeout <= 0) { 26 *timeout = 0; 27 return TRUE; 28 } 29 if (*timeout > 60 * 1000) 30 *timeout = 60 * 1000; 31 } else { 32 *timeout = 60 * 1000; 33 } 34 return FALSE; 35 } 36 37 static gboolean owl_timer_check(GSource *source) { 38 GList **timers = owl_global_get_timerlist(&g); 39 GTimeVal now; 40 41 /* TODO: In the far /far/ future, g_source_get_time is what the cool 42 * kids use to get system monotonic time. */ 43 g_source_get_current_time(source, &now); 44 45 /* FIXME: bother with millisecond accuracy now that we can? */ 46 if (*timers) { 47 owl_timer *t = (*timers)->data; 48 return t->time >= now.tv_sec; 49 } 50 return FALSE; 51 } 52 53 54 static gboolean owl_timer_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { 55 GList **timers = owl_global_get_timerlist(&g); 56 GTimeVal now; 57 58 /* TODO: In the far /far/ future, g_source_get_time is what the cool 59 * kids use to get system monotonic time. */ 60 g_source_get_current_time(source, &now); 61 62 /* FIXME: bother with millisecond accuracy now that we can? */ 63 while(*timers) { 64 owl_timer *t = (*timers)->data; 65 int remove = 0; 66 67 if(t->time > now.tv_sec) 68 break; 69 70 /* Reschedule if appropriate */ 71 if(t->interval > 0) { 72 t->time = now.tv_sec + t->interval; 73 *timers = g_list_remove(*timers, t); 74 *timers = g_list_insert_sorted(*timers, t, 75 (GCompareFunc)_owl_select_timer_cmp); 76 } else { 77 remove = 1; 78 } 79 80 /* Do the callback */ 81 t->callback(t, t->data); 82 if(remove) { 83 owl_select_remove_timer(t); 84 } 85 } 86 return TRUE; 87 } 88 89 static GSourceFuncs owl_timer_funcs = { 90 owl_timer_prepare, 91 owl_timer_check, 92 owl_timer_dispatch, 93 NULL 94 }; 95 96 static int _owl_select_timer_cmp(const owl_timer *t1, const owl_timer *t2) { 8 97 return t1->time - t2->time; 9 }10 11 int _owl_select_timer_eq(const owl_timer *t1, const owl_timer *t2) {12 return t1 == t2;13 98 } 14 99 … … 43 128 } 44 129 45 void owl_select_process_timers(struct timespec *timeout) 46 { 47 time_t now = time(NULL); 48 GList **timers = owl_global_get_timerlist(&g); 49 50 while(*timers) { 51 owl_timer *t = (*timers)->data; 52 int remove = 0; 53 54 if(t->time > now) 55 break; 56 57 /* Reschedule if appropriate */ 58 if(t->interval > 0) { 59 t->time = now + t->interval; 60 *timers = g_list_remove(*timers, t); 61 *timers = g_list_insert_sorted(*timers, t, 62 (GCompareFunc)_owl_select_timer_cmp); 63 } else { 64 remove = 1; 65 } 66 67 /* Do the callback */ 68 t->callback(t, t->data); 69 if(remove) { 70 owl_select_remove_timer(t); 71 } 72 } 73 74 if(*timers) { 75 owl_timer *t = (*timers)->data; 76 timeout->tv_sec = t->time - now; 77 if (timeout->tv_sec > 60) 78 timeout->tv_sec = 60; 79 } else { 80 timeout->tv_sec = 60; 81 } 82 83 timeout->tv_nsec = 0; 84 } 130 131 static gboolean owl_io_dispatch_prepare(GSource *source, int *timeout) { 132 *timeout = -1; 133 return FALSE; 134 } 135 136 static gboolean owl_io_dispatch_check(GSource *source) { 137 int i, len; 138 const owl_list *dl; 139 140 dl = owl_global_get_io_dispatch_list(&g); 141 len = owl_list_get_size(dl); 142 for(i = 0; i < len; i++) { 143 const owl_io_dispatch *d = owl_list_get_element(dl, i); 144 if (d->pollfd.revents & d->pollfd.events) 145 return TRUE; 146 } 147 return FALSE; 148 } 149 150 static gboolean owl_io_dispatch_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { 151 int i, len; 152 const owl_list *dl; 153 154 dispatch_active = 1; 155 dl = owl_global_get_io_dispatch_list(&g); 156 len = owl_list_get_size(dl); 157 for (i = 0; i < len; i++) { 158 owl_io_dispatch *d = owl_list_get_element(dl, i); 159 if ((d->pollfd.revents & d->pollfd.events) && d->callback != NULL) { 160 d->callback(d, d->data); 161 } 162 } 163 dispatch_active = 0; 164 owl_select_io_dispatch_gc(); 165 166 return TRUE; 167 } 168 169 static GSourceFuncs owl_io_dispatch_funcs = { 170 owl_io_dispatch_prepare, 171 owl_io_dispatch_check, 172 owl_io_dispatch_dispatch, 173 NULL 174 }; 85 175 86 176 static const owl_io_dispatch *owl_select_find_io_dispatch_by_fd(const int fd) … … 128 218 if (d->destroy) 129 219 d->destroy(d); 220 g_source_remove_poll(owl_io_dispatch_source, &d->pollfd); 130 221 g_free(d); 131 222 } … … 134 225 } 135 226 136 void owl_select_io_dispatch_gc(void)227 static void owl_select_io_dispatch_gc(void) 137 228 { 138 229 int i; … … 169 260 d->data = data; 170 261 262 /* TODO: Allow changing fd and mode in the middle? Probably don't care... */ 263 d->pollfd.fd = fd; 264 d->pollfd.events = 0; 265 if (d->mode & OWL_IO_READ) 266 d->pollfd.events |= G_IO_IN | G_IO_HUP | G_IO_ERR; 267 if (d->mode & OWL_IO_WRITE) 268 d->pollfd.events |= G_IO_OUT | G_IO_ERR; 269 if (d->mode & OWL_IO_EXCEPT) 270 d->pollfd.events |= G_IO_PRI | G_IO_ERR; 271 g_source_add_poll(owl_io_dispatch_source, &d->pollfd); 272 273 171 274 owl_select_remove_io_dispatch(owl_select_find_io_dispatch_by_fd(fd)); 172 275 owl_list_append_element(dl, d); 173 276 174 277 return d; 175 }176 177 int owl_select_prepare_io_dispatch_fd_sets(fd_set *rfds, fd_set *wfds, fd_set *efds) {178 int i, len, max_fd;179 owl_io_dispatch *d;180 owl_list *dl = owl_global_get_io_dispatch_list(&g);181 182 max_fd = 0;183 len = owl_list_get_size(dl);184 for (i = 0; i < len; i++) {185 d = owl_list_get_element(dl, i);186 if (d->mode & (OWL_IO_READ | OWL_IO_WRITE | OWL_IO_EXCEPT)) {187 if (max_fd < d->fd) max_fd = d->fd;188 if (d->mode & OWL_IO_READ) FD_SET(d->fd, rfds);189 if (d->mode & OWL_IO_WRITE) FD_SET(d->fd, wfds);190 if (d->mode & OWL_IO_EXCEPT) FD_SET(d->fd, efds);191 }192 }193 return max_fd + 1;194 }195 196 void owl_select_io_dispatch(const fd_set *rfds, const fd_set *wfds, const fd_set *efds, const int max_fd)197 {198 int i, len;199 owl_io_dispatch *d;200 owl_list *dl = owl_global_get_io_dispatch_list(&g);201 202 dispatch_active = 1;203 len = owl_list_get_size(dl);204 for (i = 0; i < len; i++) {205 d = owl_list_get_element(dl, i);206 if (d->fd < max_fd && d->callback != NULL &&207 ((d->mode & OWL_IO_READ && FD_ISSET(d->fd, rfds)) ||208 (d->mode & OWL_IO_WRITE && FD_ISSET(d->fd, wfds)) ||209 (d->mode & OWL_IO_EXCEPT && FD_ISSET(d->fd, efds)))) {210 d->callback(d, d->data);211 }212 }213 dispatch_active = 0;214 owl_select_io_dispatch_gc();215 278 } 216 279 … … 237 300 } 238 301 239 int owl_select_aim_hack(fd_set *rfds, fd_set *wfds) 240 { 241 aim_conn_t *cur; 242 aim_session_t *sess; 243 int max_fd; 244 245 max_fd = 0; 246 sess = owl_global_get_aimsess(&g); 247 for (cur = sess->connlist; cur; cur = cur->next) { 248 if (cur->fd != -1) { 249 FD_SET(cur->fd, rfds); 250 if (cur->status & AIM_CONN_STATUS_INPROGRESS) { 251 /* Yes, we're checking writable sockets here. Without it, AIM 252 login is really slow. */ 253 FD_SET(cur->fd, wfds); 254 } 255 256 if (cur->fd > max_fd) 257 max_fd = cur->fd; 258 } 259 } 260 return max_fd; 261 } 262 263 void owl_process_input_char(owl_input j) 264 { 265 int ret; 266 267 owl_global_set_lastinputtime(&g, time(NULL)); 268 ret = owl_keyhandler_process(owl_global_get_keyhandler(&g), j); 269 if (ret!=0 && ret!=1) { 270 owl_function_makemsg("Unable to handle keypress"); 271 } 272 } 273 274 void owl_select_mask_signals(sigset_t *oldmask) { 275 sigset_t set; 276 277 sigemptyset(&set); 278 sigaddset(&set, SIGWINCH); 279 sigaddset(&set, SIGALRM); 280 sigaddset(&set, SIGPIPE); 281 sigaddset(&set, SIGTERM); 282 sigaddset(&set, SIGHUP); 283 sigaddset(&set, SIGINT); 284 sigprocmask(SIG_BLOCK, &set, oldmask); 285 } 286 287 void owl_select_handle_intr(sigset_t *restore) 288 { 289 owl_input in; 290 291 owl_global_unset_interrupted(&g); 292 293 sigprocmask(SIG_SETMASK, restore, NULL); 294 295 in.ch = in.uch = owl_global_get_startup_tio(&g)->c_cc[VINTR]; 296 owl_process_input_char(in); 297 } 298 299 owl_ps_action *owl_select_add_pre_select_action(int (*cb)(owl_ps_action *, void *), void (*destroy)(owl_ps_action *), void *data) 300 { 301 owl_ps_action *a = g_new(owl_ps_action, 1); 302 owl_list *psa_list = owl_global_get_psa_list(&g); 303 a->needs_gc = 0; 304 a->callback = cb; 305 a->destroy = destroy; 306 a->data = data; 307 owl_list_append_element(psa_list, a); 308 return a; 309 } 310 311 void owl_select_psa_gc(void) 312 { 313 int i; 314 owl_list *psa_list; 315 owl_ps_action *a; 316 317 psa_list = owl_global_get_psa_list(&g); 318 for (i = owl_list_get_size(psa_list) - 1; i >= 0; i--) { 319 a = owl_list_get_element(psa_list, i); 320 if (a->needs_gc) { 321 owl_list_remove_element(psa_list, i); 322 if (a->destroy) { 323 a->destroy(a); 324 } 325 g_free(a); 326 } 327 } 328 } 329 330 void owl_select_remove_pre_select_action(owl_ps_action *a) 331 { 332 a->needs_gc = 1; 333 if (!psa_active) 334 owl_select_psa_gc(); 335 } 336 337 int owl_select_do_pre_select_actions(void) 338 { 339 int i, len, ret; 340 owl_list *psa_list; 341 342 psa_active = 1; 343 ret = 0; 344 psa_list = owl_global_get_psa_list(&g); 345 len = owl_list_get_size(psa_list); 346 for (i = 0; i < len; i++) { 347 owl_ps_action *a = owl_list_get_element(psa_list, i); 348 if (a->callback != NULL && a->callback(a, a->data)) { 349 ret = 1; 350 } 351 } 352 psa_active = 0; 353 owl_select_psa_gc(); 354 return ret; 355 } 356 357 void owl_select(void) 358 { 359 int i, max_fd, max_fd2, aim_done, ret; 360 fd_set r; 361 fd_set w; 362 fd_set e; 363 fd_set aim_rfds, aim_wfds; 364 struct timespec timeout; 365 sigset_t mask; 366 367 owl_select_process_timers(&timeout); 368 369 owl_select_mask_signals(&mask); 370 371 if(owl_global_is_interrupted(&g)) { 372 owl_select_handle_intr(&mask); 373 return; 374 } 375 FD_ZERO(&r); 376 FD_ZERO(&w); 377 FD_ZERO(&e); 378 379 max_fd = owl_select_prepare_io_dispatch_fd_sets(&r, &w, &e); 380 381 /* AIM HACK: 382 * 383 * The problem - I'm not sure where to hook into the owl/faim 384 * interface to keep track of when the AIM socket(s) open and 385 * close. In particular, the bosconn thing throws me off. So, 386 * rather than register particular dispatchers for AIM, I look up 387 * the relevant FDs and add them to select's watch lists, then 388 * check for them individually before moving on to the other 389 * dispatchers. --asedeno 390 */ 391 aim_done = 1; 392 FD_ZERO(&aim_rfds); 393 FD_ZERO(&aim_wfds); 394 if (owl_global_is_doaimevents(&g)) { 395 aim_done = 0; 396 max_fd2 = owl_select_aim_hack(&aim_rfds, &aim_wfds); 397 if (max_fd < max_fd2) max_fd = max_fd2; 398 for(i = 0; i <= max_fd2; i++) { 399 if (FD_ISSET(i, &aim_rfds)) { 400 FD_SET(i, &r); 401 FD_SET(i, &e); 402 } 403 if (FD_ISSET(i, &aim_wfds)) { 404 FD_SET(i, &w); 405 FD_SET(i, &e); 406 } 407 } 408 } 409 /* END AIM HACK */ 410 411 if (owl_select_do_pre_select_actions()) { 412 timeout.tv_sec = 0; 413 timeout.tv_nsec = 0; 414 } 415 416 ret = pselect(max_fd+1, &r, &w, &e, &timeout, &mask); 417 418 if(ret < 0 && errno == EINTR) { 419 if(owl_global_is_interrupted(&g)) { 420 owl_select_handle_intr(NULL); 421 } 422 sigprocmask(SIG_SETMASK, &mask, NULL); 423 return; 424 } 425 426 sigprocmask(SIG_SETMASK, &mask, NULL); 427 428 if(ret > 0) { 429 /* AIM HACK: process all AIM events at once. */ 430 for(i = 0; !aim_done && i <= max_fd; i++) { 431 if (FD_ISSET(i, &r) || FD_ISSET(i, &w) || FD_ISSET(i, &e)) { 432 if (FD_ISSET(i, &aim_rfds) || FD_ISSET(i, &aim_wfds)) { 433 owl_process_aim(); 434 aim_done = 1; 435 } 436 } 437 } 438 owl_select_io_dispatch(&r, &w, &e, max_fd); 439 } 302 void owl_select_init(void) 303 { 304 owl_timer_source = g_source_new(&owl_timer_funcs, sizeof(GSource)); 305 g_source_attach(owl_timer_source, NULL); 306 307 owl_io_dispatch_source = g_source_new(&owl_io_dispatch_funcs, sizeof(GSource)); 308 g_source_attach(owl_io_dispatch_source, NULL); 440 309 } 441 310 442 311 void owl_select_run_loop(void) 443 312 { 444 loop_active = 1; 445 while (loop_active) { 446 owl_select(); 447 } 313 context = g_main_context_default(); 314 loop = g_main_loop_new(context, FALSE); 315 g_main_loop_run(loop); 448 316 } 449 317 450 318 void owl_select_quit_loop(void) 451 319 { 452 loop_active = 0; 453 } 320 if (loop) { 321 g_main_loop_quit(loop); 322 loop = NULL; 323 } 324 } 325 326 typedef struct _owl_task { /*noproto*/ 327 void (*cb)(void *); 328 void *cbdata; 329 void (*destroy_cbdata)(void *); 330 } owl_task; 331 332 static gboolean _run_task(gpointer data) 333 { 334 owl_task *t = data; 335 if (t->cb) 336 t->cb(t->cbdata); 337 return FALSE; 338 } 339 340 static void _destroy_task(void *data) 341 { 342 owl_task *t = data; 343 if (t->destroy_cbdata) 344 t->destroy_cbdata(t->cbdata); 345 g_free(t); 346 } 347 348 void owl_select_post_task(void (*cb)(void*), void *cbdata, void (*destroy_cbdata)(void*)) 349 { 350 GSource *source = g_idle_source_new(); 351 owl_task *t = g_new0(owl_task, 1); 352 t->cb = cb; 353 t->cbdata = cbdata; 354 t->destroy_cbdata = destroy_cbdata; 355 g_source_set_priority(source, G_PRIORITY_DEFAULT); 356 g_source_set_callback(source, _run_task, t, _destroy_task); 357 g_source_attach(source, context); 358 g_source_unref(source); 359 } -
window.c
rb31f1c9 r7b2686d 524 524 owl_window_set_position(w, nlines, ncols, w->begin_y, w->begin_x); 525 525 } 526 527 /** Redrawing main loop hooks **/ 528 529 static bool _owl_window_should_redraw(void) { 530 return g.resizepending || owl_window_get_screen()->dirty_subtree; 531 } 532 533 static gboolean _owl_window_redraw_prepare(GSource *source, int *timeout) { 534 *timeout = -1; 535 return _owl_window_should_redraw(); 536 } 537 538 static gboolean _owl_window_redraw_check(GSource *source) { 539 return _owl_window_should_redraw(); 540 } 541 542 static gboolean _owl_window_redraw_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { 543 owl_colorpair_mgr *cpmgr; 544 545 /* if a resize has been scheduled, deal with it */ 546 owl_global_check_resize(&g); 547 /* update the terminal if we need to */ 548 owl_window_redraw_scheduled(); 549 /* On colorpair shortage, reset and redraw /everything/. NOTE: if 550 * the current screen uses too many colorpairs, this draws 551 * everything twice. But this is unlikely; COLOR_PAIRS is 64 with 552 * 8+1 colors, and 256^2 with 256+1 colors. (+1 for default.) */ 553 cpmgr = owl_global_get_colorpair_mgr(&g); 554 if (cpmgr->overflow) { 555 owl_function_debugmsg("colorpairs: color shortage; reset pairs and redraw. COLOR_PAIRS = %d", COLOR_PAIRS); 556 owl_fmtext_reset_colorpairs(cpmgr); 557 owl_function_full_redisplay(); 558 owl_window_redraw_scheduled(); 559 } 560 return TRUE; 561 } 562 563 static GSourceFuncs redraw_funcs = { 564 _owl_window_redraw_prepare, 565 _owl_window_redraw_check, 566 _owl_window_redraw_dispatch, 567 NULL 568 }; 569 570 GSource *owl_window_redraw_source_new(void) { 571 GSource *source; 572 source = g_source_new(&redraw_funcs, sizeof(GSource)); 573 /* TODO: priority?? */ 574 return source; 575 } -
window.h
r38e2250 r7b2686d 72 72 void owl_window_resize(owl_window *w, int nlines, int ncols); 73 73 74 GSource *owl_window_redraw_source_new(void); 75 74 76 /* Standard callback functions in windowcb.c */ 75 77 -
zephyr.c
rf203cad r7655e08 7 7 #include "owl.h" 8 8 9 static GSource *owl_zephyr_event_source_new(int fd); 10 11 static gboolean owl_zephyr_event_prepare(GSource *source, int *timeout); 12 static gboolean owl_zephyr_event_check(GSource *source); 13 static gboolean owl_zephyr_event_dispatch(GSource *source, GSourceFunc callback, gpointer user_data); 14 9 15 #ifdef HAVE_LIBZEPHYR 10 16 static GList *deferred_subs = NULL; … … 16 22 17 23 Code_t ZResetAuthentication(void); 24 25 static GSourceFuncs zephyr_event_funcs = { 26 owl_zephyr_event_prepare, 27 owl_zephyr_event_check, 28 owl_zephyr_event_dispatch, 29 NULL 30 }; 18 31 #endif 19 32 … … 84 97 Code_t code; 85 98 char *perl; 99 GSource *event_source; 86 100 87 101 owl_select_remove_io_dispatch(d); … … 99 113 } 100 114 101 owl_select_add_io_dispatch(ZGetFD(), OWL_IO_READ|OWL_IO_EXCEPT, &owl_zephyr_process_events, NULL, NULL); 115 event_source = owl_zephyr_event_source_new(ZGetFD()); 116 g_source_attach(event_source, NULL); 117 g_source_unref(event_source); 102 118 103 119 owl_global_set_havezephyr(&g); … … 127 143 perl = owl_perlconfig_execute("BarnOwl::Zephyr::_zephyr_startup()"); 128 144 g_free(perl); 129 130 owl_select_add_pre_select_action(owl_zephyr_pre_select_action, NULL, NULL);131 145 } 132 146 … … 180 194 if((code = ZPending()) < 0) { 181 195 owl_function_debugmsg("Error (%s) in ZPending()\n", 196 error_message(code)); 197 return 0; 198 } 199 return code; 200 } 201 #endif 202 return 0; 203 } 204 205 int owl_zephyr_zqlength(void) 206 { 207 #ifdef HAVE_LIBZEPHYR 208 Code_t code; 209 if(owl_global_is_havezephyr(&g)) { 210 if((code = ZQLength()) < 0) { 211 owl_function_debugmsg("Error (%s) in ZQLength()\n", 182 212 error_message(code)); 183 213 return 0; … … 1470 1500 } 1471 1501 1472 void owl_zephyr_process_events(const owl_io_dispatch *d, void *data) 1473 { 1502 typedef struct { /*noproto*/ 1503 GSource source; 1504 GPollFD poll_fd; 1505 } owl_zephyr_event_source; 1506 1507 static GSource *owl_zephyr_event_source_new(int fd) { 1508 GSource *source; 1509 owl_zephyr_event_source *event_source; 1510 1511 source = g_source_new(&zephyr_event_funcs, sizeof(owl_zephyr_event_source)); 1512 event_source = (owl_zephyr_event_source*) source; 1513 event_source->poll_fd.fd = fd; 1514 event_source->poll_fd.events = G_IO_IN | G_IO_HUP | G_IO_PRI | G_IO_ERR; 1515 g_source_add_poll(source, &event_source->poll_fd); 1516 1517 return source; 1518 } 1519 1520 static gboolean owl_zephyr_event_prepare(GSource *source, int *timeout) { 1521 *timeout = -1; 1522 return owl_zephyr_zqlength() > 0; 1523 } 1524 1525 static gboolean owl_zephyr_event_check(GSource *source) { 1526 owl_zephyr_event_source *event_source = (owl_zephyr_event_source*)source; 1527 if (event_source->poll_fd.revents & event_source->poll_fd.events) 1528 return owl_zephyr_zpending() > 0; 1529 return FALSE; 1530 } 1531 1532 static gboolean owl_zephyr_event_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { 1474 1533 _owl_zephyr_process_events(); 1475 } 1476 1477 int owl_zephyr_pre_select_action(owl_ps_action *a, void *p) 1478 { 1479 return _owl_zephyr_process_events(); 1480 } 1534 return TRUE; 1535 } -
cmd.c
rf25df21 r6a71113 99 99 100 100 char *owl_cmddict_execute_argv(const owl_cmddict *cd, const owl_context *ctx, const char *const *argv, int argc) { 101 GString *buf = g_string_new(""); 102 int i; 103 char *retval; 104 105 /* We weren't given a command line, so fabricate a valid one. */ 106 for(i = 0; i < argc; i++) { 107 if (i != 0) 108 g_string_append_c(buf, ' '); 109 owl_string_append_quoted_arg(buf, argv[i]); 110 } 111 112 retval = _owl_cmddict_execute(cd, ctx, argv, argc, buf->str); 113 114 g_string_free(buf, true); 101 char *buff; 102 char *retval = NULL; 103 104 buff = g_strjoinv(" ", (char**)argv); 105 retval = _owl_cmddict_execute(cd, ctx, argv, argc, buff); 106 g_free(buff); 107 115 108 return retval; 116 109 } -
perlglue.xs
rf25df21 r6a71113 43 43 rv = owl_function_command(cmd); 44 44 } else { 45 argv = g_new(const char *, items + 1); 45 /* Ensure this is NULL-terminated. */ 46 argv = g_new0(const char *, items + 1); 46 47 argv[0] = cmd; 47 48 for(i = 1; i < items; i++) { -
variable.c
rf25df21 rf203cad 30 30 NULL, NULL, NULL, NULL, NULL, NULL } 31 31 32 #define OWLVAR_STRING_FULL(name,default, summary,description,validate,set,get) \33 { name, OWL_VARIABLE_STRING, default, 0, "<string>", summary,description, NULL, \32 #define OWLVAR_STRING_FULL(name,default,validset,summary,description,validate,set,get) \ 33 { name, OWL_VARIABLE_STRING, default, 0, validset, summary,description, NULL, \ 34 34 validate, set, NULL, get, NULL, NULL } 35 35 … … 266 266 "" ), 267 267 268 OWLVAR_STRING_FULL( "tty" /* %OwlVarStub */, "", " tty name for zephyr location", "",268 OWLVAR_STRING_FULL( "tty" /* %OwlVarStub */, "", "<string>", "tty name for zephyr location", "", 269 269 NULL, owl_variable_tty_set, NULL), 270 270 … … 370 370 "delete a message right as it came in.\n" ), 371 371 372 OWLVAR_STRING_FULL( "default_exposure" /* %OwlVarStub */, "", 373 "none,opstaff,realm-visible,realm-announced,net-visible,net-announced", 374 "controls the persistent value for exposure", 375 "The default exposure level corresponds to the Zephyr exposure value\n" 376 "in ~/.zephyr.vars. Defaults to realm-visible if there is no value in\n" 377 "~/.zephyr.vars.\n" 378 "See the description of exposure for the values this can be.", 379 NULL, owl_variable_default_exposure_set, owl_variable_default_exposure_get ), 380 381 OWLVAR_STRING_FULL( "exposure" /* %OwlVarStub */, "", 382 "none,opstaff,realm-visible,realm-announced,net-visible,net-announced", 383 "controls who can zlocate you", 384 "The exposure level, defaulting to the value of default_exposure,\n" 385 "can be one of the following (from least exposure to widest exposure,\n" 386 "as listed in zctl(1)):\n" 387 "\n" 388 " none - This completely disables Zephyr for the user. \n" 389 " The user is not registered with Zephyr. No user\n" 390 " location information is retained by Zephyr. No\n" 391 " login or logout announcements will be sent. No\n" 392 " subscriptions will be entered for the user, and\n" 393 " no notices will be displayed by zwgc(1).\n" 394 " opstaff - The user is registered with Zephyr. No login or\n" 395 " logout announcements will be sent, and location\n" 396 " information will only be visible to Operations\n" 397 " staff. Default subscriptions and any additional\n" 398 " personal subscriptions will be entered for the\n" 399 " user.\n" 400 " realm-visible - The user is registered with Zephyr. User\n" 401 " location information is retained by Zephyr and\n" 402 " made available only to users within the user’s\n" 403 " Kerberos realm. No login or logout\n" 404 " announcements will be sent. This is the system\n" 405 " default. Default subscriptions and any\n" 406 " additional personal subscriptions will be\n" 407 " entered for the user.\n" 408 " realm-announced - The user is registered with Zephyr. User\n" 409 " location information is retained by Zephyr and\n" 410 " made available only to users authenticated\n" 411 " within the user’s Kerberos realm. Login and\n" 412 " logout announcements will be sent, but only to\n" 413 " users within the user’s Kerberos realm who have\n" 414 " explicitly requested such via subscriptions. \n" 415 " Default subscriptions and any additional\n" 416 " personal subscriptions will be entered for the\n" 417 " user.\n" 418 " net-visible - The user is registered with Zephyr. User\n" 419 " location information is retained by Zephyr and\n" 420 " made available to any authenticated user who\n" 421 " requests such. Login and logout announcements\n" 422 " will be sent only to users within the user’s\n" 423 " Kerberos realm who have explicitly requested\n" 424 " such via subscriptions. Default subscriptions\n" 425 " and any additional personal subscriptions will\n" 426 " be entered for the user.\n" 427 " net-announced - The user is registered with Zephyr. User\n" 428 " location information is retained by Zephyr and\n" 429 " made available to any authenticated user who\n" 430 " requests such. Login and logout announcements\n" 431 " will be sent to any user has requested such. \n" 432 " Default subscriptions and any additional\n" 433 " personal subscriptions will be entered for the\n" 434 " user.\n", 435 NULL, owl_variable_exposure_set, NULL /* use default for get */ ), 436 372 437 /* This MUST be last... */ 373 438 { NULL, 0, NULL, 0, NULL, NULL, NULL, NULL, … … 470 535 } 471 536 537 int owl_variable_default_exposure_set(owl_variable *v, const void *newval) 538 { 539 return owl_zephyr_set_default_exposure(newval); 540 } 541 542 const void *owl_variable_default_exposure_get(const owl_variable *v) 543 { 544 return owl_zephyr_get_default_exposure(); 545 } 546 547 int owl_variable_exposure_set(owl_variable *v, const void *newval) 548 { 549 int ret = owl_zephyr_set_exposure(newval); 550 if (ret != 0) 551 return ret; 552 return owl_variable_string_set_default(v, owl_zephyr_normalize_exposure(newval)); 553 } 472 554 473 555 /**************************************************************************/ … … 688 770 } 689 771 if (msg && v->get_tostring_fn) { 690 tostring = v->get_tostring_fn(v, v-> val);772 tostring = v->get_tostring_fn(v, v->get_fn(v)); 691 773 owl_function_makemsg("%s = '%s'", name, tostring); 692 774 g_free(tostring); … … 726 808 v = owl_dict_find_element(d, name); 727 809 if (v == NULL || !v->get_tostring_fn) return NULL; 728 return v->get_tostring_fn(v, v-> val);810 return v->get_tostring_fn(v, v->get_fn(v)); 729 811 } 730 812 -
viewwin.c
r237d02c r4fd211f 150 150 151 151 if (!owl_viewwin_search(v, owl_global_get_search_re(&g), consider_current, direction)) 152 owl_function_ error("No more matches");152 owl_function_makemsg("No more matches"); 153 153 return NULL; 154 154 } … … 172 172 if (!owl_viewwin_search(data->v, owl_global_get_search_re(&g), 173 173 consider_current, data->direction)) 174 owl_function_ error("No matches");174 owl_function_makemsg("No matches"); 175 175 } 176 176
Note: See TracChangeset
for help on using the changeset viewer.