public override void Open (string path, bool @abstract)
		{
			if (String.IsNullOrEmpty (path))
				throw new ArgumentException ("path");

			if (@abstract)
				socket = OpenAbstractUnix (path);
			else
				socket = OpenUnix (path);

			//socket.Blocking = true;
			SocketHandle = (long)socket.Handle;
			//Stream = new UnixStream ((int)socket.Handle);
			Stream = new UnixStream (socket);
		}
        public UnixMultiProcessFileAppender(string fileName, ICreateFileParameters parameters) : base(fileName, parameters)
        {
            int fd = Syscall.open(fileName, OpenFlags.O_CREAT | OpenFlags.O_WRONLY | OpenFlags.O_APPEND, (FilePermissions)(6 | (6 << 3) | (6 << 6)));

            if (fd == -1)
            {
                if (Stdlib.GetLastError() == Errno.ENOENT && parameters.CreateDirs)
                {
                    string dirName = Path.GetDirectoryName(fileName);
                    if (!Directory.Exists(dirName) && parameters.CreateDirs)
                    {
                        Directory.CreateDirectory(dirName);
                    }

                    fd = Syscall.open(fileName, OpenFlags.O_CREAT | OpenFlags.O_WRONLY | OpenFlags.O_APPEND, (FilePermissions)(6 | (6 << 3) | (6 << 6)));
                }
            }
            if (fd == -1)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            try
            {
                this.file = new UnixStream(fd, true);
            }
            catch
            {
                Syscall.close(fd);
                throw;
            }
        }
            public UnixMultiProcessFileAppender(string fileName, ICreateFileParameters parameters)
                : base(fileName, parameters)
            {
                int fd = Syscall.open(fileName, OpenFlags.O_CREAT | OpenFlags.O_WRONLY | OpenFlags.O_APPEND, (FilePermissions)(6 | (6 << 3) | (6 << 6)));
                if (fd == -1)
                {
                if (Stdlib.GetLastError() == Errno.ENOENT && parameters.CreateDirs)
                {
                    string dirName = Path.GetDirectoryName(fileName);
                    if (!Directory.Exists(dirName) && parameters.CreateDirs)
                        Directory.CreateDirectory(dirName);

                    fd = Syscall.open(fileName, OpenFlags.O_CREAT | OpenFlags.O_WRONLY | OpenFlags.O_APPEND, (FilePermissions)(6 | (6 << 3) | (6 << 6)));
                }
                }
                if (fd == -1)
                UnixMarshal.ThrowExceptionForLastError();

                try
                {
                this.file = new UnixStream(fd, true);
                }
                catch
                {
                Syscall.close(fd);
                throw;
                }
            }
    public static void Main()
    {
        int reading, writing;

        Mono.Unix.Native.Syscall.pipe(out reading, out writing);
        int stdout = Mono.Unix.Native.Syscall.dup(1);

        Mono.Unix.Native.Syscall.dup2(writing, 1);
        Mono.Unix.Native.Syscall.close(writing);

        Process          cmdProcess   = new Process();
        ProcessStartInfo cmdStartInfo = new ProcessStartInfo();

        cmdStartInfo.FileName       = "cat";
        cmdStartInfo.CreateNoWindow = true;
        cmdStartInfo.Arguments      = "test.exe";
        cmdProcess.StartInfo        = cmdStartInfo;
        cmdProcess.Start();

        Mono.Unix.Native.Syscall.dup2(stdout, 1);
        Mono.Unix.Native.Syscall.close(stdout);

        Stream s = new UnixStream(reading);

        byte[] buf   = new byte[1024];
        int    bytes = 0;
        int    current;

        while ((current = s.Read(buf, 0, buf.Length)) > 0)
        {
            bytes += current;
        }
        Mono.Unix.Native.Syscall.close(reading);
        Console.WriteLine("{0} bytes read", bytes);
    }
