Example #1
0
        // spheroid
        LP s_inverse(XY xy)
        {
            LP lp;

            lp.lam = lp.phi = 0;

            if (noskew)
            {
                double t = xy.x;
                xy.x = -xy.x * cAzc + xy.y * sAzc;
                xy.y = -xy.y * cAzc - t * sAzc;
            }

            double s, c, Av;

            bool neg = (xy.x < 0.0);

            if (neg)
            {
                xy.y = rhoc - xy.y;
                s    = S20;
                c    = C20;
                Av   = Azab;
            }
            else
            {
                xy.y += rhoc;
                s     = S45;
                c     = C45;
                Av    = Azba;
            }

            double rl = Libc.hypot(xy.x, xy.y);
            double rp = rl, r = rl;
            double Az  = Math.Atan2(xy.x, xy.y);
            double fAz = Math.Abs(Az);

            double z = 0;
            int    i = NITER;

            for (; i > 0; i--)
            {
                z = 2.0 * Math.Atan(Math.Pow(r / F, 1 / n));
                double al = Math.Acos((Math.Pow(Math.Tan(0.5 * z), n) + Math.Pow(Math.Tan(0.5 * (R104 - z)), n)) / T);
                if (fAz < al)
                {
                    r = rp * Math.Cos(al + (neg?Az:-Az));
                }
                if (Math.Abs(rl - r) < EPS)
                {
                    break;
                }
                rl = r;
            }

            if (i == 0)
            {
                Proj.pj_ctx_set_errno(ctx, -20); return(lp);
            }

            Az     = Av - Az / n;
            lp.phi = Math.Asin(s * Math.Cos(z) + c * Math.Sin(z) * Math.Cos(Az));
            lp.lam = Math.Atan2(Math.Sin(Az), c / Math.Tan(z) - s * Math.Cos(Az));

            if (neg)
            {
                lp.lam -= R110;
            }
            else
            {
                lp.lam = lamB - lp.lam;
            }

            return(lp);
        }
Example #2
0
        internal static void Start(uint magic, uint address, uint KernelDirectory, uint InitialHeap)
        {
            /* Kernel Logger init */
            Debug.Init();

            /* Initalize Heap */
            Heap.Init(InitialHeap);

            /* Multiboot Info Parsing */
            Multiboot.Setup(magic, address);

            /* Setup Paging */
            Paging.Setup(KernelDirectory);

            /* Setup GDT */
            GDT.Setup();

            /* Remap PIC */
            PIC.Setup();

            /* Setup IDT */
            IDT.Setup();

            /* Enable Interrupt */
            Native.Sti();

            /* Setup Scheduler */
            Scheduler.Init(KernelDirectory);

            /* Setup System Timer */
            Timer.Setup();

            /* Install SHM */
            SHM.Install();

            /* Initialise VBE 2.0 Driver */
            VBE.Init();

            /* Initialise Virtual File system */
            VirtualFileSystem.Setup();

            /* Setup Syscall */
            Syscall.Setup();

            /* Initialise C library */
            Libc.Init();

            try
            {
                Boot.Init();
            }
            catch (Exception e)
            {
                Debug.Write("[@SystemThread] => [EXIT]: %s\n", e.Message);
            }

            while (true)
            {
                ;
            }
        }
Example #3
0
        public const int IS_ANAL_CONV  = 010;           // convergence analytic

        public static bool pj_factors(LP lp, PJ P, double h, ref FACTORS fac)
        {
            IFactors PFac = P as IFactors;

            const double EPS       = 1.0e-12;
            const double DEFAULT_H = 1e-5;

            // check for forward and latitude or longitude overange
            double t = Math.Abs(lp.phi) - Proj.HALFPI;

            if (t > EPS || Math.Abs(lp.lam) > 10.0)
            {
                Proj.pj_ctx_set_errno(P.ctx, -14);
                return(true);
            }

            // proceed
            Libc.errno       = Proj.pj_errno = 0;
            P.ctx.last_errno = 0;
            if (h < EPS)
            {
                h = DEFAULT_H;
            }
            if (Math.Abs(lp.phi) > (Proj.HALFPI - h))
            {
                lp.phi = lp.phi < 0.0?(-Proj.HALFPI + h):(Proj.HALFPI - h);         // adjust to value around pi/2 where derived still exists
            }
            else if (P.geoc)
            {
                lp.phi = Math.Atan(P.rone_es * Math.Tan(lp.phi));
            }

            lp.lam -= P.lam0;           // compute del lp.lam
            if (!P.over)
            {
                lp.lam = Proj.adjlon(lp.lam);                   // adjust del longitude
            }
            if (PFac != null)
            {
                PFac.spc(lp, ref fac);                        // get what projection analytic values
            }
            if ((fac.code & (IS_ANAL_XL_YL + IS_ANAL_XP_YP)) != (IS_ANAL_XL_YL + IS_ANAL_XP_YP))
            {
                DERIVS der;
                if (pj_deriv(lp, h, P, out der))
                {
                    return(true);
                }

                if ((fac.code & IS_ANAL_XL_YL) == 0)
                {
                    fac.der.x_l = der.x_l;
                    fac.der.y_l = der.y_l;
                }
                if ((fac.code & IS_ANAL_XP_YP) == 0)
                {
                    fac.der.x_p = der.x_p;
                    fac.der.y_p = der.y_p;
                }
            }

            double cosphi = Math.Cos(lp.phi);

            double r;

            if ((fac.code & IS_ANAL_HK) == 0)
            {
                fac.h = Libc.hypot(fac.der.x_p, fac.der.y_p);
                fac.k = Libc.hypot(fac.der.x_l, fac.der.y_l) / cosphi;
                if (P.es != 0)
                {
                    t = Math.Sin(lp.phi);
                    t = 1.0 - P.es * t * t;
                    double n = Math.Sqrt(t);
                    fac.h *= t * n / P.one_es;
                    fac.k *= n;
                    r      = t * t / P.one_es;
                }
                else
                {
                    r = 1.0;
                }
            }
            else if (P.es != 0)
            {
                r = Math.Sin(lp.phi);
                r = 1.0 - P.es * r * r;
                r = r * r / P.one_es;
            }
            else
            {
                r = 1.0;
            }

            // convergence
            if ((fac.code & IS_ANAL_CONV) == 0)
            {
                fac.conv = -Math.Atan2(fac.der.y_l, fac.der.x_l);
                if ((fac.code & IS_ANAL_XL_YL) != 0)
                {
                    fac.code |= IS_ANAL_CONV;
                }
            }

            // areal scale factor
            fac.s = (fac.der.y_p * fac.der.x_l - fac.der.x_p * fac.der.y_l) * r / cosphi;

            // meridian-parallel angle theta prime
            fac.thetap = Proj.aasin(P.ctx, fac.s / (fac.h * fac.k));

            // Tissot ellips axis
            t     = fac.k * fac.k + fac.h * fac.h;
            fac.a = Math.Sqrt(t + 2.0 * fac.s);
            t     = (t = t - 2.0 * fac.s) <= 0.0?0.0:Math.Sqrt(t);
            fac.b = 0.5 * (fac.a - t);
            fac.a = 0.5 * (fac.a + t);

            // omega
            fac.omega = 2.0 * Proj.aasin(P.ctx, (fac.a - fac.b) / (fac.a + fac.b));

            return(false);
        }
