Esempio n. 1
0
/*
 * get command line flags, initialize keywords & traps.
 * get values from environment.
 * set $pid, $cflag, $*
 * fabricate bootstrap code and start it (*=(argv);. /usr/lib/rcmain $*)
 * start interpreting code
 */
int
main(int argc, char *argv[])
{
	code bootstrap[32];
	char num[12], *rcmain;
	int i;
	
	/* needed for rcmain later */
	putenv("PLAN9", unsharp("#9"));
	argc = getflags(argc, argv, "ftjSsrdiIlxepvVc:1m:1[command]", 1);
	if(argc==-1)
		usage("[file [arg ...]]");
	if(argv[0][0]=='-')
		flag['l'] = flagset;
	if(flag['I'])
		flag['i'] = 0;
	else if(flag['i']==0 && argc==1 && Isatty(0)) flag['i'] = flagset;
	rcmain = flag['m'] ? flag['m'][0] : Rcmain();
	err = openfd(2);
	kinit();
	Trapinit();
	Vinit();
	inttoascii(num, mypid = getpid());
	pathinit();
	setvar("pid", newword(num, (word *)0));
	setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0)
				:(word *)0);
	setvar("rcname", newword(argv[0], (word *)0));
	i = 0;
	bootstrap[i++].i = 1;
	bootstrap[i++].f = Xmark;
	bootstrap[i++].f = Xword;
	bootstrap[i++].s="*";
	bootstrap[i++].f = Xassign;
	bootstrap[i++].f = Xmark;
	bootstrap[i++].f = Xmark;
	bootstrap[i++].f = Xword;
	bootstrap[i++].s="*";
	bootstrap[i++].f = Xdol;
	bootstrap[i++].f = Xword;
	bootstrap[i++].s = rcmain;
	bootstrap[i++].f = Xword;
	bootstrap[i++].s=".";
	bootstrap[i++].f = Xsimple;
	bootstrap[i++].f = Xexit;
	bootstrap[i].i = 0;
	start(bootstrap, 1, (var *)0);
	/* prime bootstrap argv */
	pushlist();
	argv0 = strdup(argv[0]);
	for(i = argc-1;i!=0;--i) pushword(argv[i]);
	for(;;){
		if(flag['r'])
			pfnc(err, runq);
		runq->pc++;
		(*runq->code[runq->pc-1].f)();
		if(ntrap)
			dotrap();
	}
}
Esempio n. 2
0
/* open for writing:
   if the filesystem entry already exists, the data is appended
   if it does not exist, a file is created and the data is appended
*/
static int xioopen_open(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3) {
   const char *filename = argv[1];
   int rw = (xioflags & XIO_ACCMODE);
   bool exists;
   bool opt_unlink_close = false;
   int result;

   /* remove old file, or set user/permissions on old file; parse options */
   if ((result = _xioopen_named_early(argc, argv, fd, groups, &exists, opts)) < 0) {
      return result;
   }

   retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
   if (opt_unlink_close) {
      if ((fd->stream.unlink_close = strdup(filename)) == NULL) {
	 Error1("strdup(\"%s\"): out of memory", filename);
      }
      fd->stream.opt_unlink_close = true;
   }

   Notice3("opening %s \"%s\" for %s",
	   filetypenames[(result&S_IFMT)>>12], filename, ddirection[rw]);
   if ((result = _xioopen_open(filename, rw, opts)) < 0)
      return result;
   fd->stream.fd = result;

#if WITH_TERMIOS
   if (Isatty(fd->stream.fd)) {
      if (Tcgetattr(fd->stream.fd, &fd->stream.savetty) < 0) {
	 Warn2("cannot query current terminal settings on fd %d: %s",
	       fd->stream.fd, strerror(errno));
      } else {
	 fd->stream.ttyvalid = true;
      }
   }
#endif /* WITH_TERMIOS */

   applyopts_named(filename, opts, PH_FD);
   applyopts(fd->stream.fd, opts, PH_FD);
   applyopts_cloexec(fd->stream.fd, opts);

   applyopts_fchown(fd->stream.fd, opts);

   if ((result = _xio_openlate(&fd->stream, opts)) < 0)
      return result;

   return 0;
}
Esempio n. 3
0
/* retrieve and apply options to a standard file descriptor.
   Do not set FD_CLOEXEC flag. */
