Example #1
0
/* 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);
}
Example #2
0
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;
}
Example #3
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);
}
Example #4
0
 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;
 }
Example #5
0
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;
}
Example #6
0
File: chan.C Project: bougyman/sfs
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;
}