Example #4
0
		// ellipsoid
		LP e_inverse(XY xy)
		{
			LP lp;
			lp.lam=lp.phi=0;

			int nn;

			COMPLEX p;
			p.r=xy.x;
			p.i=xy.y;
			for(nn=20; nn>0; nn--)
			{
				COMPLEX fpxy;
				COMPLEX fxy=p.pj_zpolyd1(zcoeff, n, out fpxy);

				fxy.r-=xy.x;
				fxy.i-=xy.y;
				double den=fpxy.r*fpxy.r+fpxy.i*fpxy.i;

				COMPLEX dp;
				dp.r=-(fxy.r*fpxy.r+fxy.i*fpxy.i)/den;
				dp.i=-(fxy.i*fpxy.r-fxy.r*fpxy.i)/den;

				p.r+=dp.r;
				p.i+=dp.i;
				if((Math.Abs(dp.r)+Math.Abs(dp.i))<=EPSLN) break;
			}

			double rh=0, sinz=0, cosz=0, phi=0;
			if(nn!=0)
			{
				rh=Libc.hypot(p.r, p.i);
				double z=2.0*Math.Atan(0.5*rh);
				sinz=Math.Sin(z);
				cosz=Math.Cos(z);
				lp.lam=lam0;
				if(Math.Abs(rh)<=EPSLN)
				{
					lp.phi=phi0;
					return lp;
				}

				double chi=Proj.aasin(ctx, cosz*schio+p.i*sinz*cchio/rh);
				phi=chi;
				for(nn=20; nn>0; nn--)
				{
					double esphi=e*Math.Sin(phi);
					double dphi=2.0*Math.Atan(Math.Tan((Proj.HALFPI+chi)*0.5)*Math.Pow((1.0+esphi)/(1.0-esphi), e*0.5))-Proj.HALFPI-phi;
					phi+=dphi;
					if(Math.Abs(dphi)<=EPSLN) break;
				}
			}

			if(nn!=0)
			{
				lp.phi=phi;
				lp.lam=Math.Atan2(p.r*sinz, rh*cchio*cosz-p.i*schio*sinz);
			}
			else lp.lam=lp.phi=Libc.HUGE_VAL;

			return lp;
		}
Example #5
0
        private void LoadStat()
        {
            int r = Libc.fstat(Fd, out _stat);

            Error.ThrowExceptionForLastErrorIf(r);
        }
