Branch: Tag:

1997-12-14

1997-12-14 19:17:38 by Mirar (Pontus Hagland) <pike@sort.mirar.org>

added Process.Spawn

Rev: lib/modules/Process.pmod:1.12
Rev: tutorial/tutorial.wmml:1.60

114:   constant exece = predef::exece;       +  + class Spawn + { +  object stdin; +  object stdout; +  object stderr; +  array(object) fd; +  +  int pid; +  +  private int low_spawn(array(void|object(Stdio.File)) fdp, +  array(void|object(Stdio.File)) fd_to_close, +  string cmd, void|string *args, +  void|mapping(string:string) env, +  string|void cwd) +  { +  object(Stdio.File) pie,pied; /* interprocess communication */ +  int pid; +  +  pie=Stdio.File(); +  pied=pie->pipe(); +  +  if(!(pid=fork())) +  { +  mixed err=catch +  { +  if(cwd && !cd(cwd)) +  { +  throw(({"pike: cannot change cwd to "+cwd+ +  ": "+strerror(errno())+"\n", +  backtrace()})); +  } +  +  if (sizeof(fdp)>0 && fdp[0]) fdp[0]->dup2(Stdio.File("stdin")); +  if (sizeof(fdp)>1 && fdp[1]) fdp[1]->dup2(Stdio.File("stdout")); +  if (sizeof(fdp)>2 && fdp[2]) fdp[2]->dup2(Stdio.File("stderr")); +  /* dup2 fdd[3..] here FIXME FIXME */ +  foreach (fd_to_close,object f) +  if (objectp(f)) { f->close(); destruct(f); } +  pie->close(); +  destruct(pie); +  +  pied->set_close_on_exec(1); +  +  if (env) +  exece(cmd,args||({}),env); +  else +  exece(cmd,args||({})); +  +  throw(({"pike: failed to exece "+cmd+ +  ": "+strerror(errno())+"\n", +  backtrace()})); +  }; +  +  pied->write(encode_value(err)); +  exit(1); +  } +  +  foreach (fdp,object f) if (objectp(f)) { f->close(); destruct(f); } +  +  pied->close(); +  destruct(pied); +  +  mixed err=pie->read(); +  if (err && err!="") throw(decode_value(err)); +  +  pie->close(); +  destruct(pie); +  +  return pid; +  } +  +  void create(string cmd, +  void|array(string) args, +  void|mapping(string:string) env, +  string|void cwd, +  void|array(object(Stdio.File)|void) ownpipes, +  void|array(object(Stdio.File)|void) fds_to_close) +  { +  if (!ownpipes) +  { +  stdin=Stdio.File(); +  stdout=Stdio.File(); +  stderr=Stdio.File(); +  fd=({stdin->pipe(),stdout->pipe(),stderr->pipe()}); +  fds_to_close=({stdin,stdout,stderr}); +  } +  else +  { +  fd=ownpipes; +  if (sizeof(fd)>0) stdin=fd[0]; else stdin=0; +  if (sizeof(fd)>1) stdout=fd[1]; else stdout=0; +  if (sizeof(fd)>2) stderr=fd[2]; else stderr=0; +  } +  pid=low_spawn(fd,fds_to_close||({}),cmd,args,env,cwd); +  } +  +  int kill(int signal) +  { +  return predef::kill(pid,signal); +  } +  +  void wait() +  { +  while (kill(0)) sleep(0.01); +  } +  +  // void set_done_callback(function foo,mixed ... args); +  // int result(); +  // array rusage(); + }