Example #5
0
        public bool AcquireLock(int timeout)
        {
            bool success = false;

            if (Monitor.TryEnter(syncRoot, timeout))
            {
                if (this.stream == null)
                {
                    int fd = Syscall.open(EC0IOPath, OpenFlags.O_RDWR | OpenFlags.O_EXCL);

                    if (fd == -1)
                    {
                        var e = new Win32Exception(Marshal.GetLastWin32Error());
                        Debug.WriteLine(string.Format("Error opening {0}: {1}", EC0IOPath, e.Message));

                        Monitor.Exit(syncRoot);
                    }
                    else
                    {
                        this.stream = new UnixStream(fd);
                        success     = true;
                    }
                }
            }

            return(success);
        }
Example #6
0
        /// <summary>Creates a StreamWriter which will be appended to</summary>
        /// <returns>a StreamWriter to a file that was opened with the append flag</returns>
        /// <param name='filename'>the name of the file</param>
        public static StreamWriter CreateUnixAppendStreamWriter(string filename)
        {
            OpenFlags  flags = OpenFlags.O_WRONLY | OpenFlags.O_LARGEFILE | OpenFlags.O_APPEND;
            int        fd    = Syscall.open(filename, flags);
            UnixStream fs    = new UnixStream(fd);

            return(new StreamWriter(fs));
        }
Example #7
0
        public CameraFile(UnixStream file)
        {
            IntPtr native;

            Error.CheckError(gp_file_new_from_fd(out native, file.Handle));

            this.handle = new HandleRef(this, native);
        }
 public override void Close()
 {
     if (this.file == null)
     {
         return;
     }
     InternalLogger.Trace("Closing '{0}'", FileName);
     this.file.Close();
     this.file = null;
 }
Example #9
0
        public override void Open()
        {
            if (_Opened)
            {
                throw new InvalidOperationException("Already opened");
            }

            StringBuilder dev_sb = new StringBuilder(IFNAMSIZ);

            if (_Interface != null)
            {
                dev_sb.Append(_Interface);
            }

            int flags = 0;

            if (_Type == DeviceType.TUN)
            {
                flags |= IFF_TUN;
            }
            else if (_Type == DeviceType.TAP)
            {
                flags |= IFF_TAP;
            }
            else
            {
                throw new Exception("Unknwo device type");
            }

            int fd_or_errcode;
            int errno = tun_alloc(dev_sb, flags, out fd_or_errcode);

            if (errno != 0)
            {
                switch (errno)
                {
                case 1: throw new UnixIOException("Can't open /dev/net/tun (" + fd_or_errcode + ")");

                case 2: throw new UnixIOException("ioctl(TUNSETIFF) failed (" + fd_or_errcode + ")");

                default: throw new Exception("Unknown error (" + fd_or_errcode + ")");
                }
            }

            int err = tun_set_persist(fd_or_errcode, _Persist);

            if (err != 0)
            {
                throw new UnixIOException("ioctl(TUNSETPERSIST) failed (" + err + ")");
            }

            _Interface = dev_sb.ToString();
            _Stream    = new UnixStream(fd_or_errcode);
            _Opened    = true;
        }