Example #6
0
        // spheroid
        LP s_inverse(XY xy)
        {
            LP lp;

            lp.lam = lp.phi = 0;

            double rh   = Libc.hypot(xy.x, xy.y);
            double sinc = rh;

            if (sinc > 1.0)
            {
                if ((sinc - 1.0) > EPS10)
                {
                    Proj.pj_ctx_set_errno(ctx, -20); return(lp);
                }
                sinc = 1.0;
            }

            double cosc = Math.Sqrt(1.0 - sinc * sinc);       // in this range OK

            if (Math.Abs(rh) <= EPS10)
            {
                lp.phi = phi0;
                lp.lam = 0.0;
            }
            else
            {
                switch (mode)
                {
                case ortho_mode.N_POLE: xy.y = -xy.y; lp.phi = Math.Acos(sinc); break;

                case ortho_mode.S_POLE: lp.phi = -Math.Acos(sinc); break;

                case ortho_mode.EQUIT:
                    lp.phi = xy.y * sinc / rh;
                    xy.x  *= sinc;
                    xy.y   = cosc * rh;
                    if (Math.Abs(lp.phi) >= 1.0)
                    {
                        lp.phi = lp.phi < 0.0?-Proj.HALFPI:Proj.HALFPI;
                    }
                    else
                    {
                        lp.phi = Math.Asin(lp.phi);
                    }
                    break;

                case ortho_mode.OBLIQ:
                    lp.phi = cosc * sinph0 + xy.y * sinc * cosph0 / rh;
                    xy.y   = (cosc - sinph0 * lp.phi) * rh;
                    xy.x  *= sinc * cosph0;
                    if (Math.Abs(lp.phi) >= 1.0)
                    {
                        lp.phi = lp.phi < 0.0?-Proj.HALFPI:Proj.HALFPI;
                    }
                    else
                    {
                        lp.phi = Math.Asin(lp.phi);
                    }
                    break;
                }
                lp.lam = (xy.y == 0.0 && (mode == ortho_mode.OBLIQ || mode == ortho_mode.EQUIT))?
                         (xy.x == 0.0?0.0:xy.x < 0.0?-Proj.HALFPI:Proj.HALFPI):Math.Atan2(xy.x, xy.y);
            }

            return(lp);
        }
        private void runLinux(Control control)
        {
            this.mainControl = control;

            if (userCanvasSize.IsEmpty)
            {
                // Create physical canvas with actual terminal size
                winsize ws = Libc.GetTerminalSize(isDarwin);
                canvas = new PhysicalCanvas(ws.ws_col, ws.ws_row);
            }
            else
            {
                canvas = new PhysicalCanvas(userCanvasSize.Width, userCanvasSize.Height);
            }
            renderer.Canvas          = canvas;
            renderer.RootElementRect = userRootElementRect.IsEmpty
                ? new Rect(canvas.Size) : userRootElementRect;
            renderer.RootElement = mainControl;
            //
            mainControl.Invalidate();

            // Terminal initialization sequence

            // This is magic workaround to avoid messing up terminal after program finish
            // The bug is described at https://bugzilla.xamarin.com/show_bug.cgi?id=15118
            bool ignored = Console.KeyAvailable;

            IntPtr stdscr = NCurses.initscr();

            NCurses.cbreak();
            NCurses.noecho();
            NCurses.nonl();
            NCurses.intrflush(stdscr, false);
            NCurses.keypad(stdscr, true);
            NCurses.start_color();

            HideCursor();
            try {
                renderer.UpdateLayout( );
                renderer.FinallyApplyChangesToCanvas(  );

                termkeyHandle = LibTermKey.termkey_new(0, TermKeyFlag.TERMKEY_FLAG_SPACESYMBOL);

                // Setup the input mode
                Console.Write("\x1B[?1002h");
                pollfd fd = new pollfd( );
                fd.fd     = 0;
                fd.events = POLL_EVENTS.POLLIN;

                pollfd[] fds = new pollfd[2];
                fds[0] = fd;
                fds[1] = new pollfd( );
                int pipeResult = Libc.pipe(pipeFds);
                if (pipeResult == -1)
                {
                    throw new InvalidOperationException("Cannot create self-pipe.");
                }
                fds[1].fd     = pipeFds[0];
                fds[1].events = POLL_EVENTS.POLLIN;

                try {
#if !WIN32
                    // Catch SIGWINCH to handle terminal resizing
                    UnixSignal[] signals = new UnixSignal [] {
                        new UnixSignal(Signum.SIGWINCH)
                    };
                    Thread signal_thread = new Thread(delegate() {
                        while (true)
                        {
                            // Wait for a signal to be delivered
                            int index     = UnixSignal.WaitAny(signals, -1);
                            Signum signal = signals [index].Signum;
                            Libc.writeInt64(pipeFds[1], 2);
                        }
                    }
                                                      );
                    signal_thread.IsBackground = false;
                    signal_thread.Start();
#endif
                    TermKeyKey key = new TermKeyKey( );
                    //
                    this.running      = true;
                    this.mainThreadId = Thread.CurrentThread.ManagedThreadId;
                    //
                    int nextwait = -1;
                    while (true)
                    {
                        int pollRes = Libc.poll(fds, 2, nextwait);
                        if (pollRes == 0)
                        {
                            if (nextwait == -1)
                            {
                                throw new InvalidOperationException("Assertion failed.");
                            }
                            if (TermKeyResult.TERMKEY_RES_KEY == LibTermKey.termkey_getkey_force(termkeyHandle, ref key))
                            {
                                processLinuxInput(key);
                            }
                        }
                        if (pollRes == -1)
                        {
                            int errorCode = Marshal.GetLastWin32Error();
                            if (errorCode != Libc.EINTR)
                            {
                                throw new InvalidOperationException(string.Format("poll() returned with error code {0}", errorCode));
                            }
                        }

                        if (fds[1].revents != POLL_EVENTS.NONE)
                        {
                            UInt64 u;
                            Libc.readInt64(fds[1].fd, out u);
                            if (u == 1)
                            {
                                // Exit from application
#if !WIN32
                                signal_thread.Abort();
#endif
                                break;
                            }
                            if (u == 2)
                            {
                                // Get new term size and process appropriate INPUT_RECORD event
                                INPUT_RECORD inputRecord = new INPUT_RECORD( );
                                inputRecord.EventType = EventType.WINDOW_BUFFER_SIZE_EVENT;

                                winsize ws = Libc.GetTerminalSize(isDarwin);

                                inputRecord.WindowBufferSizeEvent.dwSize.X = ( short )ws.ws_col;
                                inputRecord.WindowBufferSizeEvent.dwSize.Y = ( short )ws.ws_row;
                                processInputEvent(inputRecord);
                            }
                            if (u == 3)
                            {
                                // It is signal from async actions invocation stuff
                            }
                        }

                        if ((fds[0].revents & POLL_EVENTS.POLLIN) == POLL_EVENTS.POLLIN ||
                            (fds[0].revents & POLL_EVENTS.POLLHUP) == POLL_EVENTS.POLLHUP ||
                            (fds[0].revents & POLL_EVENTS.POLLERR) == POLL_EVENTS.POLLERR)
                        {
                            LibTermKey.termkey_advisereadable(termkeyHandle);
                        }

                        TermKeyResult result = (LibTermKey.termkey_getkey(termkeyHandle, ref key));
                        while (result == TermKeyResult.TERMKEY_RES_KEY)
                        {
                            processLinuxInput(key);
                            result = (LibTermKey.termkey_getkey(termkeyHandle, ref key));
                        }

                        if (result == TermKeyResult.TERMKEY_RES_AGAIN)
                        {
                            nextwait = LibTermKey.termkey_get_waittime(termkeyHandle);
                        }
                        else
                        {
                            nextwait = -1;
                        }

                        while (true)
                        {
                            bool anyInvokeActions      = isAnyInvokeActions( );
                            bool anyRoutedEvent        = !EventManager.IsQueueEmpty( );
                            bool anyLayoutToRevalidate = renderer.AnyControlInvalidated;

                            if (!anyInvokeActions && !anyRoutedEvent && !anyLayoutToRevalidate)
                            {
                                break;
                            }

                            EventManager.ProcessEvents();
                            processInvokeActions(  );
                            renderer.UpdateLayout(  );
                        }

                        renderer.FinallyApplyChangesToCanvas( );
                    }
                } finally {
                    LibTermKey.termkey_destroy(termkeyHandle);
                    Libc.close(pipeFds[0]);
                    Libc.close(pipeFds[1]);
                    Console.Write("\x1B[?1002l");
                }
            } finally {
                // Restore cursor visibility before exit
                ShowCursor( );
                NCurses.endwin( );
            }

            renderer.RootElement = null;
        }
