VirtualBox

Changeset 2303 in kBuild for trunk/src/kash/shfile.c


Ignore:
Timestamp:
Mar 1, 2009 7:25:29 AM (16 years ago)
Author:
bird
Message:

kash: new execve implementation for windows. more file ops.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kash/shfile.c

    r2302 r2303  
    7373        return (rc); \
    7474    } while (0)
     75
     76#if K_OS == K_OS_WINDOWS
     77 /* See msdos.h for description. */
     78# define FOPEN              0x01
     79# define FEOFLAG            0x02
     80# define FCRLF              0x04
     81# define FPIPE              0x08
     82# define FNOINHERIT         0x10
     83# define FAPPEND            0x20
     84# define FDEV               0x40
     85# define FTEXT              0x80
     86#endif
    7587
    7688
     
    448460}
    449461
    450 #if K_OS == K_OS_WINDOWS && defined(SHFILE_IN_USE) //&& defined(SH_FORKED_MODE)
     462#if K_OS == K_OS_WINDOWS && defined(SHFILE_IN_USE)
     463
    451464/**
    452465 * Helper for shfork.
     
    461474    shmtxtmp tmp;
    462475    unsigned i;
     476    DWORD fFlag = set ? HANDLE_FLAG_INHERIT : 0;
    463477
    464478    shmtx_enter(&pfdtab->mtx, &tmp);
     
    471485        {
    472486            HANDLE hFile = (HANDLE)pfdtab->tab[i].native;
    473             DWORD  fFlag = (set || !pfdtab->tab[i].cloexec)
    474                          ? HANDLE_FLAG_INHERIT : 0;
    475487            if (set)
    476                 TRACE2((NULL, "  #%d: native=%#x flags=%#x cloexec=%d fFlag=%#x\n",
    477                         i, pfdtab->tab[i].flags, hFile, pfdtab->tab[i].cloexec, fFlag));
    478 
     488                TRACE2((NULL, "  #%d: native=%#x flags=%#x cloexec=%d\n",
     489                        i, pfdtab->tab[i].flags, hFile, pfdtab->tab[i].cloexec));
    479490            if (!SetHandleInformation(hFile, HANDLE_FLAG_INHERIT, fFlag))
    480491            {
     
    499510    shmtx_leave(&pfdtab->mtx, &tmp);
    500511}
    501 #endif
     512
     513/**
     514 * Helper for sh_execve.
     515 *
     516 * This is called before and after CreateProcess. On the first call it
     517 * will mark the non-close-on-exec handles as inheritable and produce
     518 * the startup info for the CRT. On the second call, after CreateProcess,
     519 * it will restore the handle inheritability properties.
     520 *
     521 * @returns Pointer to CRT data if prepare is 1, NULL if prepare is 0.
     522 * @param   pfdtab  The file descriptor table.
     523 * @param   prepare Which call, 1 if before and 0 if after.
     524 * @param   sizep   Where to store the size of the returned data.
     525 * @param   hndls   Where to store the three standard handles.
     526 */
     527void *shfile_exec_win(shfdtab *pfdtab, int prepare, unsigned short *sizep, intptr_t *hndls)
     528{
     529    void       *pvRet;
     530    shmtxtmp    tmp;
     531    unsigned    count;
     532    unsigned    i;
     533
     534    shmtx_enter(&pfdtab->mtx, &tmp);
     535    TRACE2((NULL, "shfile_fork_win:\n"));
     536
     537    count  = pfdtab->size < (0x10000-4) / (1 + sizeof(HANDLE))
     538           ? pfdtab->size
     539           : (0x10000-4) / (1 + sizeof(HANDLE));
     540
     541    if (prepare)
     542    {
     543        size_t      cbData = sizeof(int) + count * (1 + sizeof(HANDLE));
     544        uint8_t    *pbData = sh_malloc(shthread_get_shell(), cbData);
     545        uint8_t    *paf = pbData + sizeof(int);
     546        HANDLE     *pah = (HANDLE *)(paf + count);
     547
     548        *(int *)pbData = count;
     549
     550        i = count;
     551        while (i-- > 0)
     552        {
     553            if (    pfdtab->tab[i].fd == i
     554                &&  !pfdtab->tab[i].cloexec)
     555            {
     556                HANDLE hFile = (HANDLE)pfdtab->tab[i].native;
     557                TRACE2((NULL, "  #%d: native=%#x flags=%#x\n",
     558                        i, pfdtab->tab[i].flags, hFile));
     559
     560                if (!SetHandleInformation(hFile, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
     561                {
     562                    DWORD err = GetLastError();
     563                    assert(0);
     564                }
     565                paf[i] = FOPEN;
     566                if (pfdtab->tab[i].flags & _O_APPEND)
     567                    paf[i] = FAPPEND;
     568                if (pfdtab->tab[i].flags & _O_TEXT)
     569                    paf[i] = FTEXT;
     570                pah[i] = hFile;
     571            }
     572            else
     573            {
     574                paf[i] = 0;
     575                pah[i] = INVALID_HANDLE_VALUE;
     576            }
     577        }
     578
     579        for (i = 0; i < 3; i++)
     580        {
     581            if (    count > i
     582                &&  pfdtab->tab[i].fd == 0)
     583                hndls[i] = pfdtab->tab[i].native;
     584            else
     585                hndls[i] = (intptr_t)INVALID_HANDLE_VALUE;
     586        }
     587
     588        *sizep = (unsigned short)cbData;
     589        pvRet = pbData;
     590    }
     591    else
     592    {
     593        assert(!hndls);
     594        assert(!sizep);
     595        i = count;
     596        while (i-- > 0)
     597        {
     598            if (    pfdtab->tab[i].fd == i
     599                &&  !pfdtab->tab[i].cloexec)
     600            {
     601                HANDLE hFile = (HANDLE)pfdtab->tab[i].native;
     602                if (!SetHandleInformation(hFile, HANDLE_FLAG_INHERIT, 0))
     603                {
     604                    DWORD err = GetLastError();
     605                    assert(0);
     606                }
     607            }
     608        }
     609        pvRet = NULL;
     610    }
     611
     612    shmtx_leave(&pfdtab->mtx, &tmp);
     613    return pvRet;
     614}
     615
     616#endif /* K_OS_WINDOWS */
    502617
    503618
     
    538653    SecurityAttributes.nLength = sizeof(SecurityAttributes);
    539654    SecurityAttributes.lpSecurityDescriptor = NULL;
    540     SecurityAttributes.bInheritHandle = (flags & _O_NOINHERIT) == 0;
     655    SecurityAttributes.bInheritHandle = FALSE;
    541656
    542657    if (flags & _O_CREAT)
     
    599714# endif /* K_OS != K_OS_WINDOWS */
    600715
    601 #elif defined(SH_FORKED_MODE)
     716#else
    602717    fd = open(name, flags, mode);
    603718#endif
     
    619734    SecurityAttributes.nLength = sizeof(SecurityAttributes);
    620735    SecurityAttributes.lpSecurityDescriptor = NULL;
    621     SecurityAttributes.bInheritHandle = TRUE;
     736    SecurityAttributes.bInheritHandle = FALSE;
    622737
    623738    fds[1] = fds[0] = -1;
     
    680795    }
    681796
    682 #elif defined(SH_FORKED_MODE)
     797#else
    683798    rc = pipe(fds);
    684799#endif
     
    688803}
    689804
     805/**
     806 * dup().
     807 */
    690808int shfile_dup(shfdtab *pfdtab, int fd)
    691809{
    692     int rc;
    693 #if defined(SH_FORKED_MODE)
    694     rc = dup(fd);
    695 
    696 #else
    697 #endif
    698 
    699     TRACE2((NULL, "shfile_dup(%d) -> %d [%d]\n", fd, rc, errno));
    700     return rc;
     810    return shfile_fcntl(pfdtab,fd, F_DUPFD, 0);
    701811}
    702812
     
    724834        rc = -1;
    725835
    726 #elif defined(SH_FORKED_MODE)
     836#else
    727837    rc = close(fd);
    728838#endif
     
    758868        rc = -1;
    759869
    760 #elif defined(SH_FORKED_MODE)
     870#else
    761871    rc = read(fd, buf, len);
    762872#endif
     
    790900        rc = -1;
    791901
    792 #elif defined(SH_FORKED_MODE)
     902#else
    793903    rc = write(fd, buf, len);
    794904#endif
     
    823933        rc = -1;
    824934
    825 #elif defined(SH_FORKED_MODE)
     935#else
    826936    rc = lseek(fd, off, whench);
    827937#endif
     
    882992                                    &hNew,
    883993                                    0,
    884                                     TRUE /* bInheritHandle */,
     994                                    FALSE /* bInheritHandle */,
    885995                                    DUPLICATE_SAME_ACCESS))
    886996                    rc = shfile_insert(pfdtab, (intptr_t)hNew, file->flags, arg, "shfile_fcntl");
     
    9061016        rc = -1;
    9071017
    908 #elif defined(SH_FORKED_MODE)
     1018#else
    9091019    rc = fcntl(fd, cmd, arg);
    9101020#endif
     
    9221032int shfile_stat(shfdtab *pfdtab, const char *path, struct stat *pst)
    9231033{
    924 #if defined(SH_FORKED_MODE)
     1034#ifdef SHFILE_IN_USE
     1035    char    abspath[SHFILE_MAX_PATH];
     1036    int     rc;
     1037    rc = shfile_make_path(pfdtab, path, &abspath[0]);
     1038    if (!rc)
     1039    {
     1040# if K_OS == K_OS_WINDOWS
     1041        rc = stat(abspath, pst); /** @todo re-implement stat. */
     1042# else
     1043        rc = stat(abspath, pst);
     1044# endif
     1045    }
     1046    TRACE2((NULL, "shfile_stat(,%s,) -> %d [%d]\n", path, rc, errno));
     1047    return rc;
     1048#else
    9251049    return stat(path, pst);
    926 
    927 #else
    928 #endif
    929 }
    930 
    931 int shfile_lstat(shfdtab *pfdtab, const char *link, struct stat *pst)
    932 {
    933 #if defined(SH_FORKED_MODE)
    934 # ifdef _MSC_VER
    935     return stat(link, pst);
     1050#endif
     1051}
     1052
     1053int shfile_lstat(shfdtab *pfdtab, const char *path, struct stat *pst)
     1054{
     1055    int     rc;
     1056#ifdef SHFILE_IN_USE
     1057    char    abspath[SHFILE_MAX_PATH];
     1058
     1059    rc = shfile_make_path(pfdtab, path, &abspath[0]);
     1060    if (!rc)
     1061    {
     1062# if K_OS == K_OS_WINDOWS
     1063        rc = stat(abspath, pst); /** @todo implement lstat. */
    9361064# else
    937     return lstat(link, pst);
    938 # endif
    939 
    940 #else
    941 #endif
    942 }
    943 
     1065        rc = lstat(abspath, pst);
     1066# endif
     1067    }
     1068#else
     1069    rc = stat(path, pst);
     1070#endif
     1071    TRACE2((NULL, "shfile_stat(,%s,) -> %d [%d]\n", path, rc, errno));
     1072    return rc;
     1073}
     1074
     1075/**
     1076 * chdir().
     1077 */
    9441078int shfile_chdir(shfdtab *pfdtab, const char *path)
    9451079{
    946 #if defined(SH_FORKED_MODE)
    947 # ifdef _MSC_VER //???
    948     return chdir(path);
    949 # else
    950     return chdir(path);
    951 # endif
    952 
    953 #else
    954 #endif
    955 }
    956 
    957 char *shfile_getcwd(shfdtab *pfdtab, char *buf, int len)
    958 {
    959 #if defined(SH_FORKED_MODE)
    960     return getcwd(buf, len);
    961 
    962 #else
    963 #endif
     1080    shinstance *psh = shthread_get_shell();
     1081    int         rc;
     1082#ifdef SHFILE_IN_USE
     1083    char        abspath[SHFILE_MAX_PATH];
     1084
     1085    rc = shfile_make_path(pfdtab, path, &abspath[0]);
     1086    if (!rc)
     1087    {
     1088        char *abspath_copy = sh_strdup(psh, abspath);
     1089        char *free_me = abspath_copy;
     1090        rc = chdir(path);
     1091        if (!rc)
     1092        {
     1093            shmtxtmp    tmp;
     1094            shmtx_enter(&pfdtab->mtx, &tmp);
     1095
     1096            free_me = pfdtab->cwd;
     1097            pfdtab->cwd = abspath_copy;
     1098
     1099            shmtx_leave(&pfdtab->mtx, &tmp);
     1100        }
     1101        sh_free(psh, free_me);
     1102    }
     1103#else
     1104    rc = chdir(path);
     1105#endif
     1106
     1107    TRACE2((psh, "shfile_chdir(,%s) -> %d [%d]\n", path, rc, errno));
     1108    return rc;
     1109}
     1110
     1111/**
     1112 * getcwd().
     1113 */
     1114char *shfile_getcwd(shfdtab *pfdtab, char *buf, int size)
     1115{
     1116    char       *ret;
     1117#ifdef SHFILE_IN_USE
     1118
     1119    ret = NULL;
     1120    if (buf && !size)
     1121        errno = -EINVAL;
     1122    else
     1123    {
     1124        size_t      cwd_size;
     1125        shmtxtmp    tmp;
     1126        shmtx_enter(&pfdtab->mtx, &tmp);
     1127
     1128        cwd_size = strlen(pfdtab->cwd) + 1;
     1129        if (buf)
     1130        {
     1131            if (cwd_size <= (size_t)size)
     1132                ret = memcpy(buf, pfdtab->cwd, cwd_size);
     1133            else
     1134                errno = ERANGE;
     1135        }
     1136        else
     1137        {
     1138            if (size < cwd_size)
     1139                size = (int)cwd_size;
     1140            ret = sh_malloc(shthread_get_shell(), size);
     1141            if (ret)
     1142                ret = memcpy(ret, pfdtab->cwd, cwd_size);
     1143            else
     1144                errno = ENOMEM;
     1145        }
     1146
     1147        shmtx_leave(&pfdtab->mtx, &tmp);
     1148    }
     1149#else
     1150    ret = getcwd(buf, size);
     1151#endif
     1152
     1153    TRACE2((NULL, "shfile_getcwd(,%p,%d) -> %s [%d]\n", buf, size, ret, errno));
     1154    return ret;
    9641155}
    9651156
    9661157int shfile_access(shfdtab *pfdtab, const char *path, int type)
    9671158{
    968 #if defined(SH_FORKED_MODE)
    9691159# ifdef _MSC_VER
    9701160    type &= ~X_OK;
     
    9731163    return access(path, type);
    9741164# endif
    975 
    976 #else
    977 #endif
    978 }
    979 
     1165}
     1166
     1167/**
     1168 * isatty()
     1169 */
    9801170int shfile_isatty(shfdtab *pfdtab, int fd)
    9811171{
    982     int rc;
    983 
    984 #if defined(SH_FORKED_MODE)
     1172    int         rc;
     1173#ifdef SHFILE_IN_USE
     1174    shmtxtmp    tmp;
     1175    shfile     *file = shfile_get(pfdtab, fd, &tmp);
     1176    if (file)
     1177    {
     1178# if K_OS == K_OS_WINDOWS
     1179        errno = ENOSYS;
     1180# else
     1181        rc = isatty(file->native);
     1182# endif
     1183        shfile_put(pfdtab, file, &tmp);
     1184    }
     1185    else
     1186        rc = 0;
     1187#else
    9851188    rc = isatty(fd);
    986 #else
    9871189#endif
    9881190
     
    9911193}
    9921194
    993 
     1195/**
     1196 * fcntl F_SETFD / FD_CLOEXEC.
     1197 */
    9941198int shfile_cloexec(shfdtab *pfdtab, int fd, int closeit)
    9951199{
    996     int rc;
    997 
    998 #if defined(SH_FORKED_MODE)
    999 # ifdef _MSC_VER
    1000     errno = ENOSYS;
    1001     rc = -1;
    1002 # else
     1200    int         rc;
     1201#ifdef SHFILE_IN_USE
     1202    shmtxtmp    tmp;
     1203    shfile     *file = shfile_get(pfdtab, fd, &tmp);
     1204    if (file)
     1205    {
     1206        file->cloexec = !!(closeit);
     1207        shfile_put(pfdtab, file, &tmp);
     1208    }
     1209    else
     1210        rc = -1;
     1211#else
    10031212    rc = fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0)
    10041213                          | (closeit ? FD_CLOEXEC : 0));
    1005 # endif
    1006 
    1007 #else
    10081214#endif
    10091215
     
    10151221int shfile_ioctl(shfdtab *pfdtab, int fd, unsigned long request, void *buf)
    10161222{
    1017     int rc;
    1018 
    1019 #if defined(SH_FORKED_MODE)
    1020 # ifdef _MSC_VER
    1021     errno = ENOSYS;
    1022     rc = -1;
     1223    int         rc;
     1224#ifdef SHFILE_IN_USE
     1225    shmtxtmp    tmp;
     1226    shfile     *file = shfile_get(pfdtab, fd, &tmp);
     1227    if (file)
     1228    {
     1229# if K_OS == K_OS_WINDOWS
     1230        rc = -1;
     1231        errno = ENOSYS;
    10231232# else
     1233        rc = ioctl(file->native, request, buf);
     1234# endif
     1235        shfile_put(pfdtab, file, &tmp);
     1236    }
     1237    else
     1238        rc = -1;
     1239#else
    10241240    rc = ioctl(fd, request, buf);
    1025 # endif
    1026 
    1027 #else
    10281241#endif
    10291242
     
    10351248mode_t shfile_get_umask(shfdtab *pfdtab)
    10361249{
    1037 #if defined(SH_FORKED_MODE)
     1250    /** @todo */
    10381251    return 022;
    1039 
    1040 #else
    1041 #endif
    10421252}
    10431253
    10441254void shfile_set_umask(shfdtab *pfdtab, mode_t mask)
    10451255{
     1256    /** @todo */
    10461257    (void)mask;
    10471258}
     
    10501261shdir *shfile_opendir(shfdtab *pfdtab, const char *dir)
    10511262{
    1052 #if defined(SH_FORKED_MODE)
    1053 # ifdef _MSC_VER
     1263#ifdef SHFILE_IN_USE
    10541264    errno = ENOSYS;
    10551265    return NULL;
    1056 # else
     1266#else
    10571267    return (shdir *)opendir(dir);
    1058 # endif
    1059 
    1060 #else
    10611268#endif
    10621269}
     
    10641271shdirent *shfile_readdir(struct shdir *pdir)
    10651272{
    1066 #if defined(SH_FORKED_MODE)
    1067 # ifdef _MSC_VER
     1273#ifdef SHFILE_IN_USE
    10681274    errno = ENOSYS;
    10691275    return NULL;
    1070 # else
     1276#else
    10711277    struct dirent *pde = readdir((DIR *)pdir);
    10721278    return pde ? (shdirent *)&pde->d_name[0] : NULL;
    1073 # endif
    1074 
    1075 #else
    10761279#endif
    10771280}
     
    10791282void shfile_closedir(struct shdir *pdir)
    10801283{
    1081 #if defined(SH_FORKED_MODE)
    1082 # ifdef _MSC_VER
     1284#ifdef SHFILE_IN_USE
    10831285    errno = ENOSYS;
    1084 # else
     1286#else
    10851287    closedir((DIR *)pdir);
    1086 # endif
    1087 
    1088 #else
    1089 #endif
    1090 }
     1288#endif
     1289}
     1290
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette