Release 970914
[wine] / misc / crtdll.c
1 /*
2  * The C RunTime DLL
3  * 
4  * Implements C run-time functionality as known from UNIX.
5  *
6  * Copyright 1996 Marcus Meissner
7  * Copyright 1996 Jukka Iivonen
8  * Copyright 1997 Uwe Bonnes
9  */
10
11 /*
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
19 */
20
21 /* FIXME: all the file handling is hopelessly broken -- AJ */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <time.h>
29 #include <ctype.h>
30 #include <math.h>
31 #include <fcntl.h>
32 #include "win.h"
33 #include "windows.h"
34 #include "stddebug.h"
35 #include "debug.h"
36 #include "module.h"
37 #include "xmalloc.h"
38 #include "heap.h"
39 #include "crtdll.h"
40 #include "drive.h"
41 #include "file.h"
42
43 extern int FILE_GetUnixHandle( HFILE32  );
44
45 static DOS_FULL_NAME CRTDLL_tmpname;
46
47 extern INT32 WIN32_wsprintf32W( DWORD *args );
48
49 UINT32 CRTDLL_argc_dll;         /* CRTDLL.23 */
50 LPSTR *CRTDLL_argv_dll;         /* CRTDLL.24 */
51 LPSTR  CRTDLL_acmdln_dll;       /* CRTDLL.38 */
52 UINT32 CRTDLL_basemajor_dll;    /* CRTDLL.42 */
53 UINT32 CRTDLL_baseminor_dll;    /* CRTDLL.43 */
54 UINT32 CRTDLL_baseversion_dll;  /* CRTDLL.44 */
55 LPSTR  CRTDLL_environ_dll;      /* CRTDLL.75 */
56 UINT32 CRTDLL_osmajor_dll;      /* CRTDLL.241 */
57 UINT32 CRTDLL_osminor_dll;      /* CRTDLL.242 */
58 UINT32 CRTDLL_osver_dll;        /* CRTDLL.244 */
59 UINT32 CRTDLL_osversion_dll;    /* CRTDLL.245 */
60 UINT32 CRTDLL_winmajor_dll;     /* CRTDLL.329 */
61 UINT32 CRTDLL_winminor_dll;     /* CRTDLL.330 */
62 UINT32 CRTDLL_winver_dll;       /* CRTDLL.331 */
63
64 typedef VOID (*new_handler_type)(VOID);
65
66 static new_handler_type new_handler;
67
68 /*********************************************************************
69  *                  _GetMainArgs  (CRTDLL.022)
70  */
71 DWORD __cdecl CRTDLL__GetMainArgs(LPDWORD argc,LPSTR **argv,
72                                 LPSTR *environ,DWORD flag)
73 {
74         char *cmdline;
75         char  **xargv;
76         int     xargc,i,afterlastspace;
77         DWORD   version;
78
79         dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs(%p,%p,%p,%ld).\n",
80                 argc,argv,environ,flag
81         );
82         CRTDLL_acmdln_dll = cmdline = xstrdup( GetCommandLine32A() );
83         dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs got \"%s\"\n",
84                 cmdline);
85
86         version = GetVersion32();
87         CRTDLL_osver_dll       = version >> 16;
88         CRTDLL_winminor_dll    = version & 0xFF;
89         CRTDLL_winmajor_dll    = (version>>8) & 0xFF;
90         CRTDLL_baseversion_dll = version >> 16;
91         CRTDLL_winver_dll      = ((version >> 8) & 0xFF) + ((version & 0xFF) << 8);
92         CRTDLL_baseminor_dll   = (version >> 16) & 0xFF;
93         CRTDLL_basemajor_dll   = (version >> 24) & 0xFF;
94         CRTDLL_osversion_dll   = version & 0xFFFF;
95         CRTDLL_osminor_dll     = version & 0xFF;
96         CRTDLL_osmajor_dll     = (version>>8) & 0xFF;
97
98         /* missing threading init */
99
100         i=0;xargv=NULL;xargc=0;afterlastspace=0;
101         while (cmdline[i]) {
102                 if (cmdline[i]==' ') {
103                         xargv=(char**)xrealloc(xargv,sizeof(char*)*(++xargc));
104                         cmdline[i]='\0';
105                         xargv[xargc-1] = xstrdup(cmdline+afterlastspace);
106                         i++;
107                         while (cmdline[i]==' ')
108                                 i++;
109                         if (cmdline[i])
110                                 afterlastspace=i;
111                 } else
112                         i++;
113         }
114         xargv=(char**)xrealloc(xargv,sizeof(char*)*(++xargc));
115         cmdline[i]='\0';
116         xargv[xargc-1] = xstrdup(cmdline+afterlastspace);
117         CRTDLL_argc_dll = xargc;
118         *argc           = xargc;
119         CRTDLL_argv_dll = xargv;
120         *argv           = xargv;
121
122         dprintf_crtdll(stddeb,"CRTDLL__GetMainArgs found %d arguments\n",
123                 CRTDLL_argc_dll);
124         /* FIXME ... use real environment */
125         *environ        = xmalloc(sizeof(LPSTR));
126         CRTDLL_environ_dll = *environ;
127         (*environ)[0] = NULL;
128         return 0;
129 }
130
131
132 typedef void (*_INITTERMFUN)();
133
134 /*********************************************************************
135  *                  _initterm     (CRTDLL.135)
136  */
137 DWORD __cdecl CRTDLL__initterm(_INITTERMFUN *start,_INITTERMFUN *end)
138 {
139         _INITTERMFUN    *current;
140
141         dprintf_crtdll(stddeb,"_initterm(%p,%p)\n",start,end);
142         current=start;
143         while (current<end) {
144                 if (*current) (*current)();
145                 current++;
146         }
147         return 0;
148 }
149
150 /*********************************************************************
151  *                  _fdopen     (CRTDLL.91)
152  */
153 DWORD __cdecl CRTDLL__fdopen(INT32 handle, LPCSTR mode)
154 {
155   FILE *file;
156
157   switch (handle) 
158     {
159     case 0 : file=stdin;
160       break;
161     case 1 : file=stdout;
162       break;
163     case 2 : file=stderr;
164       break;
165     default:
166       file=fdopen(handle,mode);
167     }
168   dprintf_crtdll(stddeb,
169                  "CRTDLL_fdopen open handle %d mode %s  got file %p\n",
170                  handle, mode, file);
171   return (DWORD)file;
172 }
173
174 /*********************************************************************
175  *                  fopen     (CRTDLL.372)
176  */
177 DWORD __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
178 {
179   FILE *file;
180   HFILE32 dos_fildes;
181 #if 0
182   DOS_FULL_NAME full_name;
183   
184   if (!DOSFS_GetFullName( path, FALSE, &full_name )) {
185     dprintf_crtdll(stddeb,"CRTDLL_fopen file %s bad name\n",path);
186    return 0;
187   }
188   
189   file=fopen(full_name.long_name ,mode);
190 #endif
191   INT32 flagmode=0;
192   int unix_fildes=0;
193
194   if ((strchr(mode,'r')&&strchr(mode,'a'))||
195       (strchr(mode,'r')&&strchr(mode,'w'))||
196       (strchr(mode,'w')&&strchr(mode,'a')))
197     return 0;
198        
199   if (strstr(mode,"r+")) flagmode=O_RDWR;
200   else if (strchr(mode,'r')) flagmode = O_RDONLY;
201   else if (strstr(mode,"w+")) flagmode= O_RDWR | O_TRUNC | O_CREAT;
202   else if (strchr(mode,'w')) flagmode = O_WRONLY | O_TRUNC | O_CREAT;
203   else if (strstr(mode,"a+")) flagmode= O_RDWR | O_CREAT | O_APPEND;
204   else if (strchr(mode,'w')) flagmode = O_RDWR | O_CREAT | O_APPEND;
205   else if (strchr(mode,'b'))
206     dprintf_crtdll(stderr,
207                    "CRTDLL_fopen %s in BINARY mode\n",path);
208       
209   dos_fildes=FILE_Open(path, flagmode);
210   unix_fildes=FILE_GetUnixHandle(dos_fildes);
211   file = fdopen(unix_fildes,mode);
212
213   dprintf_crtdll(stddeb,
214                  "CRTDLL_fopen file %s mode %s got ufh %d dfh %d file %p\n",
215                  path,mode,unix_fildes,dos_fildes,file);
216   return (DWORD)file;
217 }
218
219 /*********************************************************************
220  *                  fread     (CRTDLL.377)
221  */
222 DWORD __cdecl CRTDLL_fread(LPVOID ptr, INT32 size, INT32 nmemb, LPVOID file)
223 {
224   size_t ret=1;
225 #if 0
226   int i=0;
227   void *temp=ptr;
228
229   /* If we would honour CR/LF <-> LF translation, we could do it like this.
230      We should keep track of all files opened, and probably files with \
231      known binary extensions must be unchanged */
232   while ( (i < (nmemb*size)) && (ret==1)) {
233     ret=fread(temp,1,1,file);
234     dprintf_crtdll(stddeb,
235                  "CRTDLL_fread got %c 0x%02x ret %d\n",
236                    (isalpha(*(unsigned char*)temp))? *(unsigned char*)temp:
237                     ' ',*(unsigned char*)temp, ret);
238     if (*(unsigned char*)temp != 0xd) { /* skip CR */
239       temp++;
240       i++;
241     }
242     else
243       dprintf_crtdll(stddeb, "CRTDLL_fread skipping ^M\n");
244   }
245   dprintf_crtdll(stddeb,
246                  "CRTDLL_fread 0x%08x items of size %d from file %p to %p%s\n",
247                  nmemb,size,file,ptr,(i!=nmemb)?" failed":"");
248   return i;
249 #else
250     
251   ret=fread(ptr,size,nmemb,file);
252   dprintf_crtdll(stddeb,
253                  "CRTDLL_fread 0x%08x items of size %d from file %p to %p%s\n",
254                  nmemb,size,file,ptr,(ret!=nmemb)?" failed":"");
255   return ret;
256 #endif
257 }
258   
259 /*********************************************************************
260  *                  fseek     (CRTDLL.382)
261  */
262 LONG __cdecl CRTDLL_fseek(LPVOID stream, LONG offset, INT32 whence)
263 {
264   long ret;
265
266   ret=fseek(stream,offset,whence);
267   dprintf_crtdll(stddeb,
268                  "CRTDLL_fseek file %p to 0x%08lx pos %s%s\n",
269                  stream,offset,(whence==SEEK_SET)?"SEEK_SET":
270                  (whence==SEEK_CUR)?"SEEK_CUR":
271                  (whence==SEEK_END)?"SEEK_END":"UNKNOWN",
272                  (ret)?"failed":"");
273   return ret;
274 }
275   
276 /*********************************************************************
277  *                  ftell     (CRTDLL.384)
278  */
279 LONG __cdecl CRTDLL_ftell(LPVOID stream)
280 {
281   long ret;
282
283   ret=ftell(stream);
284   dprintf_crtdll(stddeb,
285                  "CRTDLL_ftell file %p at 0x%08lx\n",
286                  stream,ret);
287   return ret;
288 }
289   
290 /*********************************************************************
291  *                  fwrite     (CRTDLL.386)
292  */
293 DWORD __cdecl CRTDLL_fwrite(LPVOID ptr, INT32 size, INT32 nmemb, LPVOID file)
294 {
295   size_t ret;
296
297   ret=fwrite(ptr,size,nmemb,file);
298   dprintf_crtdll(stddeb,
299                  "CRTDLL_fwrite 0x%08x items of size %d from %p to file %p%s\n",
300                  nmemb,size,ptr,file,(ret!=nmemb)?" failed":"");
301   return ret;
302 }
303
304 /*********************************************************************
305  *                  setbuf     (CRTDLL.452)
306  */
307 INT32 __cdecl CRTDLL_setbuf(LPVOID file, LPSTR buf)
308 {
309   dprintf_crtdll(stddeb,
310                  "CRTDLL_setbuf(file %p buf %p)\n",
311                  file,buf);
312   /* this doesn't work:"void value not ignored as it ought to be" 
313   return setbuf(file,buf); 
314   */
315   setbuf(file,buf);
316   return 0;
317 }
318
319 /*********************************************************************
320  *                  _open_osfhandle         (CRTDLL.240)
321  */
322 HFILE32 __cdecl CRTDLL__open_osfhandle(LONG osfhandle, INT32 flags)
323 {
324 HFILE32 handle;
325  
326         switch (osfhandle) {
327         case STD_INPUT_HANDLE :
328         case 0 :
329           handle=0;
330           break;
331         case STD_OUTPUT_HANDLE:
332         case 1:
333           handle=1;
334           break;
335         case STD_ERROR_HANDLE:
336         case 2:
337           handle=2;
338           break;
339         default:
340           return (-1);
341         }
342         dprintf_crtdll(stddeb,
343                        "CRTDLL_open_osfhandle(handle %08lx,flags %d) return %d\n",
344                        osfhandle,flags,handle);
345         return handle;
346         
347 }
348
349 /*********************************************************************
350  *                  srand         (CRTDLL.460)
351  */
352 void __cdecl CRTDLL_srand(DWORD seed)
353 {
354         /* FIXME: should of course be thread? process? local */
355         srand(seed);
356 }
357
358 /*********************************************************************
359  *                  fprintf       (CRTDLL.373)
360  */
361 INT32 __cdecl CRTDLL_fprintf( FILE *file, LPSTR format, ... )
362 {
363     va_list valist;
364     INT32 res;
365
366     va_start( valist, format );
367     res = vfprintf( file, format, valist );
368     va_end( valist );
369     return res;
370 }
371
372 /*********************************************************************
373  *                  vfprintf       (CRTDLL.373)
374  */
375 INT32 __cdecl CRTDLL_vfprintf( FILE *file, LPSTR format, va_list args )
376 {
377     return vfprintf( file, format, args );
378 }
379
380 /*********************************************************************
381  *                  time          (CRTDLL.488)
382  */
383 time_t __cdecl CRTDLL_time(time_t *timeptr)
384 {
385         time_t  curtime = time(NULL);
386
387         if (timeptr)
388                 *timeptr = curtime;
389         return curtime;
390 }
391
392 /*********************************************************************
393  *                  _isatty       (CRTDLL.137)
394  */
395 BOOL32 __cdecl CRTDLL__isatty(DWORD x)
396 {
397         dprintf_crtdll(stderr,"CRTDLL__isatty(%ld)\n",x);
398         return TRUE;
399 }
400
401 /*********************************************************************
402  *                  _write        (CRTDLL.332)
403  */
404 INT32 __cdecl CRTDLL__write(INT32 fd,LPCVOID buf,UINT32 count)
405 {
406         INT32 len=0;
407
408         if (fd == -1)
409           len = -1;
410         else if (fd<=2)
411           len = (UINT32)write(fd,buf,(LONG)len);
412         else
413           len = _lwrite32(fd,buf,count);
414         dprintf_crtdll(stddeb,"CRTDLL_write %d/%d byte to dfh %d from %p,\n",
415                        len,count,fd,buf);
416         return len;
417 }
418
419
420 /*********************************************************************
421  *                  _cexit          (CRTDLL.49)
422  *
423  *  FIXME: What the heck is the difference between 
424  *  FIXME           _c_exit         (CRTDLL.47)
425  *  FIXME           _cexit          (CRTDLL.49)
426  *  FIXME           _exit           (CRTDLL.87)
427  *  FIXME           exit            (CRTDLL.359)
428  *
429  */
430 void __cdecl CRTDLL__cexit(INT32 ret)
431 {
432         dprintf_crtdll(stddeb,"CRTDLL__cexit(%d)\n",ret);
433         ExitProcess(ret);
434 }
435
436
437 /*********************************************************************
438  *                  exit          (CRTDLL.359)
439  */
440 void __cdecl CRTDLL_exit(DWORD ret)
441 {
442         dprintf_crtdll(stddeb,"CRTDLL_exit(%ld)\n",ret);
443         ExitProcess(ret);
444 }
445
446
447 /*********************************************************************
448  *                  fflush        (CRTDLL.365)
449  */
450 INT32 __cdecl CRTDLL_fflush(LPVOID stream)
451 {
452     int ret;
453
454     ret = fflush(stream);
455     dprintf_crtdll(stddeb,"CRTDLL_fflush %p returnd %d %s\n",stream,ret,(ret)?"":" failed");
456     return ret;
457 }
458
459
460 /*********************************************************************
461  *                  gets          (CRTDLL.391)
462  */
463 LPSTR __cdecl CRTDLL_gets(LPSTR buf)
464 {
465   /* BAD, for the whole WINE process blocks... just done this way to test
466    * windows95's ftp.exe.
467    */
468     return gets(buf);
469 }
470
471
472 /*********************************************************************
473  *                  rand          (CRTDLL.446)
474  */
475 INT32 __cdecl CRTDLL_rand()
476 {
477     return rand();
478 }
479
480
481 /*********************************************************************
482  *                  putchar       (CRTDLL.442)
483  */
484 void __cdecl CRTDLL_putchar( INT32 x )
485 {
486     putchar(x);
487 }
488
489
490 /*********************************************************************
491  *                  fputc       (CRTDLL.374)
492  */
493 INT32 __cdecl CRTDLL_fputc( INT32 c, FILE *stream )
494 {
495   dprintf_crtdll(stddeb,
496                  "CRTDLL_fputc %c to file %p\n",c,stream);
497     return fputc(c,stream);
498 }
499
500
501 /*********************************************************************
502  *                  fputs       (CRTDLL.375)
503  */
504 INT32 __cdecl CRTDLL_fputs( LPCSTR s, FILE *stream )
505 {
506   dprintf_crtdll(stddeb,
507                  "CRTDLL_fputs %s to file %p\n",s,stream);
508     return fputs(s,stream);
509 }
510
511
512 /*********************************************************************
513  *                  puts       (CRTDLL.443)
514  */
515 INT32 __cdecl CRTDLL_puts(LPCSTR s)
516 {
517   dprintf_crtdll(stddeb,
518                  "CRTDLL_fputs %s \n",s);
519     return puts(s);
520 }
521
522
523 /*********************************************************************
524  *                  putc       (CRTDLL.441)
525  */
526 INT32 __cdecl CRTDLL_putc(INT32 c, FILE *stream)
527 {
528   dprintf_crtdll(stddeb,
529                  "CRTDLL_putc %c to file %p\n",c,stream);
530     return fputc(c,stream);
531 }
532 /*********************************************************************
533  *                  fgetc       (CRTDLL.366)
534  */
535 INT32 __cdecl CRTDLL_fgetc( FILE *stream )
536 {
537   int ret= fgetc(stream);
538   dprintf_crtdll(stddeb,
539                  "CRTDLL_fgetc got %d\n",ret);
540   return ret;
541 }
542
543
544 /*********************************************************************
545  *                  getc       (CRTDLL.388)
546  */
547 INT32 __cdecl CRTDLL_getc( FILE *stream )
548 {
549   int ret= fgetc(stream);
550   dprintf_crtdll(stddeb,
551                  "CRTDLL_getc got %d\n",ret);
552   return ret;
553 }
554
555 /*********************************************************************
556  *                  _lrotl          (CRTDLL.176)
557  */
558 DWORD __cdecl CRTDLL__lrotl(DWORD x,INT32 shift)
559 {
560    unsigned long ret = (x >> shift)|( x >>((sizeof(x))-shift));
561
562    dprintf_crtdll(stddeb,
563                   "CRTDLL_lrotl got 0x%08lx rot %d ret 0x%08lx\n",
564                   x,shift,ret);
565    return ret;
566     
567 }
568
569
570 /*********************************************************************
571  *                  fgets       (CRTDLL.368)
572  */
573 CHAR* __cdecl CRTDLL_fgets(LPSTR s,INT32 size, LPVOID stream)
574 {
575   char * ret;
576   char * control_M;
577   
578   ret=fgets(s, size,stream);
579   /*FIXME: Control with CRTDLL_setmode */
580   control_M= strrchr(s,'\r');
581   /*delete CR if we read a DOS File */
582   if (control_M)
583     {
584       *control_M='\n';
585       *(control_M+1)=0;
586     }
587   dprintf_crtdll(stddeb,
588                  "CRTDLL_fgets got %s for %d chars from file %p%s\n",
589                  s,size,stream,(ret)?"":" failed");
590   return ret;
591 }
592
593
594 /*********************************************************************
595  *                  _mbsicmp      (CRTDLL.204)
596  */
597 int __cdecl CRTDLL__mbsicmp(unsigned char *x,unsigned char *y)
598 {
599     do {
600         if (!*x)
601             return !!*y;
602         if (!*y)
603             return !!*x;
604         /* FIXME: MBCS handling... */
605         if (*x!=*y)
606             return 1;
607         x++;
608         y++;
609     } while (1);
610 }
611
612
613 /*********************************************************************
614  *                  _mbsinc       (CRTDLL.205)
615  */
616 unsigned char * __cdecl CRTDLL__mbsinc(unsigned char *x)
617 {
618     /* FIXME: mbcs */
619     return x++;
620 }
621
622
623 /*********************************************************************
624  *                  vsprintf      (CRTDLL.500)
625  */
626 INT32 __cdecl CRTDLL_vsprintf( LPSTR buffer, LPCSTR spec, va_list args )
627 {
628     return wvsprintf32A( buffer, spec, args );
629 }
630
631 /*********************************************************************
632  *                  vswprintf      (CRTDLL.501)
633  */
634 INT32 __cdecl CRTDLL_vswprintf( LPWSTR buffer, LPCWSTR spec, va_list args )
635 {
636     return wvsprintf32W( buffer, spec, args );
637 }
638
639 /*********************************************************************
640  *                  _mbscpy       (CRTDLL.200)
641  */
642 unsigned char* __cdecl CRTDLL__mbscpy(unsigned char *x,unsigned char *y)
643 {
644     dprintf_crtdll(stddeb,"CRTDLL_mbscpy %s and %s\n",x,y);
645     return strcpy(x,y);
646 }
647
648
649 /*********************************************************************
650  *                  _mbscat       (CRTDLL.197)
651  */
652 unsigned char* __cdecl CRTDLL__mbscat(unsigned char *x,unsigned char *y)
653 {
654     return strcat(x,y);
655 }
656
657
658 /*********************************************************************
659  *                  _strcmpi   (CRTDLL.282) (CRTDLL.287)
660  */
661 INT32 __cdecl CRTDLL__strcmpi( LPCSTR s1, LPCSTR s2 )
662 {
663     return lstrcmpi32A( s1, s2 );
664 }
665
666
667 /*********************************************************************
668  *                  _strnicmp   (CRTDLL.293)
669  */
670 INT32 __cdecl CRTDLL__strnicmp( LPCSTR s1, LPCSTR s2, INT32 n )
671 {
672     return lstrncmpi32A( s1, s2, n );
673 }
674
675
676 /*********************************************************************
677  *                  _strlwr      (CRTDLL.293)
678  *
679  * convert a string in place to lowercase 
680  */
681 LPSTR CRTDLL__strlwr(LPSTR x)
682 {
683   unsigned char *y =x;
684   
685   dprintf_crtdll(stddeb,
686                  "CRTDLL_strlwr got %s",x);
687   while (*y) {
688     if ((*y > 0x40) && (*y< 0x5b))
689       *y = *y + 0x20;
690     y++;
691   }
692   dprintf_crtdll(stddeb," returned %s\n",x);
693                  
694   return x;
695 }
696
697 /*********************************************************************
698  *                  system       (CRTDLL.485)
699  */
700 INT32 CRTDLL_system(LPSTR x)
701 {
702 #define SYSBUF_LENGTH 1500
703   char buffer[SYSBUF_LENGTH]="wine \"";
704   unsigned char *y =x;
705   unsigned char *bp =buffer+strlen(buffer);
706   int i =strlen(buffer) + strlen(x) +2;
707
708   /* Calculate needed buffer size tp prevent overflow*/
709   while (*y) {
710     if (*y =='\\') i++;
711     y++;
712   }
713   /* if buffer to short, exit */
714   if (i > SYSBUF_LENGTH) {
715     dprintf_crtdll(stddeb,"_system buffer to small\n");
716     return 127;
717   }
718   
719   y =x;
720
721   while (*y) {
722     *bp = *y;
723     bp++; y++;
724     if (*(y-1) =='\\') *bp++ = '\\';
725   }
726   /* remove spaces from end of string */
727   while (*(y-1) == ' ') {
728     bp--;y--;
729   }
730   *bp++ = '"';
731   *bp = 0;
732   dprintf_crtdll(stddeb,
733                  "_system got \"%s\", executing \"%s\"\n",x,buffer);
734
735   return system(buffer);
736 }
737
738 /*********************************************************************
739  *                  _strupr       (CRTDLL.300)
740  */
741 LPSTR __cdecl CRTDLL__strupr(LPSTR x)
742 {
743         LPSTR   y=x;
744
745         while (*y) {
746                 *y=toupper(*y);
747                 y++;
748         }
749         return x;
750 }
751
752 /*********************************************************************
753  *                  _wcsupr       (CRTDLL.328)
754  */
755 LPWSTR __cdecl CRTDLL__wcsupr(LPWSTR x)
756 {
757         LPWSTR  y=x;
758
759         while (*y) {
760                 *y=toupper(*y);
761                 y++;
762         }
763         return x;
764 }
765
766 /*********************************************************************
767  *                  _wcslwr       (CRTDLL.323)
768  */
769 LPWSTR __cdecl CRTDLL__wcslwr(LPWSTR x)
770 {
771         LPWSTR  y=x;
772
773         while (*y) {
774                 *y=tolower(*y);
775                 y++;
776         }
777         return x;
778 }
779
780
781 /*********************************************************************
782  *                  malloc        (CRTDLL.427)
783  */
784 VOID* __cdecl CRTDLL_malloc(DWORD size)
785 {
786     return HeapAlloc(GetProcessHeap(),0,size);
787 }
788
789 /*********************************************************************
790  *                  new           (CRTDLL.001)
791  */
792 VOID* __cdecl CRTDLL_new(DWORD size)
793 {
794     VOID* result;
795     if(!(result = HeapAlloc(GetProcessHeap(),0,size)) && new_handler)
796         (*new_handler)();
797     return result;
798 }
799
800 /*********************************************************************
801  *                  set_new_handler(CRTDLL.003)
802  */
803 new_handler_type __cdecl CRTDLL_set_new_handler(new_handler_type func)
804 {
805     new_handler_type old_handler = new_handler;
806     new_handler = func;
807     return old_handler;
808 }
809
810 /*********************************************************************
811  *                  calloc        (CRTDLL.350)
812  */
813 VOID* __cdecl CRTDLL_calloc(DWORD size, DWORD count)
814 {
815     return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
816 }
817
818 /*********************************************************************
819  *                  realloc        (CRTDLL.447)
820  */
821 VOID* __cdecl CRTDLL_realloc( VOID *ptr, DWORD size )
822 {
823     return HeapReAlloc( GetProcessHeap(), 0, ptr, size );
824 }
825
826 /*********************************************************************
827  *                  free          (CRTDLL.427)
828  */
829 VOID __cdecl CRTDLL_free(LPVOID ptr)
830 {
831     HeapFree(GetProcessHeap(),0,ptr);
832 }
833
834 /*********************************************************************
835  *                  delete       (CRTDLL.002)
836  */
837 VOID __cdecl CRTDLL_delete(VOID* ptr)
838 {
839     HeapFree(GetProcessHeap(),0,ptr);
840 }
841
842 /*********************************************************************
843  *                  _strdup          (CRTDLL.285)
844  */
845 LPSTR __cdecl CRTDLL__strdup(LPSTR ptr)
846 {
847     return HEAP_strdupA(GetProcessHeap(),0,ptr);
848 }
849
850
851 /*********************************************************************
852  *                  fclose           (CRTDLL.362)
853  */
854 INT32 __cdecl CRTDLL_fclose( FILE *stream )
855 {
856     int unix_handle=fileno(stream);
857     HFILE32 dos_handle=3;
858     HFILE32 ret=EOF;
859
860     if (unix_handle<4) ret= fclose(stream);
861     else {
862       while(FILE_GetUnixHandle(dos_handle) != unix_handle) dos_handle++;
863       fclose(stream);
864       ret = _lclose32( dos_handle);
865     }
866     dprintf_crtdll(stddeb,"CRTDLL_fclose(%p) ufh %d dfh %d%s\n",
867                    stream,unix_handle,dos_handle,(ret)?" failed":"");
868     return ret;
869 }
870
871 /*********************************************************************
872  *                  _unlink           (CRTDLL.315)
873  */
874 INT32 __cdecl CRTDLL__unlink(LPCSTR pathname)
875 {
876     int ret=0;
877     DOS_FULL_NAME full_name;
878
879     if (!DOSFS_GetFullName( pathname, FALSE, &full_name )) {
880       dprintf_crtdll(stddeb,"CRTDLL_unlink file %s bad name\n",pathname);
881       return EOF;
882     }
883   
884     ret=unlink(full_name.long_name);
885     dprintf_crtdll(stddeb,"CRTDLL_unlink(%s unix %s)%s\n",
886                    pathname,full_name.long_name, (ret)?" failed":"");
887     return ret;
888 }
889
890 /*********************************************************************
891  *                  _open           (CRTDLL.239)
892  */
893 HFILE32 __cdecl CRTDLL__open(LPCSTR path,INT32 flags)
894 {
895     HFILE32 ret=0;
896     int wineflags=0;
897     
898     /* FIXME:
899        the flags in lcc's header differ from the ones in Linux, e.g.
900        Linux: define O_APPEND         02000   (= 0x400)
901        lcc:  define _O_APPEND       0x0008  
902        so here a scheme to translate them
903        Probably lcc is wrong here, but at least a hack to get is going
904        */
905     wineflags = (flags & 3);
906     if (flags & 0x0008 ) wineflags |= O_APPEND;
907     if (flags & 0x0100 ) wineflags |= O_CREAT;
908     if (flags & 0x0200 ) wineflags |= O_TRUNC;
909     if (flags & 0x0400 ) wineflags |= O_EXCL;
910     if (flags & 0xf0f4 ) 
911       dprintf_crtdll(stddeb,"CRTDLL_open file unsupported flags 0x%04x\n",flags);
912     /* End Fixme */
913
914     ret = FILE_Open(path,wineflags);
915     dprintf_crtdll(stddeb,"CRTDLL_open file %s mode 0x%04x (lccmode 0x%04x) got dfh %d\n",
916                    path,wineflags,flags,ret);
917     return ret;
918 }
919
920 /*********************************************************************
921  *                  _close           (CRTDLL.57)
922  */
923 INT32 __cdecl CRTDLL__close(HFILE32 fd)
924 {
925     int ret=_lclose32(fd);
926
927     dprintf_crtdll(stddeb,"CRTDLL_close(%d)%s\n",fd,(ret)?" failed":"");
928     return ret;
929 }
930
931 /*********************************************************************
932  *                  feof           (CRTDLL.363)
933  */
934 INT32 __cdecl CRTDLL_feof( FILE *stream )
935 {
936     int ret;
937     
938     ret=feof(stream);
939     dprintf_crtdll(stddeb,"CRTDLL_feof(%p) %s\n",stream,(ret)?"true":"false");
940     return ret;
941 }
942
943 /*********************************************************************
944  *                  setlocale           (CRTDLL.453)
945  */
946 LPSTR __cdecl CRTDLL_setlocale(INT32 category,LPCSTR locale)
947 {
948         LPSTR categorystr;
949
950         switch (category) {
951         case CRTDLL_LC_ALL: categorystr="LC_ALL";break;
952         case CRTDLL_LC_COLLATE: categorystr="LC_COLLATE";break;
953         case CRTDLL_LC_CTYPE: categorystr="LC_CTYPE";break;
954         case CRTDLL_LC_MONETARY: categorystr="LC_MONETARY";break;
955         case CRTDLL_LC_NUMERIC: categorystr="LC_NUMERIC";break;
956         case CRTDLL_LC_TIME: categorystr="LC_TIME";break;
957         default: categorystr = "UNKNOWN?";break;
958         }
959         fprintf(stderr,"CRTDLL_setlocale(%s,%s),stub!\n",categorystr,locale);
960         return "C";
961 }
962
963 /*********************************************************************
964  *                  wcscat           (CRTDLL.503)
965  */
966 LPWSTR __cdecl CRTDLL_wcscat( LPWSTR s1, LPCWSTR s2 )
967 {
968     return lstrcat32W( s1, s2 );
969 }
970
971 /*********************************************************************
972  *                  wcschr           (CRTDLL.504)
973  */
974 LPWSTR __cdecl CRTDLL_wcschr(LPWSTR str,WCHAR xchar)
975 {
976         LPWSTR  s;
977
978         s=str;
979         do {
980                 if (*s==xchar)
981                         return s;
982         } while (*s++);
983         return NULL;
984 }
985
986 /*********************************************************************
987  *                  wcscmp           (CRTDLL.505)
988  */
989 INT32 __cdecl CRTDLL_wcscmp( LPCWSTR s1, LPCWSTR s2 )
990 {
991     return lstrcmp32W( s1, s2 );
992 }
993
994 /*********************************************************************
995  *                  wcscpy           (CRTDLL.507)
996  */
997 LPWSTR __cdecl CRTDLL_wcscpy( LPWSTR s1, LPCWSTR s2 )
998 {
999     return lstrcpy32W( s1, s2 );
1000 }
1001
1002 /*********************************************************************
1003  *                  wcscspn           (CRTDLL.508)
1004  */
1005 INT32 __cdecl CRTDLL_wcscspn(LPWSTR str,LPWSTR reject)
1006 {
1007         LPWSTR  s,t;
1008
1009         s=str;
1010         do {
1011                 t=reject;
1012                 while (*t) { if (*t==*s) break;t++;}
1013                 if (*t) break;
1014                 s++;
1015         } while (*s);
1016         return s-str; /* nr of wchars */
1017 }
1018
1019 /*********************************************************************
1020  *                  wcslen           (CRTDLL.510)
1021  */
1022 INT32 __cdecl CRTDLL_wcslen( LPCWSTR s )
1023 {
1024     return lstrlen32W( s );
1025 }
1026
1027 /*********************************************************************
1028  *                  wcsncat           (CRTDLL.511)
1029  */
1030 LPWSTR __cdecl CRTDLL_wcsncat( LPWSTR s1, LPCWSTR s2, INT32 n )
1031 {
1032     return lstrcatn32W( s1, s2, n );
1033 }
1034
1035 /*********************************************************************
1036  *                  wcsncmp           (CRTDLL.512)
1037  */
1038 INT32 __cdecl CRTDLL_wcsncmp( LPCWSTR s1, LPCWSTR s2, INT32 n )
1039 {
1040     return lstrncmp32W( s1, s2, n );
1041 }
1042
1043 /*********************************************************************
1044  *                  wcsncpy           (CRTDLL.513)
1045  */
1046 LPWSTR __cdecl CRTDLL_wcsncpy( LPWSTR s1, LPCWSTR s2, INT32 n )
1047 {
1048     return lstrcpyn32W( s1, s2, n );
1049 }
1050
1051 /*********************************************************************
1052  *                  wcsspn           (CRTDLL.516)
1053  */
1054 INT32 __cdecl CRTDLL_wcsspn(LPWSTR str,LPWSTR accept)
1055 {
1056         LPWSTR  s,t;
1057
1058         s=str;
1059         do {
1060                 t=accept;
1061                 while (*t) { if (*t==*s) break;t++;}
1062                 if (!*t) break;
1063                 s++;
1064         } while (*s);
1065         return s-str; /* nr of wchars */
1066 }
1067
1068 /*********************************************************************
1069  *                  towupper           (CRTDLL.494)
1070  */
1071 WCHAR __cdecl CRTDLL_towupper(WCHAR x)
1072 {
1073     return (WCHAR)toupper((CHAR)x);
1074 }
1075
1076 /*********************************************************************
1077  *                  _wcsicmp           (CRTDLL.321)
1078  */
1079 DWORD __cdecl CRTDLL__wcsicmp( LPCWSTR s1, LPCWSTR s2 )
1080 {
1081     return lstrcmpi32W( s1, s2 );
1082 }
1083
1084 /*********************************************************************
1085  *                  _wcsicoll           (CRTDLL.322)
1086  */
1087 DWORD __cdecl CRTDLL__wcsicoll(LPCWSTR a1,LPCWSTR a2)
1088 {
1089     /* FIXME: handle collates */
1090     return lstrcmpi32W(a1,a2);
1091 }
1092
1093 /*********************************************************************
1094  *                  _wcsnicmp           (CRTDLL.324)
1095  */
1096 DWORD __cdecl CRTDLL__wcsnicmp( LPCWSTR s1, LPCWSTR s2, INT32 len )
1097 {
1098     return lstrncmpi32W( s1, s2, len );
1099 }
1100
1101 /*********************************************************************
1102  *                  wcscoll           (CRTDLL.506)
1103  */
1104 DWORD __cdecl CRTDLL_wcscoll(LPWSTR a1,LPWSTR a2)
1105 {
1106     /* FIXME: handle collates */
1107     return lstrcmp32W(a1,a2);
1108 }
1109
1110 /*********************************************************************
1111  *                  _wcsrev           (CRTDLL.326)
1112  */
1113 VOID __cdecl CRTDLL__wcsrev(LPWSTR s) {
1114         LPWSTR  e;
1115
1116         e=s;
1117         while (*e)
1118                 e++;
1119         while (s<e) {
1120                 WCHAR   a;
1121
1122                 a=*s;*s=*e;*e=a;
1123                 s++;e--;
1124         }
1125 }
1126
1127 /*********************************************************************
1128  *                  wcsstr           (CRTDLL.517)
1129  */
1130 LPWSTR __cdecl CRTDLL_wcsstr(LPWSTR s,LPWSTR b)
1131 {
1132         LPWSTR  x,y,c;
1133
1134         x=s;
1135         while (*x) {
1136                 if (*x==*b) {
1137                         y=x;c=b;
1138                         while (*y && *c && *y==*c) { c++;y++; }
1139                         if (!*c)
1140                                 return x;
1141                 }
1142                 x++;
1143         }
1144         return NULL;
1145 }
1146
1147 /*********************************************************************
1148  *                  wcstombs   (CRTDLL.521)
1149  */
1150 INT32 __cdecl CRTDLL_wcstombs( LPSTR dst, LPCWSTR src, INT32 len )
1151 {
1152     lstrcpynWtoA( dst, src, len );
1153     return strlen(dst);  /* FIXME: is this right? */
1154 }
1155
1156 /*********************************************************************
1157  *                  wcsrchr           (CRTDLL.515)
1158  */
1159 LPWSTR __cdecl CRTDLL_wcsrchr(LPWSTR str,WCHAR xchar)
1160 {
1161         LPWSTR  s;
1162
1163         s=str+lstrlen32W(str);
1164         do {
1165                 if (*s==xchar)
1166                         return s;
1167                 s--;
1168         } while (s>=str);
1169         return NULL;
1170 }
1171
1172 /*********************************************************************
1173  *                  _setmode           (CRTDLL.265)
1174  * FIXME: At present we ignore the request to translate CR/LF to LF.
1175  *
1176  * We allways translate when we read with fgets, we never do with fread
1177  *
1178  */
1179 INT32 __cdecl CRTDLL__setmode( INT32 fh,INT32 mode)
1180 {
1181         /* FIXME */
1182 #define O_TEXT     0x4000
1183 #define O_BINARY   0x8000
1184
1185         dprintf_crtdll(stddeb,
1186                        "CRTDLL._setmode on fhandle %d mode %s, STUB.\n",
1187                 fh,(mode=O_TEXT)?"O_TEXT":
1188                 (mode=O_BINARY)?"O_BINARY":"UNKNOWN");
1189         return -1;
1190 }
1191
1192 /*********************************************************************
1193  *                  atexit           (CRTDLL.345)
1194  */
1195 INT32 __cdecl CRTDLL_atexit(LPVOID x)
1196 {
1197         /* FIXME */
1198         fprintf(stdnimp,"CRTDLL.atexit(%p), STUB.\n",x);
1199         return 0; /* successful */
1200 }
1201
1202 /*********************************************************************
1203  *                  mblen          (CRTDLL.428)
1204  * FIXME: check multibyte support
1205  */
1206 WCHAR  __cdecl CRTDLL_mblen(CHAR *mb,INT32 size)
1207 {
1208
1209     int ret=1;
1210     
1211     if (!mb)
1212       ret = 0;
1213     else if ((size<1)||(!*(mb+1)))
1214       ret = -1;
1215     else if (!(*mb))
1216       ret =0;
1217       
1218     dprintf_crtdll(stderr,"CRTDLL_mlen %s for max %d bytes ret %d\n",mb,size,ret);
1219
1220     return ret;
1221 }
1222
1223 /*********************************************************************
1224  *                  mbstowcs           (CRTDLL.429)
1225  * FIXME: check multibyte support
1226  */
1227 INT32 __cdecl CRTDLL_mbstowcs(LPWSTR wcs, LPCSTR mbs, INT32 size)
1228 {
1229
1230 /* Slightly modified lstrcpynAtoW functions from memory/strings.c
1231  *  We need the numberr of characters transfered 
1232  *  FIXME: No multibyte support yet
1233  */
1234
1235     LPWSTR p = wcs;
1236     LPCSTR src= mbs;
1237     int ret, n=size;
1238
1239     while ((n-- > 0) && *src) {
1240       *p++ = (WCHAR)(unsigned char)*src++;
1241         }
1242     p++;
1243     ret = (p -wcs);
1244           
1245     dprintf_crtdll(stddeb,"CRTDLL_mbstowcs %s for %d chars put %d wchars\n",
1246                    mbs,size,ret);
1247     return ret;
1248 }
1249
1250 /*********************************************************************
1251  *                  mbtowc           (CRTDLL.430)
1252  * FIXME: check multibyte support
1253  */
1254 WCHAR __cdecl CRTDLL_mbtowc(WCHAR* wc,CHAR* mb,INT32 size) 
1255 {
1256    int ret;
1257
1258    if (!mb)
1259      ret = 0;
1260    else if (!wc)
1261      ret =-1;
1262    else 
1263      if ( (ret = mblen(mb,size)) != -1 )
1264        {
1265          if (ret <= sizeof(char))
1266            *wc = (WCHAR) ((unsigned char)*mb);
1267         else
1268         ret=   -1;
1269         }   
1270      else
1271        ret = -1;
1272    
1273    dprintf_crtdll(stderr,"CRTDLL_mbtowc %s for %d chars\n",mb,size);
1274          
1275    return ret;
1276 }
1277
1278 /*********************************************************************
1279  *                  _isctype           (CRTDLL.138)
1280  */
1281 BOOL32 __cdecl CRTDLL__isctype(CHAR x,CHAR type)
1282 {
1283         if ((type & CRTDLL_SPACE) && isspace(x))
1284                 return TRUE;
1285         if ((type & CRTDLL_PUNCT) && ispunct(x))
1286                 return TRUE;
1287         if ((type & CRTDLL_LOWER) && islower(x))
1288                 return TRUE;
1289         if ((type & CRTDLL_UPPER) && isupper(x))
1290                 return TRUE;
1291         if ((type & CRTDLL_ALPHA) && isalpha(x))
1292                 return TRUE;
1293         if ((type & CRTDLL_DIGIT) && isdigit(x))
1294                 return TRUE;
1295         if ((type & CRTDLL_CONTROL) && iscntrl(x))
1296                 return TRUE;
1297         /* check CRTDLL_LEADBYTE */
1298         return FALSE;
1299 }
1300
1301 /*********************************************************************
1302  *                  _chdrive           (CRTDLL.52)
1303  */
1304 BOOL32 __cdecl CRTDLL__chdrive(INT32 newdrive)
1305 {
1306         /* FIXME: generates errnos */
1307         return DRIVE_SetCurrentDrive(newdrive);
1308 }
1309
1310 /*********************************************************************
1311  *                  _chdir           (CRTDLL.51)
1312  */
1313 INT32 __cdecl CRTDLL__chdir(LPCSTR newdir)
1314 {
1315         if (!SetCurrentDirectory32A(newdir))
1316                 return -1;
1317         return 0;
1318 }
1319
1320 /*********************************************************************
1321  *                  _getcwd           (CRTDLL.120)
1322  */
1323 CHAR* __cdecl CRTDLL__getcwd(LPSTR buf, INT32 size)
1324 {
1325   DOS_FULL_NAME full_name;
1326   char *ret;
1327
1328   dprintf_crtdll(stddeb,"CRTDLL_getcwd for buf %p size %d\n",
1329                  buf,size);
1330   if (buf == NULL)
1331     {
1332       dprintf_crtdll(stderr,"CRTDLL_getcwd malloc unsupported\n");
1333       printf("CRTDLL_getcwd malloc unsupported\n");
1334       return 0;
1335     }
1336   ret = getcwd(buf,size);
1337   if (!DOSFS_GetFullName( buf, FALSE, &full_name )) 
1338     {
1339       dprintf_crtdll(stddeb,"CRTDLL_getcwd failed\n");
1340       return 0;
1341     }
1342   if (strlen(full_name.short_name)>size) 
1343     {
1344       dprintf_crtdll(stddeb,"CRTDLL_getcwd string too long\n");
1345       return 0;
1346     }
1347   ret=strcpy(buf,full_name.short_name);
1348   if (ret) 
1349     dprintf_crtdll(stddeb,"CRTDLL_getcwd returned:%s\n",ret);
1350   return ret;
1351 }
1352
1353 /*********************************************************************
1354  *                  _mkdir           (CRTDLL.234)
1355  */
1356 INT32 __cdecl CRTDLL__mkdir(LPCSTR newdir)
1357 {
1358         if (!CreateDirectory32A(newdir,NULL))
1359                 return -1;
1360         return 0;
1361 }
1362
1363 /*********************************************************************
1364  *                  _errno           (CRTDLL.52)
1365  * Yes, this is a function.
1366  */
1367 LPINT32 __cdecl CRTDLL__errno()
1368 {
1369         static  int crtdllerrno;
1370         extern int LastErrorToErrno(DWORD);
1371
1372         /* FIXME: we should set the error at the failing function call time */
1373         crtdllerrno = LastErrorToErrno(GetLastError());
1374         return &crtdllerrno;
1375 }
1376
1377 /*********************************************************************
1378  *                  _tempnam           (CRTDLL.305)
1379  * 
1380  */
1381 LPSTR __cdecl CRTDLL__tempnam(LPCSTR dir, LPCSTR prefix)
1382 {
1383
1384      char *ret;
1385      DOS_FULL_NAME tempname;
1386      
1387      if ((ret = tempnam(dir,prefix))==NULL) {
1388        dprintf_crtdll(stddeb,
1389                       "CRTDLL_tempnam Unable to get unique filename\n");
1390        return NULL;
1391      }
1392      if (!DOSFS_GetFullName(ret,FALSE,&tempname))
1393      {
1394        dprintf_crtdll(stddeb,
1395                       "CRTDLL_tempnam Wrong path?\n");
1396        return NULL;
1397      }
1398      free(ret);
1399      if ((ret = CRTDLL_malloc(strlen(tempname.short_name)+1)) == NULL) {
1400          dprintf_crtdll(stddeb,
1401                         "CRTDLL_tempnam CRTDL_malloc for shortname failed\n");
1402          return NULL;
1403      }
1404      if ((ret = strcpy(ret,tempname.short_name)) == NULL) { 
1405        dprintf_crtdll(stddeb,
1406                       "CRTDLL_tempnam Malloc for shortname failed\n");
1407        return NULL;
1408      }
1409      
1410      dprintf_crtdll(stddeb,"CRTDLL_tempnam dir %s prefix %s got %s\n",
1411                     dir,prefix,ret);
1412      return ret;
1413
1414 }
1415 /*********************************************************************
1416  *                  tmpnam           (CRTDLL.490)
1417  *
1418  * lcclnk from lcc-win32 relies on a terminating dot in the name returned
1419  * 
1420  */
1421 LPSTR __cdecl CRTDLL_tmpnam(LPSTR s)
1422 {
1423      char *ret;
1424
1425      if ((ret =tmpnam(s))== NULL) {
1426        dprintf_crtdll(stddeb,
1427                       "CRTDLL_tmpnam Unable to get unique filename\n");
1428        return NULL;
1429      }
1430      if (!DOSFS_GetFullName(ret,FALSE,&CRTDLL_tmpname))
1431      {
1432        dprintf_crtdll(stddeb,
1433                       "CRTDLL_tmpnam Wrong path?\n");
1434        return NULL;
1435      }
1436      strcat(CRTDLL_tmpname.short_name,".");
1437      dprintf_crtdll(stddeb,"CRTDLL_tmpnam for buf %p got %s\n",
1438                     s,CRTDLL_tmpname.short_name);
1439      dprintf_crtdll(stddeb,"CRTDLL_tmpnam long got %s\n",
1440                     CRTDLL_tmpname.long_name);
1441      if ( s != NULL) 
1442        return strcpy(s,CRTDLL_tmpname.short_name);
1443      else 
1444        return CRTDLL_tmpname.short_name;
1445
1446 }
1447
1448 /*********************************************************************
1449  *                  _itoa           (CRTDLL.165)
1450  */
1451 LPSTR  __cdecl CRTDLL__itoa(INT32 x,LPSTR buf,INT32 buflen)
1452 {
1453     wsnprintf32A(buf,buflen,"%d",x);
1454     return buf;
1455 }