Example #10
0
        ///<summary>
        /// Load the buffer with a file
        ///</summary>
        public void Load(string filename)
        {
            if (reader != null)
            {
                reader.Close();
            }

            OperatingSystem os  = Environment.OSVersion;
            PlatformID      pid = os.Platform;

            if (pid == PlatformID.Unix)
            {
                UnixFileInfo fsInfo = new UnixFileInfo(filename);
                if (!fsInfo.Exists)
                {
                    throw new FileNotFoundException(fsInfo.FullName);
                }

                // get the size of the file or device
                if (fsInfo.IsRegularFile)
                {
                    FileLength  = fsInfo.Length;
                    isResizable = true;
                }
                else if (fsInfo.IsBlockDevice)
                {
                    UnixStream unixStream = fsInfo.OpenRead();
                    ioctl(unixStream.Handle, BLKGETSIZE64, ref FileLength);
                    unixStream.Close();
                    isResizable = false;
                }
                else
                {
                    throw new NotSupportedException("File object isn't a regular or block device.");
                }
            }

            Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read);

            if (stream.CanSeek == false)
            {
                throw new NotSupportedException("File object doesn't support seeking.");
            }

            if (pid != PlatformID.Unix)
            {
                FileLength = stream.Seek(0, SeekOrigin.End);
                stream.Seek(0, SeekOrigin.Begin);
                isResizable = false;
            }
            reader = new BinaryReader(stream);

            winOccupied = reader.Read(window, 0, window.Length);
            winOffset   = 0;
        }
        public UnixMultiProcessFileAppender(string fileName, ICreateFileParameters parameters) : base(fileName, parameters)
        {
            int fd = Syscall.open(fileName, OpenFlags.O_CREAT | OpenFlags.O_WRONLY | OpenFlags.O_APPEND, (FilePermissions)(6 | (6 << 3) | (6 << 6)));

            if (fd == -1)
            {
                if (Stdlib.GetLastError() == Errno.ENOENT && parameters.CreateDirs)
                {
                    string dirName = Path.GetDirectoryName(fileName);
                    if (!Directory.Exists(dirName) && parameters.CreateDirs)
                    {
                        Directory.CreateDirectory(dirName);
                    }

                    fd = Syscall.open(fileName, OpenFlags.O_CREAT | OpenFlags.O_WRONLY | OpenFlags.O_APPEND, (FilePermissions)(6 | (6 << 3) | (6 << 6)));
                }
            }
            if (fd == -1)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            try
            {
                bool fileExists = File.Exists(fileName);

                this.file = new UnixStream(fd, true);

                long filePosition = this.file.Position;
                if (fileExists || filePosition > 0)
                {
                    this.CreationTimeUtc = File.GetCreationTimeUtc(this.FileName);
                    if (this.CreationTimeUtc < DateTime.UtcNow - TimeSpan.FromSeconds(2) && filePosition == 0)
                    {
                        // File wasn't created "almost now".
                        Thread.Sleep(50);
                        // Having waited for a short amount of time usually means the file creation process has continued
                        // code execution just enough to the above point where it has fixed up the creation time.
                        this.CreationTimeUtc = File.GetCreationTimeUtc(this.FileName);
                    }
                }
                else
                {
                    // We actually created the file and eventually concurrent processes
                    this.CreationTimeUtc = DateTime.UtcNow;
                    File.SetCreationTimeUtc(this.FileName, this.CreationTimeUtc);
                }
            }
            catch
            {
                Syscall.close(fd);
                throw;
            }
        }
 public override void Close()
 {
     if (_file == null)
     {
         return;
     }
     InternalLogger.Trace("Closing '{0}'", FileName);
     _file.Close();
     _file = null;
     FileTouched();
 }
Example #13
0
        protected override void OnOpen()
        {
            System.Diagnostics.Debug.Assert(_socket == null);

            _socket = OpenSocket(null);

            System.Diagnostics.Debug.Assert(_socket != null);
            System.Diagnostics.Debug.Assert(_bufferSize > 0);

            Logger.Debug("Opened interface \"{0}\" with MTU {1}.", Interface, _bufferSize);
        }
Example #14
0
        public Task NewConnectionAsync(ObjectPath device, CloseSafeHandle fileDescriptor, IDictionary <string, object> properties)
        {
            SocketState     = SocketStates.Connected;
            _fileDescriptor = fileDescriptor;
            Log.Debug("Linux.BluetoothSocket: Connected to profile");

            Stream = new UnixStream(fileDescriptor.DangerousGetHandle().ToInt32());

            Task.Run(() => NewConnection?.Invoke(device, _fileDescriptor, properties));
            return(Task.CompletedTask);
        }
Example #15
0
        public override void Close()
        {
            if (!_Opened)
            {
                throw new InvalidOperationException("Not opened");
            }

            _Stream.Dispose();
            _Stream = null;

            _Opened = false;
        }
Example #16
0
        protected override void OnClose()
        {
            //this never happens....
            System.Diagnostics.Debug.Assert(_socket != null);
            if (orig_mtu != 0)
            {
                OpenSocket(orig_mtu);
            }

            _socket.Close();
            _socket = null;
        }
