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; }
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; }
/*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)); }
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; }