Example #8
0
        private static unsafe void Renderer()
        {
            int tmp_mouse_X, tmp_mouse_Y;
            int old_mouse_X = -1, old_mouse_Y = -1;

            bool update;

            while (true)
            {
                tmp_mouse_X = Mouse_X;
                tmp_mouse_Y = Mouse_Y;
                update      = false;

                Cairo.Save(MainContext);
                Cairo.Save(VideoContext);

                if (tmp_mouse_X != old_mouse_X || tmp_mouse_Y != old_mouse_Y)
                {
                    update = true;
                    Cairo.Rectangle(32, 32, old_mouse_Y, old_mouse_X, MainContext);
                    Cairo.Rectangle(32, 32, old_mouse_Y, old_mouse_X, VideoContext);
                    Cairo.Rectangle(32, 32, tmp_mouse_Y, tmp_mouse_X, VideoContext);
                }

                old_mouse_X = tmp_mouse_X;
                old_mouse_Y = tmp_mouse_Y;

                var queue = RedrawRects;
                Monitor.AcquireLock(ref RedrawRectsLock);
                while (queue.Count > 0)
                {
                    var rect = (Rect *)queue.Dequeue();

                    Cairo.Rectangle(rect->Height, rect->Width, rect->Y, rect->X, MainContext);
                    Cairo.Rectangle(rect->Height, rect->Width, rect->Y, rect->X, VideoContext);

                    Libc.free((uint)rect);

                    update = true;
                }
                Monitor.ReleaseLock(ref RedrawRectsLock);

                if (update)
                {
                    Cairo.Clip(MainContext);
                    var list = Stacking;
                    Monitor.AcquireLock(ref StackingLock);
                    int count = list.Count;
                    for (int index = 0; index < count; index++)
                    {
                        var win = list[index];
                        Cairo.Save(MainContext);
                        Cairo.Translate(win.Y, win.X, MainContext);
                        Cairo.SetSourceSurface(0, 0, win.Surface, MainContext);
                        Cairo.Paint(MainContext);
                        Cairo.Restore(MainContext);
                    }
                    Monitor.ReleaseLock(ref StackingLock);
                }

                if (update)
                {
                    Cairo.Clip(VideoContext);

                    Cairo.Translate(0, 0, VideoContext);
                    Cairo.SetOperator(Operator.Source, VideoContext);
                    Cairo.SetSourceSurface(0, 0, MainSurface, VideoContext);
                    Cairo.Paint(VideoContext);

                    Cairo.Translate(old_mouse_Y, old_mouse_X, VideoContext);
                    Cairo.SetOperator(Operator.Over, VideoContext);
                    Cairo.SetSourceSurface(0, 0, MouseSurface, VideoContext);
                    Cairo.Paint(VideoContext);
                }

                Cairo.Restore(MainContext);
                Cairo.Restore(VideoContext);

                Task.Switch();
            }
        }
Example #9
0
        // ellipsoid
        LP e_inverse(XY xy)
        {
            LP lp;

            lp.lam = lp.phi = 0;

            double sinphi, tp = 0.0, phi_l = 0.0, halfe = 0.0, halfpi = 0.0;

            double rho = Libc.hypot(xy.x, xy.y);

            switch (mode)
            {
            case stere_mode.OBLIQ:
            case stere_mode.EQUIT:
                tp = 2.0 * Math.Atan2(rho * cosX1, akm1);
                double cosphi = Math.Cos(tp);
                sinphi = Math.Sin(tp);
                if (rho == 0.0)
                {
                    phi_l = Math.Asin(cosphi * sinX1);
                }
                else
                {
                    phi_l = Math.Asin(cosphi * sinX1 + (xy.y * sinphi * cosX1 / rho));
                }
                tp     = Math.Tan(0.5 * (Proj.HALFPI + phi_l));
                xy.x  *= sinphi;
                xy.y   = rho * cosX1 * cosphi - xy.y * sinX1 * sinphi;
                halfpi = Proj.HALFPI;
                halfe  = 0.5 * e;
                break;

            case stere_mode.N_POLE:
                xy.y = -xy.y;
                goto case stere_mode.S_POLE;

            case stere_mode.S_POLE:
                tp     = -rho / akm1;
                phi_l  = Proj.HALFPI - 2.0 * Math.Atan(tp);
                halfpi = -Proj.HALFPI;
                halfe  = -0.5 * e;
                break;
            }

            for (int i = NITER - 1; i >= 0; i++)
            {
                sinphi = e * Math.Sin(phi_l);
                lp.phi = 2.0 * Math.Atan(tp * Math.Pow((1.0 + sinphi) / (1.0 - sinphi), halfe)) - halfpi;
                if (Math.Abs(phi_l - lp.phi) < CONV)
                {
                    if (mode == stere_mode.S_POLE)
                    {
                        lp.phi = -lp.phi;
                    }
                    lp.lam = (xy.x == 0.0 && xy.y == 0.0)?0.0:Math.Atan2(xy.x, xy.y);
                    return(lp);
                }
                phi_l = lp.phi;
            }

            Proj.pj_ctx_set_errno(ctx, -20);
            return(lp);
        }
Example #10
0
        // spheroid
        LP s_inverse(XY xy)
        {
            LP lp;

            lp.lam = lp.phi = 0;

            double rh   = Libc.hypot(xy.x, xy.y);
            double c    = 2.0 * Math.Atan(rh / akm1);
            double sinc = Math.Sin(c);
            double cosc = Math.Cos(c);

            lp.lam = 0.0;
            switch (mode)
            {
            case stere_mode.EQUIT:
                if (Math.Abs(rh) <= EPS10)
                {
                    lp.phi = 0.0;
                }
                else
                {
                    lp.phi = Math.Asin(xy.y * sinc / rh);
                }
                if (cosc != 0.0 || xy.x != 0.0)
                {
                    lp.lam = Math.Atan2(xy.x * sinc, cosc * rh);
                }
                break;

            case stere_mode.OBLIQ:
                if (Math.Abs(rh) <= EPS10)
                {
                    lp.phi = phi0;
                }
                else
                {
                    lp.phi = Math.Asin(cosc * sinX1 + xy.y * sinc * cosX1 / rh);
                }
                c = cosc - sinX1 * Math.Sin(lp.phi);
                if (c != 0.0 || xy.x != 0.0)
                {
                    lp.lam = Math.Atan2(xy.x * sinc * cosX1, c * rh);
                }
                break;

            case stere_mode.N_POLE:
                xy.y = -xy.y;
                goto case stere_mode.S_POLE;

            case stere_mode.S_POLE:
                if (Math.Abs(rh) <= EPS10)
                {
                    lp.phi = phi0;
                }
                else
                {
                    lp.phi = Math.Asin(mode == stere_mode.S_POLE?-cosc:cosc);
                }
                lp.lam = (xy.x == 0.0 && xy.y == 0.0)?0.0:Math.Atan2(xy.x, xy.y);
                break;
            }

            return(lp);
        }
Example #11
0
        // TODO: restructure this function
        // For example posix_spawn from chromium seems to have a
        // maintainable flow: https://chromium.googlesource.com/native_client/nacl-newlib/+/bf66148d14c7fca26b9198dd5dc81e743893bb66/newlib/libc/posix/posix_spawn.c
        private static unsafe int ForkAndExec(
            string filename, string[] argv, string[] envp,
            string cwd, bool useTty, bool redirectStdin,
            bool redirectStdout, bool redirectStderr,
            out int stdin, out int stdout, out int stderr
            )
        {
            byte **argvPtr = null;
            byte **envpPtr = null;

            bool success = true;

            ArrayHelpers.AllocNullTerminatedArray(argv, ref argvPtr);
            ArrayHelpers.AllocNullTerminatedArray(envp, ref envpPtr);

            int[] stdInFds  = new[] { -1, -1 };
            int[] stdOutFds = new[] { -1, -1 };
            int[] stdErrFds = new[] { -1, -1 };
            int   masterFd  = -1;
            int   slaveFd   = -1;

            try
            {
                int inFd, outFd, errFd;

                if (filename == null || argv == null || envp == null)
                {
                    success = false;
                    throw new ArgumentException("Provide the correct arguments");
                }

                if (Libc.access(filename, Libc.X_OK) != 0)
                {
                    success = false;
                    throw new Exception("The given file is not accessible");
                }

                if (useTty)
                {
                    var size = new winsize
                    {
                        ws_col = DEFAULT_WIDTH,
                        ws_row = DEFAULT_HEIGHT
                    };

                    if (Libc.openpty(out masterFd, out slaveFd, IntPtr.Zero, IntPtr.Zero, ref size) == -1)
                    {
                        success = false;
                        throw new Exception("Could not open a new pty");
                    }
                }
                else
                {
                    try
                    {
                        if (redirectStdin)
                        {
                            CreateCloseOnExecPipe(stdInFds);
                        }
                        if (redirectStdout)
                        {
                            CreateCloseOnExecPipe(stdOutFds);
                        }
                        if (redirectStderr)
                        {
                            CreateCloseOnExecPipe(stdErrFds);
                        }
                    }
                    catch (Exception ex)
                    {
                        success = false;
                        throw ex;
                    }
                }

                var pid = Libc.fork();

                if (pid < 0)
                {
                    success = false;
                    Error.ThrowExceptionForLastError();
                }

                if (pid == 0)
                {
                    if (useTty)
                    {
                        Libc.close(masterFd);
                        Libc.setsid();

                        if (Libc.ioctl(slaveFd, Libc.TIOCSCTTY) == -1)
                        {
                            success = false;
                            Error.ThrowExceptionForLastError();
                        }

                        inFd = outFd = errFd = slaveFd;
                    }
                    else
                    {
                        inFd  = stdInFds[READ_END_OF_PIPE];
                        outFd = stdOutFds[WRITE_END_OF_PIPE];
                        errFd = stdErrFds[WRITE_END_OF_PIPE];
                    }

                    // TODO: this code is just horrible and the likely hood introducing bugs here is quite high.
                    // I should refactor this asap. But first I would love to get some more tests in place that
                    // could catch any regressions..
                    if (redirectStdin)
                    {
                        while (Error.ShouldRetrySyscall(Libc.dup2(inFd, Libc.STDIN_FILENO)) && Libc.errno == Libc.EBUSY)
                        {
                            ;
                        }
                    }

                    if (redirectStdout)
                    {
                        while (Error.ShouldRetrySyscall(Libc.dup2(outFd, Libc.STDOUT_FILENO)) && Libc.errno == Libc.EBUSY)
                        {
                            ;
                        }
                    }

                    if (redirectStderr)
                    {
                        while (Error.ShouldRetrySyscall(Libc.dup2(errFd, Libc.STDERR_FILENO)) && Libc.errno == Libc.EBUSY)
                        {
                            ;
                        }
                    }

                    if (!string.IsNullOrEmpty(cwd))
                    {
                        var ret = Libc.chdir(cwd);

                        if (ret == -1)
                        {
                            success = false;
                            Error.ThrowExceptionForLastError();
                        }
                    }

                    Libc.execve(filename, argvPtr, envpPtr);

                    // Exec syscall should never return, and thus we should never get here, if we do then exit immediately
                    Libc._exit(Libc.errno != 0 ? Libc.errno : -1);
                }

                Libc.close(slaveFd);

                if (useTty)
                {
                    stdin  = masterFd;
                    stdout = masterFd;
                    stderr = masterFd;
                }
                else
                {
                    stdin  = stdInFds[WRITE_END_OF_PIPE];
                    stdout = stdOutFds[READ_END_OF_PIPE];
                    stderr = stdErrFds[READ_END_OF_PIPE];
                }

                return(pid);
            }
            finally
            {
                // Regardless of success or failure, close the parent's copy of the child's end of
                // any opened pipes. The parent doesn't need them anymore.
                CloseIfOpen(stdInFds[READ_END_OF_PIPE]);
                CloseIfOpen(stdOutFds[WRITE_END_OF_PIPE]);
                CloseIfOpen(stdErrFds[WRITE_END_OF_PIPE]);

                if (!success)
                {
                    // Cleanup all open fd
                    CloseIfOpen(masterFd);
                    CloseIfOpen(slaveFd);

                    CloseIfOpen(stdInFds[WRITE_END_OF_PIPE]);
                    CloseIfOpen(stdOutFds[READ_END_OF_PIPE]);
                    CloseIfOpen(stdErrFds[READ_END_OF_PIPE]);
                }

                ArrayHelpers.FreeArray(argvPtr, argv.Length);
                ArrayHelpers.FreeArray(envpPtr, envp.Length);
            }
        }
Example #12
0
        private void StartCore()
        {
            var filename = ResolvePath(_fileName);
            var args     = new List <string>
            {
                filename,
            };

            // TODO: figure out what best todo here
            // Problem when first arg is an empty string stuff goes awfully wrong
            // Some things to validate:
            // - Check if this is only a problem for the first arg
            // - Check if this is only a problem when there is just one arg
            // - Is it better to just throw an error?
            foreach (var arg in _argv)
            {
                if (!string.IsNullOrWhiteSpace(arg) && !string.IsNullOrEmpty(arg))
                {
                    args.Add(arg);
                }
            }

            Pid = ForkAndExec(
                filename: filename,
                argv: args.ToArray(),
                envp: GetEnvironmentVariables(_attr.Env),
                cwd: _attr.Dir,
                useTty: _attr.Sys != null ? _attr.Sys.UseTty : false,
                redirectStdin: _attr.RedirectStdin,
                redirectStdout: _attr.RedirectStdout,
                redirectStderr: _attr.RedirectStderr,
                stdin: out var stdin,
                stdout: out var stdout,
                stderr: out var stderr
                );

            if (_attr.RedirectStdin)
            {
                Stdin = new System.IO.StreamWriter(
                    new UnixFileDescriptorStream(stdin)
                    );
            }

            if (_attr.RedirectStdout)
            {
                Stdout = new System.IO.StreamReader(
                    new UnixFileDescriptorStream(stdout)
                    );
            }

            if (_attr.RedirectStderr)
            {
                Stderr = new System.IO.StreamReader(
                    new UnixFileDescriptorStream(stderr)
                    );
            }

            var ret = Libc.waitpid(Pid, out var status, WaitPidOptions.WNOHANG);

            if (ret == 0)
            {
                IsRunning = true;
            }
            else if (ret == Pid)
            {
                IsRunning = false;
                ExitCode  = GetUnixExitCode(status);
            }
        }
Example #13
0
        // ellipsoid
        LP e_inverse(XY xy)
        {
            LP lp;

            lp.lam = lp.phi = 0;

            double ab = 0.0;

            switch (mode)
            {
            case laea_mode.EQUIT:
            case laea_mode.OBLIQ:
                xy.x /= dd;
                xy.y *= dd;
                double rho = Libc.hypot(xy.x, xy.y);
                if (rho < EPS10)
                {
                    lp.lam = 0.0;
                    lp.phi = phi0;
                    return(lp);
                }

                double sCe = 2.0 * Math.Asin(0.5 * rho / rq);
                double cCe = Math.Cos(sCe);
                sCe   = Math.Sin(sCe);
                xy.x *= sCe;

                if (mode == laea_mode.OBLIQ)
                {
                    ab   = cCe * sinb1 + xy.y * sCe * cosb1 / rho;
                    xy.y = rho * cosb1 * cCe - xy.y * sinb1 * sCe;
                }
                else
                {
                    ab   = xy.y * sCe / rho;
                    xy.y = rho * cCe;
                }
                break;

            case laea_mode.N_POLE:
            case laea_mode.S_POLE:
                if (mode == laea_mode.N_POLE)
                {
                    xy.y = -xy.y;
                }
                double q = xy.x * xy.x + xy.y * xy.y;
                if (q == 0)
                {
                    lp.lam = 0.0;
                    lp.phi = phi0;
                    return(lp);
                }

                //q=P.qp-q;
                ab = 1.0 - q / qp;
                if (mode == laea_mode.S_POLE)
                {
                    ab = -ab;
                }
                break;
            }

            lp.lam = Math.Atan2(xy.x, xy.y);
            lp.phi = Proj.pj_authlat(Math.Asin(ab), apa);

            return(lp);
        }