Example #17
0
        public void Dispose()
        {
            lock (syncRoot)
            {
                if (this.stream != null)
                {
                    this.stream.Dispose();
                    this.stream = null;
                }

                disposed = true;
            }
        }
Example #18
0
        ///<summary>
        /// Load the buffer with a file
        ///</summary>
        public void Load(string filename)
        {
            if (reader != null)
            {
                reader.Close();
            }

#if ENABLE_UNIX_SPECIFIC
            UnixFileInfo fsInfo = new UnixFileInfo(filename);
            if (!fsInfo.Exists)
            {
                throw new FileNotFoundException(fsInfo.FullName);
            }

            // get the size of the file or device
            if (fsInfo.IsRegularFile)
            {
                FileLength  = fsInfo.Length;
                isResizable = true;
            }
            else if (fsInfo.IsBlockDevice)
            {
                UnixStream unixStream = fsInfo.OpenRead();
                ioctl(unixStream.Handle, BLKGETSIZE64, ref FileLength);
                unixStream.Close();
                isResizable = false;
            }
            else
            {
                throw new NotSupportedException("File object isn't a regular or block device.");
            }
#endif

            Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read,
                                           FileShare.ReadWrite);

            if (stream.CanSeek == false)
            {
                throw new NotSupportedException("File object doesn't support seeking.");
            }

#if !ENABLE_UNIX_SPECIFIC
            FileLength = stream.Seek(0, SeekOrigin.End);
            stream.Seek(0, SeekOrigin.Begin);
            isResizable = false;
#endif
            reader = new BinaryReader(stream);

            winOccupied = reader.Read(window, 0, window.Length);
            winOffset   = 0;
        }
Example #19
0
        public Pty(string name)
        {
            master = Syscall.open(name, OpenFlags.O_RDWR);
            stream = new UnixStream(master, true);
            IntPtr termios = Marshal.AllocHGlobal(128);             // termios struct is 60-bytes, but we allocate more just to make sure

            original = Marshal.AllocHGlobal(128);
            Tcgetattr(0, termios);
            Tcgetattr(0, original);

            Cfmakeraw(termios);
            Tcsetattr(master, 1, termios);              // 1 == TCSAFLUSH
            Marshal.FreeHGlobal(termios);
        }
Example #20
0
 private bool LockDeviceNode(string device, bool lockdoor)
 {
     try {
         using (UnixStream stream = (new UnixFileInfo(device)).Open(
                    Mono.Unix.Native.OpenFlags.O_RDONLY |
                    Mono.Unix.Native.OpenFlags.O_NONBLOCK)) {
             bool success = ioctl(stream.Handle, IoctlOperation.LockDoor, lockdoor) == 0;
             is_door_locked = success && lockdoor;
             return(success);
         }
     } catch {
         return(false);
     }
 }
Example #21
0
 public void ReleaseLock()
 {
     try
     {
         if (this.stream != null)
         {
             this.stream.Dispose();
             this.stream = null;
         }
     }
     finally
     {
         Monitor.Exit(syncRoot);
     }
 }
Example #22
0
        public bool AcquireLock(int timeout)
        {
            if (disposed)
            {
                throw new ObjectDisposedException(nameof(ECLinux));
            }

            bool success           = false;
            bool syncRootLockTaken = false;

            try
            {
                Monitor.TryEnter(syncRoot, timeout, ref syncRootLockTaken);

                if (!syncRootLockTaken)
                {
                    return(false);
                }

                if (this.stream == null)
                {
                    int fd = Syscall.open(PortFilePath, OpenFlags.O_RDWR | OpenFlags.O_EXCL);

                    if (fd == -1)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    this.stream = new UnixStream(fd);
                }

                success = this.stream != null;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }
            finally
            {
                if (syncRootLockTaken && !success)
                {
                    Monitor.Exit(syncRootLockTaken);
                }
            }

            return(success);
        }
