Folks,
We have a lot of code in msvcrt headers like so:
#define umask _umask #define unlink _unlink #define write _write
This breaks C++ that define a write method in a header, and then implement it like so:
#include <io.h> void MyClass::write(...) { write(...); }
I suggest we turn those defines into inlines, like this:
inline int write(int fd, const void* ptr, unsigned int size) { return _write(fd, ptr, size); }
Any other solutions?
On Thu, 9 Jan 2003, Dimitrie O. Paun wrote:
Folks,
We have a lot of code in msvcrt headers like so:
#define umask _umask #define unlink _unlink #define write _write
[...]
I suggest we turn those defines into inlines, like this:
inline int write(int fd, const void* ptr, unsigned int size) { return _write(fd, ptr, size); }
Any other solutions?
The strange thing is that the MSVC headers simply define their prototype, e.g.:
_CRTIMP int __cdecl umask(int);
Yet these APIs are not exported by the msvcrt library or by any other dll that I know of. And still applications compile and link!
In fact it seems that whether the application calls umask or _umask (even once preprocessed), MSVC will import _umask.
Anyway, replacing these defines with inline functions is fine with me.
Francois Gouget fgouget@free.fr writes:
The strange thing is that the MSVC headers simply define their prototype, e.g.:
_CRTIMP int __cdecl umask(int);
Yet these APIs are not exported by the msvcrt library or by any other dll that I know of. And still applications compile and link!
I think you have to link with oldnames.lib for that. We probably have to provide an oldnames.lib too.
On January 9, 2003 08:38 pm, Alexandre Julliard wrote:
I think you have to link with oldnames.lib for that. We probably have to provide an oldnames.lib too.
OK, but what do we do now about those defines?
"Dimitrie O. Paun" dpaun@rogers.com writes:
OK, but what do we do now about those defines?
I think making them inline functions should work for now.
On January 10, 2003 01:05 pm, Alexandre Julliard wrote:
I think making them inline functions should work for now.
<whine>How come I always get these assignments?</whine> :)
Hey, I did just some of them (basically io.h and sys/*.h), to preserve some form of sanity. Too much header work can lead to violent behaviour...
This patch depends on "msvcrt: stubs for chsize, dup, dup2" and it obsoletes "sys/{stat,types}.h: mode_t, umask (take 2)" since I was difficult to separate them.
Also, I did not know what to do about _open(), and _sopen() as they take variable number of arguments, so I've left them as macros. Any ideas for these are welcome.
ChangeLog Use inline functions instead of macros to avoid problems in C++ Inline functions respect scope, whereas macros don't. Define umask in sys/stat.h and sys/types.h, and mode_t in sys/types.h
Index: include/msvcrt/io.h =================================================================== RCS file: /var/cvs/wine/include/msvcrt/io.h,v retrieving revision 1.3 diff -u -r1.3 io.h --- include/msvcrt/io.h 18 Dec 2002 20:17:20 -0000 1.3 +++ include/msvcrt/io.h 10 Jan 2003 23:00:10 -0000 @@ -156,27 +156,30 @@
#ifndef USE_MSVCRT_PREFIX -#define access _access -#define chmod _chmod -#define chsize _chsize -#define close _close -#define creat _creat -#define dup _dup -#define dup2 _dup2 -#define eof _eof -#define filelength _filelength -#define isatty _isatty -#define locking _locking -#define lseek _lseek -#define mktemp _mktemp +inline int access(const char* path, int mode) { return _access(path, mode); } +inline int chmod(const char* path, int mode) { return _chmod(path, mode); } +inline int chsize(int fd, long size) { return _chsize(fd, size); } +inline int close(int fd) { return _close(fd); } +inline int creat(const char* path, int mode) { return _creat(path, mode); } +inline int dup(int od) { return _dup(od); } +inline int dup2(int od, int nd) { return _dup2(od, nd); } +inline int eof(int fd) { return _eof(fd); } +inline long filelength(int fd) { return _filelength(fd); } +inline int isatty(int fd) { return _isatty(fd); } +inline int locking(int fd, int mode, long size) { return _locking(fd, mode, size); } +inline long lseek(int fd, long off, int where) { return _lseek(fd, off, where); } +inline char* mktemp(char* pat) { return _mktemp(pat); } #define open _open -#define read _read -#define setmode _setmode +inline int read(int fd, void* buf, unsigned int size) { return _read(fd, buf, size); } +inline int setmode(int fd, int mode) { return _setmode(fd, mode); } #define sopen _sopen -#define tell _tell -#define umask _umask -#define unlink _unlink -#define write _write -#endif /* USE_MSVCRT_PREFIX */ +inline long tell(int fd) { return _tell(fd); } +#ifndef MSVCRT_UMASK_DEFINED +inline int umask(int fd) { return _umask(fd); } +#define MSVCRT_UMASK_DEFINED +#endif +inline int unlink(const char* path) { return _unlink(path); } +inline int write(int fd, const void* buf, unsigned int size) { return _write(fd, buf, size); } +#endif /* USE _MSVCRT_PREFIX */
#endif /* __WINE_IO_H */ Index: include/msvcrt/sys/stat.h =================================================================== RCS file: /var/cvs/wine/include/msvcrt/sys/stat.h,v retrieving revision 1.6 diff -u -r1.6 stat.h --- include/msvcrt/sys/stat.h 18 Dec 2002 20:17:20 -0000 1.6 +++ include/msvcrt/sys/stat.h 10 Jan 2003 19:15:38 -0000 @@ -106,6 +106,7 @@ int MSVCRT(_stat)(const char*,struct _stat*); int _fstati64(int,struct _stati64*); int _stati64(const char*,struct _stati64*); +int _umask(int);
#ifndef MSVCRT_WSTAT_DEFINED #define MSVCRT_WSTAT_DEFINED @@ -127,8 +128,12 @@ #define S_IWRITE _S_IWRITE #define S_IEXEC _S_IEXEC
-#define fstat _fstat -#define stat _stat +inline int fstat(int fd, struct _stat* ptr) { return _fstat(fd, ptr); } +inline int stat(const char* path, struct _stat* ptr) { return _stat(path, ptr); } +#ifndef MSVCRT_UMASK_DEFINED +inline int umask(int fd) { return _umask(fd); } +#define MSVCRT_UMASK_DEFINED +#endif #endif /* USE_MSVCRT_PREFIX */
#endif /* __WINE_SYS_STAT_H */ Index: include/msvcrt/sys/timeb.h =================================================================== RCS file: /var/cvs/wine/include/msvcrt/sys/timeb.h,v retrieving revision 1.4 diff -u -r1.4 timeb.h --- include/msvcrt/sys/timeb.h 18 Dec 2002 20:17:20 -0000 1.4 +++ include/msvcrt/sys/timeb.h 10 Jan 2003 18:10:39 -0000 @@ -60,7 +60,7 @@ #ifndef USE_MSVCRT_PREFIX #define timeb _timeb
-#define ftime _ftime +inline void ftime(struct _timeb* ptr) { return _ftime(ptr); } #endif /* USE_MSVCRT_PREFIX */
#endif /* __WINE_SYS_TIMEB_H */ Index: include/msvcrt/sys/types.h =================================================================== RCS file: /var/cvs/wine/include/msvcrt/sys/types.h,v retrieving revision 1.6 diff -u -r1.6 types.h --- include/msvcrt/sys/types.h 18 Dec 2002 20:17:20 -0000 1.6 +++ include/msvcrt/sys/types.h 10 Jan 2003 19:15:14 -0000 @@ -39,6 +39,11 @@ #define MSVCRT_INO_T_DEFINED #endif
+#ifndef MSVCRT_MODE_T_DEFINED +typedef unsigned short _mode_t; +#define MSVCRT_MODE_T_DEFINED +#endif + #ifndef MSVCRT_OFF_T_DEFINED typedef int MSVCRT(_off_t); #define MSVCRT_OFF_T_DEFINED @@ -49,11 +54,25 @@ #define MSVCRT_TIME_T_DEFINED #endif
+#ifdef __cplusplus +extern "C" { +#endif + +int _umask(int); + +#ifdef __cplusplus +} +#endif
#ifndef USE_MSVCRT_PREFIX #define dev_t _dev_t #define ino_t _ino_t +#define mode_t _mode_t #define off_t _off_t +#ifndef MSVCRT_UMASK_DEFINED +inline int umask(int fd) { return _umask(fd); } +#define MSVCRT_UMASK_DEFINED +#endif #endif /* USE_MSVCRT_PREFIX */
#endif /* __WINE_SYS_TYPES_H */ Index: include/msvcrt/sys/utime.h =================================================================== RCS file: /var/cvs/wine/include/msvcrt/sys/utime.h,v retrieving revision 1.4 diff -u -r1.4 utime.h --- include/msvcrt/sys/utime.h 18 Dec 2002 20:17:20 -0000 1.4 +++ include/msvcrt/sys/utime.h 10 Jan 2003 18:11:48 -0000 @@ -67,7 +67,7 @@ #ifndef USE_MSVCRT_PREFIX #define utimbuf _utimbuf
-#define utime _utime +inline int utime(const char* path, struct _utimbuf* buf) { return _utime(path, buf); } #endif /* USE_MSVCRT_PREFIX */
#endif /* __WINE_SYS_UTIME_H */
Dimitrie O. Paun wrote:
I suggest we turn those defines into inlines, like this:
inline int write(int fd, const void* ptr, unsigned int size) { return _write(fd, ptr, size); }
Any other solutions?
Sure, there are two:
0. use a linker alias for _write 1. actually have a function write() that just jumps to _write 2. actually have a function write() that calls _write
Not sure any of those are better than what you suggest, though. - Dan