int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd, int dummy2, int dummy3) {

    xfd->fd = numfd;
    xfd->howtoend = END_NONE;

#if WITH_TERMIOS
    if (Isatty(xfd->fd)) {
        if (Tcgetattr(xfd->fd, &xfd->savetty) < 0) {
            Warn2("cannot query current terminal settings on fd %d: %s",
                  xfd->fd, strerror(errno));
        } else {
            xfd->ttyvalid = true;
        }
    }
#endif /* WITH_TERMIOS */
    if (applyopts_single(xfd, opts, PH_INIT) < 0)  return -1;
    applyopts(-1, opts, PH_INIT);

    applyopts2(xfd->fd, opts, PH_INIT, PH_FD);

    return _xio_openlate(xfd, opts);
}
Esempio n. 4
0
/* process a bidirectional "stdio" or "-" argument with options. */
int xioopen_stdio_bi(xiofile_t *sock) {
   struct opt *opts1, *opts2, *optspr;
   unsigned int groups1 = xioaddr_stdio0.groups, groups2 = xioaddr_stdio0.groups;
   int result;

   sock->stream.rfd = 0 /*stdin*/;
   sock->stream.wfd = 1 /*stdout*/;

#if WITH_TERMIOS
   if (Isatty(sock->stream.rfd)) {
      if (Tcgetattr(sock->stream.rfd,
		    &sock->stream.savetty)
	  < 0) {
	 Warn2("cannot query current terminal settings on fd %d: %s",
	       sock->stream.rfd, strerror(errno));
      } else {
	 sock->stream.ttyvalid = true;
      }
   }
   if (Isatty(sock->stream.wfd) && (sock->stream.wfd != sock->stream.rfd)) {
      if (Tcgetattr(sock->stream.wfd,
		    &sock->stream.savetty)
	  < 0) {
	 Warn2("cannot query current terminal settings on fd %d: %s",
	       sock->stream.wfd, strerror(errno));
      } else {
	 sock->stream.ttyvalid = true;
      }
   }
#endif /* WITH_TERMIOS */
   if (applyopts_single(&sock->stream, sock->stream.opts, PH_INIT) < 0)
      return -1;
   applyopts(-1, sock->stream.opts, PH_INIT);
   if (sock->stream.howtoshut == XIOSHUT_UNSPEC)
      sock->stream.howtoshut = XIOSHUT_NONE;

   /* options here are one-time and one-direction, no second use */
   retropt_bool(sock->stream.opts, OPT_IGNOREEOF, &sock->stream.ignoreeof);

   /* extract opts that should be applied only once */
   if ((optspr = copyopts(sock->stream.opts, GROUP_PROCESS)) == NULL) {
      return -1;
   }
   if ((result = applyopts(-1, optspr, PH_EARLY)) < 0)
      return result;
   if ((result = applyopts(-1, optspr, PH_PREOPEN)) < 0)
      return result;

   /* here we copy opts, because most have to be applied twice! */
   if ((opts1 = copyopts(sock->stream.opts, GROUP_FD|GROUP_APPL|(groups1&~GROUP_PROCESS))) == NULL) {
      return -1;
   }

   /* apply options to first FD */
   if ((result = applyopts(sock->stream.rfd, opts1, PH_ALL)) < 0) {
      return result;
   }
   if ((result = _xio_openlate(&sock->stream, opts1)) < 0) {
      return result;
   }

   if ((opts2 = copyopts(sock->stream.opts, GROUP_FD|GROUP_APPL|(groups2&~GROUP_PROCESS))) == NULL) {
      return -1;
   }
   /* apply options to second FD */
   if ((result = applyopts(sock->stream.wfd, opts2, PH_ALL)) < 0) {
      return result;
   }
   if ((result = _xio_openlate(&sock->stream, opts2)) < 0) {
      return result;
   }

   if ((result = _xio_openlate(&sock->stream, optspr)) < 0) {
      return result;
   }

   Notice("reading from and writing to stdio");
   return 0;
}
Esempio n. 5
0
/* process a bidirectional "stdio" or "-" argument with options.
   generate a dual address. */