Example #23
0
        public void Open()
        {
            Logger.Instance.Log(LogLevel.Debug, "Trying to estabilishe connection...");
            port_descriptor = Syscall.open(port_name, OpenFlags.O_RDWR);


            if (port_descriptor == -1)
            {
                throw new IOException("Cannot open port (but please, don't ask me about the reason)!");
            }

            stream = new UnixStream(port_descriptor);
            Logger.Instance.Log(LogLevel.Info, "Connection estabilished. Port: " + port_name);

            reader = new Thread(new ThreadStart(ReadData));
            reader.Start();
        }
Example #24
0
 public Stream OpenStream(FileMode fileMode)
 {
     fd = Syscall.open(fileName, OpenFlags.O_RDONLY);
     if ((int)fd < 0)
     {
         Logger.Append(Severity.INFO, "Unable to open file with optimized parameters. Falling back to regular open. (Return code was " + fd + ")");
         return((new UnixFile(fileName)).OpenStream(fileMode));
     }
     else
     {
         //int ret = shb_fcntl(fd, 15 /*F_READAHEAD*/, 512);
         int ret = shb_fcntl(fd, 16 /*F_READAHEAD*/, 512);
         if (ret != 0)
         {
             Logger.Append(Severity.DEBUG, "Could not set F_READAHEAD to optimize file access for " + ufi.FullName + ". Return code was " + ret);
         }
         UnixStream us = new UnixStream(fd, false);
         return((Stream)us);
     }
 }
        public override void Open(string path, bool @abstract)
        {
            if (String.IsNullOrEmpty(path))
            {
                throw new ArgumentException("path");
            }

            if (@abstract)
            {
                socket = OpenAbstractUnix(path);
            }
            else
            {
                socket = OpenUnix(path);
            }

            //socket.Blocking = true;
            SocketHandle = (long)socket.Handle;
            Stream       = new UnixStream((int)socket.Handle);
        }
Example #26
0
        public void ReleaseLock()
        {
            if (disposed)
            {
                throw new ObjectDisposedException(nameof(ECLinux));
            }

            try
            {
                if (this.stream != null)
                {
                    this.stream.Dispose();
                    this.stream = null;
                }
            }
            finally
            {
                Monitor.Exit(syncRoot);
            }
        }
Example #27
0
        /// <summary>
        /// Initializes a new instance of the <see cref="RlangPipe"/> class.
        /// </summary>
        public RlangPipe()
        {
#if __MonoCS__
            if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
            {
                ureadStream = new UnixStream(int.Parse(Environment.GetEnvironmentVariable("R2PIPE_IN")));
                reader      = new StreamReader(ureadStream);

                uwriteStream = new UnixStream(int.Parse(Environment.GetEnvironmentVariable("R2PIPE_OUT")));
                writer       = new StreamWriter(uwriteStream);
            }
            else
            {
#endif
            // Using named pipes on windows. I like this.
            inclient = new NamedPipeClientStream("R2PIPE_PATH");
            reader   = new StreamReader(inclient);
            writer   = new StreamWriter(inclient);
#if __MonoCS__
        }
#endif
        }
 /// <summary>
 /// Closes this instance.
 /// </summary>
 public override void Close()
 {
     if (this.file == null)
     {
         return;
     }
     InternalLogger.Trace("Closing '{0}'", FileName);
     try
     {
         this.file.Close();
     }
     catch (Exception ex)
     {
         // Swallow exception as the file-stream now is in final state (broken instead of closed)
         InternalLogger.Warn(ex, "Failed to close file '{0}'", FileName);
         System.Threading.Thread.Sleep(1);   // Artificial delay to avoid hammering a bad file location
     }
     finally
     {
         this.file = null;
     }
 }
