private void SetPermissions(string path, string mask) { Logger.Debug("Setting permissions: {0} on {1}", mask, path); var filePermissions = NativeConvert.FromOctalPermissionString(mask); if (Syscall.chmod(path, filePermissions) < 0) { var error = Stdlib.GetLastError(); throw new LinuxPermissionsException("Error setting file permissions: " + error); } }
private Errno Remove(string path) { Trace.WriteLine($"Remove {path}"); int r = Stdlib.remove(path); if (r < 0) { return(GetLastError()); } return(0); }
public override Errno OnRenamePath(string oldpath, string newpath) { Trace.WriteLine($"OnRenamePath {oldpath} to {newpath}"); int r = Stdlib.rename(oldpath, newpath); if (r < 0) { return(Stdlib.GetLastError()); } return(0); }
public static string GetLoginName() { int num; StringBuilder stringBuilder = new StringBuilder(4); do { StringBuilder capacity = stringBuilder; capacity.Capacity = capacity.Capacity * 2; num = Syscall.getlogin_r(stringBuilder, (ulong)stringBuilder.Capacity); }while (num == -1 && Stdlib.GetLastError() == Errno.ERANGE); UnixMarshal.ThrowExceptionForLastErrorIf(num); return(stringBuilder.ToString()); }
/// <summary> /// Instantiates a new instance of <see cref="LinuxDisk"/>. /// </summary> /// <param name="path">The path to the disk device node.</param> public LinuxDisk(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } fd = Syscall.open(path, OpenFlags.O_RDONLY); if (fd == -1) { var errno = Stdlib.GetLastError(); throw new IOException(UnixMarshal.GetErrorDescription(errno)); } DisplayName = path; }
/// <summary> /// Moves file from <paramref name="sourcePath"/> to <paramref name="destinationPath"/> the same way <see /// cref="System.IO.File.Move"/> does but it checks whether the file pointed to by <paramref /// name="sourcePath"/> is a dangling symlink and, if yes, it does not call <see cref="System.IO.File.Move"/> /// but instead uses <c>readlink(2)</c> and <c>symlink(2)</c> to recreate the symlink at the destination. This /// is to work around a bug in Mono 6 series which will throw an exception when trying to move a dangling /// symlink. /// </summary> public static void FileMove(string sourcePath, string destinationPath) { if (String.IsNullOrEmpty(sourcePath)) { throw new ArgumentException("must not be null or empty", nameof(sourcePath)); } if (String.IsNullOrEmpty(destinationPath)) { throw new ArgumentException("must not be null or empty", nameof(destinationPath)); } int ret = Syscall.lstat(sourcePath, out Stat sbuf); if (ret != 0 || (ret == 0 && (sbuf.st_mode & FilePermissions.S_IFLNK) != FilePermissions.S_IFLNK)) { // Not a symlink or an error, just call to the BCL and let it handle both situations File.Move(sourcePath, destinationPath); return; } // Source is a symlink ret = Syscall.stat(sourcePath, out sbuf); Log.DebugLine($"stat on {sourcePath} returned {ret}. Errno: {Stdlib.GetLastError ()}"); if (!FileIsDanglingSymlink(sourcePath)) { // let BCL handle it File.Move(sourcePath, destinationPath); return; } Log.DebugLine($"Moving a dangling symlink from {sourcePath} to {destinationPath}"); // We have a dangling symlink, we'll just recreate it at the destination and remove the source var sb = new StringBuilder(checked ((int)sbuf.st_size)); ret = Syscall.readlink(sourcePath, sb); if (ret < 0) { throw new IOException($"Failed to read a symbolic link '{sourcePath}'. {Stdlib.strerror (Stdlib.GetLastError ())}"); } string sourceLinkContents = sb.ToString(); Log.DebugLine($"Source symlink {sourcePath} points to: {sourceLinkContents}"); ret = Syscall.symlink(sourceLinkContents, destinationPath); if (ret < 0) { throw new IOException($"Failed to create a symbolic link '{destinationPath}' -> '{sourceLinkContents}'. {Stdlib.strerror (Stdlib.GetLastError ())}"); } }
void CreateLink(string s) { string link = UnixPath.Combine(TempFolder, "link"); //File.Delete (link); // Fails for long link target paths if (Syscall.unlink(link) < 0 && Stdlib.GetLastError() != Errno.ENOENT) { UnixMarshal.ThrowExceptionForLastError(); } if (Syscall.symlink(s, link) < 0) { UnixMarshal.ThrowExceptionForLastError(); } }
public UnixSignal(Mono.Unix.Native.RealTimeSignum rtsig) { this.signum = NativeConvert.FromRealTimeSignum(rtsig); this.signal_info = UnixSignal.install(this.signum); Errno lastError = Stdlib.GetLastError(); if (this.signal_info == IntPtr.Zero) { if (lastError != Errno.EADDRINUSE) { throw new ArgumentException("Unable to handle signal", "signum"); } throw new ArgumentException("Signal registered outside of Mono.Posix", "signum"); } }
private static IPAddress PtrToAddress(IntPtr ptr) { IPAddress address = null; if (ptr != IntPtr.Zero) { IntPtr buf = Stdlib.malloc(256); IntPtr addrPtr = avahi_address_snprint(buf, 256, ptr); address = IPAddress.Parse(GLib.Marshaller.Utf8PtrToString(addrPtr)); Stdlib.free(addrPtr); } return(address); }
public static bool ShouldRetrySyscall(int r, out Errno errno) { errno = (Errno)0; if (r == -1) { Errno lastError = Stdlib.GetLastError(); Errno errno1 = lastError; errno = lastError; if (errno1 == Errno.EINTR) { return(true); } } return(false); }
public virtual Errno FlushHandle(string path, OpenedPathInfo info) { /* This is called from every close on an open file, so call the * close on the underlying filesystem. But since flush may be * called multiple times for an open file, this must not really * close the file. This is important if used on a network * filesystem like NFS which flush the data/metadata on close() */ int r = Syscall.close(Syscall.dup((int)info.Handle)); if (r == -1) { return(Stdlib.GetLastError()); } return(0); }
public virtual void GetExtendedAttribute(string path, string name, byte[] value, out int bytesWritten) { bytesWritten = (int)Syscall.lgetxattr(path.GetPath(_source), name, value, (ulong)(value?.Length ?? 0)); if (bytesWritten != -1) { return; } var err = Stdlib.GetLastError(); if (err != Errno.ENODATA) { throw new NativeException((int)err); } }
private bool Refresh(bool throwException) { int num = Syscall.statvfs(this.mount_point, out this.stat); if (num == -1 && throwException) { Errno lastError = Stdlib.GetLastError(); throw new InvalidOperationException(UnixMarshal.GetErrorDescription(lastError), new UnixIOException(lastError)); } if (num == -1) { return(false); } return(true); }
private static bool TryDoFileLocking(int fd, bool lockFile, FlockOperation?specificFlag = null) { if (fd >= 0) { int res; Errno lastError; do { res = Flock(fd, specificFlag ?? (lockFile ? FlockOperation.LOCK_EX : FlockOperation.LOCK_UN)); lastError = Stdlib.GetLastError(); }while(res != 0 && lastError == Errno.EINTR); // if can't get lock ... return(res == 0); } return(false); }
public int Execute(int ms = 500) { int events = Syscall.epoll_wait(_epoll, _events, _events.Length, ms); if (events == -1) { Errno error = Stdlib.GetLastError(); if (error != Errno.EINTR) { throw new InvalidOperationException(String.Format("Error {0} occured while waiting for an event", error)); } } return(events); }
public void TestRaiseRTMINSignal() { if (!TestHelper.CanUseRealTimeSignals()) { return; } RealTimeSignum rts = new RealTimeSignum(0); using (UnixSignal signal = new UnixSignal(rts)) { MultiThreadTest(signal, 5000, delegate() { Thread.Sleep(1000); Stdlib.raise(rts); }); } }
static bool FileIsDanglingSymlink(string path) { int ret = Syscall.stat(path, out Stat sbuf); if (ret < 0) { Log.DebugLine($"stat on {path} returned {ret}. Errno: {Stdlib.GetLastError ()}"); } if (ret == 0 || (ret < 0 && Stdlib.GetLastError() != Errno.ENOENT)) { // Either a valid symlink or an error other than ENOENT return(false); } return(true); }
public bool Unlink() { lock (_syncObject) { if (Syscall.unlink(_name) == -1) { Errno errno = Stdlib.GetLastError(); if (errno == Errno.ENOENT) { return(false); } throw new NativeException((int)errno); } return(true); } }
public override long Seek(long offset, SeekOrigin origin) { this.AssertNotDisposed(); if (!this.CanSeek) { throw new NotSupportedException("The File Stream does not support seeking"); } SeekFlags seekFlag = SeekFlags.SEEK_CUR; switch (origin) { case SeekOrigin.Begin: { seekFlag = SeekFlags.SEEK_SET; break; } case SeekOrigin.Current: { seekFlag = SeekFlags.SEEK_CUR; break; } case SeekOrigin.End: { seekFlag = SeekFlags.SEEK_END; break; } default: { throw new ArgumentException("origin"); } } if (Stdlib.fseek(this.file, offset, seekFlag) != 0) { throw new IOException("Unable to seek", UnixMarshal.CreateExceptionForLastError()); } long num = Stdlib.ftell(this.file); if (num == (long)-1) { throw new IOException("Unable to get current file position", UnixMarshal.CreateExceptionForLastError()); } GC.KeepAlive(this); return(num); }
// can be called in the context of a worker thread public int OnWriteReady() { if (state != EState.Writing) { //Log.Error("Writing in state " + state); return(0); } Log.Epoll("[{0}] Writing {1} bytes from {2}", socketHandle, ResponseTotalLength - totalWritten, ResponseStart + totalWritten); var written = Syscall.write(socketHandle, IntPtr.Add(bufferPtr, ResponseStart + totalWritten), (ulong)(ResponseTotalLength - totalWritten)); Log.Epoll("[{0}] write() returned {1}", socketHandle, written); if (written < 0) { var errno = Stdlib.GetLastError(); if (errno != 0 && errno != Errno.EAGAIN) { Log.Error("[{0}] write() socket error {1}", socketHandle, errno); return(-1); // waiting for the socket to be detached/closed } return(0); } if (written == 0) { Log.Epoll("[{0}] peer closed connection", socketHandle); // waiting for the socket to be detached/closed return(0); } Log.Epoll("[{0}] Written {1} bytes", socketHandle, written); totalWritten += (int)written; if (totalWritten < ResponseTotalLength) { // not all was written, try again } else { //Console.Write('>'); Log.Epoll("[{0}] Request processing complete!", socketHandle); Stats.ReportContextTime(ContextType, Stats.Watch.Elapsed - processingStarted); processingStarted = new TimeSpan(); setReading(); } return(0); }
public virtual unsafe Errno WriteHandle(string path, OpenedPathInfo info, byte[] buf, long offset, out int bytesWritten) { int r; fixed(byte *pb = buf) { r = bytesWritten = (int)Syscall.pwrite((int)info.Handle, pb, (ulong)buf.Length, offset); } if (r == -1) { return(Stdlib.GetLastError()); } return(0); }
public void SetProcessName(string name) { if (OSName == "Linux") { if (prctl(15 /* PR_SET_NAME */, Encoding.ASCII.GetBytes(name + "\0"), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero) != 0) { throw new ApplicationException("Error setting process name: " + Stdlib.GetLastError()); } } else if (OSName == "FreeBSD") // XXX: I'm not sure this is right { setproctitle(Encoding.ASCII.GetBytes("%s\0"), Encoding.ASCII.GetBytes(name + "\0")); } }
public void TestConcurrentWaitOneSameInstance() { UnixSignal s1 = new UnixSignal(Signum.SIGINT); Thread a = CreateWaitSignalThread(s1, 10000); Thread b = CreateWaitSignalThread(s1, 10000); Thread c = new Thread(delegate() { Thread.Sleep(500); Stdlib.raise(Signum.SIGINT); }); a.Start(); b.Start(); c.Start(); a.Join(); b.Join(); c.Join(); }
public override void GetExtendedAttribute(string path, string name, byte[] value, out int bytesWritten) { var encPath = FileSystem.Path.GetEncryptedPath(path, true); bytesWritten = (int)Syscall.lgetxattr(encPath.GetPath(_source), name, value, (ulong)(value?.Length ?? 0)); if (bytesWritten != -1) { return; } var err = Stdlib.GetLastError(); if (err != Errno.ENODATA) { throw new NativeException((int)err); } }
public static string GetCurrentDirectory() { StringBuilder stringBuilder = new StringBuilder(16); IntPtr zero = IntPtr.Zero; do { StringBuilder capacity = stringBuilder; capacity.Capacity = capacity.Capacity * 2; zero = Syscall.getcwd(stringBuilder, (ulong)stringBuilder.Capacity); }while (zero == IntPtr.Zero && Stdlib.GetLastError() == Errno.ERANGE); if (zero == IntPtr.Zero) { UnixMarshal.ThrowExceptionForLastError(); } return(stringBuilder.ToString()); }
protected override unsafe Errno OnReadHandle(string path, OpenedPathInfo info, byte[] buf, long offset, out int bytesRead) { int r; fixed(byte *pb = buf) { r = bytesRead = (int)Syscall.pread((int)info.Handle, pb, (ulong)buf.Length, offset); } if (r == -1) { return(Stdlib.GetLastError()); } return(0); }
private static string strerror_r(Errno errno) { StringBuilder stringBuilder = new StringBuilder(16); int num = 0; do { StringBuilder capacity = stringBuilder; capacity.Capacity = capacity.Capacity * 2; num = Syscall.strerror_r(errno, stringBuilder); }while (num == -1 && Stdlib.GetLastError() == Errno.ERANGE); if (num != -1) { return(stringBuilder.ToString()); } return(string.Concat("** Unknown error code: ", (int)errno, "**")); }
private static Errno ProcessFile(string path, OpenFlags flags, FdCb cb) { int fd = Syscall.open(path, flags); if (fd == -1) { return(Stdlib.GetLastError()); } int r = cb(fd); Errno res = 0; if (r == -1) { res = Stdlib.GetLastError(); } Syscall.close(fd); return(res); }
public bool Update(int fd, EpollEvents flags) { var ev = new EpollEvent() { events = flags, u32 = (uint)fd }; Log.Epoll("[{0}] EPOLL_CTL_MOD({1})", fd, flags); var r = Syscall.epoll_ctl(epfd, EpollOp.EPOLL_CTL_MOD, fd, ref ev); if (r != 0) { Log.Error($"Call to epoll_ctl(MOD) failed with code {r}: {Stdlib.GetLastError()}"); return(false); } return(true); }
public virtual Errno SynchronizeHandle(string path, OpenedPathInfo info, bool onlyUserData) { int r; if (onlyUserData) { r = Syscall.fdatasync((int)info.Handle); } else { r = Syscall.fsync((int)info.Handle); } if (r == -1) { return(Stdlib.GetLastError()); } return(0); }
static UnixMarshal () { Stdlib s = new Stdlib (); }