Annotation of uae/src/od-win32/posixemu.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * UAE - The Un*x Amiga Emulator
                      3:  *
                      4:  * Win32 interface
                      5:  *
                      6:  * Copyright 1997 Mathias Ortmann
                      7:  */
                      8: 
                      9: #ifdef __GNUC__
                     10: #define __int64 long long
                     11: #include "machdep/winstuff.h"
                     12: #else
                     13: #include <windows.h>
                     14: #include <ddraw.h>
                     15: #include <stdlib.h>
                     16: #include <stdarg.h>
                     17: #include <commctrl.h>
                     18: #include <commdlg.h>
                     19: #include <stdio.h>
                     20: #include <fcntl.h>
                     21: #include <sys/stat.h>
                     22: #include <io.h>
                     23: #endif
                     24: 
                     25: #include "config.h"
                     26: #include "sysconfig.h"
                     27: #include "sysdeps.h"
                     28: #include "options.h"
                     29: #include "memory.h"
                     30: #include "osdep/win32.h"
                     31: 
                     32: /* stdioemu, posixemu, mallocemu, and various file system helper routines */
                     33: static DWORD lasterror;
                     34: 
                     35: static int isillegal (unsigned char *str)
                     36: {
                     37:     unsigned char a = *str, b = str[1], c = str[2];
                     38: 
                     39:     if (a >= 'a' && a <= 'z')
                     40:        a &= ~' ';
                     41:     if (b >= 'a' && b <= 'z')
                     42:        b &= ~' ';
                     43:     if (c >= 'a' && c <= 'z')
                     44:        c &= ~' ';
                     45: 
                     46:     return (a == 'A' && b == 'U' && c == 'X' ||
                     47:            a == 'C' && b == 'O' && c == 'N' ||
                     48:            a == 'P' && b == 'R' && c == 'N' ||
                     49:            a == 'N' && b == 'U' && c == 'L');
                     50: }
                     51: 
                     52: static int checkspace (char *str, char s, char d)
                     53: {
                     54:     char *ptr = str;
                     55: 
                     56:     while (*ptr && *ptr == s)
                     57:        ptr++;
                     58: 
                     59:     if (!*ptr || *ptr == '/' || *ptr == '\\') {
                     60:        while (str < ptr)
                     61:            *(str++) = d;
                     62:        return 0;
                     63:     }
                     64:     return 1;
                     65: }
                     66: 
                     67: /* This is sick and incomplete... in the meantime, I have discovered six new illegal file name formats
                     68:  * M$ sucks! */
                     69: void fname_atow (char *src, char *dst, int size)
                     70: {
                     71:     char *lastslash = dst, *strt = dst;
                     72:     int i, j;
                     73: 
                     74:     while (size-- > 0) {
                     75:        if (!(*dst = *src++))
                     76:            break;
                     77: 
                     78:        if (*dst == '~' || *dst == '|' || *dst == '*' || *dst == '?') {
                     79:            if (size > 2) {
                     80:                sprintf (dst, "~%02x", *dst);
                     81:                size -= 2;
                     82:                dst += 2;
                     83:            }
                     84:        } else if (*dst == '/') {
                     85:            if (checkspace (lastslash, ' ', 0xa0) && (dst - lastslash == 3 || (dst - lastslash > 3 && lastslash[3] == '.')) && isillegal (lastslash)) {
                     86:                i = dst - lastslash - 3;
                     87:                dst++;
                     88:                for (j = i + 1; j--; dst--)
                     89:                    *dst = dst[-1];
                     90:                *(dst++) = 0xa0;
                     91:                dst += i;
                     92:                size--;
                     93:            } else if (*lastslash == '.' && (dst - lastslash == 1 || lastslash[1] == '.' && dst - lastslash == 2) && size) {
                     94:                *(dst++) = 0xa0;
                     95:                size--;
                     96:            }
                     97:            *dst = '\\';
                     98:            lastslash = dst + 1;
                     99:        }
                    100:        dst++;
                    101:     }
                    102: 
                    103:     if (checkspace (lastslash, ' ', 0xa0) && (dst - lastslash == 3 || (dst - lastslash > 3 && lastslash[3] == '.')) && isillegal (lastslash) && size > 1) {
                    104:        i = dst - lastslash - 3;
                    105:        dst++;
                    106:        for (j = i + 1; j--; dst--)
                    107:            *dst = dst[-1];
                    108:        *(dst++) = 0xa0;
                    109:     } else if (!strcmp (lastslash, ".") || !strcmp (lastslash, ".."))
                    110:        strcat (lastslash, "\xa0");
                    111: }
                    112: 
                    113: int getdiskfreespace (char *name, int *f_blocks, int *f_bavail, int *f_bsize)
                    114: {
                    115:     char buf1[1024];
                    116:     char buf2[1024];
                    117:     DWORD SectorsPerCluster;
                    118:     DWORD BytesPerSector;
                    119:     DWORD NumberOfFreeClusters;
                    120:     DWORD TotalNumberOfClusters;
                    121: 
                    122:     fname_atow (name, buf1, sizeof buf1);
                    123: 
                    124:     GetFullPathName (buf1, sizeof buf2, buf2, NULL);
                    125: 
                    126:     buf2[3] = 0;
                    127: 
                    128:     if (!GetDiskFreeSpace (buf2, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters)) {
                    129:        lasterror = GetLastError ();
                    130:        return FALSE;
                    131:     }
                    132:     *f_blocks = TotalNumberOfClusters;
                    133:     *f_bavail = NumberOfFreeClusters;
                    134:     *f_bsize = SectorsPerCluster * BytesPerSector;
                    135: 
                    136:     return TRUE;
                    137: }
                    138: 
                    139: /* Translate lasterror to valid AmigaDOS error code
                    140:  * The mapping is probably not 100% correct yet */
                    141: long dos_errno (void)
                    142: {
                    143:     int i;
                    144: 
                    145:     static DWORD errtbl[][2] =
                    146:     {
                    147:        {ERROR_FILE_NOT_FOUND, 205},    /* 2 */
                    148:        {ERROR_PATH_NOT_FOUND, 205},    /* 3 */
                    149:        {ERROR_SHARING_VIOLATION, 202},
                    150:        {ERROR_ACCESS_DENIED, 223},     /* 5 */
                    151:        {ERROR_ARENA_TRASHED, 103},     /* 7 */
                    152:        {ERROR_NOT_ENOUGH_MEMORY, 103},         /* 8 */
                    153:        {ERROR_INVALID_BLOCK, 219},     /* 9 */
                    154:        {ERROR_INVALID_DRIVE, 204},     /* 15 */
                    155:        {ERROR_CURRENT_DIRECTORY, 214},         /* 16 */
                    156:        {ERROR_NO_MORE_FILES, 232},     /* 18 */
                    157:        {ERROR_LOCK_VIOLATION, 214},    /* 33 */
                    158:        {ERROR_BAD_NETPATH, 204},       /* 53 */
                    159:        {ERROR_NETWORK_ACCESS_DENIED, 214},     /* 65 */
                    160:        {ERROR_BAD_NET_NAME, 204},      /* 67 */
                    161:        {ERROR_FILE_EXISTS, 203},       /* 80 */
                    162:        {ERROR_CANNOT_MAKE, 214},       /* 82 */
                    163:        {ERROR_FAIL_I24, 223},  /* 83 */
                    164:        {ERROR_DRIVE_LOCKED, 202},      /* 108 */
                    165:        {ERROR_DISK_FULL, 221},         /* 112 */
                    166:        {ERROR_NEGATIVE_SEEK, 219},     /* 131 */
                    167:        {ERROR_SEEK_ON_DEVICE, 219},    /* 132 */
                    168:        {ERROR_DIR_NOT_EMPTY, 216},     /* 145 */
                    169:        {ERROR_ALREADY_EXISTS, 203},    /* 183 */
                    170:        {ERROR_FILENAME_EXCED_RANGE, 205},      /* 206 */
                    171:        {ERROR_NOT_ENOUGH_QUOTA, 221},  /* 1816 */
                    172:        {ERROR_DIRECTORY, 212}};
                    173: 
                    174:     for (i = sizeof (errtbl) / sizeof (errtbl[0]); i--;) {
                    175:        if (errtbl[i][0] == lasterror)
                    176:            return errtbl[i][1];
                    177:     }
                    178:     return 236;
                    179: }
                    180: 
                    181: static DWORD getattr (char *name, LPFILETIME lpft, size_t * size)
                    182: {
                    183:     HANDLE hFind;
                    184:     WIN32_FIND_DATA fd;
                    185: 
                    186:     if ((hFind = FindFirstFile (name, &fd)) == INVALID_HANDLE_VALUE) {
                    187:        lasterror = GetLastError ();
                    188: 
                    189:        fd.dwFileAttributes = GetFileAttributes (name);
                    190: 
                    191:        return fd.dwFileAttributes;
                    192:     }
                    193:     FindClose (hFind);
                    194: 
                    195:     if (lpft)
                    196:        *lpft = fd.ftLastWriteTime;
                    197:     if (size)
                    198:        *size = fd.nFileSizeLow;
                    199: 
                    200:     return fd.dwFileAttributes;
                    201: }
                    202: 
                    203: int posixemu_access (char *name, int mode)
                    204: {
                    205:     DWORD attr;
                    206:     char buf[1024];
                    207: 
                    208:     fname_atow (name, buf, sizeof buf - 4);
                    209: 
                    210:     if ((attr = getattr (buf, NULL, NULL)) == ~0)
                    211:        return -1;
                    212: 
                    213:     if (attr & FILE_ATTRIBUTE_READONLY && (mode & 4)) {
                    214:        lasterror = ERROR_ACCESS_DENIED;
                    215:        return -1;
                    216:     } else
                    217:        return 0;
                    218: }
                    219: 
                    220: int posixemu_open (char *name, int oflag, int dummy)
                    221: {
                    222:     DWORD fileaccess;
                    223:     DWORD filecreate;
                    224:     char buf[1024];
                    225: 
                    226:     HANDLE hFile;
                    227: 
                    228:     switch (oflag & (O_RDONLY | O_WRONLY | O_RDWR)) {
                    229:     case O_RDONLY:
                    230:        fileaccess = GENERIC_READ;
                    231:        break;
                    232:     case O_WRONLY:
                    233:        fileaccess = GENERIC_WRITE;
                    234:        break;
                    235:     case O_RDWR:
                    236:        fileaccess = GENERIC_READ | GENERIC_WRITE;
                    237:        break;
                    238:     default:
                    239:        return -1;
                    240:     }
                    241: 
                    242:     switch (oflag & (O_CREAT | O_EXCL | O_TRUNC)) {
                    243:     case 0:
                    244:     case O_EXCL:
                    245:        filecreate = OPEN_EXISTING;
                    246:        break;
                    247:     case O_CREAT:
                    248:        filecreate = OPEN_ALWAYS;
                    249:        break;
                    250:     case O_CREAT | O_EXCL:
                    251:     case O_CREAT | O_TRUNC | O_EXCL:
                    252:        filecreate = CREATE_NEW;
                    253:        break;
                    254:     case O_TRUNC:
                    255:     case O_TRUNC | O_EXCL:
                    256:        filecreate = TRUNCATE_EXISTING;
                    257:        break;
                    258:     case O_CREAT | O_TRUNC:
                    259:        filecreate = CREATE_ALWAYS;
                    260:        break;
                    261:     }
                    262: 
                    263:     fname_atow (name, buf, sizeof buf);
                    264: 
                    265:     if ((hFile = CreateFile (buf,
                    266:                             fileaccess,
                    267:                             FILE_SHARE_READ | FILE_SHARE_WRITE,
                    268:                             NULL,
                    269:                             filecreate,
                    270:                             FILE_ATTRIBUTE_NORMAL,
                    271:                             NULL)) == INVALID_HANDLE_VALUE)
                    272:        lasterror = GetLastError ();
                    273: 
                    274:     return (int) hFile;
                    275: }
                    276: 
                    277: void posixemu_close (int hFile)
                    278: {
                    279:     CloseHandle ((HANDLE) hFile);
                    280: }
                    281: 
                    282: int w32fopendel (char *name, char *mode, int delflag)
                    283: {
                    284:     HANDLE hFile;
                    285:     hFile = CreateFile (name,
                    286:                        mode[1] == '+' ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ,
                    287:                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                    288:                        NULL,
                    289:                        OPEN_EXISTING,
                    290:                        delflag ? FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE : FILE_ATTRIBUTE_NORMAL,
                    291:                        NULL);
                    292: 
                    293:     if (hFile == INVALID_HANDLE_VALUE) {
                    294:        lasterror = GetLastError ();
                    295:        hFile = 0;
                    296:     }
                    297:     return (int) hFile;
                    298: }
                    299: 
                    300: int stdioemu_fclose (FILE * fd)
                    301: {
                    302:     if (fd)
                    303:        CloseHandle ((HANDLE) fd);
                    304:     return 0;
                    305: }
                    306: 
                    307: void *mallocemu_malloc (int size)
                    308: {
                    309:     return GlobalAlloc (GPTR, size);
                    310: }
                    311: 
                    312: void mallocemu_free (void *ptr)
                    313: {
                    314:     GlobalFree (ptr);
                    315: }
                    316: 
                    317: static int hextol (char a)
                    318: {
                    319:     if (a >= '0' && a <= '9')
                    320:        return a - '0';
                    321:     if (a >= 'a' && a <= 'f')
                    322:        return a - 'a' + 10;
                    323:     if (a >= 'A' && a <= 'F')
                    324:        return a - 'A' + 10;
                    325:     return 2;
                    326: }
                    327: 
                    328: /* Win32 file name restrictions suck... */
                    329: void fname_wtoa (unsigned char *ptr)
                    330: {
                    331:     unsigned char *lastslash = ptr;
                    332: 
                    333:     while (*ptr) {
                    334:        if (*ptr == '~') {
                    335:            *ptr = hextol (ptr[1]) * 16 + hextol (ptr[2]);
                    336:            strcpy (ptr + 1, ptr + 3);
                    337:        } else if (*ptr == '\\') {
                    338:            if (checkspace (lastslash, ' ', 0xa0) && ptr - lastslash > 3 && lastslash[3] == 0xa0 && isillegal (lastslash)) {
                    339:                ptr--;
                    340:                strcpy (lastslash + 3, lastslash + 4);
                    341:            }
                    342:            *ptr = '/';
                    343:            lastslash = ptr + 1;
                    344:        }
                    345:        ptr++;
                    346:     }
                    347: 
                    348:     if (checkspace (lastslash, ' ', 0xa0) && ptr - lastslash > 3 && lastslash[3] == 0xa0 && isillegal (lastslash))
                    349:        strcpy (lastslash + 3, lastslash + 4);
                    350: }
                    351: 
                    352: DIR {
                    353:     WIN32_FIND_DATA finddata;
                    354:     HANDLE hDir;
                    355:     int getnext;
                    356: };
                    357: 
                    358: DIR *opendir (char *path)
                    359: {
                    360:     char buf[1024];
                    361:     DIR *dir;
                    362: 
                    363:     if (!(dir = (DIR *) GlobalAlloc (GPTR, sizeof (DIR)))) {
                    364:        lasterror = GetLastError ();
                    365:        return 0;
                    366:     }
                    367:     fname_atow (path, buf, sizeof buf - 4);
                    368:     strcat (buf, "\\*");
                    369: 
                    370:     if ((dir->hDir = FindFirstFile (buf, &dir->finddata)) == INVALID_HANDLE_VALUE) {
                    371:        lasterror = GetLastError ();
                    372:        GlobalFree (dir);
                    373:        return 0;
                    374:     }
                    375:     return dir;
                    376: }
                    377: 
                    378: struct dirent *readdir (DIR * dir)
                    379: {
                    380:     if (dir->getnext) {
                    381:        if (!FindNextFile (dir->hDir, &dir->finddata)) {
                    382:            lasterror = GetLastError ();
                    383:            return 0;
                    384:        }
                    385:     }
                    386:     dir->getnext = TRUE;
                    387: 
                    388:     fname_wtoa (dir->finddata.cFileName);
                    389:     return (struct dirent *) dir->finddata.cFileName;
                    390: }
                    391: 
                    392: void closedir (DIR * dir)
                    393: {
                    394:     FindClose (dir->hDir);
                    395:     GlobalFree (dir);
                    396: }
                    397: 
                    398: int setfiletime (char *name, unsigned int days, int minute, int tick)
                    399: {
                    400:     FILETIME LocalFileTime, FileTime;
                    401:     HANDLE hFile;
                    402:     int success;
                    403:     char buf[1024];
                    404: 
                    405:     fname_atow (name, buf, sizeof buf);
                    406: 
                    407:     if ((hFile = CreateFile (buf, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) {
                    408:        lasterror = GetLastError ();
                    409:        return 0;
                    410:     }
                    411:     *(__int64 *) & LocalFileTime = (((__int64) (377 * 365 + 91 + days) * (__int64) 1440 + (__int64) minute) * (__int64) (60 * 50) + (__int64) tick) * (__int64) 200000;
                    412: 
                    413:     if (!LocalFileTimeToFileTime (&LocalFileTime, &FileTime))
                    414:        FileTime = LocalFileTime;
                    415: 
                    416:     if (!(success = SetFileTime (hFile, &FileTime, &FileTime, &FileTime)))
                    417:        lasterror = GetLastError ();
                    418:     CloseHandle (hFile);
                    419: 
                    420:     return success;
                    421: }
                    422: 
                    423: int posixemu_read (int hFile, char *ptr, int size)
                    424: {
                    425:     DWORD actual;
                    426: 
                    427:     if (!ReadFile ((HANDLE) hFile, ptr, size, &actual, NULL))
                    428:        lasterror = GetLastError ();
                    429: 
                    430:     return actual;
                    431: }
                    432: 
                    433: int posixemu_write (int hFile, char *ptr, int size)
                    434: {
                    435:     DWORD actual;
                    436: 
                    437:     if (!WriteFile ((HANDLE) hFile, ptr, size, &actual, NULL))
                    438:        lasterror = GetLastError ();
                    439: 
                    440:     return actual;
                    441: }
                    442: 
                    443: int posixemu_seek (int hFile, int pos, int type)
                    444: {
                    445:     int result;
                    446: 
                    447:     switch (type) {
                    448:     case SEEK_SET:
                    449:        type = FILE_BEGIN;
                    450:        break;
                    451:     case SEEK_CUR:
                    452:        type = FILE_CURRENT;
                    453:        break;
                    454:     case SEEK_END:
                    455:        type = FILE_END;
                    456:     }
                    457: 
                    458:     if ((result = SetFilePointer ((HANDLE) hFile, pos, NULL, type)) == ~0)
                    459:        lasterror = GetLastError ();
                    460: 
                    461:     return result;
                    462: }
                    463: 
                    464: int stdioemu_fread (char *buf, int l1, int l2, FILE * hFile)
                    465: {
                    466:     return posixemu_read ((int) hFile, buf, l1 * l2);
                    467: }
                    468: 
                    469: int stdioemu_fwrite (char *buf, int l1, int l2, FILE * hFile)
                    470: {
                    471:     return posixemu_write ((int) hFile, buf, l1 * l2);
                    472: }
                    473: 
                    474: int stdioemu_fseek (FILE * hFile, int pos, int type)
                    475: {
                    476:     return posixemu_seek ((int) hFile, pos, type);
                    477: }
                    478: 
                    479: int stdioemu_ftell (FILE * hFile)
                    480: {
                    481:     return SetFilePointer ((HANDLE) hFile, 0, 0, FILE_CURRENT);
                    482: }
                    483: 
                    484: int posixemu_stat (char *name, struct stat *statbuf)
                    485: {
                    486:     char buf[1024];
                    487:     DWORD attr;
                    488:     HANDLE hFile;
                    489:     FILETIME ft, lft;
                    490: 
                    491:     fname_atow (name, buf, sizeof buf);
                    492: 
                    493:     if ((attr = getattr (buf, &ft, &statbuf->st_size)) == ~0) {
                    494:        lasterror = GetLastError ();
                    495:        return -1;
                    496:     } else {
                    497:        statbuf->st_mode = (attr & FILE_ATTRIBUTE_READONLY) ? 5 : 0;
                    498:        if (attr & FILE_ATTRIBUTE_ARCHIVE)
                    499:            statbuf->st_mode |= 0x10;
                    500:        if (attr & FILE_ATTRIBUTE_DIRECTORY)
                    501:            statbuf->st_mode |= 0x100;
                    502: 
                    503:        FileTimeToLocalFileTime (&ft, &lft);
                    504:        statbuf->st_mtime = (*(__int64 *) & lft - ((__int64) (369 * 365 + 89) * (__int64) (24 * 60 * 60) * (__int64) 10000000)) / (__int64) 10000000;
                    505:     }
                    506: 
                    507:     return 0;
                    508: }
                    509: 
                    510: int posixemu_mkdir (char *name, int mode)
                    511: {
                    512:     char buf[1024];
                    513: 
                    514:     fname_atow (name, buf, sizeof buf);
                    515: 
                    516:     if (CreateDirectory (buf, NULL))
                    517:        return 0;
                    518: 
                    519:     lasterror = GetLastError ();
                    520: 
                    521:     return -1;
                    522: }
                    523: 
                    524: int posixemu_unlink (char *name)
                    525: {
                    526:     char buf[1024];
                    527: 
                    528:     fname_atow (name, buf, sizeof buf);
                    529:     if (DeleteFile (buf))
                    530:        return 0;
                    531: 
                    532:     lasterror = GetLastError ();
                    533: 
                    534:     return -1;
                    535: }
                    536: 
                    537: int posixemu_rmdir (char *name)
                    538: {
                    539:     char buf[1024];
                    540: 
                    541:     fname_atow (name, buf, sizeof buf);
                    542:     if (RemoveDirectory (buf))
                    543:        return 0;
                    544: 
                    545:     lasterror = GetLastError ();
                    546: 
                    547:     return -1;
                    548: }
                    549: 
                    550: int posixemu_rename (char *name1, char *name2)
                    551: {
                    552:     char buf1[1024];
                    553:     char buf2[1024];
                    554: 
                    555:     fname_atow (name1, buf1, sizeof buf1);
                    556:     fname_atow (name2, buf2, sizeof buf2);
                    557:     if (MoveFile (name1, name2))
                    558:        return 0;
                    559: 
                    560:     lasterror = GetLastError ();
                    561: 
                    562:     return -1;
                    563: }
                    564: 
                    565: int posixemu_chmod (char *name, int mode)
                    566: {
                    567:     char buf[1024];
                    568:     DWORD attr = FILE_ATTRIBUTE_NORMAL;
                    569: 
                    570:     fname_atow (name, buf, sizeof buf);
                    571: 
                    572:     if (mode & 1)
                    573:        attr |= FILE_ATTRIBUTE_READONLY;
                    574:     if (mode & 0x10)
                    575:        attr |= FILE_ATTRIBUTE_ARCHIVE;
                    576: 
                    577:     if (SetFileAttributes (buf, attr))
                    578:        return 1;
                    579: 
                    580:     lasterror = GetLastError ();
                    581: 
                    582:     return 0;
                    583: }
                    584: 
                    585: void posixemu_tmpnam (char *name)
                    586: {
                    587:     char buf[MAX_PATH];
                    588: 
                    589:     GetTempPath (MAX_PATH, buf);
                    590:     GetTempFileName (buf, "uae", 0, name);
                    591: }
                    592: 
                    593: /* pthread Win32 emulation */
                    594: void sem_init (HANDLE * event, int manual_reset, int initial_state)
                    595: {
                    596:     *event = CreateEvent (NULL, manual_reset, initial_state, NULL);
                    597: }
                    598: 
                    599: void sem_wait (HANDLE * event)
                    600: {
                    601:     WaitForSingleObject (*event, INFINITE);
                    602: }
                    603: 
                    604: void sem_post (HANDLE * event)
                    605: {
                    606:     SetEvent (*event);
                    607: }
                    608: 
                    609: int sem_trywait (HANDLE * event)
                    610: {
                    611:     return WaitForSingleObject (*event, 0) == WAIT_OBJECT_0;
                    612: }
                    613: 
                    614: /* Mega-klduge to prevent problems with Watcom's habit of passing
                    615:  * arguments in registers... */
                    616: static HANDLE thread_sem;
                    617: static void *(*thread_startfunc) (void *);
                    618: #ifndef __GNUC__
                    619: static void * __stdcall thread_starter (void *arg)
                    620: #else
                    621: static void * thread_starter( void *arg )
                    622: #endif
                    623: {
                    624:     void *(*func) (void *) = thread_startfunc;
                    625:     SetEvent (thread_sem);
                    626:     return (*func) (arg);
                    627: }
                    628: 
                    629: /* this creates high priority threads by default to speed up the file system (kludge, will be
                    630:  * replaced by a set_penguin_priority() routine soon) */
                    631: int start_penguin (void *(*f) (void *), void *arg, DWORD * foo)
                    632: {
                    633:     static int have_event = 0;
                    634:     HANDLE hThread;
                    635: 
                    636:     if (! have_event) {
                    637:        thread_sem = CreateEvent (NULL, 0, 0, NULL);
                    638:        have_event = 1;
                    639:     }
                    640:     thread_startfunc = f;
                    641:     hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) thread_starter, arg, 0, foo);
                    642:     SetThreadPriority (hThread, THREAD_PRIORITY_HIGHEST);
                    643:     WaitForSingleObject (thread_sem, INFINITE);
                    644: }
                    645: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.