Example #29
0
        private void Init()
        {
            active = false;
            // if there is no /dev/net/tun, run in a "dummy" mode
            if (!File.Exists("/dev/net/tun"))
            {
                this.Log(LogLevel.Warning, "No TUN device found, running in dummy mode.");
                return;
            }

            IntPtr devName;

            if (deviceName != "")
            {
                // non-anonymous mapping
                devName = Marshal.StringToHGlobalAnsi(deviceName);
            }
            else
            {
                devName = Marshal.AllocHGlobal(DeviceNameBufferSize);
                Marshal.WriteByte(devName, 0); // null termination
            }
            try
            {
                tapFileDescriptor = LibC.OpenTAP(devName, persistent);
                if (tapFileDescriptor < 0)
                {
                    var process = new Process();
                    var output  = string.Empty;
                    process.StartInfo.FileName  = "mono";
                    process.StartInfo.Arguments = string.Format("{0} {1} true", DynamicModuleSpawner.GetTAPHelper(), deviceName);

                    try
                    {
                        SudoTools.EnsureSudoProcess(process, "TAP creator");
                    }
                    catch (Exception ex)
                    {
                        throw new RecoverableException("Process elevation failed: " + ex.Message);
                    }

                    process.EnableRaisingEvents              = true;
                    process.StartInfo.CreateNoWindow         = false;
                    process.StartInfo.UseShellExecute        = false;
                    process.StartInfo.RedirectStandardError  = true;
                    process.StartInfo.RedirectStandardOutput = true;

                    var started = process.Start();
                    if (started)
                    {
                        output = process.StandardError.ReadToEnd();
                        process.WaitForExit();
                    }
                    if (!started || process.ExitCode != 0)
                    {
                        this.Log(LogLevel.Warning, "Could not create TUN/TAP interface, running in dummy mode.");
                        this.Log(LogLevel.Debug, "Error {0} while opening tun device '{1}': {2}", process.ExitCode, deviceName, output);
                        return;
                    }
                    Init();
                    return;
                }
                stream        = new UnixStream(tapFileDescriptor, true);
                InterfaceName = Marshal.PtrToStringAnsi(devName);
                this.Log(LogLevel.Info,
                         "Opened interface {0}.", InterfaceName);
            }
            finally
            {
                Marshal.FreeHGlobal(devName);
            }
            active = true;
        }
 public override void Close()
 {
     if (this.file == null)
     return;
     InternalLogger.Trace("Closing '{0}'", FileName);
     this.file.Close();
     this.file = null;
     FileTouched();
 }
Example #31
0
        private UnixStream OpenSocket(uint?mtu)
        {
            /*
             * sockaddr_ll sa = new sockaddr_ll();
             * sa.sll_family = AF_CAN;
             * sa.sll_protocol = CAN_RAW;
             * sa.sll_ifindex = if_nametoindex(Interface);
             */
            sockaddr_can addr = new sockaddr_can();

            addr.can_family = AF_CAN;

            int fd = -1, ret = -1;

            try
            {
                fd = socket(AF_CAN, SOCK_RAW, CAN_RAW);
                UnixMarshal.ThrowExceptionForLastErrorIf(fd);

                ifreq ifr = new ifreq(Interface);

                /* Doesn't seem to work
                 * ret = ioctl(fd, SIOCGIFINDEX, ref ifr);
                 * UnixMarshal.ThrowExceptionForLastErrorIf(ret);
                 */
                addr.can_ifindex = if_nametoindex(Interface);

                if (addr.can_ifindex == 0)
                {
                    throw new ArgumentException("The interface \"" + Interface + "\" is not valid.");
                }

                ret = bind(fd, ref addr, Marshal.SizeOf(addr));
                UnixMarshal.ThrowExceptionForLastErrorIf(ret);

/*
 *                              if (orig_mtu == 0)
 *                              {
 *                                      ret = ioctl(fd, SIOCGIFMTU, ref ifr);
 *                                      UnixMarshal.ThrowExceptionForLastErrorIf(ret);
 *                                      orig_mtu = ifr.ifru_mtu;
 *                              }
 *
 *                              if (mtu != null)
 *                              {
 *                                      ifr.ifru_mtu = mtu.Value;
 *                                      //ret = ioctl(fd, SIOCSIFMTU, ref ifr);
 *                                      ret = ioctl(fd, SIOCGIFMTU, ref ifr);
 *                                      UnixMarshal.ThrowExceptionForLastErrorIf(ret);
 *                              }
 *
 */
                ret = ioctl(fd, SIOCGIFMTU, ref ifr);
                UnixMarshal.ThrowExceptionForLastErrorIf(ret);

/*
 *                              if (mtu != null && ifr.ifru_mtu != mtu.Value)
 *                                      throw new PeachException("MTU change did not take effect.");
 */

                _mtu = ifr.ifru_mtu;

/*
 *
 *                              if (ifr.ifru_mtu > (MaxMTU - EthernetHeaderSize))
 *                                      _bufferSize = (int)MaxMTU;
 *                              else
 *                                      _bufferSize = (int)(ifr.ifru_mtu + EthernetHeaderSize);
 */
                _bufferSize = CAN_MTU;

                var stream = new UnixStream(fd);

                fd = -1;

                return(stream);
            }
            catch (InvalidOperationException ex)
            {
                if (ex.InnerException != null)
                {
                    var inner = ex.InnerException as UnixIOException;
                    if (inner != null && inner.ErrorCode == Errno.EPERM)
                    {
                        throw new PeachException("Access denied when opening the raw ethernet publisher.  Ensure the user has the appropriate permissions.", ex);
                    }
                }

                throw;
            }
            finally
            {
                if (fd != -1)
                {
                    Syscall.close(fd);
                }
            }
        }
