/* * the dialstring is of the form '[/net/]proto!dest' */ int kdial(char *dest, char *local, char *dir, int *cfdp) { DS ds; int rv; char *err, *alterr; err = kmalloc(ERRMAX, KMALLOC_WAIT); alterr = kmalloc(ERRMAX, KMALLOC_WAIT); ds.local = local; ds.dir = dir; ds.cfdp = cfdp; _dial_string_parse(dest, &ds); if (ds.netdir) { rv = csdial(&ds); goto out; } ds.netdir = "/net"; rv = csdial(&ds); if (rv >= 0) goto out; err[0] = 0; strlcpy(err, current_errstr(), ERRMAX); if (strstr(err, "refused") != 0) { goto out; } ds.netdir = "/net.alt"; rv = csdial(&ds); if (rv >= 0) goto out; alterr[0] = 0; kerrstr(alterr, ERRMAX); if (strstr(alterr, "translate") || strstr(alterr, "does not exist")) kerrstr(err, ERRMAX); else kerrstr(alterr, ERRMAX); out: kfree(err); kfree(alterr); return rv; }
/* Fires off tap, with the events of filter having occurred. Returns -1 on * error, though this need a little more thought. * * Some callers may require this to not block. */ int fire_tap(struct fd_tap *tap, int filter) { ERRSTACK(1); struct event_msg ev_msg = {0}; int fire_filt = tap->filter & filter; if (!fire_filt) return 0; if (waserror()) { /* The process owning the tap could trigger a kernel PF, as with any * send_event() call. Eventually we'll catch that with waserror. */ warn("Tap for proc %d, fd %d, threw %s", tap->proc->pid, tap->fd, current_errstr()); poperror(); return -1; } ev_msg.ev_type = tap->ev_id; /* e.g. CEQ idx */ ev_msg.ev_arg2 = fire_filt; /* e.g. CEQ coalesce */ ev_msg.ev_arg3 = tap->data; /* e.g. CEQ data */ send_event(tap->proc, tap->ev_q, &ev_msg, 0); poperror(); return 0; }
/* only used here for now. */ static void kerrstr(void *err, int len) { strlcpy(err, current_errstr(), len); }