wincompat.h (4175B)
1 /* C99 (ISO/IEC 9899:1999) - 5hif7y */ 2 /* A little helper to force POSIX compatibility for suckless tools on Windows */ 3 4 #ifndef WINCOMPAT_H 5 #define WINCOMPAT_H 6 #ifdef _WIN32 7 8 #pragma warning(disable:4996) /* TODO: reimplement '_fdopen' for MSVC */ 9 //#define _CRT_SECURE_NO_WARNINGS /* TODO: use secure implementation 'strcpy' to 'strcpy_s' */ 10 #define WIN32_LEAN_AND_MEAN 11 #include <windows.h> 12 #include <sys/stat.h> 13 #include <io.h> 14 #include <direct.h> 15 #include <fcntl.h> 16 #include <stdlib.h> 17 18 /* --------- posix datatype --------- */ 19 typedef int mode_t; 20 21 /* --------- misc defines --------- */ 22 #define PATH_MAX 260 23 #ifdef _MSC_VER 24 #define access _access 25 #define fdopen _fdopen /* TODO: reimplement 'fdopen' for Windows MSVC */ 26 #define umask _umask 27 #define chmod _chmod 28 #endif 29 #define warnx(fmt, ...) (fprintf(stderr, fmt "\n", ##__VA_ARGS__)) 30 #define err(exitcode, fmt, ...) do { \ 31 fprintf(stderr, fmt "\n", ##__VA_ARGS__); \ 32 exit(exitcode); \ 33 } while (0) 34 #define errx(exitcode, fmt, ...) err(exitcode, fmt, ##__VA_ARGS__) 35 /* if your toolchain is using MSVC, use the native implementation '_strdup' */ 36 #if defined(_MSC_VER) 37 #define strdup _strdup 38 /* Use this if your toolchain doesn't have an 'strdup' implementation */ 39 #elif defined(CUSTOM_STRDUP) 40 static char *custom_strdup(const char *s){ 41 if(!s){ return NULL;} 42 size_t len = strlen(s) + 1; 43 char *copy = malloc(len); 44 if (copy) { memcpy(copy, s, len); } 45 return copy; 46 } 47 #define strdup custom_strdup 48 #endif /* _MSC_VER xor CUSTOM_STRDUP */ 49 50 /* --------- posix functions reimplementations --------- */ 51 static int mkstemp(char *templte){ 52 char *XXXXXX = strstr(templte, "XXXXXX"); 53 if (!XXXXXX || strlen(XXXXXX) != 6) { 54 return -1; 55 } 56 for (int i = 0; i < 100; ++i) { 57 for (int j = 0; j < 6; ++j) { 58 XXXXXX[j] = 'A' + rand() % 26; 59 } 60 int fd = _open(templte, _O_RDWR | _O_CREAT | _O_EXCL, _S_IREAD | _S_IWRITE); 61 if (fd != -1) { 62 return fd; 63 } 64 } 65 return -1; 66 } 67 68 static char *win_basename(const char *path){ 69 if (!path || !*path){ return NULL; } 70 71 const char *last_slash = strrchr(path, '\\'); 72 const char *last_fslash = strrchr(path, '/'); 73 const char *base = path; 74 75 if (last_slash && last_fslash){ 76 base = (last_slash > last_fslash) ? last_slash + 1 : last_fslash + 1; 77 } 78 else if (last_slash) { 79 base = last_slash + 1; 80 } 81 else if (last_fslash){ 82 base = last_fslash + 1; 83 } 84 return strdup(base); 85 } 86 #define basename(path) win_basename(path) 87 88 static char *win_dirname(char *path){ 89 static char buffer[MAX_PATH]; 90 char *slash; 91 if (!path || !*path){ 92 strcpy(buffer, "."); 93 return buffer; 94 } 95 strncpy(buffer, path, MAX_PATH); 96 buffer[MAX_PATH - 1] = '\0'; // prevenir falta de terminación nula 97 slash = strrchr(buffer, '\\'); 98 if (!slash){ 99 slash = strrchr(buffer, '/'); 100 } 101 if (slash){ 102 *slash = '\0'; 103 } else { 104 strcpy(buffer, "."); 105 } 106 return buffer; 107 } 108 #define dirname(path) win_dirname(path) 109 110 static char *realpath(const char *path, char *resolved_path){ 111 if(!resolved_path){ resolved_path = (char*)malloc(MAX_PATH); } 112 _fullpath(resolved_path, path, MAX_PATH); 113 return resolved_path; 114 } 115 116 static int win_mkdir(const char *path, mode_t mode){ 117 (void)mode; /* discard unused variable in a way the compiler doesn't complain */ 118 return _mkdir(path); 119 } 120 #define mkdir(path, mode) win_mkdir(path, mode) 121 122 /* --------- access --------- */ 123 #ifndef F_OK 124 #define F_OK 0 125 #endif 126 127 /* --------- permission macros --------- */ 128 #define S_IRWXU 0700 129 #define S_IRUSR 0400 130 #define S_IWUSR 0200 131 #define S_IXUSR 0100 132 #define S_IRWXG 0070 133 #define S_IRGRP 0040 134 #define S_IWGRP 0020 135 #define S_IXGRP 0010 136 #define S_IRWXO 0007 137 #define S_IROTH 0004 138 #define S_IWOTH 0002 139 #define S_IXOTH 0001 140 #define S_ISUID 0004000 141 #define S_ISGID 0002000 142 #define S_ISVTX 0001000 143 144 /* --------- S_ISXXX macros --------- */ 145 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 146 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 147 #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) 148 #define S_ISBLK(m) (0) // doesn't exist in Windows 149 #define S_ISFIFO(m) (0) 150 #define S_ISLNK(m) (0) 151 #define S_ISSOCK(m) (0) 152 153 #endif /* _WIN32 */ 154 #endif /* WINCOMPAT_H */