Example #32
0
        public ProcessInfo Start(ProcessStartInfo psi)
        {
            if (!(psi.User is UnixUserIdentifier) && psi.User != null)
            {
                throw new InvalidOperationException();
            }

            var user_identifier = (UnixUserIdentifier)(psi.User ?? new UnixUserIdentifier((int)Syscall.getuid(), (int)Syscall.getgid()));
            var arguments = new string[] { Path.GetFileName(psi.Path) }.Concat(psi.Arguments).Concat(new string[] { null }).ToArray();

            // instead of these, we just open /dev/null for now
            // this might change when we get better logging facilities
            //Syscall.pipe(out int stdout_read, out int stdout_write); // used to communicate stdout back to parent
            //Syscall.pipe(out int stderr_read, out int stderr_write); // used to communicate stderr back to parent
            int stdin_read  = Syscall.open("/dev/null", OpenFlags.O_RDWR);
            int stdin_write = Syscall.open("/dev/null", OpenFlags.O_RDWR);

            int stdout_read  = Syscall.open("/dev/null", OpenFlags.O_RDWR);
            int stdout_write = Syscall.open("/dev/null", OpenFlags.O_RDWR);

            int stderr_read  = Syscall.open("/dev/null", OpenFlags.O_RDWR);
            int stderr_write = Syscall.open("/dev/null", OpenFlags.O_RDWR);

            Syscall.pipe(out int control_read, out int control_write); // used to communicate errors during process creation back to parent

            var stdout_w_ptr  = new IntPtr(stdout_write);
            var stderr_w_ptr  = new IntPtr(stderr_write);
            var control_w_ptr = new IntPtr(control_write);

#pragma warning disable CS0618 // Type or member is obsolete
            int fork_ret = Mono.Posix.Syscall.fork();
#pragma warning restore CS0618 // Type or member is obsolete

            if (fork_ret == 0) // child process
            {
                int error = 0;

                Syscall.close(stdout_read);
                Syscall.close(stderr_read);
                Syscall.close(control_read);

                var control_w_stream = new UnixStream(control_write);
                var write_to_control = (Action <string>)(_ => control_w_stream.Write(Encoding.ASCII.GetBytes(_), 0, _.Length));

                write_to_control("starting\n");

                while (Syscall.dup2(stdout_write, 1) == -1)
                {
                    if (Syscall.GetLastError() == Errno.EINTR)
                    {
                        continue;
                    }
                    else
                    {
                        write_to_control($"dup2-stdout:{(int)Syscall.GetLastError()}\n");
                        Syscall.exit(1);
                    }
                }

                while (Syscall.dup2(stderr_write, 2) == -1)
                {
                    if (Syscall.GetLastError() == Errno.EINTR)
                    {
                        continue;
                    }
                    else
                    {
                        write_to_control($"dup2-stderr:{(int)Syscall.GetLastError()}\n");
                        Syscall.exit(1);
                    }
                }

                if ((error = Syscall.setgid(user_identifier.GroupId)) != 0)
                {
                    write_to_control($"setgid:{(int)Syscall.GetLastError()}\n");
                    Syscall.exit(1);
                }

                if ((error = Syscall.setuid(user_identifier.UserId)) != 0)
                {
                    write_to_control($"setuid:{(int)Syscall.GetLastError()}\n");
                    Syscall.exit(1);
                }

                if (psi.WorkingDirectory != "")
                {
                    Syscall.chdir(psi.WorkingDirectory);
                }

                if ((error = Syscall.execv(psi.Path, arguments)) != 0)
                {
                    write_to_control($"execv:{(int)Syscall.GetLastError()}\n");
                    Syscall.exit(1);
                }
            }

            if (fork_ret < 0)
            {
                throw new InvalidOperationException($"fork() returned {fork_ret}, errno: {Syscall.GetLastError()}");
            }

            Syscall.close(stdout_write);
            Syscall.close(stderr_write);
            Syscall.close(control_write);

            var stdout_stream  = new Mono.Unix.UnixStream(stdout_read);
            var stderr_stream  = new Mono.Unix.UnixStream(stderr_read);
            var control_stream = new Mono.Unix.UnixStream(control_read);

            var control_sr = new StreamReader(control_stream);

            var starting_line = control_sr.ReadLine();
            if (starting_line != "starting")
            {
                throw new Exception($"Expected starting message from control pipe, received {starting_line}");
            }

            Processes.Add(fork_ret);
            return(new ProcessInfo(System.Diagnostics.Process.GetProcessById(fork_ret)));
        }
        public UnixMultiProcessFileAppender(string fileName, ICreateFileParameters parameters) : base(fileName, parameters)
        {
            UnixFileInfo fileInfo   = null;
            bool         fileExists = false;

            try
            {
                fileInfo   = new UnixFileInfo(fileName);
                fileExists = fileInfo.Exists;
            }
            catch
            {
            }

            int fd = Syscall.open(fileName, OpenFlags.O_CREAT | OpenFlags.O_WRONLY | OpenFlags.O_APPEND, (FilePermissions)(6 | (6 << 3) | (6 << 6)));

            if (fd == -1)
            {
                if (Stdlib.GetLastError() == Errno.ENOENT && parameters.CreateDirs)
                {
                    string dirName = Path.GetDirectoryName(fileName);
                    if (!Directory.Exists(dirName) && parameters.CreateDirs)
                    {
                        Directory.CreateDirectory(dirName);
                    }

                    fd = Syscall.open(fileName, OpenFlags.O_CREAT | OpenFlags.O_WRONLY | OpenFlags.O_APPEND, (FilePermissions)(6 | (6 << 3) | (6 << 6)));
                }
            }
            if (fd == -1)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            try
            {
                _file = new UnixStream(fd, true);

                long filePosition = _file.Position;
                if (fileExists || filePosition > 0)
                {
                    if (fileInfo != null)
                    {
                        CreationTimeUtc = FileInfoHelper.LookupValidFileCreationTimeUtc(fileInfo, (f) => File.GetCreationTimeUtc(f.FullName), (f) => { f.Refresh(); return(f.LastStatusChangeTimeUtc); }, (f) => DateTime.UtcNow).Value;
                    }
                    else
                    {
                        CreationTimeUtc = FileInfoHelper.LookupValidFileCreationTimeUtc(fileName, (f) => File.GetCreationTimeUtc(f), (f) => DateTime.UtcNow).Value;
                    }
                }
                else
                {
                    // We actually created the file and eventually concurrent processes
                    CreationTimeUtc = DateTime.UtcNow;
                    File.SetCreationTimeUtc(FileName, CreationTimeUtc);
                }
            }
            catch
            {
                Syscall.close(fd);
                throw;
            }
        }