| 1719 | #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos"))] |
| 1720 | impl PosixSpawnArgs { |
| 1721 | fn spawn(self, spawnp: bool, vm: &VirtualMachine) -> PyResult<libc::pid_t> { |
| 1722 | use nix::sys::signal; |
| 1723 | |
| 1724 | use crate::TryFromBorrowedObject; |
| 1725 | |
| 1726 | let path = self |
| 1727 | .path |
| 1728 | .clone() |
| 1729 | .into_cstring(vm) |
| 1730 | .map_err(|_| vm.new_value_error("path should not have nul bytes"))?; |
| 1731 | |
| 1732 | let mut file_actions = |
| 1733 | nix::spawn::PosixSpawnFileActions::init().map_err(|e| e.into_pyexception(vm))?; |
| 1734 | if let Some(it) = self.file_actions { |
| 1735 | for action in it.iter(vm)? { |
| 1736 | let action = action?; |
| 1737 | let (id, args) = action.split_first().ok_or_else(|| { |
| 1738 | vm.new_type_error("Each file_actions element must be a non-empty tuple") |
| 1739 | })?; |
| 1740 | let id = i32::try_from_borrowed_object(vm, id)?; |
| 1741 | let id = PosixSpawnFileActionIdentifier::try_from(id) |
| 1742 | .map_err(|_| vm.new_type_error("Unknown file_actions identifier"))?; |
| 1743 | let args: crate::function::FuncArgs = args.to_vec().into(); |
| 1744 | let ret = match id { |
| 1745 | PosixSpawnFileActionIdentifier::Open => { |
| 1746 | let (fd, path, oflag, mode): (_, OsPath, _, _) = args.bind(vm)?; |
| 1747 | let path = CString::new(path.into_bytes()).map_err(|_| { |
| 1748 | vm.new_value_error( |
| 1749 | "POSIX_SPAWN_OPEN path should not have nul bytes", |
| 1750 | ) |
| 1751 | })?; |
| 1752 | let oflag = nix::fcntl::OFlag::from_bits_retain(oflag); |
| 1753 | let mode = nix::sys::stat::Mode::from_bits_retain(mode); |
| 1754 | file_actions.add_open(fd, &*path, oflag, mode) |
| 1755 | } |
| 1756 | PosixSpawnFileActionIdentifier::Close => { |
| 1757 | let (fd,) = args.bind(vm)?; |
| 1758 | file_actions.add_close(fd) |
| 1759 | } |
| 1760 | PosixSpawnFileActionIdentifier::Dup2 => { |
| 1761 | let (fd, newfd) = args.bind(vm)?; |
| 1762 | file_actions.add_dup2(fd, newfd) |
| 1763 | } |
| 1764 | }; |
| 1765 | if let Err(err) = ret { |
| 1766 | let err = err.into(); |
| 1767 | return Err(OSErrorBuilder::with_filename(&err, self.path, vm)); |
| 1768 | } |
| 1769 | } |
| 1770 | } |
| 1771 | |
| 1772 | let mut attrp = |
| 1773 | nix::spawn::PosixSpawnAttr::init().map_err(|e| e.into_pyexception(vm))?; |
| 1774 | let mut flags = nix::spawn::PosixSpawnFlags::empty(); |
| 1775 | |
| 1776 | if let Some(sigs) = self.setsigdef { |
| 1777 | let mut set = signal::SigSet::empty(); |
| 1778 | for sig in sigs.iter(vm)? { |