int xioopen_stdio_bi(xiofile_t *sock) {
   struct opt *optspr;
   unsigned int groups1 = addr_stdio.groups;
   int result;

   if (xioopen_makedual(sock) < 0) {
      return -1;
   }

   sock->dual.stream[0]->tag = XIO_TAG_RDONLY;
   sock->dual.stream[0]->fd = 0 /*stdin*/;
   sock->dual.stream[1]->tag = XIO_TAG_WRONLY;
   sock->dual.stream[1]->fd = 1 /*stdout*/;
   sock->dual.stream[0]->howtoend =
      sock->dual.stream[1]->howtoend = END_NONE;

#if WITH_TERMIOS
   if (Isatty(sock->dual.stream[0]->fd)) {
      if (Tcgetattr(sock->dual.stream[0]->fd,
		    &sock->dual.stream[0]->savetty)
	  < 0) {
	 Warn2("cannot query current terminal settings on fd %d: %s",
	       sock->dual.stream[0]->fd, strerror(errno));
      } else {
	 sock->dual.stream[0]->ttyvalid = true;
      }
   }
   if (Isatty(sock->dual.stream[1]->fd)) {
      if (Tcgetattr(sock->dual.stream[1]->fd,
		    &sock->dual.stream[1]->savetty)
	  < 0) {
	 Warn2("cannot query current terminal settings on fd %d: %s",
	       sock->dual.stream[1]->fd, strerror(errno));
      } else {
	 sock->dual.stream[1]->ttyvalid = true;
      }
   }
#endif /* WITH_TERMIOS */

   /* options here are one-time and one-direction, no second use */
   retropt_bool(sock->stream.opts, OPT_IGNOREEOF, &sock->dual.stream[0]->ignoreeof);

   /* extract opts that should be applied only once */
   if ((optspr = copyopts(sock->stream.opts, GROUP_PROCESS)) == NULL) {
      return -1;
   }
   /* here we copy opts, because most have to be applied twice! */
   if ((sock->dual.stream[1]->opts = copyopts(sock->stream.opts, GROUP_FD|GROUP_APPL|(groups1&~GROUP_PROCESS))) == NULL) {
      return -1;
   }
   sock->dual.stream[0]->opts = sock->stream.opts;
   sock->stream.opts = NULL;

   if (applyopts_single(sock->dual.stream[0],
			sock->dual.stream[0]->opts, PH_INIT)
       < 0)
      return -1;
   if (applyopts_single(sock->dual.stream[1],
			sock->dual.stream[1]->opts, PH_INIT)
       < 0)
      return -1;
   applyopts(-1, sock->dual.stream[0]->opts, PH_INIT);
   applyopts(-1, sock->dual.stream[1]->opts, PH_INIT);
   if ((result = applyopts(-1, optspr, PH_EARLY)) < 0)
      return result;
   if ((result = applyopts(-1, optspr, PH_PREOPEN)) < 0)
      return result;

   /* apply options to first FD */
   if ((result =
	applyopts(sock->dual.stream[0]->fd,
		  sock->dual.stream[0]->opts, PH_ALL))
       < 0) {
      return result;
   }
   if ((result = _xio_openlate(sock->dual.stream[0],
			       sock->dual.stream[0]->opts)) < 0) {
      return result;
   }
#if 0
   /* ignore this opt */
   retropt_bool(sock->dual.stream[0]->opts, OPT_COOL_WRITE);
#endif

   /* apply options to second FD */
   if ((result = applyopts(sock->dual.stream[1]->fd,
			   sock->dual.stream[1]->opts, PH_ALL)) < 0) {
      return result;
   }
   if ((result = _xio_openlate(sock->dual.stream[1],
			       sock->dual.stream[1]->opts)) < 0) {
      return result;
   }

#if 0
   if ((result = _xio_openlate(sock->dual.stream[1], optspr)) < 0) {
      return result;
   }
#endif

   Notice("reading from and writing to stdio");
   return 0;
}