Example #14
0
        public static PJ pj_init_ctx(projCtx ctx, string[] argv)
        {
            ctx.last_errno = 0;

            if (argv.Length <= 0)
            {
                pj_ctx_set_errno(ctx, -1); return(null);
            }

            List <string> start = new List <string>();

            Libc.errno = pj_errno = 0;

            // put arguments into internal linked list
            for (int a = 0; a < argv.Length; a++)
            {
                string curr = pj_mkparam(argv[a]);
                if (curr == null)
                {
                    pj_ctx_set_errno(ctx, Libc.errno); return(null);
                }
                start.Add(curr);
            }

            // check if +init present
            if (pj_param_t(ctx, start, "init"))
            {
                bool   found_def;
                string curr = get_init(ctx, start, pj_param_s(ctx, start, "init"), out found_def);
                if (curr == null || !found_def)
                {
                    if (pj_errno != 0 || Libc.errno != 0)
                    {
                        if (pj_errno == 0)
                        {
                            pj_ctx_set_errno(ctx, Libc.errno);
                        }
                    }
                    else
                    {
                        pj_ctx_set_errno(ctx, -2);
                    }

                    return(null);
                }
            }

            // find projection selection
            string name = pj_param_s(ctx, start, "proj");

            if (name == "")
            {
                pj_ctx_set_errno(ctx, -4); return(null);
            }

            // set defaults, unless inhibited
            if (!pj_param_b(ctx, start, "no_defs"))
            {
                get_defaults(ctx, start, name);
            }

            // allocate projection structure
            PJ PIN = GetPJ(name);

            if (PIN == null)
            {
                pj_ctx_set_errno(ctx, -5); return(null);
            }
            PIN.ctx              = ctx;
            PIN.parameters       = start;
            PIN.is_latlong       = false;
            PIN.is_geocent       = false;
            PIN.is_long_wrap_set = false;
            PIN.long_wrap_center = 0.0;
            PIN.axis             = "enu";

            PIN.gridlist        = null;
            PIN.vgridlist_geoid = null;

            // set datum parameters
            if (pj_datum_set(ctx, start, PIN))
            {
                return(null);
            }

            // set ellipsoid/sphere parameters
            if (pj_ell_set(ctx, start, out PIN.a, out PIN.es))
            {
                return(null);
            }

            PIN.a_orig  = PIN.a;
            PIN.es_orig = PIN.es;

            PIN.e      = Math.Sqrt(PIN.es);
            PIN.ra     = 1.0 / PIN.a;
            PIN.one_es = 1.0 - PIN.es;
            if (PIN.one_es == 0.0)
            {
                pj_ctx_set_errno(ctx, -6); return(null);
            }
            PIN.rone_es = 1.0 / PIN.one_es;

            // Now that we have ellipse information check for WGS84 datum
            if (PIN.datum_type == PJD._3PARAM && PIN.datum_params[0] == 0.0 && PIN.datum_params[1] == 0.0 && PIN.datum_params[2] == 0.0 &&
                PIN.a == 6378137.0 && Math.Abs(PIN.es - 0.006694379990) < 0.000000000050)
            {
                PIN.datum_type = PJD.WGS84;                                                                                 //WGS84/GRS80
            }
            // set PIN.geoc coordinate system
            PIN.geoc = PIN.es != 0.0 && pj_param_b(ctx, start, "geoc");

            // over-ranging flag
            PIN.over = pj_param_b(ctx, start, "over");

            // vertical datum geoid grids
            PIN.has_geoid_vgrids = pj_param_t(ctx, start, "geoidgrids");
            if (PIN.has_geoid_vgrids)            // we need to mark it as used.
            {
                pj_param_s(ctx, start, "geoidgrids");
            }

            // longitude center for wrapping
            PIN.is_long_wrap_set = pj_param_b(ctx, start, "lon_wrap");
            if (PIN.is_long_wrap_set)
            {
                PIN.long_wrap_center = pj_param_r(ctx, start, "lon_wrap");
            }

            // axis orientation
            string axis_arg = pj_param_s(ctx, start, "axis");

            if (axis_arg != null && axis_arg.Length != 0)
            {
                string axis_legal = "ewnsud";
                if (axis_arg.Length != 3)
                {
                    pj_ctx_set_errno(ctx, (int)PJD_ERR.AXIS);
                    return(null);
                }

                if (axis_legal.IndexOf(axis_arg[0]) == -1 || axis_legal.IndexOf(axis_arg[1]) == -1 || (axis_arg.Length >= 3 && axis_legal.IndexOf(axis_arg[2]) == -1))
                {
                    pj_ctx_set_errno(ctx, (int)PJD_ERR.AXIS);
                    return(null);
                }

                // it would be nice to validate we don't have on axis repeated
                PIN.axis = axis_arg;
            }

            // central meridian
            PIN.lam0 = pj_param_r(ctx, start, "lon_0");

            // central latitude
            PIN.phi0 = pj_param_r(ctx, start, "lat_0");

            // false easting and northing
            PIN.x0 = pj_param_d(ctx, start, "x_0");
            PIN.y0 = pj_param_d(ctx, start, "y_0");

            // general scaling factor
            if (pj_param_t(ctx, start, "k_0"))
            {
                PIN.k0 = pj_param_d(ctx, start, "k_0");
            }
            else if (pj_param_t(ctx, start, "k"))
            {
                PIN.k0 = pj_param_d(ctx, start, "k");
            }
            else
            {
                PIN.k0 = 1.0;
            }

            if (PIN.k0 <= 0.0)
            {
                pj_ctx_set_errno(ctx, -31); return(null);
            }

            // set units
            double to_meter = double.NaN;

            name = pj_param_s(ctx, start, "units");
            if (name != "")
            {
                to_meter = GetUnitFactor(name);
                if (double.IsNaN(to_meter))
                {
                    pj_ctx_set_errno(ctx, -7); return(null);
                }
                PIN.to_meter = to_meter;
            }

            if (double.IsNaN(to_meter))
            {
                string s = pj_param_s(ctx, start, "to_meter");
                if (s != "")
                {
                    PIN.to_meter = Libc.strtod(s, out s);
                    if (s.Length > 0 && s[0] == '/')
                    {
                        PIN.to_meter /= Libc.strtod(s.Substring(1), out s);                                         // ratio number
                    }
                    PIN.fr_meter = 1.0 / PIN.to_meter;
                }
                else
                {
                    PIN.to_meter = PIN.fr_meter = 1.0;
                }
            }
            else
            {
                PIN.fr_meter = 1.0 / PIN.to_meter;
            }

            // set vertical units
            double vto_meter = double.NaN;

            name = pj_param_s(ctx, start, "vunits");
            if (name != "")
            {
                vto_meter = GetUnitFactor(name);
                if (double.IsNaN(vto_meter))
                {
                    pj_ctx_set_errno(ctx, -7); return(null);
                }
                PIN.vto_meter = vto_meter;
            }

            if (double.IsNaN(vto_meter))
            {
                string s = pj_param_s(ctx, start, "vto_meter");
                if (s != "")
                {
                    PIN.vto_meter = Libc.strtod(s, out s);
                    if (s.Length > 0 && s[0] == '/')
                    {
                        PIN.vto_meter /= Libc.strtod(s.Substring(1), out s);                                         // ratio number
                    }
                    PIN.vfr_meter = 1.0 / PIN.vto_meter;
                }
                else
                {
                    PIN.vto_meter = PIN.to_meter;
                    PIN.vfr_meter = PIN.fr_meter;
                }
            }
            else
            {
                PIN.vfr_meter = 1.0 / PIN.vto_meter;
            }

            // prime meridian
            name = pj_param_s(ctx, start, "pm");
            if (name != "")
            {
                string value = GetPrimeMeridian(name);

                string next_str;
                if (value == null)
                {
                    double tmp = dmstor_ctx(ctx, name, out next_str);
                    if ((tmp != 0.0 || name[0] == '0') && next_str == "")
                    {
                        value = name;
                    }
                }

                if (value == null)
                {
                    pj_ctx_set_errno(ctx, -46); return(null);
                }
                PIN.from_greenwich = dmstor_ctx(ctx, value, out next_str);
            }
            else
            {
                PIN.from_greenwich = 0.0;
            }

            // projection specific initialization
            PIN = PIN.Init();
            if (PIN == null || ctx.last_errno != 0)
            {
                // cleanup error return
                return(null);
            }

            return(PIN);
        }
