4 * Implements C run-time functionality as known from UNIX.
6 * Copyright 1996 Marcus Meissner
7 * Copyright 1996 Jukka Iivonen
8 * Copyright 1997 Uwe Bonnes
12 Unresolved issues Uwe Bonnes 970904:
13 - Handling of Binary/Text Files is crude. If in doubt, use fromdos or recode
14 - Arguments in crtdll.spec for functions with double argument
15 - system-call calls another wine process, but without debugging arguments
16 and uses the first wine executable in the path
17 - tested with ftp://ftp.remcomp.com/pub/remcomp/lcc-win32.zip, a C-Compiler
18 for Win32, based on lcc, from Jacob Navia
21 /* FIXME: all the file handling is hopelessly broken -- AJ */
28 #include <sys/times.h>
46 extern int FILE_GetUnixHandle( HFILE32 );
48 static DOS_FULL_NAME CRTDLL_tmpname;
50 extern INT32 WIN32_wsprintf32W( DWORD *args );
52 UINT32 CRTDLL_argc_dll; /* CRTDLL.23 */
53 LPSTR *CRTDLL_argv_dll; /* CRTDLL.24 */
54 LPSTR CRTDLL_acmdln_dll; /* CRTDLL.38 */
55 UINT32 CRTDLL_basemajor_dll; /* CRTDLL.42 */
56 UINT32 CRTDLL_baseminor_dll; /* CRTDLL.43 */
57 UINT32 CRTDLL_baseversion_dll; /* CRTDLL.44 */
58 UINT32 CRTDLL_commode_dll; /* CRTDLL.59 */
59 LPSTR CRTDLL_environ_dll; /* CRTDLL.75 */
60 UINT32 CRTDLL_fmode_dll; /* CRTDLL.104 */
61 UINT32 CRTDLL_osmajor_dll; /* CRTDLL.241 */
62 UINT32 CRTDLL_osminor_dll; /* CRTDLL.242 */
63 UINT32 CRTDLL_osmode_dll; /* CRTDLL.243 */
64 UINT32 CRTDLL_osver_dll; /* CRTDLL.244 */
65 UINT32 CRTDLL_osversion_dll; /* CRTDLL.245 */
66 UINT32 CRTDLL_winmajor_dll; /* CRTDLL.329 */
67 UINT32 CRTDLL_winminor_dll; /* CRTDLL.330 */
68 UINT32 CRTDLL_winver_dll; /* CRTDLL.331 */
70 typedef VOID (*new_handler_type)(VOID);
72 static new_handler_type new_handler;
74 /*********************************************************************
75 * _GetMainArgs (CRTDLL.022)
77 DWORD __cdecl CRTDLL__GetMainArgs(LPDWORD argc,LPSTR **argv,
78 LPSTR *environ,DWORD flag)
82 int xargc,i,afterlastspace;
85 TRACE(crtdll,"(%p,%p,%p,%ld).\n",
86 argc,argv,environ,flag
88 CRTDLL_acmdln_dll = cmdline = HEAP_strdupA( GetProcessHeap(), 0,
89 GetCommandLine32A() );
90 TRACE(crtdll,"got '%s'\n", cmdline);
92 version = GetVersion32();
93 CRTDLL_osver_dll = version >> 16;
94 CRTDLL_winminor_dll = version & 0xFF;
95 CRTDLL_winmajor_dll = (version>>8) & 0xFF;
96 CRTDLL_baseversion_dll = version >> 16;
97 CRTDLL_winver_dll = ((version >> 8) & 0xFF) + ((version & 0xFF) << 8);
98 CRTDLL_baseminor_dll = (version >> 16) & 0xFF;
99 CRTDLL_basemajor_dll = (version >> 24) & 0xFF;
100 CRTDLL_osversion_dll = version & 0xFFFF;
101 CRTDLL_osminor_dll = version & 0xFF;
102 CRTDLL_osmajor_dll = (version>>8) & 0xFF;
104 /* missing threading init */
106 i=0;xargv=NULL;xargc=0;afterlastspace=0;
108 if (cmdline[i]==' ') {
109 xargv=(char**)HeapReAlloc( GetProcessHeap(), 0, xargv,
110 sizeof(char*)*(++xargc));
112 xargv[xargc-1] = HEAP_strdupA( GetProcessHeap(), 0,
113 cmdline+afterlastspace);
115 while (cmdline[i]==' ')
122 xargv=(char**)HeapReAlloc( GetProcessHeap(), 0, xargv,
123 sizeof(char*)*(++xargc));
125 xargv[xargc-1] = HEAP_strdupA( GetProcessHeap(), 0,
126 cmdline+afterlastspace);
127 CRTDLL_argc_dll = xargc;
129 CRTDLL_argv_dll = xargv;
132 TRACE(crtdll,"found %d arguments\n",
134 CRTDLL_environ_dll = *environ = GetEnvironmentStrings32A();
139 typedef void (*_INITTERMFUN)();
141 /*********************************************************************
142 * _initterm (CRTDLL.135)
144 DWORD __cdecl CRTDLL__initterm(_INITTERMFUN *start,_INITTERMFUN *end)
146 _INITTERMFUN *current;
148 TRACE(crtdll,"(%p,%p)\n",start,end);
150 while (current<end) {
151 if (*current) (*current)();
157 /*********************************************************************
158 * _fdopen (CRTDLL.91)
160 DWORD __cdecl CRTDLL__fdopen(INT32 handle, LPCSTR mode)
168 case 1 : file=stdout;
170 case 2 : file=stderr;
173 file=fdopen(handle,mode);
175 TRACE(crtdll, "open handle %d mode %s got file %p\n",
180 /*******************************************************************
181 * _global_unwind2 (CRTDLL.129)
183 void __cdecl CRTDLL__global_unwind2( CONTEXT *context )
185 /* Retrieve the arguments (args[0] is return addr, args[1] is first arg) */
186 DWORD *args = (DWORD *)ESP_reg(context);
187 RtlUnwind( (PEXCEPTION_FRAME)args[1], (LPVOID)EIP_reg(context),
191 /*******************************************************************
192 * _local_unwind2 (CRTDLL.173)
194 void __cdecl CRTDLL__local_unwind2( CONTEXT *context )
196 /* Retrieve the arguments (args[0] is return addr, args[1] is first arg) */
197 DWORD *args = (DWORD *)ESP_reg(context);
198 PEXCEPTION_FRAME endframe = (PEXCEPTION_FRAME)args[1];
200 TRACE(crtdll,"(%p,%ld)\n",endframe,nr);
203 /*********************************************************************
206 DWORD __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
211 DOS_FULL_NAME full_name;
213 if (!DOSFS_GetFullName( path, FALSE, &full_name )) {
214 WARN(crtdll, "file %s bad name\n",path);
218 file=fopen(full_name.long_name ,mode);
223 if ((strchr(mode,'r')&&strchr(mode,'a'))||
224 (strchr(mode,'r')&&strchr(mode,'w'))||
225 (strchr(mode,'w')&&strchr(mode,'a')))
228 if (strstr(mode,"r+")) flagmode=O_RDWR;
229 else if (strchr(mode,'r')) flagmode = O_RDONLY;
230 else if (strstr(mode,"w+")) flagmode= O_RDWR | O_TRUNC | O_CREAT;
231 else if (strchr(mode,'w')) flagmode = O_WRONLY | O_TRUNC | O_CREAT;
232 else if (strstr(mode,"a+")) flagmode= O_RDWR | O_CREAT | O_APPEND;
233 else if (strchr(mode,'w')) flagmode = O_RDWR | O_CREAT | O_APPEND;
234 else if (strchr(mode,'b'))
235 TRACE(crtdll, "%s in BINARY mode\n",path);
237 dos_fildes=FILE_Open(path, flagmode);
238 unix_fildes=FILE_GetUnixHandle(dos_fildes);
239 file = fdopen(unix_fildes,mode);
241 TRACE(crtdll, "file %s mode %s got ufh %d dfh %d file %p\n",
242 path,mode,unix_fildes,dos_fildes,file);
246 /*********************************************************************
249 DWORD __cdecl CRTDLL_fread(LPVOID ptr, INT32 size, INT32 nmemb, LPVOID file)
256 /* If we would honour CR/LF <-> LF translation, we could do it like this.
257 We should keep track of all files opened, and probably files with \
258 known binary extensions must be unchanged */
259 while ( (i < (nmemb*size)) && (ret==1)) {
260 ret=fread(temp,1,1,file);
261 TRACE(crtdll, "got %c 0x%02x ret %d\n",
262 (isalpha(*(unsigned char*)temp))? *(unsigned char*)temp:
263 ' ',*(unsigned char*)temp, ret);
264 if (*(unsigned char*)temp != 0xd) { /* skip CR */
269 TRACE(crtdll, "skipping ^M\n");
271 TRACE(crtdll, "0x%08x items of size %d from file %p to %p\n",
272 nmemb,size,file,ptr,);
274 WARN(crtdll, " failed!\n");
279 ret=fread(ptr,size,nmemb,file);
280 TRACE(crtdll, "0x%08x items of size %d from file %p to %p\n",
281 nmemb,size,file,ptr);
283 WARN(crtdll, " failed!\n");
289 /*********************************************************************
292 LONG __cdecl CRTDLL_fseek(LPVOID stream, LONG offset, INT32 whence)
296 ret=fseek(stream,offset,whence);
297 TRACE(crtdll, "file %p to 0x%08lx pos %s\n",
298 stream,offset,(whence==SEEK_SET)?"SEEK_SET":
299 (whence==SEEK_CUR)?"SEEK_CUR":
300 (whence==SEEK_END)?"SEEK_END":"UNKNOWN");
302 WARN(crtdll, " failed!\n");
307 /*********************************************************************
310 LONG __cdecl CRTDLL_ftell(LPVOID stream)
315 TRACE(crtdll, "file %p at 0x%08lx\n",
320 /*********************************************************************
321 * fwrite (CRTDLL.386)
323 DWORD __cdecl CRTDLL_fwrite(LPVOID ptr, INT32 size, INT32 nmemb, LPVOID file)
327 ret=fwrite(ptr,size,nmemb,file);
328 TRACE(crtdll, "0x%08x items of size %d from %p to file %p\n",
329 nmemb,size,ptr,file);
331 WARN(crtdll, " Failed!\n");
336 /*********************************************************************
337 * setbuf (CRTDLL.452)
339 INT32 __cdecl CRTDLL_setbuf(LPVOID file, LPSTR buf)
341 TRACE(crtdll, "(file %p buf %p)\n", file, buf);
342 /* this doesn't work:"void value not ignored as it ought to be"
343 return setbuf(file,buf);
349 /*********************************************************************
350 * _open_osfhandle (CRTDLL.240)
352 HFILE32 __cdecl CRTDLL__open_osfhandle(LONG osfhandle, INT32 flags)
357 case STD_INPUT_HANDLE :
361 case STD_OUTPUT_HANDLE:
365 case STD_ERROR_HANDLE:
372 TRACE(crtdll, "(handle %08lx,flags %d) return %d\n",
373 osfhandle,flags,handle);
378 /*********************************************************************
381 void __cdecl CRTDLL_srand(DWORD seed)
383 /* FIXME: should of course be thread? process? local */
387 /*********************************************************************
388 * fprintf (CRTDLL.373)
390 INT32 __cdecl CRTDLL_fprintf( FILE *file, LPSTR format, ... )
395 va_start( valist, format );
396 res = vfprintf( file, format, valist );
401 /*********************************************************************
402 * vfprintf (CRTDLL.373)
404 INT32 __cdecl CRTDLL_vfprintf( FILE *file, LPSTR format, va_list args )
406 return vfprintf( file, format, args );
409 /*********************************************************************
412 time_t __cdecl CRTDLL_time(time_t *timeptr)
414 time_t curtime = time(NULL);
421 /*********************************************************************
424 clock_t __cdecl CRTDLL_clock(void)
430 res = alltimes.tms_utime + alltimes.tms_stime+
431 alltimes.tms_cutime + alltimes.tms_cstime;
432 /* Fixme: We need some symbolic representation
433 for (Hostsystem_)CLOCKS_PER_SEC
434 and (Emulated_system_)CLOCKS_PER_SEC
435 10 holds only for Windows/Linux_i86)
440 /*********************************************************************
441 * _isatty (CRTDLL.137)
443 BOOL32 __cdecl CRTDLL__isatty(DWORD x)
445 TRACE(crtdll,"(%ld)\n",x);
449 /*********************************************************************
450 * _write (CRTDLL.332)
452 INT32 __cdecl CRTDLL__write(INT32 fd,LPCVOID buf,UINT32 count)
459 len = (UINT32)write(fd,buf,(LONG)count);
461 len = _lwrite32(fd,buf,count);
462 TRACE(crtdll,"%d/%d byte to dfh %d from %p,\n",
468 /*********************************************************************
471 * FIXME: What the heck is the difference between
472 * FIXME _c_exit (CRTDLL.47)
473 * FIXME _cexit (CRTDLL.49)
474 * FIXME _exit (CRTDLL.87)
475 * FIXME exit (CRTDLL.359)
477 * atexit-processing comes to mind -- MW.
480 void __cdecl CRTDLL__cexit(INT32 ret)
482 TRACE(crtdll,"(%d)\n",ret);
487 /*********************************************************************
490 void __cdecl CRTDLL_exit(DWORD ret)
492 TRACE(crtdll,"(%ld)\n",ret);
497 /*********************************************************************
498 * _abnormal_termination (CRTDLL.36 )
500 INT32 __cdecl CRTDLL__abnormal_termination(void)
502 TRACE(crtdll,"(void)\n");
507 /*********************************************************************
508 * fflush (CRTDLL.365)
510 INT32 __cdecl CRTDLL_fflush(LPVOID stream)
514 ret = fflush(stream);
515 TRACE(crtdll,"%p returnd %d\n",stream,ret);
517 WARN(crtdll, " Failed!\n");
523 /*********************************************************************
526 LPSTR __cdecl CRTDLL_gets(LPSTR buf)
529 /* BAD, for the whole WINE process blocks... just done this way to test
530 * windows95's ftp.exe.
533 TRACE(crtdll,"got %s\n",ret);
538 /*********************************************************************
541 INT32 __cdecl CRTDLL_rand()
547 /*********************************************************************
548 * putchar (CRTDLL.442)
550 void __cdecl CRTDLL_putchar( INT32 x )
556 /*********************************************************************
559 INT32 __cdecl CRTDLL_fputc( INT32 c, FILE *stream )
561 TRACE(crtdll, "%c to file %p\n",c,stream);
562 return fputc(c,stream);
566 /*********************************************************************
569 INT32 __cdecl CRTDLL_fputs( LPCSTR s, FILE *stream )
571 TRACE(crtdll, "%s to file %p\n",s,stream);
572 return fputs(s,stream);
576 /*********************************************************************
579 INT32 __cdecl CRTDLL_puts(LPCSTR s)
581 TRACE(crtdll, "%s \n",s);
586 /*********************************************************************
589 INT32 __cdecl CRTDLL_putc(INT32 c, FILE *stream)
591 TRACE(crtdll, " %c to file %p\n",c,stream);
592 return fputc(c,stream);
594 /*********************************************************************
597 INT32 __cdecl CRTDLL_fgetc( FILE *stream )
599 int ret= fgetc(stream);
600 TRACE(crtdll, "got %d\n",ret);
605 /*********************************************************************
608 INT32 __cdecl CRTDLL_getc( FILE *stream )
610 int ret= fgetc(stream);
611 TRACE(crtdll, "got %d\n",ret);
615 /*********************************************************************
618 UINT32 __cdecl CRTDLL__rotl(UINT32 x,INT32 shift)
620 unsigned int ret = (x >> shift)|( x >>((sizeof(x))-shift));
622 TRACE(crtdll, "got 0x%08x rot %d ret 0x%08x\n",
627 /*********************************************************************
628 * _lrotl (CRTDLL.176)
630 DWORD __cdecl CRTDLL__lrotl(DWORD x,INT32 shift)
632 unsigned long ret = (x >> shift)|( x >>((sizeof(x))-shift));
634 TRACE(crtdll, "got 0x%08lx rot %d ret 0x%08lx\n",
641 /*********************************************************************
644 CHAR* __cdecl CRTDLL_fgets(LPSTR s,INT32 size, LPVOID stream)
649 ret=fgets(s, size,stream);
650 /*FIXME: Control with CRTDLL_setmode */
651 control_M= strrchr(s,'\r');
652 /*delete CR if we read a DOS File */
658 TRACE(crtdll, "got %s for %d chars from file %p\n",
661 WARN(crtdll, " Failed!\n");
667 /*********************************************************************
668 * _mbsicmp (CRTDLL.204)
670 int __cdecl CRTDLL__mbsicmp(unsigned char *x,unsigned char *y)
677 /* FIXME: MBCS handling... */
686 /*********************************************************************
687 * _mbsinc (CRTDLL.205)
689 unsigned char * __cdecl CRTDLL__mbsinc(unsigned char *x)
696 /*********************************************************************
697 * vsprintf (CRTDLL.500)
699 INT32 __cdecl CRTDLL_vsprintf( LPSTR buffer, LPCSTR spec, va_list args )
701 return wvsprintf32A( buffer, spec, args );
704 /*********************************************************************
705 * vswprintf (CRTDLL.501)
707 INT32 __cdecl CRTDLL_vswprintf( LPWSTR buffer, LPCWSTR spec, va_list args )
709 return wvsprintf32W( buffer, spec, args );
712 /*********************************************************************
713 * _mbscpy (CRTDLL.200)
715 unsigned char* __cdecl CRTDLL__mbscpy(unsigned char *x,unsigned char *y)
717 TRACE(crtdll,"CRTDLL_mbscpy %s and %s\n",x,y);
722 /*********************************************************************
723 * _mbscat (CRTDLL.197)
725 unsigned char* __cdecl CRTDLL__mbscat(unsigned char *x,unsigned char *y)
731 /*********************************************************************
732 * _strcmpi (CRTDLL.282) (CRTDLL.287)
734 INT32 __cdecl CRTDLL__strcmpi( LPCSTR s1, LPCSTR s2 )
736 return lstrcmpi32A( s1, s2 );
740 /*********************************************************************
741 * _strnicmp (CRTDLL.293)
743 INT32 __cdecl CRTDLL__strnicmp( LPCSTR s1, LPCSTR s2, INT32 n )
745 return lstrncmpi32A( s1, s2, n );
749 /*********************************************************************
750 * _strlwr (CRTDLL.293)
752 * convert a string in place to lowercase
754 LPSTR CRTDLL__strlwr(LPSTR x)
758 TRACE(crtdll, "CRTDLL_strlwr got %s\n", x);
760 if ((*y > 0x40) && (*y< 0x5b))
764 TRACE(crtdll, " returned %s\n", x);
769 /*********************************************************************
770 * system (CRTDLL.485)
772 INT32 CRTDLL_system(LPSTR x)
774 #define SYSBUF_LENGTH 1500
775 char buffer[SYSBUF_LENGTH];
776 unsigned char *y = x;
780 sprintf( buffer, "%s \"", Options.argv0 );
781 bp = buffer + strlen(buffer);
782 i = strlen(buffer) + strlen(x) +2;
784 /* Calculate needed buffer size to prevent overflow. */
789 /* If buffer too short, exit. */
790 if (i > SYSBUF_LENGTH) {
791 TRACE(crtdll,"_system buffer to small\n");
800 if (*(y-1) =='\\') *bp++ = '\\';
802 /* Remove spaces from end of string. */
803 while (*(y-1) == ' ') {
808 TRACE(crtdll, "_system got '%s', executing '%s'\n",x,buffer);
810 return system(buffer);
813 /*********************************************************************
814 * _strupr (CRTDLL.300)
816 LPSTR __cdecl CRTDLL__strupr(LPSTR x)
827 /*********************************************************************
828 * _wcsupr (CRTDLL.328)
830 LPWSTR __cdecl CRTDLL__wcsupr(LPWSTR x)
841 /*********************************************************************
842 * _wcslwr (CRTDLL.323)
844 LPWSTR __cdecl CRTDLL__wcslwr(LPWSTR x)
856 /*********************************************************************
857 * longjmp (CRTDLL.426)
859 VOID __cdecl CRTDLL_longjmp(jmp_buf env, int val)
861 FIXME(crtdll,"CRTDLL_longjmp semistup, expect crash\n");
862 return longjmp(env, val);
865 /*********************************************************************
866 * malloc (CRTDLL.427)
868 VOID* __cdecl CRTDLL_malloc(DWORD size)
870 return HeapAlloc(GetProcessHeap(),0,size);
873 /*********************************************************************
876 VOID* __cdecl CRTDLL_new(DWORD size)
879 if(!(result = HeapAlloc(GetProcessHeap(),0,size)) && new_handler)
884 /*********************************************************************
885 * set_new_handler(CRTDLL.003)
887 new_handler_type __cdecl CRTDLL_set_new_handler(new_handler_type func)
889 new_handler_type old_handler = new_handler;
894 /*********************************************************************
895 * calloc (CRTDLL.350)
897 VOID* __cdecl CRTDLL_calloc(DWORD size, DWORD count)
899 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
902 /*********************************************************************
903 * realloc (CRTDLL.447)
905 VOID* __cdecl CRTDLL_realloc( VOID *ptr, DWORD size )
907 return HeapReAlloc( GetProcessHeap(), 0, ptr, size );
910 /*********************************************************************
913 VOID __cdecl CRTDLL_free(LPVOID ptr)
915 HeapFree(GetProcessHeap(),0,ptr);
918 /*********************************************************************
919 * delete (CRTDLL.002)
921 VOID __cdecl CRTDLL_delete(VOID* ptr)
923 HeapFree(GetProcessHeap(),0,ptr);
926 /*********************************************************************
927 * _strdup (CRTDLL.285)
929 LPSTR __cdecl CRTDLL__strdup(LPSTR ptr)
931 return HEAP_strdupA(GetProcessHeap(),0,ptr);
935 /*********************************************************************
936 * fclose (CRTDLL.362)
938 INT32 __cdecl CRTDLL_fclose( FILE *stream )
940 int unix_handle=fileno(stream);
941 HFILE32 dos_handle=1;
944 if (unix_handle<4) ret= fclose(stream);
946 while(FILE_GetUnixHandle(dos_handle) != unix_handle) dos_handle++;
948 ret = _lclose32( dos_handle);
950 TRACE(crtdll,"(%p) ufh %d dfh %d\n",
951 stream,unix_handle,dos_handle);
954 WARN(crtdll, " Failed!\n");
959 /*********************************************************************
960 * _unlink (CRTDLL.315)
962 INT32 __cdecl CRTDLL__unlink(LPCSTR pathname)
965 DOS_FULL_NAME full_name;
967 if (!DOSFS_GetFullName( pathname, FALSE, &full_name )) {
968 WARN(crtdll, "CRTDLL_unlink file %s bad name\n",pathname);
972 ret=unlink(full_name.long_name);
973 TRACE(crtdll,"(%s unix %s)\n",
974 pathname,full_name.long_name);
976 WARN(crtdll, " Failed!\n");
981 /*********************************************************************
982 * rename (CRTDLL.449)
984 INT32 __cdecl CRTDLL_rename(LPCSTR oldpath,LPCSTR newpath)
986 BOOL32 ok = MoveFileEx32A( oldpath, newpath, MOVEFILE_REPLACE_EXISTING );
991 /*********************************************************************
1010 int __cdecl CRTDLL__stat(const char * filename, struct win_stat * buf)
1013 DOS_FULL_NAME full_name;
1016 if (!DOSFS_GetFullName( filename, TRUE, &full_name ))
1018 WARN(crtdll, "CRTDLL__stat filename %s bad name\n",filename);
1021 ret=stat(full_name.long_name,&mystat);
1022 TRACE(crtdll,"CRTDLL__stat %s\n", filename);
1024 WARN(crtdll, " Failed!\n");
1026 /* FIXME: should check what Windows returns */
1028 buf->win_st_dev = mystat.st_dev;
1029 buf->win_st_ino = mystat.st_ino;
1030 buf->win_st_mode = mystat.st_mode;
1031 buf->win_st_nlink = mystat.st_nlink;
1032 buf->win_st_uid = mystat.st_uid;
1033 buf->win_st_gid = mystat.st_gid;
1034 buf->win_st_rdev = mystat.st_rdev;
1035 buf->win_st_size = mystat.st_size;
1036 buf->win_st_atime = mystat.st_atime;
1037 buf->win_st_mtime = mystat.st_mtime;
1038 buf->win_st_ctime = mystat.st_ctime;
1042 /*********************************************************************
1043 * _open (CRTDLL.239)
1045 HFILE32 __cdecl CRTDLL__open(LPCSTR path,INT32 flags)
1051 the flags in lcc's header differ from the ones in Linux, e.g.
1052 Linux: define O_APPEND 02000 (= 0x400)
1053 lcc: define _O_APPEND 0x0008
1054 so here a scheme to translate them
1055 Probably lcc is wrong here, but at least a hack to get is going
1057 wineflags = (flags & 3);
1058 if (flags & 0x0008 ) wineflags |= O_APPEND;
1059 if (flags & 0x0100 ) wineflags |= O_CREAT;
1060 if (flags & 0x0200 ) wineflags |= O_TRUNC;
1061 if (flags & 0x0400 ) wineflags |= O_EXCL;
1062 if (flags & 0xf0f4 )
1063 TRACE(crtdll,"CRTDLL_open file unsupported flags 0x%04x\n",flags);
1066 ret = FILE_Open(path,wineflags);
1067 TRACE(crtdll,"CRTDLL_open file %s mode 0x%04x (lccmode 0x%04x) got dfh %d\n",
1068 path,wineflags,flags,ret);
1072 /*********************************************************************
1073 * _close (CRTDLL.57)
1075 INT32 __cdecl CRTDLL__close(HFILE32 fd)
1077 int ret=_lclose32(fd);
1079 TRACE(crtdll,"(%d)\n",fd);
1081 WARN(crtdll, " Failed!\n");
1086 /*********************************************************************
1089 INT32 __cdecl CRTDLL_feof( FILE *stream )
1094 TRACE(crtdll,"(%p) %s\n",stream,(ret)?"true":"false");
1098 /*********************************************************************
1099 * setlocale (CRTDLL.453)
1101 LPSTR __cdecl CRTDLL_setlocale(INT32 category,LPCSTR locale)
1106 case CRTDLL_LC_ALL: categorystr="LC_ALL";break;
1107 case CRTDLL_LC_COLLATE: categorystr="LC_COLLATE";break;
1108 case CRTDLL_LC_CTYPE: categorystr="LC_CTYPE";break;
1109 case CRTDLL_LC_MONETARY: categorystr="LC_MONETARY";break;
1110 case CRTDLL_LC_NUMERIC: categorystr="LC_NUMERIC";break;
1111 case CRTDLL_LC_TIME: categorystr="LC_TIME";break;
1112 default: categorystr = "UNKNOWN?";break;
1114 FIXME(crtdll,"(%s,%s),stub!\n",categorystr,locale);
1118 /*********************************************************************
1119 * wcscat (CRTDLL.503)
1121 LPWSTR __cdecl CRTDLL_wcscat( LPWSTR s1, LPCWSTR s2 )
1123 return lstrcat32W( s1, s2 );
1126 /*********************************************************************
1127 * wcschr (CRTDLL.504)
1129 LPWSTR __cdecl CRTDLL_wcschr(LPCWSTR str,WCHAR xchar)
1141 /*********************************************************************
1142 * wcscmp (CRTDLL.505)
1144 INT32 __cdecl CRTDLL_wcscmp( LPCWSTR s1, LPCWSTR s2 )
1146 return lstrcmp32W( s1, s2 );
1149 /*********************************************************************
1150 * wcscpy (CRTDLL.507)
1152 LPWSTR __cdecl CRTDLL_wcscpy( LPWSTR s1, LPCWSTR s2 )
1154 return lstrcpy32W( s1, s2 );
1157 /*********************************************************************
1158 * wcscspn (CRTDLL.508)
1160 INT32 __cdecl CRTDLL_wcscspn(LPWSTR str,LPWSTR reject)
1167 while (*t) { if (*t==*s) break;t++;}
1171 return s-str; /* nr of wchars */
1174 /*********************************************************************
1175 * wcslen (CRTDLL.510)
1177 INT32 __cdecl CRTDLL_wcslen( LPCWSTR s )
1179 return lstrlen32W( s );
1182 /*********************************************************************
1183 * wcsncat (CRTDLL.511)
1185 LPWSTR __cdecl CRTDLL_wcsncat( LPWSTR s1, LPCWSTR s2, INT32 n )
1187 return lstrcatn32W( s1, s2, n );
1190 /*********************************************************************
1191 * wcsncmp (CRTDLL.512)
1193 INT32 __cdecl CRTDLL_wcsncmp( LPCWSTR s1, LPCWSTR s2, INT32 n )
1195 return lstrncmp32W( s1, s2, n );
1198 /*********************************************************************
1199 * wcsncpy (CRTDLL.513)
1201 LPWSTR __cdecl CRTDLL_wcsncpy( LPWSTR s1, LPCWSTR s2, INT32 n )
1203 return lstrcpyn32W( s1, s2, n );
1206 /*********************************************************************
1207 * wcsspn (CRTDLL.516)
1209 INT32 __cdecl CRTDLL_wcsspn(LPWSTR str,LPWSTR accept)
1216 while (*t) { if (*t==*s) break;t++;}
1220 return s-str; /* nr of wchars */
1223 /*********************************************************************
1224 * towupper (CRTDLL.494)
1226 WCHAR __cdecl CRTDLL_towupper(WCHAR x)
1228 return (WCHAR)toupper((CHAR)x);
1231 /*********************************************************************
1232 * _wcsicmp (CRTDLL.321)
1234 DWORD __cdecl CRTDLL__wcsicmp( LPCWSTR s1, LPCWSTR s2 )
1236 return lstrcmpi32W( s1, s2 );
1239 /*********************************************************************
1240 * _wcsicoll (CRTDLL.322)
1242 DWORD __cdecl CRTDLL__wcsicoll(LPCWSTR a1,LPCWSTR a2)
1244 /* FIXME: handle collates */
1245 return lstrcmpi32W(a1,a2);
1248 /*********************************************************************
1249 * _wcsnicmp (CRTDLL.324)
1251 DWORD __cdecl CRTDLL__wcsnicmp( LPCWSTR s1, LPCWSTR s2, INT32 len )
1253 return lstrncmpi32W( s1, s2, len );
1256 /*********************************************************************
1257 * wcscoll (CRTDLL.506)
1259 DWORD __cdecl CRTDLL_wcscoll(LPWSTR a1,LPWSTR a2)
1261 /* FIXME: handle collates */
1262 return lstrcmp32W(a1,a2);
1265 /*********************************************************************
1266 * _wcsrev (CRTDLL.326)
1268 VOID __cdecl CRTDLL__wcsrev(LPWSTR s) {
1282 /*********************************************************************
1283 * wcsstr (CRTDLL.517)
1285 LPWSTR __cdecl CRTDLL_wcsstr(LPWSTR s,LPWSTR b)
1293 while (*y && *c && *y==*c) { c++;y++; }
1302 /*********************************************************************
1303 * wcstombs (CRTDLL.521)
1305 INT32 __cdecl CRTDLL_wcstombs( LPSTR dst, LPCWSTR src, INT32 len )
1307 lstrcpynWtoA( dst, src, len );
1308 return strlen(dst); /* FIXME: is this right? */
1311 /*********************************************************************
1312 * wcsrchr (CRTDLL.515)
1314 LPWSTR __cdecl CRTDLL_wcsrchr(LPWSTR str,WCHAR xchar)
1318 s=str+lstrlen32W(str);
1327 /*********************************************************************
1328 * _setmode (CRTDLL.265)
1329 * FIXME: At present we ignore the request to translate CR/LF to LF.
1331 * We allways translate when we read with fgets, we never do with fread
1334 INT32 __cdecl CRTDLL__setmode( INT32 fh,INT32 mode)
1337 #define O_TEXT 0x4000
1338 #define O_BINARY 0x8000
1340 FIXME(crtdll, "on fhandle %d mode %s, STUB.\n",
1341 fh,(mode=O_TEXT)?"O_TEXT":
1342 (mode=O_BINARY)?"O_BINARY":"UNKNOWN");
1346 /*********************************************************************
1347 * atexit (CRTDLL.345)
1349 INT32 __cdecl CRTDLL_atexit(LPVOID x)
1351 FIXME(crtdll,"(%p), STUB.\n",x);
1352 return 0; /* successful */
1355 /*********************************************************************
1356 * mblen (CRTDLL.428)
1357 * FIXME: check multibyte support
1359 WCHAR __cdecl CRTDLL_mblen(CHAR *mb,INT32 size)
1366 else if ((size<1)||(!*(mb+1)))
1371 TRACE(crtdll,"CRTDLL_mlen %s for max %d bytes ret %d\n",mb,size,ret);
1376 /*********************************************************************
1377 * mbstowcs (CRTDLL.429)
1378 * FIXME: check multibyte support
1380 INT32 __cdecl CRTDLL_mbstowcs(LPWSTR wcs, LPCSTR mbs, INT32 size)
1383 /* Slightly modified lstrcpynAtoW functions from memory/strings.c
1384 * We need the number of characters transfered
1385 * FIXME: No multibyte support yet
1392 while ((n-- > 0) && *src) {
1393 *p++ = (WCHAR)(unsigned char)*src++;
1398 TRACE(crtdll,"CRTDLL_mbstowcs %s for %d chars put %d wchars\n",
1403 /*********************************************************************
1404 * mbtowc (CRTDLL.430)
1405 * FIXME: check multibyte support
1407 WCHAR __cdecl CRTDLL_mbtowc(WCHAR* wc,CHAR* mb,INT32 size)
1416 if ( (ret = mblen(mb,size)) != -1 )
1418 if (ret <= sizeof(char))
1419 *wc = (WCHAR) ((unsigned char)*mb);
1426 TRACE(crtdll,"CRTDLL_mbtowc %s for %d chars\n",mb,size);
1431 /*********************************************************************
1432 * _isctype (CRTDLL.138)
1434 BOOL32 __cdecl CRTDLL__isctype(CHAR x,CHAR type)
1436 if ((type & CRTDLL_SPACE) && isspace(x))
1438 if ((type & CRTDLL_PUNCT) && ispunct(x))
1440 if ((type & CRTDLL_LOWER) && islower(x))
1442 if ((type & CRTDLL_UPPER) && isupper(x))
1444 if ((type & CRTDLL_ALPHA) && isalpha(x))
1446 if ((type & CRTDLL_DIGIT) && isdigit(x))
1448 if ((type & CRTDLL_CONTROL) && iscntrl(x))
1450 /* check CRTDLL_LEADBYTE */
1454 /*********************************************************************
1455 * _chdrive (CRTDLL.52)
1457 BOOL32 __cdecl CRTDLL__chdrive(INT32 newdrive)
1459 /* FIXME: generates errnos */
1460 return DRIVE_SetCurrentDrive(newdrive);
1463 /*********************************************************************
1464 * _chdir (CRTDLL.51)
1466 INT32 __cdecl CRTDLL__chdir(LPCSTR newdir)
1468 if (!SetCurrentDirectory32A(newdir))
1473 /*********************************************************************
1474 * _fullpath (CRTDLL.114)
1476 LPSTR __cdecl CRTDLL__fullpath(LPSTR buf, LPCSTR name, INT32 size)
1478 DOS_FULL_NAME full_name;
1483 if(!(buf = CRTDLL_malloc(size))) return NULL;
1485 if (!DOSFS_GetFullName( name, FALSE, &full_name )) return NULL;
1486 lstrcpyn32A(buf,full_name.short_name,size);
1487 TRACE(crtdll,"CRTDLL_fullpath got %s\n",buf);
1491 /*********************************************************************
1492 * _splitpath (CRTDLL.279)
1494 VOID __cdecl CRTDLL__splitpath(LPCSTR path, LPSTR drive, LPSTR directory, LPSTR filename, LPSTR extension )
1497 directory includes leading and trailing (forward and backward slashes)
1498 filename without dot and slashes
1499 extension with leading dot
1501 char * drivechar,*dirchar,*namechar;
1503 TRACE(crtdll,"CRTDLL__splitpath got %s\n",path);
1505 drivechar = strchr(path,':');
1506 dirchar = strrchr(path,'/');
1507 namechar = strrchr(path,'\\');
1508 dirchar = MAX(dirchar,namechar);
1510 namechar = strrchr(dirchar,'.');
1512 namechar = strrchr(path,'.');
1520 strncat(drive,path,drivechar-path+1);
1529 strncat(directory,path,dirchar-path+1);
1538 strncat(filename,path,namechar-path);
1542 strcat(extension,namechar);
1547 TRACE(crtdll,"CRTDLL__splitpath found %s %s %s %s\n",drive,directory,filename,extension);
1551 /*********************************************************************
1552 * _getcwd (CRTDLL.120)
1554 CHAR* __cdecl CRTDLL__getcwd(LPSTR buf, INT32 size)
1561 if (size < 0) /* allocate as big as nescessary */
1562 len =GetCurrentDirectory32A(1,test) + 1;
1563 if(!(buf = CRTDLL_malloc(len)))
1565 /* set error to OutOfRange */
1570 if(!(len =GetCurrentDirectory32A(len,buf)))
1576 /* set error to ERANGE */
1577 TRACE(crtdll,"CRTDLL_getcwd buffer to small\n");
1584 /*********************************************************************
1585 * _mkdir (CRTDLL.234)
1587 INT32 __cdecl CRTDLL__mkdir(LPCSTR newdir)
1589 if (!CreateDirectory32A(newdir,NULL))
1594 /*********************************************************************
1595 * _errno (CRTDLL.52)
1596 * Yes, this is a function.
1598 LPINT32 __cdecl CRTDLL__errno()
1600 static int crtdllerrno;
1601 extern int LastErrorToErrno(DWORD);
1603 /* FIXME: we should set the error at the failing function call time */
1604 crtdllerrno = LastErrorToErrno(GetLastError());
1605 return &crtdllerrno;
1608 /*********************************************************************
1609 * _tempnam (CRTDLL.305)
1612 LPSTR __cdecl CRTDLL__tempnam(LPCSTR dir, LPCSTR prefix)
1616 DOS_FULL_NAME tempname;
1618 if ((ret = tempnam(dir,prefix))==NULL) {
1619 WARN(crtdll, "Unable to get unique filename\n");
1622 if (!DOSFS_GetFullName(ret,FALSE,&tempname))
1624 TRACE(crtdll, "Wrong path?\n");
1628 if ((ret = CRTDLL_malloc(strlen(tempname.short_name)+1)) == NULL) {
1629 WARN(crtdll, "CRTDL_malloc for shortname failed\n");
1632 if ((ret = strcpy(ret,tempname.short_name)) == NULL) {
1633 WARN(crtdll, "Malloc for shortname failed\n");
1637 TRACE(crtdll,"dir %s prefix %s got %s\n",
1642 /*********************************************************************
1643 * tmpnam (CRTDLL.490)
1645 * lcclnk from lcc-win32 relies on a terminating dot in the name returned
1648 LPSTR __cdecl CRTDLL_tmpnam(LPSTR s)
1652 if ((ret =tmpnam(s))== NULL) {
1653 WARN(crtdll, "Unable to get unique filename\n");
1656 if (!DOSFS_GetFullName(ret,FALSE,&CRTDLL_tmpname))
1658 TRACE(crtdll, "Wrong path?\n");
1661 strcat(CRTDLL_tmpname.short_name,".");
1662 TRACE(crtdll,"for buf %p got %s\n",
1663 s,CRTDLL_tmpname.short_name);
1664 TRACE(crtdll,"long got %s\n",
1665 CRTDLL_tmpname.long_name);
1667 return strcpy(s,CRTDLL_tmpname.short_name);
1669 return CRTDLL_tmpname.short_name;
1673 /*********************************************************************
1674 * _itoa (CRTDLL.165)
1676 LPSTR __cdecl CRTDLL__itoa(INT32 x,LPSTR buf,INT32 buflen)
1678 wsnprintf32A(buf,buflen,"%d",x);
1682 typedef VOID (*sig_handler_type)(VOID);
1684 /*********************************************************************
1685 * signal (CRTDLL.455)
1687 VOID __cdecl CRTDLL_signal(int sig, sig_handler_type ptr)
1689 FIXME(crtdll, "(%d %p): STUB!\n", sig, ptr);
1692 /*********************************************************************
1693 * _ftol (CRTDLL.113)
1695 LONG __cdecl CRTDLL__ftol(double fl) {
1698 /*********************************************************************
1699 * _sleep (CRTDLL.267)
1701 VOID __cdecl CRTDLL__sleep(unsigned long timeout)
1703 TRACE(crtdll,"CRTDLL__sleep for %ld milliseconds\n",timeout);
1704 Sleep((timeout)?timeout:1);