mingw.c 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904
  1. #include "../git-compat-util.h"
  2. #include "win32.h"
  3. #include <conio.h>
  4. #include <wchar.h>
  5. #include "../strbuf.h"
  6. #include "../run-command.h"
  7. #include "../cache.h"
  8. #include "win32/lazyload.h"
  9. #include "../config.h"
  10. #include "dir.h"
  11. #define HCAST(type, handle) ((type)(intptr_t)handle)
  12. static const int delay[] = { 0, 1, 10, 20, 40 };
  13. void open_in_gdb(void)
  14. {
  15. static struct child_process cp = CHILD_PROCESS_INIT;
  16. extern char *_pgmptr;
  17. strvec_pushl(&cp.args, "mintty", "gdb", NULL);
  18. strvec_pushf(&cp.args, "--pid=%d", getpid());
  19. cp.clean_on_exit = 1;
  20. if (start_command(&cp) < 0)
  21. die_errno("Could not start gdb");
  22. sleep(1);
  23. }
  24. int err_win_to_posix(DWORD winerr)
  25. {
  26. int error = ENOSYS;
  27. switch(winerr) {
  28. case ERROR_ACCESS_DENIED: error = EACCES; break;
  29. case ERROR_ACCOUNT_DISABLED: error = EACCES; break;
  30. case ERROR_ACCOUNT_RESTRICTION: error = EACCES; break;
  31. case ERROR_ALREADY_ASSIGNED: error = EBUSY; break;
  32. case ERROR_ALREADY_EXISTS: error = EEXIST; break;
  33. case ERROR_ARITHMETIC_OVERFLOW: error = ERANGE; break;
  34. case ERROR_BAD_COMMAND: error = EIO; break;
  35. case ERROR_BAD_DEVICE: error = ENODEV; break;
  36. case ERROR_BAD_DRIVER_LEVEL: error = ENXIO; break;
  37. case ERROR_BAD_EXE_FORMAT: error = ENOEXEC; break;
  38. case ERROR_BAD_FORMAT: error = ENOEXEC; break;
  39. case ERROR_BAD_LENGTH: error = EINVAL; break;
  40. case ERROR_BAD_PATHNAME: error = ENOENT; break;
  41. case ERROR_BAD_PIPE: error = EPIPE; break;
  42. case ERROR_BAD_UNIT: error = ENODEV; break;
  43. case ERROR_BAD_USERNAME: error = EINVAL; break;
  44. case ERROR_BROKEN_PIPE: error = EPIPE; break;
  45. case ERROR_BUFFER_OVERFLOW: error = ENAMETOOLONG; break;
  46. case ERROR_BUSY: error = EBUSY; break;
  47. case ERROR_BUSY_DRIVE: error = EBUSY; break;
  48. case ERROR_CALL_NOT_IMPLEMENTED: error = ENOSYS; break;
  49. case ERROR_CANNOT_MAKE: error = EACCES; break;
  50. case ERROR_CANTOPEN: error = EIO; break;
  51. case ERROR_CANTREAD: error = EIO; break;
  52. case ERROR_CANTWRITE: error = EIO; break;
  53. case ERROR_CRC: error = EIO; break;
  54. case ERROR_CURRENT_DIRECTORY: error = EACCES; break;
  55. case ERROR_DEVICE_IN_USE: error = EBUSY; break;
  56. case ERROR_DEV_NOT_EXIST: error = ENODEV; break;
  57. case ERROR_DIRECTORY: error = EINVAL; break;
  58. case ERROR_DIR_NOT_EMPTY: error = ENOTEMPTY; break;
  59. case ERROR_DISK_CHANGE: error = EIO; break;
  60. case ERROR_DISK_FULL: error = ENOSPC; break;
  61. case ERROR_DRIVE_LOCKED: error = EBUSY; break;
  62. case ERROR_ENVVAR_NOT_FOUND: error = EINVAL; break;
  63. case ERROR_EXE_MARKED_INVALID: error = ENOEXEC; break;
  64. case ERROR_FILENAME_EXCED_RANGE: error = ENAMETOOLONG; break;
  65. case ERROR_FILE_EXISTS: error = EEXIST; break;
  66. case ERROR_FILE_INVALID: error = ENODEV; break;
  67. case ERROR_FILE_NOT_FOUND: error = ENOENT; break;
  68. case ERROR_GEN_FAILURE: error = EIO; break;
  69. case ERROR_HANDLE_DISK_FULL: error = ENOSPC; break;
  70. case ERROR_INSUFFICIENT_BUFFER: error = ENOMEM; break;
  71. case ERROR_INVALID_ACCESS: error = EACCES; break;
  72. case ERROR_INVALID_ADDRESS: error = EFAULT; break;
  73. case ERROR_INVALID_BLOCK: error = EFAULT; break;
  74. case ERROR_INVALID_DATA: error = EINVAL; break;
  75. case ERROR_INVALID_DRIVE: error = ENODEV; break;
  76. case ERROR_INVALID_EXE_SIGNATURE: error = ENOEXEC; break;
  77. case ERROR_INVALID_FLAGS: error = EINVAL; break;
  78. case ERROR_INVALID_FUNCTION: error = ENOSYS; break;
  79. case ERROR_INVALID_HANDLE: error = EBADF; break;
  80. case ERROR_INVALID_LOGON_HOURS: error = EACCES; break;
  81. case ERROR_INVALID_NAME: error = EINVAL; break;
  82. case ERROR_INVALID_OWNER: error = EINVAL; break;
  83. case ERROR_INVALID_PARAMETER: error = EINVAL; break;
  84. case ERROR_INVALID_PASSWORD: error = EPERM; break;
  85. case ERROR_INVALID_PRIMARY_GROUP: error = EINVAL; break;
  86. case ERROR_INVALID_SIGNAL_NUMBER: error = EINVAL; break;
  87. case ERROR_INVALID_TARGET_HANDLE: error = EIO; break;
  88. case ERROR_INVALID_WORKSTATION: error = EACCES; break;
  89. case ERROR_IO_DEVICE: error = EIO; break;
  90. case ERROR_IO_INCOMPLETE: error = EINTR; break;
  91. case ERROR_LOCKED: error = EBUSY; break;
  92. case ERROR_LOCK_VIOLATION: error = EACCES; break;
  93. case ERROR_LOGON_FAILURE: error = EACCES; break;
  94. case ERROR_MAPPED_ALIGNMENT: error = EINVAL; break;
  95. case ERROR_META_EXPANSION_TOO_LONG: error = E2BIG; break;
  96. case ERROR_MORE_DATA: error = EPIPE; break;
  97. case ERROR_NEGATIVE_SEEK: error = ESPIPE; break;
  98. case ERROR_NOACCESS: error = EFAULT; break;
  99. case ERROR_NONE_MAPPED: error = EINVAL; break;
  100. case ERROR_NOT_ENOUGH_MEMORY: error = ENOMEM; break;
  101. case ERROR_NOT_READY: error = EAGAIN; break;
  102. case ERROR_NOT_SAME_DEVICE: error = EXDEV; break;
  103. case ERROR_NO_DATA: error = EPIPE; break;
  104. case ERROR_NO_MORE_SEARCH_HANDLES: error = EIO; break;
  105. case ERROR_NO_PROC_SLOTS: error = EAGAIN; break;
  106. case ERROR_NO_SUCH_PRIVILEGE: error = EACCES; break;
  107. case ERROR_OPEN_FAILED: error = EIO; break;
  108. case ERROR_OPEN_FILES: error = EBUSY; break;
  109. case ERROR_OPERATION_ABORTED: error = EINTR; break;
  110. case ERROR_OUTOFMEMORY: error = ENOMEM; break;
  111. case ERROR_PASSWORD_EXPIRED: error = EACCES; break;
  112. case ERROR_PATH_BUSY: error = EBUSY; break;
  113. case ERROR_PATH_NOT_FOUND: error = ENOENT; break;
  114. case ERROR_PIPE_BUSY: error = EBUSY; break;
  115. case ERROR_PIPE_CONNECTED: error = EPIPE; break;
  116. case ERROR_PIPE_LISTENING: error = EPIPE; break;
  117. case ERROR_PIPE_NOT_CONNECTED: error = EPIPE; break;
  118. case ERROR_PRIVILEGE_NOT_HELD: error = EACCES; break;
  119. case ERROR_READ_FAULT: error = EIO; break;
  120. case ERROR_SEEK: error = EIO; break;
  121. case ERROR_SEEK_ON_DEVICE: error = ESPIPE; break;
  122. case ERROR_SHARING_BUFFER_EXCEEDED: error = ENFILE; break;
  123. case ERROR_SHARING_VIOLATION: error = EACCES; break;
  124. case ERROR_STACK_OVERFLOW: error = ENOMEM; break;
  125. case ERROR_SUCCESS: BUG("err_win_to_posix() called without an error!");
  126. case ERROR_SWAPERROR: error = ENOENT; break;
  127. case ERROR_TOO_MANY_MODULES: error = EMFILE; break;
  128. case ERROR_TOO_MANY_OPEN_FILES: error = EMFILE; break;
  129. case ERROR_UNRECOGNIZED_MEDIA: error = ENXIO; break;
  130. case ERROR_UNRECOGNIZED_VOLUME: error = ENODEV; break;
  131. case ERROR_WAIT_NO_CHILDREN: error = ECHILD; break;
  132. case ERROR_WRITE_FAULT: error = EIO; break;
  133. case ERROR_WRITE_PROTECT: error = EROFS; break;
  134. }
  135. return error;
  136. }
  137. static inline int is_file_in_use_error(DWORD errcode)
  138. {
  139. switch (errcode) {
  140. case ERROR_SHARING_VIOLATION:
  141. case ERROR_ACCESS_DENIED:
  142. return 1;
  143. }
  144. return 0;
  145. }
  146. static int read_yes_no_answer(void)
  147. {
  148. char answer[1024];
  149. if (fgets(answer, sizeof(answer), stdin)) {
  150. size_t answer_len = strlen(answer);
  151. int got_full_line = 0, c;
  152. /* remove the newline */
  153. if (answer_len >= 2 && answer[answer_len-2] == '\r') {
  154. answer[answer_len-2] = '\0';
  155. got_full_line = 1;
  156. } else if (answer_len >= 1 && answer[answer_len-1] == '\n') {
  157. answer[answer_len-1] = '\0';
  158. got_full_line = 1;
  159. }
  160. /* flush the buffer in case we did not get the full line */
  161. if (!got_full_line)
  162. while ((c = getchar()) != EOF && c != '\n')
  163. ;
  164. } else
  165. /* we could not read, return the
  166. * default answer which is no */
  167. return 0;
  168. if (tolower(answer[0]) == 'y' && !answer[1])
  169. return 1;
  170. if (!strncasecmp(answer, "yes", sizeof(answer)))
  171. return 1;
  172. if (tolower(answer[0]) == 'n' && !answer[1])
  173. return 0;
  174. if (!strncasecmp(answer, "no", sizeof(answer)))
  175. return 0;
  176. /* did not find an answer we understand */
  177. return -1;
  178. }
  179. static int ask_yes_no_if_possible(const char *format, ...)
  180. {
  181. char question[4096];
  182. const char *retry_hook[] = { NULL, NULL, NULL };
  183. va_list args;
  184. va_start(args, format);
  185. vsnprintf(question, sizeof(question), format, args);
  186. va_end(args);
  187. if ((retry_hook[0] = mingw_getenv("GIT_ASK_YESNO"))) {
  188. retry_hook[1] = question;
  189. return !run_command_v_opt(retry_hook, 0);
  190. }
  191. if (!isatty(_fileno(stdin)) || !isatty(_fileno(stderr)))
  192. return 0;
  193. while (1) {
  194. int answer;
  195. fprintf(stderr, "%s (y/n) ", question);
  196. if ((answer = read_yes_no_answer()) >= 0)
  197. return answer;
  198. fprintf(stderr, "Sorry, I did not understand your answer. "
  199. "Please type 'y' or 'n'\n");
  200. }
  201. }
  202. /* Windows only */
  203. enum hide_dotfiles_type {
  204. HIDE_DOTFILES_FALSE = 0,
  205. HIDE_DOTFILES_TRUE,
  206. HIDE_DOTFILES_DOTGITONLY
  207. };
  208. static int core_restrict_inherited_handles = -1;
  209. static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
  210. static char *unset_environment_variables;
  211. int mingw_core_config(const char *var, const char *value, void *cb)
  212. {
  213. if (!strcmp(var, "core.hidedotfiles")) {
  214. if (value && !strcasecmp(value, "dotgitonly"))
  215. hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
  216. else
  217. hide_dotfiles = git_config_bool(var, value);
  218. return 0;
  219. }
  220. if (!strcmp(var, "core.unsetenvvars")) {
  221. free(unset_environment_variables);
  222. unset_environment_variables = xstrdup(value);
  223. return 0;
  224. }
  225. if (!strcmp(var, "core.restrictinheritedhandles")) {
  226. if (value && !strcasecmp(value, "auto"))
  227. core_restrict_inherited_handles = -1;
  228. else
  229. core_restrict_inherited_handles =
  230. git_config_bool(var, value);
  231. return 0;
  232. }
  233. return 0;
  234. }
  235. /* Normalizes NT paths as returned by some low-level APIs. */
  236. static wchar_t *normalize_ntpath(wchar_t *wbuf)
  237. {
  238. int i;
  239. /* fix absolute path prefixes */
  240. if (wbuf[0] == '\\') {
  241. /* strip NT namespace prefixes */
  242. if (!wcsncmp(wbuf, L"\\??\\", 4) ||
  243. !wcsncmp(wbuf, L"\\\\?\\", 4))
  244. wbuf += 4;
  245. else if (!wcsnicmp(wbuf, L"\\DosDevices\\", 12))
  246. wbuf += 12;
  247. /* replace remaining '...UNC\' with '\\' */
  248. if (!wcsnicmp(wbuf, L"UNC\\", 4)) {
  249. wbuf += 2;
  250. *wbuf = '\\';
  251. }
  252. }
  253. /* convert backslashes to slashes */
  254. for (i = 0; wbuf[i]; i++)
  255. if (wbuf[i] == '\\')
  256. wbuf[i] = '/';
  257. return wbuf;
  258. }
  259. int mingw_unlink(const char *pathname)
  260. {
  261. int ret, tries = 0;
  262. wchar_t wpathname[MAX_PATH];
  263. if (xutftowcs_path(wpathname, pathname) < 0)
  264. return -1;
  265. if (DeleteFileW(wpathname))
  266. return 0;
  267. /* read-only files cannot be removed */
  268. _wchmod(wpathname, 0666);
  269. while ((ret = _wunlink(wpathname)) == -1 && tries < ARRAY_SIZE(delay)) {
  270. if (!is_file_in_use_error(GetLastError()))
  271. break;
  272. /*
  273. * We assume that some other process had the source or
  274. * destination file open at the wrong moment and retry.
  275. * In order to give the other process a higher chance to
  276. * complete its operation, we give up our time slice now.
  277. * If we have to retry again, we do sleep a bit.
  278. */
  279. Sleep(delay[tries]);
  280. tries++;
  281. }
  282. while (ret == -1 && is_file_in_use_error(GetLastError()) &&
  283. ask_yes_no_if_possible("Unlink of file '%s' failed. "
  284. "Should I try again?", pathname))
  285. ret = _wunlink(wpathname);
  286. return ret;
  287. }
  288. static int is_dir_empty(const wchar_t *wpath)
  289. {
  290. WIN32_FIND_DATAW findbuf;
  291. HANDLE handle;
  292. wchar_t wbuf[MAX_PATH + 2];
  293. wcscpy(wbuf, wpath);
  294. wcscat(wbuf, L"\\*");
  295. handle = FindFirstFileW(wbuf, &findbuf);
  296. if (handle == INVALID_HANDLE_VALUE)
  297. return GetLastError() == ERROR_NO_MORE_FILES;
  298. while (!wcscmp(findbuf.cFileName, L".") ||
  299. !wcscmp(findbuf.cFileName, L".."))
  300. if (!FindNextFileW(handle, &findbuf)) {
  301. DWORD err = GetLastError();
  302. FindClose(handle);
  303. return err == ERROR_NO_MORE_FILES;
  304. }
  305. FindClose(handle);
  306. return 0;
  307. }
  308. int mingw_rmdir(const char *pathname)
  309. {
  310. int ret, tries = 0;
  311. wchar_t wpathname[MAX_PATH];
  312. if (xutftowcs_path(wpathname, pathname) < 0)
  313. return -1;
  314. while ((ret = _wrmdir(wpathname)) == -1 && tries < ARRAY_SIZE(delay)) {
  315. if (!is_file_in_use_error(GetLastError()))
  316. errno = err_win_to_posix(GetLastError());
  317. if (errno != EACCES)
  318. break;
  319. if (!is_dir_empty(wpathname)) {
  320. errno = ENOTEMPTY;
  321. break;
  322. }
  323. /*
  324. * We assume that some other process had the source or
  325. * destination file open at the wrong moment and retry.
  326. * In order to give the other process a higher chance to
  327. * complete its operation, we give up our time slice now.
  328. * If we have to retry again, we do sleep a bit.
  329. */
  330. Sleep(delay[tries]);
  331. tries++;
  332. }
  333. while (ret == -1 && errno == EACCES && is_file_in_use_error(GetLastError()) &&
  334. ask_yes_no_if_possible("Deletion of directory '%s' failed. "
  335. "Should I try again?", pathname))
  336. ret = _wrmdir(wpathname);
  337. return ret;
  338. }
  339. static inline int needs_hiding(const char *path)
  340. {
  341. const char *basename;
  342. if (hide_dotfiles == HIDE_DOTFILES_FALSE)
  343. return 0;
  344. /* We cannot use basename(), as it would remove trailing slashes */
  345. win32_skip_dos_drive_prefix((char **)&path);
  346. if (!*path)
  347. return 0;
  348. for (basename = path; *path; path++)
  349. if (is_dir_sep(*path)) {
  350. do {
  351. path++;
  352. } while (is_dir_sep(*path));
  353. /* ignore trailing slashes */
  354. if (*path)
  355. basename = path;
  356. else
  357. break;
  358. }
  359. if (hide_dotfiles == HIDE_DOTFILES_TRUE)
  360. return *basename == '.';
  361. assert(hide_dotfiles == HIDE_DOTFILES_DOTGITONLY);
  362. return !strncasecmp(".git", basename, 4) &&
  363. (!basename[4] || is_dir_sep(basename[4]));
  364. }
  365. static int set_hidden_flag(const wchar_t *path, int set)
  366. {
  367. DWORD original = GetFileAttributesW(path), modified;
  368. if (set)
  369. modified = original | FILE_ATTRIBUTE_HIDDEN;
  370. else
  371. modified = original & ~FILE_ATTRIBUTE_HIDDEN;
  372. if (original == modified || SetFileAttributesW(path, modified))
  373. return 0;
  374. errno = err_win_to_posix(GetLastError());
  375. return -1;
  376. }
  377. int mingw_mkdir(const char *path, int mode)
  378. {
  379. int ret;
  380. wchar_t wpath[MAX_PATH];
  381. if (!is_valid_win32_path(path, 0)) {
  382. errno = EINVAL;
  383. return -1;
  384. }
  385. if (xutftowcs_path(wpath, path) < 0)
  386. return -1;
  387. ret = _wmkdir(wpath);
  388. if (!ret && needs_hiding(path))
  389. return set_hidden_flag(wpath, 1);
  390. return ret;
  391. }
  392. /*
  393. * Calling CreateFile() using FILE_APPEND_DATA and without FILE_WRITE_DATA
  394. * is documented in [1] as opening a writable file handle in append mode.
  395. * (It is believed that) this is atomic since it is maintained by the
  396. * kernel unlike the O_APPEND flag which is racily maintained by the CRT.
  397. *
  398. * [1] https://docs.microsoft.com/en-us/windows/desktop/fileio/file-access-rights-constants
  399. *
  400. * This trick does not appear to work for named pipes. Instead it creates
  401. * a named pipe client handle that cannot be written to. Callers should
  402. * just use the regular _wopen() for them. (And since client handle gets
  403. * bound to a unique server handle, it isn't really an issue.)
  404. */
  405. static int mingw_open_append(wchar_t const *wfilename, int oflags, ...)
  406. {
  407. HANDLE handle;
  408. int fd;
  409. DWORD create = (oflags & O_CREAT) ? OPEN_ALWAYS : OPEN_EXISTING;
  410. /* only these flags are supported */
  411. if ((oflags & ~O_CREAT) != (O_WRONLY | O_APPEND))
  412. return errno = ENOSYS, -1;
  413. /*
  414. * FILE_SHARE_WRITE is required to permit child processes
  415. * to append to the file.
  416. */
  417. handle = CreateFileW(wfilename, FILE_APPEND_DATA,
  418. FILE_SHARE_WRITE | FILE_SHARE_READ,
  419. NULL, create, FILE_ATTRIBUTE_NORMAL, NULL);
  420. if (handle == INVALID_HANDLE_VALUE) {
  421. DWORD err = GetLastError();
  422. /*
  423. * Some network storage solutions (e.g. Isilon) might return
  424. * ERROR_INVALID_PARAMETER instead of expected error
  425. * ERROR_PATH_NOT_FOUND, which results in an unknown error. If
  426. * so, let's turn the error to ERROR_PATH_NOT_FOUND instead.
  427. */
  428. if (err == ERROR_INVALID_PARAMETER)
  429. err = ERROR_PATH_NOT_FOUND;
  430. errno = err_win_to_posix(err);
  431. return -1;
  432. }
  433. /*
  434. * No O_APPEND here, because the CRT uses it only to reset the
  435. * file pointer to EOF before each write(); but that is not
  436. * necessary (and may lead to races) for a file created with
  437. * FILE_APPEND_DATA.
  438. */
  439. fd = _open_osfhandle((intptr_t)handle, O_BINARY);
  440. if (fd < 0)
  441. CloseHandle(handle);
  442. return fd;
  443. }
  444. /*
  445. * Does the pathname map to the local named pipe filesystem?
  446. * That is, does it have a "//./pipe/" prefix?
  447. */
  448. static int is_local_named_pipe_path(const char *filename)
  449. {
  450. return (is_dir_sep(filename[0]) &&
  451. is_dir_sep(filename[1]) &&
  452. filename[2] == '.' &&
  453. is_dir_sep(filename[3]) &&
  454. !strncasecmp(filename+4, "pipe", 4) &&
  455. is_dir_sep(filename[8]) &&
  456. filename[9]);
  457. }
  458. int mingw_open (const char *filename, int oflags, ...)
  459. {
  460. typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...);
  461. va_list args;
  462. unsigned mode;
  463. int fd, create = (oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
  464. wchar_t wfilename[MAX_PATH];
  465. open_fn_t open_fn;
  466. va_start(args, oflags);
  467. mode = va_arg(args, int);
  468. va_end(args);
  469. if (!is_valid_win32_path(filename, !create)) {
  470. errno = create ? EINVAL : ENOENT;
  471. return -1;
  472. }
  473. if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename))
  474. open_fn = mingw_open_append;
  475. else
  476. open_fn = _wopen;
  477. if (filename && !strcmp(filename, "/dev/null"))
  478. wcscpy(wfilename, L"nul");
  479. else if (xutftowcs_path(wfilename, filename) < 0)
  480. return -1;
  481. fd = open_fn(wfilename, oflags, mode);
  482. if (fd < 0 && (oflags & O_ACCMODE) != O_RDONLY && errno == EACCES) {
  483. DWORD attrs = GetFileAttributesW(wfilename);
  484. if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY))
  485. errno = EISDIR;
  486. }
  487. if ((oflags & O_CREAT) && needs_hiding(filename)) {
  488. /*
  489. * Internally, _wopen() uses the CreateFile() API which errors
  490. * out with an ERROR_ACCESS_DENIED if CREATE_ALWAYS was
  491. * specified and an already existing file's attributes do not
  492. * match *exactly*. As there is no mode or flag we can set that
  493. * would correspond to FILE_ATTRIBUTE_HIDDEN, let's just try
  494. * again *without* the O_CREAT flag (that corresponds to the
  495. * CREATE_ALWAYS flag of CreateFile()).
  496. */
  497. if (fd < 0 && errno == EACCES)
  498. fd = open_fn(wfilename, oflags & ~O_CREAT, mode);
  499. if (fd >= 0 && set_hidden_flag(wfilename, 1))
  500. warning("could not mark '%s' as hidden.", filename);
  501. }
  502. return fd;
  503. }
  504. static BOOL WINAPI ctrl_ignore(DWORD type)
  505. {
  506. return TRUE;
  507. }
  508. #undef fgetc
  509. int mingw_fgetc(FILE *stream)
  510. {
  511. int ch;
  512. if (!isatty(_fileno(stream)))
  513. return fgetc(stream);
  514. SetConsoleCtrlHandler(ctrl_ignore, TRUE);
  515. while (1) {
  516. ch = fgetc(stream);
  517. if (ch != EOF || GetLastError() != ERROR_OPERATION_ABORTED)
  518. break;
  519. /* Ctrl+C was pressed, simulate SIGINT and retry */
  520. mingw_raise(SIGINT);
  521. }
  522. SetConsoleCtrlHandler(ctrl_ignore, FALSE);
  523. return ch;
  524. }
  525. #undef fopen
  526. FILE *mingw_fopen (const char *filename, const char *otype)
  527. {
  528. int hide = needs_hiding(filename);
  529. FILE *file;
  530. wchar_t wfilename[MAX_PATH], wotype[4];
  531. if (filename && !strcmp(filename, "/dev/null"))
  532. wcscpy(wfilename, L"nul");
  533. else if (!is_valid_win32_path(filename, 1)) {
  534. int create = otype && strchr(otype, 'w');
  535. errno = create ? EINVAL : ENOENT;
  536. return NULL;
  537. } else if (xutftowcs_path(wfilename, filename) < 0)
  538. return NULL;
  539. if (xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
  540. return NULL;
  541. if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) {
  542. error("could not unhide %s", filename);
  543. return NULL;
  544. }
  545. file = _wfopen(wfilename, wotype);
  546. if (!file && GetLastError() == ERROR_INVALID_NAME)
  547. errno = ENOENT;
  548. if (file && hide && set_hidden_flag(wfilename, 1))
  549. warning("could not mark '%s' as hidden.", filename);
  550. return file;
  551. }
  552. FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream)
  553. {
  554. int hide = needs_hiding(filename);
  555. FILE *file;
  556. wchar_t wfilename[MAX_PATH], wotype[4];
  557. if (filename && !strcmp(filename, "/dev/null"))
  558. wcscpy(wfilename, L"nul");
  559. else if (!is_valid_win32_path(filename, 1)) {
  560. int create = otype && strchr(otype, 'w');
  561. errno = create ? EINVAL : ENOENT;
  562. return NULL;
  563. } else if (xutftowcs_path(wfilename, filename) < 0)
  564. return NULL;
  565. if (xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
  566. return NULL;
  567. if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) {
  568. error("could not unhide %s", filename);
  569. return NULL;
  570. }
  571. file = _wfreopen(wfilename, wotype, stream);
  572. if (file && hide && set_hidden_flag(wfilename, 1))
  573. warning("could not mark '%s' as hidden.", filename);
  574. return file;
  575. }
  576. #undef fflush
  577. int mingw_fflush(FILE *stream)
  578. {
  579. int ret = fflush(stream);
  580. /*
  581. * write() is used behind the scenes of stdio output functions.
  582. * Since git code does not check for errors after each stdio write
  583. * operation, it can happen that write() is called by a later
  584. * stdio function even if an earlier write() call failed. In the
  585. * case of a pipe whose readable end was closed, only the first
  586. * call to write() reports EPIPE on Windows. Subsequent write()
  587. * calls report EINVAL. It is impossible to notice whether this
  588. * fflush invocation triggered such a case, therefore, we have to
  589. * catch all EINVAL errors whole-sale.
  590. */
  591. if (ret && errno == EINVAL)
  592. errno = EPIPE;
  593. return ret;
  594. }
  595. #undef write
  596. ssize_t mingw_write(int fd, const void *buf, size_t len)
  597. {
  598. ssize_t result = write(fd, buf, len);
  599. if (result < 0 && errno == EINVAL && buf) {
  600. /* check if fd is a pipe */
  601. HANDLE h = (HANDLE) _get_osfhandle(fd);
  602. if (GetFileType(h) == FILE_TYPE_PIPE)
  603. errno = EPIPE;
  604. else
  605. errno = EINVAL;
  606. }
  607. return result;
  608. }
  609. int mingw_access(const char *filename, int mode)
  610. {
  611. wchar_t wfilename[MAX_PATH];
  612. if (xutftowcs_path(wfilename, filename) < 0)
  613. return -1;
  614. /* X_OK is not supported by the MSVCRT version */
  615. return _waccess(wfilename, mode & ~X_OK);
  616. }
  617. int mingw_chdir(const char *dirname)
  618. {
  619. wchar_t wdirname[MAX_PATH];
  620. if (xutftowcs_path(wdirname, dirname) < 0)
  621. return -1;
  622. return _wchdir(wdirname);
  623. }
  624. int mingw_chmod(const char *filename, int mode)
  625. {
  626. wchar_t wfilename[MAX_PATH];
  627. if (xutftowcs_path(wfilename, filename) < 0)
  628. return -1;
  629. return _wchmod(wfilename, mode);
  630. }
  631. /*
  632. * The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC.
  633. * Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch.
  634. */
  635. static inline long long filetime_to_hnsec(const FILETIME *ft)
  636. {
  637. long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
  638. /* Windows to Unix Epoch conversion */
  639. return winTime - 116444736000000000LL;
  640. }
  641. static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts)
  642. {
  643. long long hnsec = filetime_to_hnsec(ft);
  644. ts->tv_sec = (time_t)(hnsec / 10000000);
  645. ts->tv_nsec = (hnsec % 10000000) * 100;
  646. }
  647. /**
  648. * Verifies that safe_create_leading_directories() would succeed.
  649. */
  650. static int has_valid_directory_prefix(wchar_t *wfilename)
  651. {
  652. int n = wcslen(wfilename);
  653. while (n > 0) {
  654. wchar_t c = wfilename[--n];
  655. DWORD attributes;
  656. if (!is_dir_sep(c))
  657. continue;
  658. wfilename[n] = L'\0';
  659. attributes = GetFileAttributesW(wfilename);
  660. wfilename[n] = c;
  661. if (attributes == FILE_ATTRIBUTE_DIRECTORY ||
  662. attributes == FILE_ATTRIBUTE_DEVICE)
  663. return 1;
  664. if (attributes == INVALID_FILE_ATTRIBUTES)
  665. switch (GetLastError()) {
  666. case ERROR_PATH_NOT_FOUND:
  667. continue;
  668. case ERROR_FILE_NOT_FOUND:
  669. /* This implies parent directory exists. */
  670. return 1;
  671. }
  672. return 0;
  673. }
  674. return 1;
  675. }
  676. /* We keep the do_lstat code in a separate function to avoid recursion.
  677. * When a path ends with a slash, the stat will fail with ENOENT. In
  678. * this case, we strip the trailing slashes and stat again.
  679. *
  680. * If follow is true then act like stat() and report on the link
  681. * target. Otherwise report on the link itself.
  682. */
  683. static int do_lstat(int follow, const char *file_name, struct stat *buf)
  684. {
  685. WIN32_FILE_ATTRIBUTE_DATA fdata;
  686. wchar_t wfilename[MAX_PATH];
  687. if (xutftowcs_path(wfilename, file_name) < 0)
  688. return -1;
  689. if (GetFileAttributesExW(wfilename, GetFileExInfoStandard, &fdata)) {
  690. buf->st_ino = 0;
  691. buf->st_gid = 0;
  692. buf->st_uid = 0;
  693. buf->st_nlink = 1;
  694. buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
  695. buf->st_size = fdata.nFileSizeLow |
  696. (((off_t)fdata.nFileSizeHigh)<<32);
  697. buf->st_dev = buf->st_rdev = 0; /* not used by Git */
  698. filetime_to_timespec(&(fdata.ftLastAccessTime), &(buf->st_atim));
  699. filetime_to_timespec(&(fdata.ftLastWriteTime), &(buf->st_mtim));
  700. filetime_to_timespec(&(fdata.ftCreationTime), &(buf->st_ctim));
  701. if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
  702. WIN32_FIND_DATAW findbuf;
  703. HANDLE handle = FindFirstFileW(wfilename, &findbuf);
  704. if (handle != INVALID_HANDLE_VALUE) {
  705. if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
  706. (findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
  707. if (follow) {
  708. char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
  709. buf->st_size = readlink(file_name, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
  710. } else {
  711. buf->st_mode = S_IFLNK;
  712. }
  713. buf->st_mode |= S_IREAD;
  714. if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  715. buf->st_mode |= S_IWRITE;
  716. }
  717. FindClose(handle);
  718. }
  719. }
  720. return 0;
  721. }
  722. switch (GetLastError()) {
  723. case ERROR_ACCESS_DENIED:
  724. case ERROR_SHARING_VIOLATION:
  725. case ERROR_LOCK_VIOLATION:
  726. case ERROR_SHARING_BUFFER_EXCEEDED:
  727. errno = EACCES;
  728. break;
  729. case ERROR_BUFFER_OVERFLOW:
  730. errno = ENAMETOOLONG;
  731. break;
  732. case ERROR_NOT_ENOUGH_MEMORY:
  733. errno = ENOMEM;
  734. break;
  735. case ERROR_PATH_NOT_FOUND:
  736. if (!has_valid_directory_prefix(wfilename)) {
  737. errno = ENOTDIR;
  738. break;
  739. }
  740. /* fallthru */
  741. default:
  742. errno = ENOENT;
  743. break;
  744. }
  745. return -1;
  746. }
  747. /* We provide our own lstat/fstat functions, since the provided
  748. * lstat/fstat functions are so slow. These stat functions are
  749. * tailored for Git's usage (read: fast), and are not meant to be
  750. * complete. Note that Git stat()s are redirected to mingw_lstat()
  751. * too, since Windows doesn't really handle symlinks that well.
  752. */
  753. static int do_stat_internal(int follow, const char *file_name, struct stat *buf)
  754. {
  755. int namelen;
  756. char alt_name[PATH_MAX];
  757. if (!do_lstat(follow, file_name, buf))
  758. return 0;
  759. /* if file_name ended in a '/', Windows returned ENOENT;
  760. * try again without trailing slashes
  761. */
  762. if (errno != ENOENT)
  763. return -1;
  764. namelen = strlen(file_name);
  765. if (namelen && file_name[namelen-1] != '/')
  766. return -1;
  767. while (namelen && file_name[namelen-1] == '/')
  768. --namelen;
  769. if (!namelen || namelen >= PATH_MAX)
  770. return -1;
  771. memcpy(alt_name, file_name, namelen);
  772. alt_name[namelen] = 0;
  773. return do_lstat(follow, alt_name, buf);
  774. }
  775. static int get_file_info_by_handle(HANDLE hnd, struct stat *buf)
  776. {
  777. BY_HANDLE_FILE_INFORMATION fdata;
  778. if (!GetFileInformationByHandle(hnd, &fdata)) {
  779. errno = err_win_to_posix(GetLastError());
  780. return -1;
  781. }
  782. buf->st_ino = 0;
  783. buf->st_gid = 0;
  784. buf->st_uid = 0;
  785. buf->st_nlink = 1;
  786. buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
  787. buf->st_size = fdata.nFileSizeLow |
  788. (((off_t)fdata.nFileSizeHigh)<<32);
  789. buf->st_dev = buf->st_rdev = 0; /* not used by Git */
  790. filetime_to_timespec(&(fdata.ftLastAccessTime), &(buf->st_atim));
  791. filetime_to_timespec(&(fdata.ftLastWriteTime), &(buf->st_mtim));
  792. filetime_to_timespec(&(fdata.ftCreationTime), &(buf->st_ctim));
  793. return 0;
  794. }
  795. int mingw_lstat(const char *file_name, struct stat *buf)
  796. {
  797. return do_stat_internal(0, file_name, buf);
  798. }
  799. int mingw_stat(const char *file_name, struct stat *buf)
  800. {
  801. return do_stat_internal(1, file_name, buf);
  802. }
  803. int mingw_fstat(int fd, struct stat *buf)
  804. {
  805. HANDLE fh = (HANDLE)_get_osfhandle(fd);
  806. DWORD avail, type = GetFileType(fh) & ~FILE_TYPE_REMOTE;
  807. switch (type) {
  808. case FILE_TYPE_DISK:
  809. return get_file_info_by_handle(fh, buf);
  810. case FILE_TYPE_CHAR:
  811. case FILE_TYPE_PIPE:
  812. /* initialize stat fields */
  813. memset(buf, 0, sizeof(*buf));
  814. buf->st_nlink = 1;
  815. if (type == FILE_TYPE_CHAR) {
  816. buf->st_mode = _S_IFCHR;
  817. } else {
  818. buf->st_mode = _S_IFIFO;
  819. if (PeekNamedPipe(fh, NULL, 0, NULL, &avail, NULL))
  820. buf->st_size = avail;
  821. }
  822. return 0;
  823. default:
  824. errno = EBADF;
  825. return -1;
  826. }
  827. }
  828. static inline void time_t_to_filetime(time_t t, FILETIME *ft)
  829. {
  830. long long winTime = t * 10000000LL + 116444736000000000LL;
  831. ft->dwLowDateTime = winTime;
  832. ft->dwHighDateTime = winTime >> 32;
  833. }
  834. int mingw_utime (const char *file_name, const struct utimbuf *times)
  835. {
  836. FILETIME mft, aft;
  837. int fh, rc;
  838. DWORD attrs;
  839. wchar_t wfilename[MAX_PATH];
  840. if (xutftowcs_path(wfilename, file_name) < 0)
  841. return -1;
  842. /* must have write permission */
  843. attrs = GetFileAttributesW(wfilename);
  844. if (attrs != INVALID_FILE_ATTRIBUTES &&
  845. (attrs & FILE_ATTRIBUTE_READONLY)) {
  846. /* ignore errors here; open() will report them */
  847. SetFileAttributesW(wfilename, attrs & ~FILE_ATTRIBUTE_READONLY);
  848. }
  849. if ((fh = _wopen(wfilename, O_RDWR | O_BINARY)) < 0) {
  850. rc = -1;
  851. goto revert_attrs;
  852. }
  853. if (times) {
  854. time_t_to_filetime(times->modtime, &mft);
  855. time_t_to_filetime(times->actime, &aft);
  856. } else {
  857. GetSystemTimeAsFileTime(&mft);
  858. aft = mft;
  859. }
  860. if (!SetFileTime((HANDLE)_get_osfhandle(fh), NULL, &aft, &mft)) {
  861. errno = EINVAL;
  862. rc = -1;
  863. } else
  864. rc = 0;
  865. close(fh);
  866. revert_attrs:
  867. if (attrs != INVALID_FILE_ATTRIBUTES &&
  868. (attrs & FILE_ATTRIBUTE_READONLY)) {
  869. /* ignore errors again */
  870. SetFileAttributesW(wfilename, attrs);
  871. }
  872. return rc;
  873. }
  874. #undef strftime
  875. size_t mingw_strftime(char *s, size_t max,
  876. const char *format, const struct tm *tm)
  877. {
  878. /* a pointer to the original strftime in case we can't find the UCRT version */
  879. static size_t (*fallback)(char *, size_t, const char *, const struct tm *) = strftime;
  880. size_t ret;
  881. DECLARE_PROC_ADDR(ucrtbase.dll, size_t, strftime, char *, size_t,
  882. const char *, const struct tm *);
  883. if (INIT_PROC_ADDR(strftime))
  884. ret = strftime(s, max, format, tm);
  885. else
  886. ret = fallback(s, max, format, tm);
  887. if (!ret && errno == EINVAL)
  888. die("invalid strftime format: '%s'", format);
  889. return ret;
  890. }
  891. unsigned int sleep (unsigned int seconds)
  892. {
  893. Sleep(seconds*1000);
  894. return 0;
  895. }
  896. char *mingw_mktemp(char *template)
  897. {
  898. wchar_t wtemplate[MAX_PATH];
  899. if (xutftowcs_path(wtemplate, template) < 0)
  900. return NULL;
  901. if (!_wmktemp(wtemplate))
  902. return NULL;
  903. if (xwcstoutf(template, wtemplate, strlen(template) + 1) < 0)
  904. return NULL;
  905. return template;
  906. }
  907. int mkstemp(char *template)
  908. {
  909. char *filename = mktemp(template);
  910. if (filename == NULL)
  911. return -1;
  912. return open(filename, O_RDWR | O_CREAT, 0600);
  913. }
  914. int gettimeofday(struct timeval *tv, void *tz)
  915. {
  916. FILETIME ft;
  917. long long hnsec;
  918. GetSystemTimeAsFileTime(&ft);
  919. hnsec = filetime_to_hnsec(&ft);
  920. tv->tv_sec = hnsec / 10000000;
  921. tv->tv_usec = (hnsec % 10000000) / 10;
  922. return 0;
  923. }
  924. int pipe(int filedes[2])
  925. {
  926. HANDLE h[2];
  927. /* this creates non-inheritable handles */
  928. if (!CreatePipe(&h[0], &h[1], NULL, 8192)) {
  929. errno = err_win_to_posix(GetLastError());
  930. return -1;
  931. }
  932. filedes[0] = _open_osfhandle(HCAST(int, h[0]), O_NOINHERIT);
  933. if (filedes[0] < 0) {
  934. CloseHandle(h[0]);
  935. CloseHandle(h[1]);
  936. return -1;
  937. }
  938. filedes[1] = _open_osfhandle(HCAST(int, h[1]), O_NOINHERIT);
  939. if (filedes[1] < 0) {
  940. close(filedes[0]);
  941. CloseHandle(h[1]);
  942. return -1;
  943. }
  944. return 0;
  945. }
  946. struct tm *gmtime_r(const time_t *timep, struct tm *result)
  947. {
  948. if (gmtime_s(result, timep) == 0)
  949. return result;
  950. return NULL;
  951. }
  952. struct tm *localtime_r(const time_t *timep, struct tm *result)
  953. {
  954. if (localtime_s(result, timep) == 0)
  955. return result;
  956. return NULL;
  957. }
  958. char *mingw_getcwd(char *pointer, int len)
  959. {
  960. wchar_t cwd[MAX_PATH], wpointer[MAX_PATH];
  961. DWORD ret = GetCurrentDirectoryW(ARRAY_SIZE(cwd), cwd);
  962. if (!ret || ret >= ARRAY_SIZE(cwd)) {
  963. errno = ret ? ENAMETOOLONG : err_win_to_posix(GetLastError());
  964. return NULL;
  965. }
  966. ret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));
  967. if (!ret && GetLastError() == ERROR_ACCESS_DENIED) {
  968. HANDLE hnd = CreateFileW(cwd, 0,
  969. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
  970. OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  971. if (hnd == INVALID_HANDLE_VALUE)
  972. return NULL;
  973. ret = GetFinalPathNameByHandleW(hnd, wpointer, ARRAY_SIZE(wpointer), 0);
  974. CloseHandle(hnd);
  975. if (!ret || ret >= ARRAY_SIZE(wpointer))
  976. return NULL;
  977. if (xwcstoutf(pointer, normalize_ntpath(wpointer), len) < 0)
  978. return NULL;
  979. return pointer;
  980. }
  981. if (!ret || ret >= ARRAY_SIZE(wpointer))
  982. return NULL;
  983. if (xwcstoutf(pointer, wpointer, len) < 0)
  984. return NULL;
  985. convert_slashes(pointer);
  986. return pointer;
  987. }
  988. /*
  989. * See "Parsing C++ Command-Line Arguments" at Microsoft's Docs:
  990. * https://docs.microsoft.com/en-us/cpp/cpp/parsing-cpp-command-line-arguments
  991. */
  992. static const char *quote_arg_msvc(const char *arg)
  993. {
  994. /* count chars to quote */
  995. int len = 0, n = 0;
  996. int force_quotes = 0;
  997. char *q, *d;
  998. const char *p = arg;
  999. if (!*p) force_quotes = 1;
  1000. while (*p) {
  1001. if (isspace(*p) || *p == '*' || *p == '?' || *p == '{' || *p == '\'')
  1002. force_quotes = 1;
  1003. else if (*p == '"')
  1004. n++;
  1005. else if (*p == '\\') {
  1006. int count = 0;
  1007. while (*p == '\\') {
  1008. count++;
  1009. p++;
  1010. len++;
  1011. }
  1012. if (*p == '"' || !*p)
  1013. n += count*2 + 1;
  1014. continue;
  1015. }
  1016. len++;
  1017. p++;
  1018. }
  1019. if (!force_quotes && n == 0)
  1020. return arg;
  1021. /* insert \ where necessary */
  1022. d = q = xmalloc(st_add3(len, n, 3));
  1023. *d++ = '"';
  1024. while (*arg) {
  1025. if (*arg == '"')
  1026. *d++ = '\\';
  1027. else if (*arg == '\\') {
  1028. int count = 0;
  1029. while (*arg == '\\') {
  1030. count++;
  1031. *d++ = *arg++;
  1032. }
  1033. if (*arg == '"' || !*arg) {
  1034. while (count-- > 0)
  1035. *d++ = '\\';
  1036. /* don't escape the surrounding end quote */
  1037. if (!*arg)
  1038. break;
  1039. *d++ = '\\';
  1040. }
  1041. }
  1042. *d++ = *arg++;
  1043. }
  1044. *d++ = '"';
  1045. *d++ = '\0';
  1046. return q;
  1047. }
  1048. #include "quote.h"
  1049. static const char *quote_arg_msys2(const char *arg)
  1050. {
  1051. struct strbuf buf = STRBUF_INIT;
  1052. const char *p2 = arg, *p;
  1053. for (p = arg; *p; p++) {
  1054. int ws = isspace(*p);
  1055. if (!ws && *p != '\\' && *p != '"' && *p != '{' && *p != '\'' &&
  1056. *p != '?' && *p != '*' && *p != '~')
  1057. continue;
  1058. if (!buf.len)
  1059. strbuf_addch(&buf, '"');
  1060. if (p != p2)
  1061. strbuf_add(&buf, p2, p - p2);
  1062. if (*p == '\\' || *p == '"')
  1063. strbuf_addch(&buf, '\\');
  1064. p2 = p;
  1065. }
  1066. if (p == arg)
  1067. strbuf_addch(&buf, '"');
  1068. else if (!buf.len)
  1069. return arg;
  1070. else
  1071. strbuf_add(&buf, p2, p - p2);
  1072. strbuf_addch(&buf, '"');
  1073. return strbuf_detach(&buf, 0);
  1074. }
  1075. static const char *parse_interpreter(const char *cmd)
  1076. {
  1077. static char buf[100];
  1078. char *p, *opt;
  1079. int n, fd;
  1080. /* don't even try a .exe */
  1081. n = strlen(cmd);
  1082. if (n >= 4 && !strcasecmp(cmd+n-4, ".exe"))
  1083. return NULL;
  1084. fd = open(cmd, O_RDONLY);
  1085. if (fd < 0)
  1086. return NULL;
  1087. n = read(fd, buf, sizeof(buf)-1);
  1088. close(fd);
  1089. if (n < 4) /* at least '#!/x' and not error */
  1090. return NULL;
  1091. if (buf[0] != '#' || buf[1] != '!')
  1092. return NULL;
  1093. buf[n] = '\0';
  1094. p = buf + strcspn(buf, "\r\n");
  1095. if (!*p)
  1096. return NULL;
  1097. *p = '\0';
  1098. if (!(p = strrchr(buf+2, '/')) && !(p = strrchr(buf+2, '\\')))
  1099. return NULL;
  1100. /* strip options */
  1101. if ((opt = strchr(p+1, ' ')))
  1102. *opt = '\0';
  1103. return p+1;
  1104. }
  1105. /*
  1106. * exe_only means that we only want to detect .exe files, but not scripts
  1107. * (which do not have an extension)
  1108. */
  1109. static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
  1110. int isexe, int exe_only)
  1111. {
  1112. char path[MAX_PATH];
  1113. wchar_t wpath[MAX_PATH];
  1114. snprintf(path, sizeof(path), "%.*s\\%s.exe", dirlen, dir, cmd);
  1115. if (xutftowcs_path(wpath, path) < 0)
  1116. return NULL;
  1117. if (!isexe && _waccess(wpath, F_OK) == 0)
  1118. return xstrdup(path);
  1119. wpath[wcslen(wpath)-4] = '\0';
  1120. if ((!exe_only || isexe) && _waccess(wpath, F_OK) == 0) {
  1121. if (!(GetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY)) {
  1122. path[strlen(path)-4] = '\0';
  1123. return xstrdup(path);
  1124. }
  1125. }
  1126. return NULL;
  1127. }
  1128. /*
  1129. * Determines the absolute path of cmd using the split path in path.
  1130. * If cmd contains a slash or backslash, no lookup is performed.
  1131. */
  1132. static char *path_lookup(const char *cmd, int exe_only)
  1133. {
  1134. const char *path;
  1135. char *prog = NULL;
  1136. int len = strlen(cmd);
  1137. int isexe = len >= 4 && !strcasecmp(cmd+len-4, ".exe");
  1138. if (strpbrk(cmd, "/\\"))
  1139. return xstrdup(cmd);
  1140. path = mingw_getenv("PATH");
  1141. if (!path)
  1142. return NULL;
  1143. while (!prog) {
  1144. const char *sep = strchrnul(path, ';');
  1145. int dirlen = sep - path;
  1146. if (dirlen)
  1147. prog = lookup_prog(path, dirlen, cmd, isexe, exe_only);
  1148. if (!*sep)
  1149. break;
  1150. path = sep + 1;
  1151. }
  1152. return prog;
  1153. }
  1154. static const wchar_t *wcschrnul(const wchar_t *s, wchar_t c)
  1155. {
  1156. while (*s && *s != c)
  1157. s++;
  1158. return s;
  1159. }
  1160. /* Compare only keys */
  1161. static int wenvcmp(const void *a, const void *b)
  1162. {
  1163. wchar_t *p = *(wchar_t **)a, *q = *(wchar_t **)b;
  1164. size_t p_len, q_len;
  1165. /* Find the keys */
  1166. p_len = wcschrnul(p, L'=') - p;
  1167. q_len = wcschrnul(q, L'=') - q;
  1168. /* If the length differs, include the shorter key's NUL */
  1169. if (p_len < q_len)
  1170. p_len++;
  1171. else if (p_len > q_len)
  1172. p_len = q_len + 1;
  1173. return _wcsnicmp(p, q, p_len);
  1174. }
  1175. /*
  1176. * Build an environment block combining the inherited environment
  1177. * merged with the given list of settings.
  1178. *
  1179. * Values of the form "KEY=VALUE" in deltaenv override inherited values.
  1180. * Values of the form "KEY" in deltaenv delete inherited values.
  1181. *
  1182. * Multiple entries in deltaenv for the same key are explicitly allowed.
  1183. *
  1184. * We return a contiguous block of UNICODE strings with a final trailing
  1185. * zero word.
  1186. */
  1187. static wchar_t *make_environment_block(char **deltaenv)
  1188. {
  1189. wchar_t *wenv = GetEnvironmentStringsW(), *wdeltaenv, *result, *p;
  1190. size_t wlen, s, delta_size, size;
  1191. wchar_t **array = NULL;
  1192. size_t alloc = 0, nr = 0, i;
  1193. size = 1; /* for extra NUL at the end */
  1194. /* If there is no deltaenv to apply, simply return a copy. */
  1195. if (!deltaenv || !*deltaenv) {
  1196. for (p = wenv; p && *p; ) {
  1197. size_t s = wcslen(p) + 1;
  1198. size += s;
  1199. p += s;
  1200. }
  1201. ALLOC_ARRAY(result, size);
  1202. COPY_ARRAY(result, wenv, size);
  1203. FreeEnvironmentStringsW(wenv);
  1204. return result;
  1205. }
  1206. /*
  1207. * If there is a deltaenv, let's accumulate all keys into `array`,
  1208. * sort them using the stable git_stable_qsort() and then copy,
  1209. * skipping duplicate keys
  1210. */
  1211. for (p = wenv; p && *p; ) {
  1212. ALLOC_GROW(array, nr + 1, alloc);
  1213. s = wcslen(p) + 1;
  1214. array[nr++] = p;
  1215. p += s;
  1216. size += s;
  1217. }
  1218. /* (over-)assess size needed for wchar version of deltaenv */
  1219. for (delta_size = 0, i = 0; deltaenv[i]; i++)
  1220. delta_size += strlen(deltaenv[i]) * 2 + 1;
  1221. ALLOC_ARRAY(wdeltaenv, delta_size);
  1222. /* convert the deltaenv, appending to array */
  1223. for (i = 0, p = wdeltaenv; deltaenv[i]; i++) {
  1224. ALLOC_GROW(array, nr + 1, alloc);
  1225. wlen = xutftowcs(p, deltaenv[i], wdeltaenv + delta_size - p);
  1226. array[nr++] = p;
  1227. p += wlen + 1;
  1228. }
  1229. git_stable_qsort(array, nr, sizeof(*array), wenvcmp);
  1230. ALLOC_ARRAY(result, size + delta_size);
  1231. for (p = result, i = 0; i < nr; i++) {
  1232. /* Skip any duplicate keys; last one wins */
  1233. while (i + 1 < nr && !wenvcmp(array + i, array + i + 1))
  1234. i++;
  1235. /* Skip "to delete" entry */
  1236. if (!wcschr(array[i], L'='))
  1237. continue;
  1238. size = wcslen(array[i]) + 1;
  1239. COPY_ARRAY(p, array[i], size);
  1240. p += size;
  1241. }
  1242. *p = L'\0';
  1243. free(array);
  1244. free(wdeltaenv);
  1245. FreeEnvironmentStringsW(wenv);
  1246. return result;
  1247. }
  1248. static void do_unset_environment_variables(void)
  1249. {
  1250. static int done;
  1251. char *p = unset_environment_variables;
  1252. if (done || !p)
  1253. return;
  1254. done = 1;
  1255. for (;;) {
  1256. char *comma = strchr(p, ',');
  1257. if (comma)
  1258. *comma = '\0';
  1259. unsetenv(p);
  1260. if (!comma)
  1261. break;
  1262. p = comma + 1;
  1263. }
  1264. }
  1265. struct pinfo_t {
  1266. struct pinfo_t *next;
  1267. pid_t pid;
  1268. HANDLE proc;
  1269. };
  1270. static struct pinfo_t *pinfo = NULL;
  1271. CRITICAL_SECTION pinfo_cs;
  1272. /* Used to match and chomp off path components */
  1273. static inline int match_last_path_component(const char *path, size_t *len,
  1274. const char *component)
  1275. {
  1276. size_t component_len = strlen(component);
  1277. if (*len < component_len + 1 ||
  1278. !is_dir_sep(path[*len - component_len - 1]) ||
  1279. fspathncmp(path + *len - component_len, component, component_len))
  1280. return 0;
  1281. *len -= component_len + 1;
  1282. /* chomp off repeated dir separators */
  1283. while (*len > 0 && is_dir_sep(path[*len - 1]))
  1284. (*len)--;
  1285. return 1;
  1286. }
  1287. static int is_msys2_sh(const char *cmd)
  1288. {
  1289. if (!cmd)
  1290. return 0;
  1291. if (!strcmp(cmd, "sh")) {
  1292. static int ret = -1;
  1293. char *p;
  1294. if (ret >= 0)
  1295. return ret;
  1296. p = path_lookup(cmd, 0);
  1297. if (!p)
  1298. ret = 0;
  1299. else {
  1300. size_t len = strlen(p);
  1301. ret = match_last_path_component(p, &len, "sh.exe") &&
  1302. match_last_path_component(p, &len, "bin") &&
  1303. match_last_path_component(p, &len, "usr");
  1304. free(p);
  1305. }
  1306. return ret;
  1307. }
  1308. if (ends_with(cmd, "\\sh.exe")) {
  1309. static char *sh;
  1310. if (!sh)
  1311. sh = path_lookup("sh", 0);
  1312. return !fspathcmp(cmd, sh);
  1313. }
  1314. return 0;
  1315. }
  1316. static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaenv,
  1317. const char *dir,
  1318. int prepend_cmd, int fhin, int fhout, int fherr)
  1319. {
  1320. static int restrict_handle_inheritance = -1;
  1321. STARTUPINFOEXW si;
  1322. PROCESS_INFORMATION pi;
  1323. LPPROC_THREAD_ATTRIBUTE_LIST attr_list = NULL;
  1324. HANDLE stdhandles[3];
  1325. DWORD stdhandles_count = 0;
  1326. SIZE_T size;
  1327. struct strbuf args;
  1328. wchar_t wcmd[MAX_PATH], wdir[MAX_PATH], *wargs, *wenvblk = NULL;
  1329. unsigned flags = CREATE_UNICODE_ENVIRONMENT;
  1330. BOOL ret;
  1331. HANDLE cons;
  1332. const char *(*quote_arg)(const char *arg) =
  1333. is_msys2_sh(cmd ? cmd : *argv) ?
  1334. quote_arg_msys2 : quote_arg_msvc;
  1335. const char *strace_env;
  1336. /* Make sure to override previous errors, if any */
  1337. errno = 0;
  1338. if (restrict_handle_inheritance < 0)
  1339. restrict_handle_inheritance = core_restrict_inherited_handles;
  1340. /*
  1341. * The following code to restrict which handles are inherited seems
  1342. * to work properly only on Windows 7 and later, so let's disable it
  1343. * on Windows Vista and 2008.
  1344. */
  1345. if (restrict_handle_inheritance < 0)
  1346. restrict_handle_inheritance = GetVersion() >> 16 >= 7601;
  1347. do_unset_environment_variables();
  1348. /* Determine whether or not we are associated to a console */
  1349. cons = CreateFileW(L"CONOUT$", GENERIC_WRITE,
  1350. FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
  1351. FILE_ATTRIBUTE_NORMAL, NULL);
  1352. if (cons == INVALID_HANDLE_VALUE) {
  1353. /* There is no console associated with this process.
  1354. * Since the child is a console process, Windows
  1355. * would normally create a console window. But
  1356. * since we'll be redirecting std streams, we do
  1357. * not need the console.
  1358. * It is necessary to use DETACHED_PROCESS
  1359. * instead of CREATE_NO_WINDOW to make ssh
  1360. * recognize that it has no console.
  1361. */
  1362. flags |= DETACHED_PROCESS;
  1363. } else {
  1364. /* There is already a console. If we specified
  1365. * DETACHED_PROCESS here, too, Windows would
  1366. * disassociate the child from the console.
  1367. * The same is true for CREATE_NO_WINDOW.
  1368. * Go figure!
  1369. */
  1370. CloseHandle(cons);
  1371. }
  1372. memset(&si, 0, sizeof(si));
  1373. si.StartupInfo.cb = sizeof(si);
  1374. si.StartupInfo.hStdInput = winansi_get_osfhandle(fhin);
  1375. si.StartupInfo.hStdOutput = winansi_get_osfhandle(fhout);
  1376. si.StartupInfo.hStdError = winansi_get_osfhandle(fherr);
  1377. /* The list of handles cannot contain duplicates */
  1378. if (si.StartupInfo.hStdInput != INVALID_HANDLE_VALUE)
  1379. stdhandles[stdhandles_count++] = si.StartupInfo.hStdInput;
  1380. if (si.StartupInfo.hStdOutput != INVALID_HANDLE_VALUE &&
  1381. si.StartupInfo.hStdOutput != si.StartupInfo.hStdInput)
  1382. stdhandles[stdhandles_count++] = si.StartupInfo.hStdOutput;
  1383. if (si.StartupInfo.hStdError != INVALID_HANDLE_VALUE &&
  1384. si.StartupInfo.hStdError != si.StartupInfo.hStdInput &&
  1385. si.StartupInfo.hStdError != si.StartupInfo.hStdOutput)
  1386. stdhandles[stdhandles_count++] = si.StartupInfo.hStdError;
  1387. if (stdhandles_count)
  1388. si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
  1389. if (*argv && !strcmp(cmd, *argv))
  1390. wcmd[0] = L'\0';
  1391. else if (xutftowcs_path(wcmd, cmd) < 0)
  1392. return -1;
  1393. if (dir && xutftowcs_path(wdir, dir) < 0)
  1394. return -1;
  1395. /* concatenate argv, quoting args as we go */
  1396. strbuf_init(&args, 0);
  1397. if (prepend_cmd) {
  1398. char *quoted = (char *)quote_arg(cmd);
  1399. strbuf_addstr(&args, quoted);
  1400. if (quoted != cmd)
  1401. free(quoted);
  1402. }
  1403. for (; *argv; argv++) {
  1404. char *quoted = (char *)quote_arg(*argv);
  1405. if (*args.buf)
  1406. strbuf_addch(&args, ' ');
  1407. strbuf_addstr(&args, quoted);
  1408. if (quoted != *argv)
  1409. free(quoted);
  1410. }
  1411. strace_env = getenv("GIT_STRACE_COMMANDS");
  1412. if (strace_env) {
  1413. char *p = path_lookup("strace.exe", 1);
  1414. if (!p)
  1415. return error("strace not found!");
  1416. if (xutftowcs_path(wcmd, p) < 0) {
  1417. free(p);
  1418. return -1;
  1419. }
  1420. free(p);
  1421. if (!strcmp("1", strace_env) ||
  1422. !strcasecmp("yes", strace_env) ||
  1423. !strcasecmp("true", strace_env))
  1424. strbuf_insert(&args, 0, "strace ", 7);
  1425. else {
  1426. const char *quoted = quote_arg(strace_env);
  1427. struct strbuf buf = STRBUF_INIT;
  1428. strbuf_addf(&buf, "strace -o %s ", quoted);
  1429. if (quoted != strace_env)
  1430. free((char *)quoted);
  1431. strbuf_insert(&args, 0, buf.buf, buf.len);
  1432. strbuf_release(&buf);
  1433. }
  1434. }
  1435. ALLOC_ARRAY(wargs, st_add(st_mult(2, args.len), 1));
  1436. xutftowcs(wargs, args.buf, 2 * args.len + 1);
  1437. strbuf_release(&args);
  1438. wenvblk = make_environment_block(deltaenv);
  1439. memset(&pi, 0, sizeof(pi));
  1440. if (restrict_handle_inheritance && stdhandles_count &&
  1441. (InitializeProcThreadAttributeList(NULL, 1, 0, &size) ||
  1442. GetLastError() == ERROR_INSUFFICIENT_BUFFER) &&
  1443. (attr_list = (LPPROC_THREAD_ATTRIBUTE_LIST)
  1444. (HeapAlloc(GetProcessHeap(), 0, size))) &&
  1445. InitializeProcThreadAttributeList(attr_list, 1, 0, &size) &&
  1446. UpdateProcThreadAttribute(attr_list, 0,
  1447. PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
  1448. stdhandles,
  1449. stdhandles_count * sizeof(HANDLE),
  1450. NULL, NULL)) {
  1451. si.lpAttributeList = attr_list;
  1452. flags |= EXTENDED_STARTUPINFO_PRESENT;
  1453. }
  1454. ret = CreateProcessW(*wcmd ? wcmd : NULL, wargs, NULL, NULL,
  1455. stdhandles_count ? TRUE : FALSE,
  1456. flags, wenvblk, dir ? wdir : NULL,
  1457. &si.StartupInfo, &pi);
  1458. /*
  1459. * On Windows 2008 R2, it seems that specifying certain types of handles
  1460. * (such as FILE_TYPE_CHAR or FILE_TYPE_PIPE) will always produce an
  1461. * error. Rather than playing finicky and fragile games, let's just try
  1462. * to detect this situation and simply try again without restricting any
  1463. * handle inheritance. This is still better than failing to create
  1464. * processes.
  1465. */
  1466. if (!ret && restrict_handle_inheritance && stdhandles_count) {
  1467. DWORD err = GetLastError();
  1468. struct strbuf buf = STRBUF_INIT;
  1469. if (err != ERROR_NO_SYSTEM_RESOURCES &&
  1470. /*
  1471. * On Windows 7 and earlier, handles on pipes and character
  1472. * devices are inherited automatically, and cannot be
  1473. * specified in the thread handle list. Rather than trying
  1474. * to catch each and every corner case (and running the
  1475. * chance of *still* forgetting a few), let's just fall
  1476. * back to creating the process without trying to limit the
  1477. * handle inheritance.
  1478. */
  1479. !(err == ERROR_INVALID_PARAMETER &&
  1480. GetVersion() >> 16 < 9200) &&
  1481. !getenv("SUPPRESS_HANDLE_INHERITANCE_WARNING")) {
  1482. DWORD fl = 0;
  1483. int i;
  1484. setenv("SUPPRESS_HANDLE_INHERITANCE_WARNING", "1", 1);
  1485. for (i = 0; i < stdhandles_count; i++) {
  1486. HANDLE h = stdhandles[i];
  1487. strbuf_addf(&buf, "handle #%d: %p (type %lx, "
  1488. "handle info (%d) %lx\n", i, h,
  1489. GetFileType(h),
  1490. GetHandleInformation(h, &fl),
  1491. fl);
  1492. }
  1493. strbuf_addstr(&buf, "\nThis is a bug; please report it "
  1494. "at\nhttps://github.com/git-for-windows/"
  1495. "git/issues/new\n\n"
  1496. "To suppress this warning, please set "
  1497. "the environment variable\n\n"
  1498. "\tSUPPRESS_HANDLE_INHERITANCE_WARNING=1"
  1499. "\n");
  1500. }
  1501. restrict_handle_inheritance = 0;
  1502. flags &= ~EXTENDED_STARTUPINFO_PRESENT;
  1503. ret = CreateProcessW(*wcmd ? wcmd : NULL, wargs, NULL, NULL,
  1504. TRUE, flags, wenvblk, dir ? wdir : NULL,
  1505. &si.StartupInfo, &pi);
  1506. if (!ret)
  1507. errno = err_win_to_posix(GetLastError());
  1508. if (ret && buf.len) {
  1509. warning("failed to restrict file handles (%ld)\n\n%s",
  1510. err, buf.buf);
  1511. }
  1512. strbuf_release(&buf);
  1513. } else if (!ret)
  1514. errno = err_win_to_posix(GetLastError());
  1515. if (si.lpAttributeList)
  1516. DeleteProcThreadAttributeList(si.lpAttributeList);
  1517. if (attr_list)
  1518. HeapFree(GetProcessHeap(), 0, attr_list);
  1519. free(wenvblk);
  1520. free(wargs);
  1521. if (!ret)
  1522. return -1;
  1523. CloseHandle(pi.hThread);
  1524. /*
  1525. * The process ID is the human-readable identifier of the process
  1526. * that we want to present in log and error messages. The handle
  1527. * is not useful for this purpose. But we cannot close it, either,
  1528. * because it is not possible to turn a process ID into a process
  1529. * handle after the process terminated.
  1530. * Keep the handle in a list for waitpid.
  1531. */
  1532. EnterCriticalSection(&pinfo_cs);
  1533. {
  1534. struct pinfo_t *info = xmalloc(sizeof(struct pinfo_t));
  1535. info->pid = pi.dwProcessId;
  1536. info->proc = pi.hProcess;
  1537. info->next = pinfo;
  1538. pinfo = info;
  1539. }
  1540. LeaveCriticalSection(&pinfo_cs);
  1541. return (pid_t)pi.dwProcessId;
  1542. }
  1543. static pid_t mingw_spawnv(const char *cmd, const char **argv, int prepend_cmd)
  1544. {
  1545. return mingw_spawnve_fd(cmd, argv, NULL, NULL, prepend_cmd, 0, 1, 2);
  1546. }
  1547. pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **deltaenv,
  1548. const char *dir,
  1549. int fhin, int fhout, int fherr)
  1550. {
  1551. pid_t pid;
  1552. char *prog = path_lookup(cmd, 0);
  1553. if (!prog) {
  1554. errno = ENOENT;
  1555. pid = -1;
  1556. }
  1557. else {
  1558. const char *interpr = parse_interpreter(prog);
  1559. if (interpr) {
  1560. const char *argv0 = argv[0];
  1561. char *iprog = path_lookup(interpr, 1);
  1562. argv[0] = prog;
  1563. if (!iprog) {
  1564. errno = ENOENT;
  1565. pid = -1;
  1566. }
  1567. else {
  1568. pid = mingw_spawnve_fd(iprog, argv, deltaenv, dir, 1,
  1569. fhin, fhout, fherr);
  1570. free(iprog);
  1571. }
  1572. argv[0] = argv0;
  1573. }
  1574. else
  1575. pid = mingw_spawnve_fd(prog, argv, deltaenv, dir, 0,
  1576. fhin, fhout, fherr);
  1577. free(prog);
  1578. }
  1579. return pid;
  1580. }
  1581. static int try_shell_exec(const char *cmd, char *const *argv)
  1582. {
  1583. const char *interpr = parse_interpreter(cmd);
  1584. char *prog;
  1585. int pid = 0;
  1586. if (!interpr)
  1587. return 0;
  1588. prog = path_lookup(interpr, 1);
  1589. if (prog) {
  1590. int exec_id;
  1591. int argc = 0;
  1592. #ifndef _MSC_VER
  1593. const
  1594. #endif
  1595. char **argv2;
  1596. while (argv[argc]) argc++;
  1597. ALLOC_ARRAY(argv2, argc + 1);
  1598. argv2[0] = (char *)cmd; /* full path to the script file */
  1599. COPY_ARRAY(&argv2[1], &argv[1], argc);
  1600. exec_id = trace2_exec(prog, argv2);
  1601. pid = mingw_spawnv(prog, argv2, 1);
  1602. if (pid >= 0) {
  1603. int status;
  1604. if (waitpid(pid, &status, 0) < 0)
  1605. status = 255;
  1606. trace2_exec_result(exec_id, status);
  1607. exit(status);
  1608. }
  1609. trace2_exec_result(exec_id, -1);
  1610. pid = 1; /* indicate that we tried but failed */
  1611. free(prog);
  1612. free(argv2);
  1613. }
  1614. return pid;
  1615. }
  1616. int mingw_execv(const char *cmd, char *const *argv)
  1617. {
  1618. /* check if git_command is a shell script */
  1619. if (!try_shell_exec(cmd, argv)) {
  1620. int pid, status;
  1621. int exec_id;
  1622. exec_id = trace2_exec(cmd, (const char **)argv);
  1623. pid = mingw_spawnv(cmd, (const char **)argv, 0);
  1624. if (pid < 0) {
  1625. trace2_exec_result(exec_id, -1);
  1626. return -1;
  1627. }
  1628. if (waitpid(pid, &status, 0) < 0)
  1629. status = 255;
  1630. trace2_exec_result(exec_id, status);
  1631. exit(status);
  1632. }
  1633. return -1;
  1634. }
  1635. int mingw_execvp(const char *cmd, char *const *argv)
  1636. {
  1637. char *prog = path_lookup(cmd, 0);
  1638. if (prog) {
  1639. mingw_execv(prog, argv);
  1640. free(prog);
  1641. } else
  1642. errno = ENOENT;
  1643. return -1;
  1644. }
  1645. int mingw_kill(pid_t pid, int sig)
  1646. {
  1647. if (pid > 0 && sig == SIGTERM) {
  1648. HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
  1649. if (TerminateProcess(h, -1)) {
  1650. CloseHandle(h);
  1651. return 0;
  1652. }
  1653. errno = err_win_to_posix(GetLastError());
  1654. CloseHandle(h);
  1655. return -1;
  1656. } else if (pid > 0 && sig == 0) {
  1657. HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
  1658. if (h) {
  1659. CloseHandle(h);
  1660. return 0;
  1661. }
  1662. }
  1663. errno = EINVAL;
  1664. return -1;
  1665. }
  1666. /*
  1667. * UTF-8 versions of getenv(), putenv() and unsetenv().
  1668. * Internally, they use the CRT's stock UNICODE routines
  1669. * to avoid data loss.
  1670. */
  1671. char *mingw_getenv(const char *name)
  1672. {
  1673. #define GETENV_MAX_RETAIN 64
  1674. static char *values[GETENV_MAX_RETAIN];
  1675. static int value_counter;
  1676. int len_key, len_value;
  1677. wchar_t *w_key;
  1678. char *value;
  1679. wchar_t w_value[32768];
  1680. if (!name || !*name)
  1681. return NULL;
  1682. len_key = strlen(name) + 1;
  1683. /* We cannot use xcalloc() here because that uses getenv() itself */
  1684. w_key = calloc(len_key, sizeof(wchar_t));
  1685. if (!w_key)
  1686. die("Out of memory, (tried to allocate %u wchar_t's)", len_key);
  1687. xutftowcs(w_key, name, len_key);
  1688. /* GetEnvironmentVariableW() only sets the last error upon failure */
  1689. SetLastError(ERROR_SUCCESS);
  1690. len_value = GetEnvironmentVariableW(w_key, w_value, ARRAY_SIZE(w_value));
  1691. if (!len_value && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
  1692. free(w_key);
  1693. return NULL;
  1694. }
  1695. free(w_key);
  1696. len_value = len_value * 3 + 1;
  1697. /* We cannot use xcalloc() here because that uses getenv() itself */
  1698. value = calloc(len_value, sizeof(char));
  1699. if (!value)
  1700. die("Out of memory, (tried to allocate %u bytes)", len_value);
  1701. xwcstoutf(value, w_value, len_value);
  1702. /*
  1703. * We return `value` which is an allocated value and the caller is NOT
  1704. * expecting to have to free it, so we keep a round-robin array,
  1705. * invalidating the buffer after GETENV_MAX_RETAIN getenv() calls.
  1706. */
  1707. free(values[value_counter]);
  1708. values[value_counter++] = value;
  1709. if (value_counter >= ARRAY_SIZE(values))
  1710. value_counter = 0;
  1711. return value;
  1712. }
  1713. int mingw_putenv(const char *namevalue)
  1714. {
  1715. int size;
  1716. wchar_t *wide, *equal;
  1717. BOOL result;
  1718. if (!namevalue || !*namevalue)
  1719. return 0;
  1720. size = strlen(namevalue) * 2 + 1;
  1721. wide = calloc(size, sizeof(wchar_t));
  1722. if (!wide)
  1723. die("Out of memory, (tried to allocate %u wchar_t's)", size);
  1724. xutftowcs(wide, namevalue, size);
  1725. equal = wcschr(wide, L'=');
  1726. if (!equal)
  1727. result = SetEnvironmentVariableW(wide, NULL);
  1728. else {
  1729. *equal = L'\0';
  1730. result = SetEnvironmentVariableW(wide, equal + 1);
  1731. }
  1732. free(wide);
  1733. if (!result)
  1734. errno = err_win_to_posix(GetLastError());
  1735. return result ? 0 : -1;
  1736. }
  1737. static void ensure_socket_initialization(void)
  1738. {
  1739. WSADATA wsa;
  1740. static int initialized = 0;
  1741. if (initialized)
  1742. return;
  1743. if (WSAStartup(MAKEWORD(2,2), &wsa))
  1744. die("unable to initialize winsock subsystem, error %d",
  1745. WSAGetLastError());
  1746. atexit((void(*)(void)) WSACleanup);
  1747. initialized = 1;
  1748. }
  1749. #undef gethostname
  1750. int mingw_gethostname(char *name, int namelen)
  1751. {
  1752. ensure_socket_initialization();
  1753. return gethostname(name, namelen);
  1754. }
  1755. #undef gethostbyname
  1756. struct hostent *mingw_gethostbyname(const char *host)
  1757. {
  1758. ensure_socket_initialization();
  1759. return gethostbyname(host);
  1760. }
  1761. #undef getaddrinfo
  1762. int mingw_getaddrinfo(const char *node, const char *service,
  1763. const struct addrinfo *hints, struct addrinfo **res)
  1764. {
  1765. ensure_socket_initialization();
  1766. return getaddrinfo(node, service, hints, res);
  1767. }
  1768. int mingw_socket(int domain, int type, int protocol)
  1769. {
  1770. int sockfd;
  1771. SOCKET s;
  1772. ensure_socket_initialization();
  1773. s = WSASocket(domain, type, protocol, NULL, 0, 0);
  1774. if (s == INVALID_SOCKET) {
  1775. /*
  1776. * WSAGetLastError() values are regular BSD error codes
  1777. * biased by WSABASEERR.
  1778. * However, strerror() does not know about networking
  1779. * specific errors, which are values beginning at 38 or so.
  1780. * Therefore, we choose to leave the biased error code
  1781. * in errno so that _if_ someone looks up the code somewhere,
  1782. * then it is at least the number that are usually listed.
  1783. */
  1784. errno = WSAGetLastError();
  1785. return -1;
  1786. }
  1787. /* convert into a file descriptor */
  1788. if ((sockfd = _open_osfhandle(s, O_RDWR|O_BINARY)) < 0) {
  1789. closesocket(s);
  1790. return error("unable to make a socket file descriptor: %s",
  1791. strerror(errno));
  1792. }
  1793. return sockfd;
  1794. }
  1795. #undef connect
  1796. int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz)
  1797. {
  1798. SOCKET s = (SOCKET)_get_osfhandle(sockfd);
  1799. return connect(s, sa, sz);
  1800. }
  1801. #undef bind
  1802. int mingw_bind(int sockfd, struct sockaddr *sa, size_t sz)
  1803. {
  1804. SOCKET s = (SOCKET)_get_osfhandle(sockfd);
  1805. return bind(s, sa, sz);
  1806. }
  1807. #undef setsockopt
  1808. int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen)
  1809. {
  1810. SOCKET s = (SOCKET)_get_osfhandle(sockfd);
  1811. return setsockopt(s, lvl, optname, (const char*)optval, optlen);
  1812. }
  1813. #undef shutdown
  1814. int mingw_shutdown(int sockfd, int how)
  1815. {
  1816. SOCKET s = (SOCKET)_get_osfhandle(sockfd);
  1817. return shutdown(s, how);
  1818. }
  1819. #undef listen
  1820. int mingw_listen(int sockfd, int backlog)
  1821. {
  1822. SOCKET s = (SOCKET)_get_osfhandle(sockfd);
  1823. return listen(s, backlog);
  1824. }
  1825. #undef accept
  1826. int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz)
  1827. {
  1828. int sockfd2;
  1829. SOCKET s1 = (SOCKET)_get_osfhandle(sockfd1);
  1830. SOCKET s2 = accept(s1, sa, sz);
  1831. /* convert into a file descriptor */
  1832. if ((sockfd2 = _open_osfhandle(s2, O_RDWR|O_BINARY)) < 0) {
  1833. int err = errno;
  1834. closesocket(s2);
  1835. return error("unable to make a socket file descriptor: %s",
  1836. strerror(err));
  1837. }
  1838. return sockfd2;
  1839. }
  1840. #undef rename
  1841. int mingw_rename(const char *pold, const char *pnew)
  1842. {
  1843. DWORD attrs, gle;
  1844. int tries = 0;
  1845. wchar_t wpold[MAX_PATH], wpnew[MAX_PATH];
  1846. if (xutftowcs_path(wpold, pold) < 0 || xutftowcs_path(wpnew, pnew) < 0)
  1847. return -1;
  1848. /*
  1849. * Try native rename() first to get errno right.
  1850. * It is based on MoveFile(), which cannot overwrite existing files.
  1851. */
  1852. if (!_wrename(wpold, wpnew))
  1853. return 0;
  1854. if (errno != EEXIST)
  1855. return -1;
  1856. repeat:
  1857. if (MoveFileExW(wpold, wpnew, MOVEFILE_REPLACE_EXISTING))
  1858. return 0;
  1859. /* TODO: translate more errors */
  1860. gle = GetLastError();
  1861. if (gle == ERROR_ACCESS_DENIED &&
  1862. (attrs = GetFileAttributesW(wpnew)) != INVALID_FILE_ATTRIBUTES) {
  1863. if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
  1864. DWORD attrsold = GetFileAttributesW(wpold);
  1865. if (attrsold == INVALID_FILE_ATTRIBUTES ||
  1866. !(attrsold & FILE_ATTRIBUTE_DIRECTORY))
  1867. errno = EISDIR;
  1868. else if (!_wrmdir(wpnew))
  1869. goto repeat;
  1870. return -1;
  1871. }
  1872. if ((attrs & FILE_ATTRIBUTE_READONLY) &&
  1873. SetFileAttributesW(wpnew, attrs & ~FILE_ATTRIBUTE_READONLY)) {
  1874. if (MoveFileExW(wpold, wpnew, MOVEFILE_REPLACE_EXISTING))
  1875. return 0;
  1876. gle = GetLastError();
  1877. /* revert file attributes on failure */
  1878. SetFileAttributesW(wpnew, attrs);
  1879. }
  1880. }
  1881. if (tries < ARRAY_SIZE(delay) && gle == ERROR_ACCESS_DENIED) {
  1882. /*
  1883. * We assume that some other process had the source or
  1884. * destination file open at the wrong moment and retry.
  1885. * In order to give the other process a higher chance to
  1886. * complete its operation, we give up our time slice now.
  1887. * If we have to retry again, we do sleep a bit.
  1888. */
  1889. Sleep(delay[tries]);
  1890. tries++;
  1891. goto repeat;
  1892. }
  1893. if (gle == ERROR_ACCESS_DENIED &&
  1894. ask_yes_no_if_possible("Rename from '%s' to '%s' failed. "
  1895. "Should I try again?", pold, pnew))
  1896. goto repeat;
  1897. errno = EACCES;
  1898. return -1;
  1899. }
  1900. /*
  1901. * Note that this doesn't return the actual pagesize, but
  1902. * the allocation granularity. If future Windows specific git code
  1903. * needs the real getpagesize function, we need to find another solution.
  1904. */
  1905. int mingw_getpagesize(void)
  1906. {
  1907. SYSTEM_INFO si;
  1908. GetSystemInfo(&si);
  1909. return si.dwAllocationGranularity;
  1910. }
  1911. /* See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724435.aspx */
  1912. enum EXTENDED_NAME_FORMAT {
  1913. NameDisplay = 3,
  1914. NameUserPrincipal = 8
  1915. };
  1916. static char *get_extended_user_info(enum EXTENDED_NAME_FORMAT type)
  1917. {
  1918. DECLARE_PROC_ADDR(secur32.dll, BOOL, GetUserNameExW,
  1919. enum EXTENDED_NAME_FORMAT, LPCWSTR, PULONG);
  1920. static wchar_t wbuffer[1024];
  1921. DWORD len;
  1922. if (!INIT_PROC_ADDR(GetUserNameExW))
  1923. return NULL;
  1924. len = ARRAY_SIZE(wbuffer);
  1925. if (GetUserNameExW(type, wbuffer, &len)) {
  1926. char *converted = xmalloc((len *= 3));
  1927. if (xwcstoutf(converted, wbuffer, len) >= 0)
  1928. return converted;
  1929. free(converted);
  1930. }
  1931. return NULL;
  1932. }
  1933. char *mingw_query_user_email(void)
  1934. {
  1935. return get_extended_user_info(NameUserPrincipal);
  1936. }
  1937. struct passwd *getpwuid(int uid)
  1938. {
  1939. static unsigned initialized;
  1940. static char user_name[100];
  1941. static struct passwd *p;
  1942. wchar_t buf[100];
  1943. DWORD len;
  1944. if (initialized)
  1945. return p;
  1946. len = ARRAY_SIZE(buf);
  1947. if (!GetUserNameW(buf, &len)) {
  1948. initialized = 1;
  1949. return NULL;
  1950. }
  1951. if (xwcstoutf(user_name, buf, sizeof(user_name)) < 0) {
  1952. initialized = 1;
  1953. return NULL;
  1954. }
  1955. p = xmalloc(sizeof(*p));
  1956. p->pw_name = user_name;
  1957. p->pw_gecos = get_extended_user_info(NameDisplay);
  1958. if (!p->pw_gecos)
  1959. p->pw_gecos = "unknown";
  1960. p->pw_dir = NULL;
  1961. initialized = 1;
  1962. return p;
  1963. }
  1964. static HANDLE timer_event;
  1965. static HANDLE timer_thread;
  1966. static int timer_interval;
  1967. static int one_shot;
  1968. static sig_handler_t timer_fn = SIG_DFL, sigint_fn = SIG_DFL;
  1969. /* The timer works like this:
  1970. * The thread, ticktack(), is a trivial routine that most of the time
  1971. * only waits to receive the signal to terminate. The main thread tells
  1972. * the thread to terminate by setting the timer_event to the signalled
  1973. * state.
  1974. * But ticktack() interrupts the wait state after the timer's interval
  1975. * length to call the signal handler.
  1976. */
  1977. static unsigned __stdcall ticktack(void *dummy)
  1978. {
  1979. while (WaitForSingleObject(timer_event, timer_interval) == WAIT_TIMEOUT) {
  1980. mingw_raise(SIGALRM);
  1981. if (one_shot)
  1982. break;
  1983. }
  1984. return 0;
  1985. }
  1986. static int start_timer_thread(void)
  1987. {
  1988. timer_event = CreateEvent(NULL, FALSE, FALSE, NULL);
  1989. if (timer_event) {
  1990. timer_thread = (HANDLE) _beginthreadex(NULL, 0, ticktack, NULL, 0, NULL);
  1991. if (!timer_thread )
  1992. return errno = ENOMEM,
  1993. error("cannot start timer thread");
  1994. } else
  1995. return errno = ENOMEM,
  1996. error("cannot allocate resources for timer");
  1997. return 0;
  1998. }
  1999. static void stop_timer_thread(void)
  2000. {
  2001. if (timer_event)
  2002. SetEvent(timer_event); /* tell thread to terminate */
  2003. if (timer_thread) {
  2004. int rc = WaitForSingleObject(timer_thread, 10000);
  2005. if (rc == WAIT_TIMEOUT)
  2006. error("timer thread did not terminate timely");
  2007. else if (rc != WAIT_OBJECT_0)
  2008. error("waiting for timer thread failed: %lu",
  2009. GetLastError());
  2010. CloseHandle(timer_thread);
  2011. }
  2012. if (timer_event)
  2013. CloseHandle(timer_event);
  2014. timer_event = NULL;
  2015. timer_thread = NULL;
  2016. }
  2017. static inline int is_timeval_eq(const struct timeval *i1, const struct timeval *i2)
  2018. {
  2019. return i1->tv_sec == i2->tv_sec && i1->tv_usec == i2->tv_usec;
  2020. }
  2021. int setitimer(int type, struct itimerval *in, struct itimerval *out)
  2022. {
  2023. static const struct timeval zero;
  2024. static int atexit_done;
  2025. if (out != NULL)
  2026. return errno = EINVAL,
  2027. error("setitimer param 3 != NULL not implemented");
  2028. if (!is_timeval_eq(&in->it_interval, &zero) &&
  2029. !is_timeval_eq(&in->it_interval, &in->it_value))
  2030. return errno = EINVAL,
  2031. error("setitimer: it_interval must be zero or eq it_value");
  2032. if (timer_thread)
  2033. stop_timer_thread();
  2034. if (is_timeval_eq(&in->it_value, &zero) &&
  2035. is_timeval_eq(&in->it_interval, &zero))
  2036. return 0;
  2037. timer_interval = in->it_value.tv_sec * 1000 + in->it_value.tv_usec / 1000;
  2038. one_shot = is_timeval_eq(&in->it_interval, &zero);
  2039. if (!atexit_done) {
  2040. atexit(stop_timer_thread);
  2041. atexit_done = 1;
  2042. }
  2043. return start_timer_thread();
  2044. }
  2045. int sigaction(int sig, struct sigaction *in, struct sigaction *out)
  2046. {
  2047. if (sig != SIGALRM)
  2048. return errno = EINVAL,
  2049. error("sigaction only implemented for SIGALRM");
  2050. if (out != NULL)
  2051. return errno = EINVAL,
  2052. error("sigaction: param 3 != NULL not implemented");
  2053. timer_fn = in->sa_handler;
  2054. return 0;
  2055. }
  2056. #undef signal
  2057. sig_handler_t mingw_signal(int sig, sig_handler_t handler)
  2058. {
  2059. sig_handler_t old;
  2060. switch (sig) {
  2061. case SIGALRM:
  2062. old = timer_fn;
  2063. timer_fn = handler;
  2064. break;
  2065. case SIGINT:
  2066. old = sigint_fn;
  2067. sigint_fn = handler;
  2068. break;
  2069. default:
  2070. return signal(sig, handler);
  2071. }
  2072. return old;
  2073. }
  2074. #undef raise
  2075. int mingw_raise(int sig)
  2076. {
  2077. switch (sig) {
  2078. case SIGALRM:
  2079. if (timer_fn == SIG_DFL) {
  2080. if (isatty(STDERR_FILENO))
  2081. fputs("Alarm clock\n", stderr);
  2082. exit(128 + SIGALRM);
  2083. } else if (timer_fn != SIG_IGN)
  2084. timer_fn(SIGALRM);
  2085. return 0;
  2086. case SIGINT:
  2087. if (sigint_fn == SIG_DFL)
  2088. exit(128 + SIGINT);
  2089. else if (sigint_fn != SIG_IGN)
  2090. sigint_fn(SIGINT);
  2091. return 0;
  2092. #if defined(_MSC_VER)
  2093. case SIGILL:
  2094. case SIGFPE:
  2095. case SIGSEGV:
  2096. case SIGTERM:
  2097. case SIGBREAK:
  2098. case SIGABRT:
  2099. case SIGABRT_COMPAT:
  2100. /*
  2101. * The <signal.h> header in the MS C Runtime defines 8 signals
  2102. * as being supported on the platform. Anything else causes an
  2103. * "Invalid signal or error" (which in DEBUG builds causes the
  2104. * Abort/Retry/Ignore dialog). We by-pass the CRT for things we
  2105. * already know will fail.
  2106. */
  2107. return raise(sig);
  2108. default:
  2109. errno = EINVAL;
  2110. return -1;
  2111. #else
  2112. default:
  2113. return raise(sig);
  2114. #endif
  2115. }
  2116. }
  2117. int link(const char *oldpath, const char *newpath)
  2118. {
  2119. wchar_t woldpath[MAX_PATH], wnewpath[MAX_PATH];
  2120. if (xutftowcs_path(woldpath, oldpath) < 0 ||
  2121. xutftowcs_path(wnewpath, newpath) < 0)
  2122. return -1;
  2123. if (!CreateHardLinkW(wnewpath, woldpath, NULL)) {
  2124. errno = err_win_to_posix(GetLastError());
  2125. return -1;
  2126. }
  2127. return 0;
  2128. }
  2129. pid_t waitpid(pid_t pid, int *status, int options)
  2130. {
  2131. HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
  2132. FALSE, pid);
  2133. if (!h) {
  2134. errno = ECHILD;
  2135. return -1;
  2136. }
  2137. if (pid > 0 && options & WNOHANG) {
  2138. if (WAIT_OBJECT_0 != WaitForSingleObject(h, 0)) {
  2139. CloseHandle(h);
  2140. return 0;
  2141. }
  2142. options &= ~WNOHANG;
  2143. }
  2144. if (options == 0) {
  2145. struct pinfo_t **ppinfo;
  2146. if (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0) {
  2147. CloseHandle(h);
  2148. return 0;
  2149. }
  2150. if (status)
  2151. GetExitCodeProcess(h, (LPDWORD)status);
  2152. EnterCriticalSection(&pinfo_cs);
  2153. ppinfo = &pinfo;
  2154. while (*ppinfo) {
  2155. struct pinfo_t *info = *ppinfo;
  2156. if (info->pid == pid) {
  2157. CloseHandle(info->proc);
  2158. *ppinfo = info->next;
  2159. free(info);
  2160. break;
  2161. }
  2162. ppinfo = &info->next;
  2163. }
  2164. LeaveCriticalSection(&pinfo_cs);
  2165. CloseHandle(h);
  2166. return pid;
  2167. }
  2168. CloseHandle(h);
  2169. errno = EINVAL;
  2170. return -1;
  2171. }
  2172. int xutftowcsn(wchar_t *wcs, const char *utfs, size_t wcslen, int utflen)
  2173. {
  2174. int upos = 0, wpos = 0;
  2175. const unsigned char *utf = (const unsigned char*) utfs;
  2176. if (!utf || !wcs || wcslen < 1) {
  2177. errno = EINVAL;
  2178. return -1;
  2179. }
  2180. /* reserve space for \0 */
  2181. wcslen--;
  2182. if (utflen < 0)
  2183. utflen = INT_MAX;
  2184. while (upos < utflen) {
  2185. int c = utf[upos++] & 0xff;
  2186. if (utflen == INT_MAX && c == 0)
  2187. break;
  2188. if (wpos >= wcslen) {
  2189. wcs[wpos] = 0;
  2190. errno = ERANGE;
  2191. return -1;
  2192. }
  2193. if (c < 0x80) {
  2194. /* ASCII */
  2195. wcs[wpos++] = c;
  2196. } else if (c >= 0xc2 && c < 0xe0 && upos < utflen &&
  2197. (utf[upos] & 0xc0) == 0x80) {
  2198. /* 2-byte utf-8 */
  2199. c = ((c & 0x1f) << 6);
  2200. c |= (utf[upos++] & 0x3f);
  2201. wcs[wpos++] = c;
  2202. } else if (c >= 0xe0 && c < 0xf0 && upos + 1 < utflen &&
  2203. !(c == 0xe0 && utf[upos] < 0xa0) && /* over-long encoding */
  2204. (utf[upos] & 0xc0) == 0x80 &&
  2205. (utf[upos + 1] & 0xc0) == 0x80) {
  2206. /* 3-byte utf-8 */
  2207. c = ((c & 0x0f) << 12);
  2208. c |= ((utf[upos++] & 0x3f) << 6);
  2209. c |= (utf[upos++] & 0x3f);
  2210. wcs[wpos++] = c;
  2211. } else if (c >= 0xf0 && c < 0xf5 && upos + 2 < utflen &&
  2212. wpos + 1 < wcslen &&
  2213. !(c == 0xf0 && utf[upos] < 0x90) && /* over-long encoding */
  2214. !(c == 0xf4 && utf[upos] >= 0x90) && /* > \u10ffff */
  2215. (utf[upos] & 0xc0) == 0x80 &&
  2216. (utf[upos + 1] & 0xc0) == 0x80 &&
  2217. (utf[upos + 2] & 0xc0) == 0x80) {
  2218. /* 4-byte utf-8: convert to \ud8xx \udcxx surrogate pair */
  2219. c = ((c & 0x07) << 18);
  2220. c |= ((utf[upos++] & 0x3f) << 12);
  2221. c |= ((utf[upos++] & 0x3f) << 6);
  2222. c |= (utf[upos++] & 0x3f);
  2223. c -= 0x10000;
  2224. wcs[wpos++] = 0xd800 | (c >> 10);
  2225. wcs[wpos++] = 0xdc00 | (c & 0x3ff);
  2226. } else if (c >= 0xa0) {
  2227. /* invalid utf-8 byte, printable unicode char: convert 1:1 */
  2228. wcs[wpos++] = c;
  2229. } else {
  2230. /* invalid utf-8 byte, non-printable unicode: convert to hex */
  2231. static const char *hex = "0123456789abcdef";
  2232. wcs[wpos++] = hex[c >> 4];
  2233. if (wpos < wcslen)
  2234. wcs[wpos++] = hex[c & 0x0f];
  2235. }
  2236. }
  2237. wcs[wpos] = 0;
  2238. return wpos;
  2239. }
  2240. int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen)
  2241. {
  2242. if (!wcs || !utf || utflen < 1) {
  2243. errno = EINVAL;
  2244. return -1;
  2245. }
  2246. utflen = WideCharToMultiByte(CP_UTF8, 0, wcs, -1, utf, utflen, NULL, NULL);
  2247. if (utflen)
  2248. return utflen - 1;
  2249. errno = ERANGE;
  2250. return -1;
  2251. }
  2252. static void setup_windows_environment(void)
  2253. {
  2254. char *tmp = getenv("TMPDIR");
  2255. /* on Windows it is TMP and TEMP */
  2256. if (!tmp) {
  2257. if (!(tmp = getenv("TMP")))
  2258. tmp = getenv("TEMP");
  2259. if (tmp) {
  2260. setenv("TMPDIR", tmp, 1);
  2261. tmp = getenv("TMPDIR");
  2262. }
  2263. }
  2264. if (tmp) {
  2265. /*
  2266. * Convert all dir separators to forward slashes,
  2267. * to help shell commands called from the Git
  2268. * executable (by not mistaking the dir separators
  2269. * for escape characters).
  2270. */
  2271. convert_slashes(tmp);
  2272. }
  2273. /* simulate TERM to enable auto-color (see color.c) */
  2274. if (!getenv("TERM"))
  2275. setenv("TERM", "cygwin", 1);
  2276. /* calculate HOME if not set */
  2277. if (!getenv("HOME")) {
  2278. /*
  2279. * try $HOMEDRIVE$HOMEPATH - the home share may be a network
  2280. * location, thus also check if the path exists (i.e. is not
  2281. * disconnected)
  2282. */
  2283. if ((tmp = getenv("HOMEDRIVE"))) {
  2284. struct strbuf buf = STRBUF_INIT;
  2285. strbuf_addstr(&buf, tmp);
  2286. if ((tmp = getenv("HOMEPATH"))) {
  2287. strbuf_addstr(&buf, tmp);
  2288. if (is_directory(buf.buf))
  2289. setenv("HOME", buf.buf, 1);
  2290. else
  2291. tmp = NULL; /* use $USERPROFILE */
  2292. }
  2293. strbuf_release(&buf);
  2294. }
  2295. /* use $USERPROFILE if the home share is not available */
  2296. if (!tmp && (tmp = getenv("USERPROFILE")))
  2297. setenv("HOME", tmp, 1);
  2298. }
  2299. }
  2300. int is_valid_win32_path(const char *path, int allow_literal_nul)
  2301. {
  2302. const char *p = path;
  2303. int preceding_space_or_period = 0, i = 0, periods = 0;
  2304. if (!protect_ntfs)
  2305. return 1;
  2306. skip_dos_drive_prefix((char **)&path);
  2307. goto segment_start;
  2308. for (;;) {
  2309. char c = *(path++);
  2310. switch (c) {
  2311. case '\0':
  2312. case '/': case '\\':
  2313. /* cannot end in ` ` or `.`, except for `.` and `..` */
  2314. if (preceding_space_or_period &&
  2315. (i != periods || periods > 2))
  2316. return 0;
  2317. if (!c)
  2318. return 1;
  2319. i = periods = preceding_space_or_period = 0;
  2320. segment_start:
  2321. switch (*path) {
  2322. case 'a': case 'A': /* AUX */
  2323. if (((c = path[++i]) != 'u' && c != 'U') ||
  2324. ((c = path[++i]) != 'x' && c != 'X')) {
  2325. not_a_reserved_name:
  2326. path += i;
  2327. continue;
  2328. }
  2329. break;
  2330. case 'c': case 'C':
  2331. /* COM1 ... COM9, CON, CONIN$, CONOUT$ */
  2332. if ((c = path[++i]) != 'o' && c != 'O')
  2333. goto not_a_reserved_name;
  2334. c = path[++i];
  2335. if (c == 'm' || c == 'M') { /* COM1 ... COM9 */
  2336. c = path[++i];
  2337. if (c < '1' || c > '9')
  2338. goto not_a_reserved_name;
  2339. } else if (c == 'n' || c == 'N') { /* CON */
  2340. c = path[i + 1];
  2341. if ((c == 'i' || c == 'I') &&
  2342. ((c = path[i + 2]) == 'n' ||
  2343. c == 'N') &&
  2344. path[i + 3] == '$')
  2345. i += 3; /* CONIN$ */
  2346. else if ((c == 'o' || c == 'O') &&
  2347. ((c = path[i + 2]) == 'u' ||
  2348. c == 'U') &&
  2349. ((c = path[i + 3]) == 't' ||
  2350. c == 'T') &&
  2351. path[i + 4] == '$')
  2352. i += 4; /* CONOUT$ */
  2353. } else
  2354. goto not_a_reserved_name;
  2355. break;
  2356. case 'l': case 'L': /* LPT<N> */
  2357. if (((c = path[++i]) != 'p' && c != 'P') ||
  2358. ((c = path[++i]) != 't' && c != 'T') ||
  2359. !isdigit(path[++i]))
  2360. goto not_a_reserved_name;
  2361. break;
  2362. case 'n': case 'N': /* NUL */
  2363. if (((c = path[++i]) != 'u' && c != 'U') ||
  2364. ((c = path[++i]) != 'l' && c != 'L') ||
  2365. (allow_literal_nul &&
  2366. !path[i + 1] && p == path))
  2367. goto not_a_reserved_name;
  2368. break;
  2369. case 'p': case 'P': /* PRN */
  2370. if (((c = path[++i]) != 'r' && c != 'R') ||
  2371. ((c = path[++i]) != 'n' && c != 'N'))
  2372. goto not_a_reserved_name;
  2373. break;
  2374. default:
  2375. continue;
  2376. }
  2377. /*
  2378. * So far, this looks like a reserved name. Let's see
  2379. * whether it actually is one: trailing spaces, a file
  2380. * extension, or an NTFS Alternate Data Stream do not
  2381. * matter, the name is still reserved if any of those
  2382. * follow immediately after the actual name.
  2383. */
  2384. i++;
  2385. if (path[i] == ' ') {
  2386. preceding_space_or_period = 1;
  2387. while (path[++i] == ' ')
  2388. ; /* skip all spaces */
  2389. }
  2390. c = path[i];
  2391. if (c && c != '.' && c != ':' && c != '/' && c != '\\')
  2392. goto not_a_reserved_name;
  2393. /* contains reserved name */
  2394. return 0;
  2395. case '.':
  2396. periods++;
  2397. /* fallthru */
  2398. case ' ':
  2399. preceding_space_or_period = 1;
  2400. i++;
  2401. continue;
  2402. case ':': /* DOS drive prefix was already skipped */
  2403. case '<': case '>': case '"': case '|': case '?': case '*':
  2404. /* illegal character */
  2405. return 0;
  2406. default:
  2407. if (c > '\0' && c < '\x20')
  2408. /* illegal character */
  2409. return 0;
  2410. }
  2411. preceding_space_or_period = 0;
  2412. i++;
  2413. }
  2414. }
  2415. #if !defined(_MSC_VER)
  2416. /*
  2417. * Disable MSVCRT command line wildcard expansion (__getmainargs called from
  2418. * mingw startup code, see init.c in mingw runtime).
  2419. */
  2420. int _CRT_glob = 0;
  2421. #endif
  2422. static NORETURN void die_startup(void)
  2423. {
  2424. fputs("fatal: not enough memory for initialization", stderr);
  2425. exit(128);
  2426. }
  2427. static void *malloc_startup(size_t size)
  2428. {
  2429. void *result = malloc(size);
  2430. if (!result)
  2431. die_startup();
  2432. return result;
  2433. }
  2434. static char *wcstoutfdup_startup(char *buffer, const wchar_t *wcs, size_t len)
  2435. {
  2436. len = xwcstoutf(buffer, wcs, len) + 1;
  2437. return memcpy(malloc_startup(len), buffer, len);
  2438. }
  2439. static void maybe_redirect_std_handle(const wchar_t *key, DWORD std_id, int fd,
  2440. DWORD desired_access, DWORD flags)
  2441. {
  2442. DWORD create_flag = fd ? OPEN_ALWAYS : OPEN_EXISTING;
  2443. wchar_t buf[MAX_PATH];
  2444. DWORD max = ARRAY_SIZE(buf);
  2445. HANDLE handle;
  2446. DWORD ret = GetEnvironmentVariableW(key, buf, max);
  2447. if (!ret || ret >= max)
  2448. return;
  2449. /* make sure this does not leak into child processes */
  2450. SetEnvironmentVariableW(key, NULL);
  2451. if (!wcscmp(buf, L"off")) {
  2452. close(fd);
  2453. handle = GetStdHandle(std_id);
  2454. if (handle != INVALID_HANDLE_VALUE)
  2455. CloseHandle(handle);
  2456. return;
  2457. }
  2458. if (std_id == STD_ERROR_HANDLE && !wcscmp(buf, L"2>&1")) {
  2459. handle = GetStdHandle(STD_OUTPUT_HANDLE);
  2460. if (handle == INVALID_HANDLE_VALUE) {
  2461. close(fd);
  2462. handle = GetStdHandle(std_id);
  2463. if (handle != INVALID_HANDLE_VALUE)
  2464. CloseHandle(handle);
  2465. } else {
  2466. int new_fd = _open_osfhandle((intptr_t)handle, O_BINARY);
  2467. SetStdHandle(std_id, handle);
  2468. dup2(new_fd, fd);
  2469. /* do *not* close the new_fd: that would close stdout */
  2470. }
  2471. return;
  2472. }
  2473. handle = CreateFileW(buf, desired_access, 0, NULL, create_flag,
  2474. flags, NULL);
  2475. if (handle != INVALID_HANDLE_VALUE) {
  2476. int new_fd = _open_osfhandle((intptr_t)handle, O_BINARY);
  2477. SetStdHandle(std_id, handle);
  2478. dup2(new_fd, fd);
  2479. close(new_fd);
  2480. }
  2481. }
  2482. static void maybe_redirect_std_handles(void)
  2483. {
  2484. maybe_redirect_std_handle(L"GIT_REDIRECT_STDIN", STD_INPUT_HANDLE, 0,
  2485. GENERIC_READ, FILE_ATTRIBUTE_NORMAL);
  2486. maybe_redirect_std_handle(L"GIT_REDIRECT_STDOUT", STD_OUTPUT_HANDLE, 1,
  2487. GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL);
  2488. maybe_redirect_std_handle(L"GIT_REDIRECT_STDERR", STD_ERROR_HANDLE, 2,
  2489. GENERIC_WRITE, FILE_FLAG_NO_BUFFERING);
  2490. }
  2491. #ifdef _MSC_VER
  2492. #ifdef _DEBUG
  2493. #include <crtdbg.h>
  2494. #endif
  2495. #endif
  2496. /*
  2497. * We implement wmain() and compile with -municode, which would
  2498. * normally ignore main(), but we call the latter from the former
  2499. * so that we can handle non-ASCII command-line parameters
  2500. * appropriately.
  2501. *
  2502. * To be more compatible with the core git code, we convert
  2503. * argv into UTF8 and pass them directly to main().
  2504. */
  2505. int wmain(int argc, const wchar_t **wargv)
  2506. {
  2507. int i, maxlen, exit_status;
  2508. char *buffer, **save;
  2509. const char **argv;
  2510. trace2_initialize_clock();
  2511. #ifdef _MSC_VER
  2512. #ifdef _DEBUG
  2513. _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
  2514. #endif
  2515. #ifdef USE_MSVC_CRTDBG
  2516. _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
  2517. #endif
  2518. #endif
  2519. maybe_redirect_std_handles();
  2520. /* determine size of argv and environ conversion buffer */
  2521. maxlen = wcslen(wargv[0]);
  2522. for (i = 1; i < argc; i++)
  2523. maxlen = max(maxlen, wcslen(wargv[i]));
  2524. /* allocate buffer (wchar_t encodes to max 3 UTF-8 bytes) */
  2525. maxlen = 3 * maxlen + 1;
  2526. buffer = malloc_startup(maxlen);
  2527. /*
  2528. * Create a UTF-8 version of w_argv. Also create a "save" copy
  2529. * to remember all the string pointers because parse_options()
  2530. * will remove claimed items from the argv that we pass down.
  2531. */
  2532. ALLOC_ARRAY(argv, argc + 1);
  2533. ALLOC_ARRAY(save, argc + 1);
  2534. for (i = 0; i < argc; i++)
  2535. argv[i] = save[i] = wcstoutfdup_startup(buffer, wargv[i], maxlen);
  2536. argv[i] = save[i] = NULL;
  2537. free(buffer);
  2538. /* fix Windows specific environment settings */
  2539. setup_windows_environment();
  2540. unset_environment_variables = xstrdup("PERL5LIB");
  2541. /* initialize critical section for waitpid pinfo_t list */
  2542. InitializeCriticalSection(&pinfo_cs);
  2543. /* set up default file mode and file modes for stdin/out/err */
  2544. _fmode = _O_BINARY;
  2545. _setmode(_fileno(stdin), _O_BINARY);
  2546. _setmode(_fileno(stdout), _O_BINARY);
  2547. _setmode(_fileno(stderr), _O_BINARY);
  2548. /* initialize Unicode console */
  2549. winansi_init();
  2550. /* invoke the real main() using our utf8 version of argv. */
  2551. exit_status = main(argc, argv);
  2552. for (i = 0; i < argc; i++)
  2553. free(save[i]);
  2554. free(save);
  2555. free(argv);
  2556. return exit_status;
  2557. }
  2558. int uname(struct utsname *buf)
  2559. {
  2560. unsigned v = (unsigned)GetVersion();
  2561. memset(buf, 0, sizeof(*buf));
  2562. xsnprintf(buf->sysname, sizeof(buf->sysname), "Windows");
  2563. xsnprintf(buf->release, sizeof(buf->release),
  2564. "%u.%u", v & 0xff, (v >> 8) & 0xff);
  2565. /* assuming NT variants only.. */
  2566. xsnprintf(buf->version, sizeof(buf->version),
  2567. "%u", (v >> 16) & 0x7fff);
  2568. return 0;
  2569. }