/* unixfd specific arguments: localfd_in: local file descriptor for input (or everything for non-tty) localfd_out: local file descriptor for output (only used for tty support) Set localfd_out = -1 (or omit the argument entirely) if you're not working with a remote tty; then the localfd_in is connected directly to the remote FD for both reads and writes (except it it's RO or WO). noclose: Unixfd will not use close or shutdown calls on the local file descriptor (localfd_in); useful for terminal descriptors, which must hang around so that raw mode can be disabled, etc. shutrdonexit: When the remote module exits, we shutdown the read direction of the local file descriptor (_in). This isn't always done since not all file descriptors managed on the REX channel are necessarily connected to the remote module. */ unixfd::unixfd (rexchannel *pch, int fd, int localfd_in, int localfd_out, bool noclose, bool shutrdonexit, cbv closecb) : rexfd::rexfd (pch, fd), localfd_in (localfd_in), localfd_out (localfd_out), rsize (0), unixsock (isunixsocket (localfd_in)), weof (false), reof (false), shutrdonexit (shutrdonexit), closecb (closecb) { if (noclose) { int duplocalfd = dup (localfd_in); if (duplocalfd < 0) warn ("failed to duplicate fd for noclose behavior (%m)\n"); else unixfd::localfd_in = duplocalfd; } make_async (this->localfd_in); if (!is_fd_wronly (this->localfd_in)) fdcb (this->localfd_in, selread, wrap (this, &unixfd::rcb)); /* for tty support we split the input/output to two local FDs */ if (localfd_out >= 0) paios_out = aios::alloc (this->localfd_out); else paios_out = aios::alloc (this->localfd_in); }
int main (int argc, char **argv) { setprogname (argv[0]); if (!isunixsocket (0)) fatal << "stdin must be a unix domain socket\n"; if (argc < 2) fatal << "usage: " << progname << " command [arg1 arg2 ... ]\n"; char **cmdargv = argv + 1; str path = find_program_plus_libsfs (cmdargv[0]); if (!path) fatal << "Could not locate program: " << cmdargv[0] << "\n"; make_sync (0); char buf[1024]; int fd; while (readfd (0, buf, 1024, &fd) > 0) if (fd >= 0) { aspawn (path, cmdargv, fd, fd, errfd); close (fd); } return 0; }
static void pathinfo (char *path) { int fd; struct stat sb; dev_t dev; char cwd[PATH_MAX+1]; char buf[2*PATH_MAX+3]; char res[3*PATH_MAX+40]; char *rp; FILE *dfpipe; if (chdir (path) < 0 || (fd = open (".", O_RDONLY)) < 0 || fstat (fd, &sb) < 0) fperror (path); dev = sb.st_dev; if (!getcwd (cwd, sizeof (cwd))) fperror ("getcwd"); strcpy (buf, cwd); while ((rp = strrchr (buf, '/'))) { rp[1] = '\0'; if (stat (buf, &sb) < 0) fperror (buf); if (sb.st_dev != dev) { if (!(rp = strchr (cwd + (rp - buf) + 1, '/'))) rp = "/"; break; } rp[0] = '\0'; } if (!rp) rp = cwd; dfpipe = popen (PATH_DF #ifdef DF_NEEDS_DASH_K " -k" #endif /* DF_NEEDS_DASH_K */ " . | sed -ne '2s/ .*//; 2p'", "r"); if (!dfpipe || !fgets (buf, sizeof (buf) - 1, dfpipe) || pclose (dfpipe) < 0) fperror (PATH_DF); if (!strchr (buf, '\n')) strcat (buf, "\n"); sprintf (res, "0x%" U64F "x\n%s%s\n", (u_int64_t) dev, buf, rp); if (isunixsocket (1) < 0) { int i = write (1, res, strlen (res)); i++; } else writefd (1, res, strlen (res), fd); }
bool slave_acceptor_t::init () { bool ret = true; if (!isunixsocket (_fd)) { warn ("non-unixsocket given (fd=%d)\n", _fd); ret = false; } else { _x = axprt_unix::alloc (_fd); } return ret; }
int agentconn::cagent_fd (bool required) { if (agentfd >= 0) return agentfd; static rxx sockfdre ("^-(\\d+)?$"); if (agentsock && sockfdre.search (agentsock)) { if (sockfdre[1]) agentfd = atoi (sockfdre[1]); else agentfd = 0; if (!isunixsocket (agentfd)) fatal << "fd specified with '-S' not unix domain socket\n"; } else if (agentsock) { agentfd = unixsocket_connect (agentsock); if (agentfd < 0 && required) fatal ("%s: %m\n", agentsock.cstr ()); } else if (ccd (false)) { int32_t res; if (clnt_stat err = ccd ()->scall (AGENT_GETAGENT, NULL, &res)) { if (required) fatal << "sfscd: " << err << "\n"; } else if (res) { if (required) fatal << "connecting to agent via sfscd: " << strerror (res) << "\n"; } else if ((agentfd = sfscdxprt->recvfd ()) < 0) { fatal << "connecting to agent via sfscd: " << "could not get file descriptor\n"; } } else { if (str sock = agent_usersock (true)) agentfd = unixsocket_connect (sock); if (agentfd < 0 && required) fatal << "sfscd not running and no standalone agent socket\n"; } return agentfd; }
int chanfd::newfd (int rfd, bool _enablercb) { size_t i; for (i = 0; i < fdi.size (); i++) if (fdi[i].fd == -1 && fdi[i].closed && !fdi[i].rsize) break; if (i == fdi.size ()) fdi.push_back (); fdi[i].reset (); fdi[i].fd = rfd; fdi[i].isunixsocket = isunixsocket (rfd); if (_enablercb) enablercb (i); make_async (fdi[i].fd); return i; }