if (__close (action->action.close_action.fd) != 0)
if (close_not_cancel (action->action.close_action.fd) != 0)
__spawni (pid_t *pid, const char *file,	  const posix_spawn_file_actions_t *file_actions,	  const posix_spawnattr_t *attrp, char *const argv[],	  char *const envp[], int use_path){  pid_t new_pid;  char *path, *p, *name;  size_t len;  size_t pathlen;  short int flags;  /* Generate the new process.  */  new_pid = __fork ();  if (new_pid != 0)    {      if (new_pid < 0)	return errno;      /* The call was successful.  Store the PID if necessary.  */      if (pid != NULL)	*pid = new_pid;      return 0;    }  /* Do this once.  */  flags = attrp == NULL ? 0 : attrp->__flags;  /* Set signal mask.  */  if ((flags & POSIX_SPAWN_SETSIGMASK) != 0      && __sigprocmask (SIG_SETMASK, &attrp->__ss, NULL) != 0)    _exit (SPAWN_ERROR);  /* Set signal default action.  */  if ((flags & POSIX_SPAWN_SETSIGDEF) != 0)    {      /* We have to iterate over all signals.  This could possibly be	 done better but it requires system specific solutions since	 the sigset_t data type can be very different on different	 architectures.  */      int sig;      struct sigaction sa;      memset (&sa, '\0', sizeof (sa));      sa.sa_handler = SIG_DFL;      for (sig = 1; sig <= _NSIG; ++sig)	if (__sigismember (&attrp->__sd, sig) != 0	    && __sigaction (sig, &sa, NULL) != 0)	  _exit (SPAWN_ERROR);    }#ifdef _POSIX_PRIORITY_SCHEDULING  /* Set the scheduling algorithm and parameters.  */  if ((flags & (POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER))      == POSIX_SPAWN_SETSCHEDPARAM)    {      if (__sched_setparam (0, &attrp->__sp) == -1)	_exit (SPAWN_ERROR);    }  else if ((flags & POSIX_SPAWN_SETSCHEDULER) != 0)    {      if (__sched_setscheduler (0, attrp->__policy,				(flags & POSIX_SPAWN_SETSCHEDPARAM) != 0				? &attrp->__sp : NULL) == -1)	_exit (SPAWN_ERROR);    }#endif  /* Set the process group ID.  */  if ((flags & POSIX_SPAWN_SETPGROUP) != 0      && __setpgid (0, attrp->__pgrp) != 0)    _exit (SPAWN_ERROR);  /* Set the effective user and group IDs.  */  if ((flags & POSIX_SPAWN_RESETIDS) != 0      && (seteuid (__getuid ()) != 0 || setegid (__getgid ()) != 0))    _exit (SPAWN_ERROR);  /* Execute the file actions.  */  if (file_actions != NULL)    {      int cnt;      for (cnt = 0; cnt < file_actions->__used; ++cnt)	{	  struct __spawn_action *action = &file_actions->__actions[cnt];	  switch (action->tag)	    {	    case spawn_do_close:	      if (__close (action->action.close_action.fd) != 0)		/* Signal the error.  */		_exit (SPAWN_ERROR);	      break;	    case spawn_do_open:	      {		int new_fd = __open64 (action->action.open_action.path,				       action->action.open_action.oflag,				       action->action.open_action.mode);		if (new_fd == -1)		  /* The `open' call failed.  */		  _exit (SPAWN_ERROR);		/* Make sure the desired file descriptor is used.  */		if (new_fd != action->action.open_action.fd)		  {		    if (__dup2 (new_fd, action->action.open_action.fd)			!= action->action.open_action.fd)		      /* The `dup2' call failed.  */		      _exit (SPAWN_ERROR);		    if (__close (new_fd) != 0)		      /* The `close' call failed.  */		      _exit (SPAWN_ERROR);		  }	      }	      break;	    case spawn_do_dup2:	      if (__dup2 (action->action.dup2_action.fd,			  action->action.dup2_action.newfd)		  != action->action.dup2_action.newfd)		/* The `dup2' call failed.  */		_exit (SPAWN_ERROR);	      break;	    }	}    }  if (! use_path || strchr (file, '/') != NULL)    {      /* The FILE parameter is actually a path.  */      __execve (file, argv, envp);      if (errno == ENOEXEC)	script_execute (file, argv, envp);      /* Oh, oh.  `execve' returns.  This is bad.  */      _exit (SPAWN_ERROR);    }  /* We have to search for FILE on the path.  */  path = getenv ("PATH");  if (path == NULL)    {      /* There is no `PATH' in the environment.	 The default search path is the current directory	 followed by the path `confstr' returns for `_CS_PATH'.  */      len = confstr (_CS_PATH, (char *) NULL, 0);      path = (char *) __alloca (1 + len);      path[0] = ':';      (void) confstr (_CS_PATH, path + 1, len);    }  len = strlen (file) + 1;  pathlen = strlen (path);  name = __alloca (pathlen + len + 1);  /* Copy the file name at the top.  */  name = (char *) memcpy (name + pathlen + 1, file, len);  /* And add the slash.  */  *--name = '/';  p = path;  do    {      char *startp;      path = p;      p = __strchrnul (path, ':');      if (p == path)	/* Two adjacent colons, or a colon at the beginning or the end	   of `PATH' means to search the current directory.  */	startp = name + 1;      else	startp = (char *) memcpy (name - (p - path), path, p - path);      /* Try to execute this name.  If it works, execv will not return.  */      __execve (startp, argv, envp);      if (errno == ENOEXEC)	script_execute (startp, argv, envp);      switch (errno)	{	case EACCES:	case ENOENT:	case ESTALE:	case ENOTDIR:	  /* Those errors indicate the file is missing or not executable	     by us, in which case we want to just try the next path	     directory.  */	  break;	default:	  /* Some other error means we found an executable file, but	     something went wrong executing it; return the error to our	     caller.  */	  _exit (SPAWN_ERROR);	    }    }  while (*p++ != '\0');  /* Return with an error.  */  _exit (SPAWN_ERROR);}