Exemplo n.º 1
0
long xexec(WORD flag, char *path, char *tail, char *env)
{
    PD *p;
    PGMHDR01 hdr;
    MD *m, *env_md;
    LONG rc;
    long max, needed;
    FH fh;

    KDEBUG(("BDOS xexec: flag or mode = %d\n",flag));

    /* first branch - actions that do not require loading files */
    switch(flag) {
#if DETECT_NATIVE_FEATURES
    case PE_RELOCATE:   /* internal use only, see bootstrap() in bios/bios.c */
        p = (PD *) tail;
        rc = kpgm_relocate(p, (long)path);
        if (rc) {
            KDEBUG(("BDOS xexec: kpgm_reloc returned %ld (0x%lx)\n",rc,rc));
            return rc;
        }

        /* invalidate instruction cache for the TEXT segment only
         * programs that jump into their DATA, BSS or HEAP are kindly invited
         * to do their cache management themselves.
         */
        invalidate_instruction_cache( p+1, p->p_tlen);

        return (long)p;
#endif
    case PE_BASEPAGE:           /* just create a basepage */
        path = (char *) 0L;     /* (same as basepage+flags with flags set to zero) */
    /* drop thru */
    case PE_BASEPAGEFLAGS:      /* create a basepage, respecting the flags */
        env_md = alloc_env(env);
        if (env_md == NULL) {
            KDEBUG(("BDOS xexec: not enough memory!\n"));
            return ENSMEM;
        }
        m = alloc_tpa((ULONG)path,sizeof(PD),&max);

        if (m == NULL) {    /* not even enough memory for basepage */
            freeit(env_md, &pmd);
            KDEBUG(("BDOS xexec: No memory for basepage\n"));
            return ENSMEM;
        }

        p = (PD *) m->m_start;

        /* memory ownership */
        m->m_own = env_md->m_own = run;

        /* initialize the PD */
        init_pd_fields(p, tail, max, env_md);
        p->p_flags = (ULONG)path;   /* set the flags */
        init_pd_files(p);

        return (long)p;
    case PE_GOTHENFREE:
        /* set the owner of the memory to be this process */
        p = (PD *) tail;
        set_owner(p, p, find_mpb(p));
        set_owner(p->p_env, p, find_mpb(p->p_env));
    /* fall through */
    case PE_GO:
        p = (PD *) tail;
        proc_go(p);
        /* should not return ? */
        return (long)p;
    case PE_LOADGO:
    case PE_LOAD:
        break;
    default:
        return EINVFN;
    }

    /* we now need to load a file */
    KDEBUG(("BDOS xexec: trying to find the command ...\n"));
    if (ixsfirst(path,0,0L)) {
        KDEBUG(("BDOS xexec: command %s not found!!!\n",path));
        return EFILNF;      /*  file not found      */
    }

    /* load the header - if I/O error occurs now, the longjmp in rwabs will
     * jump directly back to bdosmain.c, which is not a problem because
     * we haven't allocated anything yet.
     */
    rc = kpgmhdrld(path, &hdr, &fh);
    if (rc) {
        KDEBUG(("BDOS xexec: kpgmhdrld returned %ld (0x%lx)\n",rc,rc));
        return rc;
    }

    /* allocate the environment first, always in ST RAM */
    env_md = alloc_env(env);
    if (env_md == NULL) {
        KDEBUG(("BDOS xexec: not enough memory!\n"));
        return ENSMEM;
    }

    /* allocate the basepage depending on memory policy */
    needed = hdr.h01_tlen + hdr.h01_dlen + hdr.h01_blen + sizeof(PD);
    m = alloc_tpa(hdr.h01_flags,needed,&max);

    /* if failed, free env_md and return */
    if (m == NULL) {
        KDEBUG(("BDOS xexec: no memory for TPA\n"));
        freeit(env_md, &pmd);
        return ENSMEM;
    }

    p = (PD *) m->m_start;

    /* memory ownership - the owner is either the new process being created,
     * or the parent
     */
    if (flag == PE_LOADGO) {
        m->m_own = env_md->m_own = p;
    } else {
        m->m_own = env_md->m_own = run;
    }

    /* initialize the fields in the PD structure */
    init_pd_fields(p, tail, max, env_md);

    /* set the flags (must be done after init_pd) */
    p->p_flags = hdr.h01_flags;

    /* use static variable to avoid the obscure longjmp warning */
    cur_p = p;
    cur_m = m;
    cur_env_md = env_md;

    /* we have now allocated memory, so we need to intercept longjmp. */
    memcpy(bakbuf, errbuf, sizeof(errbuf));
    if (setjmp(errbuf)) {

        KDEBUG(("Error and longjmp in xexec()!\n"));

        /* free any memory allocated yet */
        freeit(cur_env_md, &pmd);
        freeit(cur_m, find_mpb(cur_m->m_start));

        /* we still have to jump back to bdosmain.c so that the proper error
         * handling can occur.
         */
        longjmp(bakbuf, 1);
    }

    /* now, load the rest of the program and perform relocation */
    rc = kpgmld(cur_p, fh, &hdr);
    if (rc) {
        KDEBUG(("BDOS xexec: kpgmld returned %ld (0x%lx)\n",rc,rc));
        /* free any memory allocated yet */
        freeit(cur_env_md, &pmd);
        freeit(cur_m, find_mpb(cur_m->m_start));

        return rc;
    }

    /* at this point the program has been correctly loaded in memory, and
     * more I/O errors cannot occur, so it is safe now to finish initializing
     * the new process.
     */
    init_pd_files(cur_p);

    /* invalidate instruction cache for the TEXT segment only
     * programs that jump into their DATA, BSS or HEAP are kindly invited
     * to do their cache management themselves.
     */
    invalidate_instruction_cache(((char *)cur_p) + sizeof(PD), hdr.h01_tlen);

    if (flag != PE_LOAD)
        proc_go(cur_p);
    return (long)cur_p;
}
Exemplo n.º 2
0
long xsfirst(char *name, int att)
{
        long    result;
        DTAINFO *dt;                                            /* M01.01.1209.01 */

        dt = (DTAINFO *)(run->p_xdta);                          /* M01.01.1209.01 */

        /* set an indication of 'uninitialized DTA' */
        dt->dt_dnd = (DND*)NULLPTR;                                     /* M01.01.1209.01 */

#if DBGFSDIR
        kprintf("\nxsfirst(%s, DTA=%08lx)", name, (long)dt);
#endif
        result = ixsfirst(name , att , dt);                   /* M01.01.1209.01 */

                /* check whether the name is a search mask or a pure filename */
                {
                        int     is_mask;
                        char    *n_char;
                        register int i;

                        is_mask = 0;
                        n_char = &dt->dt_name[0];
                        for (i=0; i < 11 ; i++) {
                                if ( *n_char == '*' || *n_char == '?' ) {
                                        is_mask = 1;
                                        break;
                                }
                                n_char++;
                        }

#if DBGFSDIR
                        kprintf("\nxsfirst(DTA->dt_name %s DND=%08lx)", dt->dt_name, (long)dt->dt_dnd);
#endif
                        /* no lock is needed on error or in case of the filename */
                        if ( result < 0 || is_mask == 0 )
                                return result;

                        /* lock the directory if success */

                        /* search whether it is locked or not */
                        for (i = 1; i < NCURDIR; i++)
                                if (diruse[i] && dirtbl[i] == dt->dt_dnd)
                                        break;

                        /* if not search for free entry */
                        if (i == NCURDIR) {
                                for (i = 1; i < NCURDIR; i++)
                                        if (!diruse[i])
                                                break;
                        }

                        /* no empty entry found nor locked - no system memory */
                        if (i == NCURDIR)
                                return (ENSMEM);

                        diruse[i]++;
                        dirtbl[i] = dt->dt_dnd;

#if DBGFSDIR
                        kprintf("\nxsfirst(DND=%08lx lock %d [at %d])", (long)dt->dt_dnd, diruse[i], i);
#endif
                }

                return result;
}
Exemplo n.º 3
0
/*ARGSUSED*/
long xrename(int n, char *p1, char *p2)
{
        register OFD *fd2;
        OFD     *f1,*fd;
        FCB     *f;
        DND     *dn1,*dn2;
        const char *s1,*s2;
        char    buf[11];
        int     hnew,att;
        long    rc, h1;

        if (!ixsfirst(p2,0,(DTAINFO *)0L))
                return(EACCDN);

        if ((long)(dn1 = findit(p1,&s1,0)) < 0)          /* M01.01.1212.01 */
                return( (long)dn1 );
        if (!dn1)                                        /* M01.01.1214.01 */
                return( EPTHNF );

        if ((long)(dn2 = findit(p2,&s2,0)) < 0)          /* M01.01.1212.01 */
                return( (long)dn2 );
        if (!dn2)                                        /* M01.01.1214.01 */
                return( EPTHNF );

        if (contains_illegal_characters(s2))
                return( EACCDN ) ;

        if ((h1 = xopen(p1, 2)) < 0L)
                return (h1);

        f1 = getofd ((int)h1);

        fd = f1->o_dirfil;
        buf[0] = 0xe5;
        ixlseek(fd,f1->o_dirbyt);

        if (dn1 != dn2)
        {
                /* get old attribute */
                f = (FCB *) ixread(fd,32L,NULLPTR);
                att = f->f_attrib;
                /* erase (0xe5) old file */
                ixlseek(fd,f1->o_dirbyt);
                ixwrite(fd,1L,buf);

                /* copy time/date/clust, etc. */

                ixlseek(fd,f1->o_dirbyt + 22);
                ixread(fd,10L,buf);
                hnew = xcreat(p2,att);
                fd2 = getofd(hnew);
                ixlseek(fd2->o_dirfil,fd2->o_dirbyt + 22);
                ixwrite(fd2->o_dirfil,10L,buf);
                fd2->o_flag &= ~O_DIRTY;
                xclose(hnew);
                ixclose(fd2->o_dirfil,CL_DIR);
        }
        else
        {
                builds(s2,buf);
                ixwrite(fd,11L,buf);
        }

        if ((rc = xclose((int)h1)) < 0L)
                return(rc);

        return(ixclose(fd,CL_DIR));
}
Exemplo n.º 4
0
long xexec(WORD flag, char *path, char *tail, char *env)
{
    PD *p;
    PGMHDR01 hdr;
    MD *m, *env_md;
    LONG rc;
    long max, needed;
    FH fh;

    D(("BDOS: xexec - flag or mode = %d\n", flag));

    /* first branch - actions that do not require loading files */
    switch(flag) {
    case PE_RELOCATE: 
        p = (PD *) tail;
        rc = kpgm_relocate(p, (long)path);
        if(rc) {
            D(("BDOS: xexec - kpgm_relloc returned %ld (0x%lx)\n", rc, rc));
            return(rc);
        }

        /* invalidate instruction cache for the TEXT segment only
         * programs that jump into their DATA, BSS or HEAP are kindly invited 
         * to do their cache management themselves.
         */
        invalidate_icache( p+1, p->p_tlen);

        return (long) p;
    case PE_BASEPAGE:        
        /* just create a basepage */
        env_md = alloc_env(env);
        if(env_md == NULL) {
            D(("xexec: Not Enough Memory!\n"));
            return(ENSMEM);
        }
        max = (long) ffit(-1L, &pmd); 
        if(max >= sizeof(PD)) {
            m = ffit(max, &pmd);
            p = (PD *) m->m_start;
        } else {
            /* not even enough memory for basepage */
            freeit(env_md, &pmd);
            D(("xexec: No memory for TPA\n"));
            return(ENSMEM);
        }
        /* memory ownership */
        m->m_own = env_md->m_own = run;

        /* initialize the PD */
        init_pd_fields(p, tail, max, env_md);
        init_pd_files(p);

        return (long) p;
    case PE_GOTHENFREE:
        /* set the owner of the memory to be this process */
        p = (PD *) tail;
        set_owner(p, p, find_mpb(p));
        set_owner(p->p_env, p, find_mpb(p->p_env));
        /* fall through */
    case PE_GO:
        p = (PD *) tail;
        proc_go(p);
        /* should not return ? */
        return (long)p;
    case PE_LOADGO:
    case PE_LOAD:
        break;
    default:
        return EINVFN;
    }
    
    /* we now need to load a file */
    D(("BDOS: xexec - trying to find the command ...\n"));
    if (ixsfirst(path,0,0L)) {
        D(("BDOS: Command %s not found!!!\n", path));
        return(EFILNF);     /*  file not found      */
    }

    /* load the header - if IO error occurs now, the longjmp in rwabs will
     * jump directly back to bdosmain.c, which is not a problem because
     * we haven't allocated anything yet.
     */
    rc = kpgmhdrld(path, &hdr, &fh);
    if(rc) {
        D(("BDOS: xexec - kpgmhdrld returned %ld (0x%lx)\n", rc, rc));
        return(rc);
    }

    /* allocate the environment first, always in ST RAM */
    env_md = alloc_env(env);
    if ( env_md == NULL ) {
        D(("xexec: Not Enough Memory!\n"));
        return(ENSMEM);
    }
    
    /* allocate the basepage depending on memory policy */
    needed = hdr.h01_tlen + hdr.h01_dlen + hdr.h01_blen + sizeof(PD);
    max = 0;
        
    /* first try */
    p = NULL;
    m = NULL;
#if CONF_WITH_ALT_RAM
    if(has_alt_ram && (hdr.h01_flags & PF_TTRAMLOAD)) {
        /* use alternate ram preferably */
        max = (long) ffit(-1L, &pmdalt); 
        if(max >= needed) {
            m = ffit(max, &pmdalt);
            p = (PD *) m->m_start;
        } 
    }
#endif
    /* second try */
    if(p == NULL) {
        max = (long) ffit(-1L, &pmd); 
        if(max >= needed) {
            m = ffit(max, &pmd);
            p = (PD *) m->m_start;
        } 
    }
    /* still failed? free env_md and return */
    if(p == NULL) {
        D(("xexec: No memory for TPA\n"));
        freeit(env_md, &pmd);
        return(ENSMEM);
    }
    assert(m != NULL);

    /* memory ownership - the owner is either the new process being created,
     * or the parent 
     */
    if(flag == PE_LOADGO) {
        m->m_own = env_md->m_own = p;
    } else {
        m->m_own = env_md->m_own = run;
    }   

    /* initialize the fields in the PD structure */
    init_pd_fields(p, tail, max, env_md);
    
    /* set the flags (must be done after init_pd) */
    p->p_flags = hdr.h01_flags;

    /* use static variable to avoid the obscure longjmp warning */
    cur_p = p;
    cur_m = m;
    cur_env_md = env_md;

    /* we have now allocated memory, so we need to intercept longjmp. */
    memcpy(bakbuf, errbuf, sizeof(errbuf));
    if ( setjmp(errbuf) ) {

        kprintf("Error and longjmp in xexec()!\n");

        /* free any memory allocated yet */
        freeit(cur_env_md, &pmd);
        freeit(cur_m, find_mpb((void *)cur_m->m_start));
        
        /* we still have to jump back to bdosmain.c so that the proper error
         * handling can occur.
         */
        longjmp(bakbuf, 1);
    }

    /* now, load the rest of the program and perform relocation */
    rc = kpgmld(cur_p, fh, &hdr);
    if ( rc ) {
        D(("BDOS: xexec - kpgmld returned %ld (0x%lx)\n", rc, rc));
        /* free any memory allocated yet */
        freeit(cur_env_md, &pmd);
        freeit(cur_m, find_mpb((void *)cur_m->m_start));
    
        return rc;
    }

    /* at this point the program has been correctly loaded in memory, and 
     * more IO errors cannot occur, so it is safe now to finish initializing
     * the new process.
     */
    init_pd_files(cur_p);
    
    /* invalidate instruction cache for the TEXT segment only
     * programs that jump into their DATA, BSS or HEAP are kindly invited 
     * to do their cache management themselves.
     */
    invalidate_icache(((char *)cur_p) + sizeof(PD), hdr.h01_tlen);

    if(flag != PE_LOAD)
        proc_go(cur_p);
    return (long) cur_p;
}