Example #15
0
        public static void gen_cheb(bool inverse, ProjFunc proj, string s, PJ P, int iargc, string[] iargv)
        {
            InputFunc input = Proj.dmstor;

            if (inverse)
            {
                input = Libc.strtod;
            }

            int    errin = 0;
            projUV low, upp;

            low.u = low.v = upp.u = upp.v = 0;
            if (s.Length > 0)
            {
                low.u = input(s, out s);
            }
            else
            {
                errin++;
            }
            if (s.Length > 1 && s[0] == ',')
            {
                upp.u = input(s.Substring(1), out s);
            }
            else
            {
                errin++;
            }
            if (s.Length > 1 && s[0] == ',')
            {
                low.v = input(s.Substring(1), out s);
            }
            else
            {
                errin++;
            }
            if (s.Length > 1 && s[0] == ',')
            {
                upp.v = input(s.Substring(1), out s);
            }
            else
            {
                errin++;
            }

            if (errin != 0)
            {
                emess(16, "null or absent -T parameters");
            }

            int NU = 15, NV = 15, res = -1;

            if (s.Length > 1 && s[0] == ',')
            {
                s = s.Substring(1);
                if (s[0] != ',')
                {
                    res = Libc.strtol(s, out s, 10);
                }
            }
            if (s.Length > 1 && s[0] == ',')
            {
                s = s.Substring(1);
                if (s[0] != ',')
                {
                    NU = Libc.strtol(s, out s, 10);
                }
            }
            if (s.Length > 1 && s[0] == ',')
            {
                s = s.Substring(1);
                if (s[0] != ',')
                {
                    NV = Libc.strtol(s, out s, 10);
                }
            }

            bool pwr = s.Length > 0 && s.StartsWith(",P");

            Console.WriteLine("#proj_{0}\n#\trun-line:", pwr?"Power":"Chebyshev");

            // proj execution audit trail
            if (iargc > 0)
            {
                int n = 0;

                for (int i = 0; i < iargc; i++)
                {
                    string arg = iargv[i];
                    if (arg[0] != '+')
                    {
                        if (n == 0)
                        {
                            Console.Write("#");
                            n++;
                        }
                        Console.Write(" " + arg);
                        n += arg.Length + 1;
                        if (n > 50)
                        {
                            Console.WriteLine(); n = 0;
                        }
                    }
                }
                if (n != 0)
                {
                    Console.WriteLine();
                }
            }

            Console.WriteLine("# projection parameters");
            Console.WriteLine("#" + P.DescriptionName);
            Console.WriteLine("#" + P.DescriptionParameters);
            Console.WriteLine("#" + P.DescriptionType);
            Console.WriteLine("#" + P.ToProj4String());

            if (low.u == upp.u || low.v >= upp.v)
            {
                emess(16, "approx. argument range error");
            }
            if (low.u > upp.u)
            {
                low.u -= Proj.TWOPI;
            }
            if (NU < 2 || NV < 2)
            {
                emess(16, "approx. work dimensions ({0} {1}) too small", NU, NV);
            }

            projUV  resid = new projUV();
            Tseries F     = mk_cheby(low, upp, Math.Pow(10.0, res) * 0.5, ref resid, proj, NU, NV, pwr);

            if (F == null)
            {
                emess(16, "generation of approx failed\nreason: {0}\n", Proj.pj_strerrno(Libc.errno));
            }

            Console.WriteLine("{0},{1:G12},{2:G12},{3:G12},{4:G12},{5:G12}", inverse?'I':'F', P.lam0 * Proj.RAD_TO_DEG,
                              low.u * (inverse?1.0:Proj.RAD_TO_DEG), upp.u * (inverse?1.0:Proj.RAD_TO_DEG),
                              low.v * (inverse?1.0:Proj.RAD_TO_DEG), upp.v * (inverse?1.0:Proj.RAD_TO_DEG));

            string fmt;

            if (pwr)
            {
                fmt = "G15";
            }
            else if (res <= 0)
            {
                fmt = string.Format("F{0}", -res + 1);
            }
            else
            {
                fmt = "F0";
            }

            p_series(F, Console.Out, fmt);
            Console.WriteLine("# |u,v| sums {0} {1}\n#end_proj_{2}", resid.u, resid.v, pwr?"Power":"Chebyshev");
        }