unix.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964
  1. /* Copyright (C) 2002-2015 Free Software Foundation, Inc.
  2. Contributed by Andy Vaught
  3. F2003 I/O support contributed by Jerry DeLisle
  4. This file is part of the GNU Fortran runtime library (libgfortran).
  5. Libgfortran is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. Libgfortran is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. Under Section 7 of GPL version 3, you are granted additional
  14. permissions described in the GCC Runtime Library Exception, version
  15. 3.1, as published by the Free Software Foundation.
  16. You should have received a copy of the GNU General Public License and
  17. a copy of the GCC Runtime Library Exception along with this program;
  18. see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. <http://www.gnu.org/licenses/>. */
  20. /* Unix stream I/O module */
  21. #include "io.h"
  22. #include "unix.h"
  23. #include <stdlib.h>
  24. #include <limits.h>
  25. #ifdef HAVE_UNISTD_H
  26. #include <unistd.h>
  27. #endif
  28. #include <sys/stat.h>
  29. #include <fcntl.h>
  30. #include <assert.h>
  31. #include <string.h>
  32. #include <errno.h>
  33. /* For mingw, we don't identify files by their inode number, but by a
  34. 64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */
  35. #ifdef __MINGW32__
  36. #define WIN32_LEAN_AND_MEAN
  37. #include <windows.h>
  38. #if !defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
  39. #undef lseek
  40. #define lseek _lseeki64
  41. #undef fstat
  42. #define fstat _fstati64
  43. #undef stat
  44. #define stat _stati64
  45. #endif
  46. #ifndef HAVE_WORKING_STAT
  47. static uint64_t
  48. id_from_handle (HANDLE hFile)
  49. {
  50. BY_HANDLE_FILE_INFORMATION FileInformation;
  51. if (hFile == INVALID_HANDLE_VALUE)
  52. return 0;
  53. memset (&FileInformation, 0, sizeof(FileInformation));
  54. if (!GetFileInformationByHandle (hFile, &FileInformation))
  55. return 0;
  56. return ((uint64_t) FileInformation.nFileIndexLow)
  57. | (((uint64_t) FileInformation.nFileIndexHigh) << 32);
  58. }
  59. static uint64_t
  60. id_from_path (const char *path)
  61. {
  62. HANDLE hFile;
  63. uint64_t res;
  64. if (!path || !*path || access (path, F_OK))
  65. return (uint64_t) -1;
  66. hFile = CreateFile (path, 0, 0, NULL, OPEN_EXISTING,
  67. FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
  68. NULL);
  69. res = id_from_handle (hFile);
  70. CloseHandle (hFile);
  71. return res;
  72. }
  73. static uint64_t
  74. id_from_fd (const int fd)
  75. {
  76. return id_from_handle ((HANDLE) _get_osfhandle (fd));
  77. }
  78. #endif /* HAVE_WORKING_STAT */
  79. #endif /* __MINGW32__ */
  80. /* min macro that evaluates its arguments only once. */
  81. #ifdef min
  82. #undef min
  83. #endif
  84. #define min(a,b) \
  85. ({ typeof (a) _a = (a); \
  86. typeof (b) _b = (b); \
  87. _a < _b ? _a : _b; })
  88. /* These flags aren't defined on all targets (mingw32), so provide them
  89. here. */
  90. #ifndef S_IRGRP
  91. #define S_IRGRP 0
  92. #endif
  93. #ifndef S_IWGRP
  94. #define S_IWGRP 0
  95. #endif
  96. #ifndef S_IROTH
  97. #define S_IROTH 0
  98. #endif
  99. #ifndef S_IWOTH
  100. #define S_IWOTH 0
  101. #endif
  102. #ifndef HAVE_ACCESS
  103. #ifndef W_OK
  104. #define W_OK 2
  105. #endif
  106. #ifndef R_OK
  107. #define R_OK 4
  108. #endif
  109. #ifndef F_OK
  110. #define F_OK 0
  111. #endif
  112. /* Fallback implementation of access() on systems that don't have it.
  113. Only modes R_OK, W_OK and F_OK are used in this file. */
  114. static int
  115. fallback_access (const char *path, int mode)
  116. {
  117. int fd;
  118. if ((mode & R_OK) && (fd = open (path, O_RDONLY)) < 0)
  119. return -1;
  120. close (fd);
  121. if ((mode & W_OK) && (fd = open (path, O_WRONLY)) < 0)
  122. return -1;
  123. close (fd);
  124. if (mode == F_OK)
  125. {
  126. struct stat st;
  127. return stat (path, &st);
  128. }
  129. return 0;
  130. }
  131. #undef access
  132. #define access fallback_access
  133. #endif
  134. /* Fallback directory for creating temporary files. P_tmpdir is
  135. defined on many POSIX platforms. */
  136. #ifndef P_tmpdir
  137. #ifdef _P_tmpdir
  138. #define P_tmpdir _P_tmpdir /* MinGW */
  139. #else
  140. #define P_tmpdir "/tmp"
  141. #endif
  142. #endif
  143. /* Unix and internal stream I/O module */
  144. static const int BUFFER_SIZE = 8192;
  145. typedef struct
  146. {
  147. stream st;
  148. gfc_offset buffer_offset; /* File offset of the start of the buffer */
  149. gfc_offset physical_offset; /* Current physical file offset */
  150. gfc_offset logical_offset; /* Current logical file offset */
  151. gfc_offset file_length; /* Length of the file. */
  152. char *buffer; /* Pointer to the buffer. */
  153. int fd; /* The POSIX file descriptor. */
  154. int active; /* Length of valid bytes in the buffer */
  155. int ndirty; /* Dirty bytes starting at buffer_offset */
  156. /* Cached stat(2) values. */
  157. dev_t st_dev;
  158. ino_t st_ino;
  159. bool unbuffered; /* Buffer should be flushed after each I/O statement. */
  160. }
  161. unix_stream;
  162. /* fix_fd()-- Given a file descriptor, make sure it is not one of the
  163. * standard descriptors, returning a non-standard descriptor. If the
  164. * user specifies that system errors should go to standard output,
  165. * then closes standard output, we don't want the system errors to a
  166. * file that has been given file descriptor 1 or 0. We want to send
  167. * the error to the invalid descriptor. */
  168. static int
  169. fix_fd (int fd)
  170. {
  171. #ifdef HAVE_DUP
  172. int input, output, error;
  173. input = output = error = 0;
  174. /* Unix allocates the lowest descriptors first, so a loop is not
  175. required, but this order is. */
  176. if (fd == STDIN_FILENO)
  177. {
  178. fd = dup (fd);
  179. input = 1;
  180. }
  181. if (fd == STDOUT_FILENO)
  182. {
  183. fd = dup (fd);
  184. output = 1;
  185. }
  186. if (fd == STDERR_FILENO)
  187. {
  188. fd = dup (fd);
  189. error = 1;
  190. }
  191. if (input)
  192. close (STDIN_FILENO);
  193. if (output)
  194. close (STDOUT_FILENO);
  195. if (error)
  196. close (STDERR_FILENO);
  197. #endif
  198. return fd;
  199. }
  200. /* If the stream corresponds to a preconnected unit, we flush the
  201. corresponding C stream. This is bugware for mixed C-Fortran codes
  202. where the C code doesn't flush I/O before returning. */
  203. void
  204. flush_if_preconnected (stream * s)
  205. {
  206. int fd;
  207. fd = ((unix_stream *) s)->fd;
  208. if (fd == STDIN_FILENO)
  209. fflush (stdin);
  210. else if (fd == STDOUT_FILENO)
  211. fflush (stdout);
  212. else if (fd == STDERR_FILENO)
  213. fflush (stderr);
  214. }
  215. /********************************************************************
  216. Raw I/O functions (read, write, seek, tell, truncate, close).
  217. These functions wrap the basic POSIX I/O syscalls. Any deviation in
  218. semantics is a bug, except the following: write restarts in case
  219. of being interrupted by a signal, and as the first argument the
  220. functions take the unix_stream struct rather than an integer file
  221. descriptor. Also, for POSIX read() and write() a nbyte argument larger
  222. than SSIZE_MAX is undefined; here the type of nbyte is ssize_t rather
  223. than size_t as for POSIX read/write.
  224. *********************************************************************/
  225. static int
  226. raw_flush (unix_stream * s __attribute__ ((unused)))
  227. {
  228. return 0;
  229. }
  230. static ssize_t
  231. raw_read (unix_stream * s, void * buf, ssize_t nbyte)
  232. {
  233. /* For read we can't do I/O in a loop like raw_write does, because
  234. that will break applications that wait for interactive I/O. */
  235. return read (s->fd, buf, nbyte);
  236. }
  237. static ssize_t
  238. raw_write (unix_stream * s, const void * buf, ssize_t nbyte)
  239. {
  240. ssize_t trans, bytes_left;
  241. char *buf_st;
  242. bytes_left = nbyte;
  243. buf_st = (char *) buf;
  244. /* We must write in a loop since some systems don't restart system
  245. calls in case of a signal. */
  246. while (bytes_left > 0)
  247. {
  248. trans = write (s->fd, buf_st, bytes_left);
  249. if (trans < 0)
  250. {
  251. if (errno == EINTR)
  252. continue;
  253. else
  254. return trans;
  255. }
  256. buf_st += trans;
  257. bytes_left -= trans;
  258. }
  259. return nbyte - bytes_left;
  260. }
  261. static gfc_offset
  262. raw_seek (unix_stream * s, gfc_offset offset, int whence)
  263. {
  264. return lseek (s->fd, offset, whence);
  265. }
  266. static gfc_offset
  267. raw_tell (unix_stream * s)
  268. {
  269. return lseek (s->fd, 0, SEEK_CUR);
  270. }
  271. static gfc_offset
  272. raw_size (unix_stream * s)
  273. {
  274. struct stat statbuf;
  275. int ret = fstat (s->fd, &statbuf);
  276. if (ret == -1)
  277. return ret;
  278. if (S_ISREG (statbuf.st_mode))
  279. return statbuf.st_size;
  280. else
  281. return 0;
  282. }
  283. static int
  284. raw_truncate (unix_stream * s, gfc_offset length)
  285. {
  286. #ifdef __MINGW32__
  287. HANDLE h;
  288. gfc_offset cur;
  289. if (isatty (s->fd))
  290. {
  291. errno = EBADF;
  292. return -1;
  293. }
  294. h = (HANDLE) _get_osfhandle (s->fd);
  295. if (h == INVALID_HANDLE_VALUE)
  296. {
  297. errno = EBADF;
  298. return -1;
  299. }
  300. cur = lseek (s->fd, 0, SEEK_CUR);
  301. if (cur == -1)
  302. return -1;
  303. if (lseek (s->fd, length, SEEK_SET) == -1)
  304. goto error;
  305. if (!SetEndOfFile (h))
  306. {
  307. errno = EBADF;
  308. goto error;
  309. }
  310. if (lseek (s->fd, cur, SEEK_SET) == -1)
  311. return -1;
  312. return 0;
  313. error:
  314. lseek (s->fd, cur, SEEK_SET);
  315. return -1;
  316. #elif defined HAVE_FTRUNCATE
  317. return ftruncate (s->fd, length);
  318. #elif defined HAVE_CHSIZE
  319. return chsize (s->fd, length);
  320. #else
  321. runtime_error ("required ftruncate or chsize support not present");
  322. return -1;
  323. #endif
  324. }
  325. static int
  326. raw_close (unix_stream * s)
  327. {
  328. int retval;
  329. if (s->fd == -1)
  330. retval = -1;
  331. else if (s->fd != STDOUT_FILENO
  332. && s->fd != STDERR_FILENO
  333. && s->fd != STDIN_FILENO)
  334. retval = close (s->fd);
  335. else
  336. retval = 0;
  337. free (s);
  338. return retval;
  339. }
  340. static int
  341. raw_markeor (unix_stream * s __attribute__ ((unused)))
  342. {
  343. return 0;
  344. }
  345. static const struct stream_vtable raw_vtable = {
  346. .read = (void *) raw_read,
  347. .write = (void *) raw_write,
  348. .seek = (void *) raw_seek,
  349. .tell = (void *) raw_tell,
  350. .size = (void *) raw_size,
  351. .trunc = (void *) raw_truncate,
  352. .close = (void *) raw_close,
  353. .flush = (void *) raw_flush,
  354. .markeor = (void *) raw_markeor
  355. };
  356. static int
  357. raw_init (unix_stream * s)
  358. {
  359. s->st.vptr = &raw_vtable;
  360. s->buffer = NULL;
  361. return 0;
  362. }
  363. /*********************************************************************
  364. Buffered I/O functions. These functions have the same semantics as the
  365. raw I/O functions above, except that they are buffered in order to
  366. improve performance. The buffer must be flushed when switching from
  367. reading to writing and vice versa.
  368. *********************************************************************/
  369. static int
  370. buf_flush (unix_stream * s)
  371. {
  372. int writelen;
  373. /* Flushing in read mode means discarding read bytes. */
  374. s->active = 0;
  375. if (s->ndirty == 0)
  376. return 0;
  377. if (s->physical_offset != s->buffer_offset
  378. && lseek (s->fd, s->buffer_offset, SEEK_SET) < 0)
  379. return -1;
  380. writelen = raw_write (s, s->buffer, s->ndirty);
  381. s->physical_offset = s->buffer_offset + writelen;
  382. if (s->physical_offset > s->file_length)
  383. s->file_length = s->physical_offset;
  384. s->ndirty -= writelen;
  385. if (s->ndirty != 0)
  386. return -1;
  387. return 0;
  388. }
  389. static ssize_t
  390. buf_read (unix_stream * s, void * buf, ssize_t nbyte)
  391. {
  392. if (s->active == 0)
  393. s->buffer_offset = s->logical_offset;
  394. /* Is the data we want in the buffer? */
  395. if (s->logical_offset + nbyte <= s->buffer_offset + s->active
  396. && s->buffer_offset <= s->logical_offset)
  397. memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset), nbyte);
  398. else
  399. {
  400. /* First copy the active bytes if applicable, then read the rest
  401. either directly or filling the buffer. */
  402. char *p;
  403. int nread = 0;
  404. ssize_t to_read, did_read;
  405. gfc_offset new_logical;
  406. p = (char *) buf;
  407. if (s->logical_offset >= s->buffer_offset
  408. && s->buffer_offset + s->active >= s->logical_offset)
  409. {
  410. nread = s->active - (s->logical_offset - s->buffer_offset);
  411. memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset),
  412. nread);
  413. p += nread;
  414. }
  415. /* At this point we consider all bytes in the buffer discarded. */
  416. to_read = nbyte - nread;
  417. new_logical = s->logical_offset + nread;
  418. if (s->physical_offset != new_logical
  419. && lseek (s->fd, new_logical, SEEK_SET) < 0)
  420. return -1;
  421. s->buffer_offset = s->physical_offset = new_logical;
  422. if (to_read <= BUFFER_SIZE/2)
  423. {
  424. did_read = raw_read (s, s->buffer, BUFFER_SIZE);
  425. s->physical_offset += did_read;
  426. s->active = did_read;
  427. did_read = (did_read > to_read) ? to_read : did_read;
  428. memcpy (p, s->buffer, did_read);
  429. }
  430. else
  431. {
  432. did_read = raw_read (s, p, to_read);
  433. s->physical_offset += did_read;
  434. s->active = 0;
  435. }
  436. nbyte = did_read + nread;
  437. }
  438. s->logical_offset += nbyte;
  439. return nbyte;
  440. }
  441. static ssize_t
  442. buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
  443. {
  444. if (s->ndirty == 0)
  445. s->buffer_offset = s->logical_offset;
  446. /* Does the data fit into the buffer? As a special case, if the
  447. buffer is empty and the request is bigger than BUFFER_SIZE/2,
  448. write directly. This avoids the case where the buffer would have
  449. to be flushed at every write. */
  450. if (!(s->ndirty == 0 && nbyte > BUFFER_SIZE/2)
  451. && s->logical_offset + nbyte <= s->buffer_offset + BUFFER_SIZE
  452. && s->buffer_offset <= s->logical_offset
  453. && s->buffer_offset + s->ndirty >= s->logical_offset)
  454. {
  455. memcpy (s->buffer + (s->logical_offset - s->buffer_offset), buf, nbyte);
  456. int nd = (s->logical_offset - s->buffer_offset) + nbyte;
  457. if (nd > s->ndirty)
  458. s->ndirty = nd;
  459. }
  460. else
  461. {
  462. /* Flush, and either fill the buffer with the new data, or if
  463. the request is bigger than the buffer size, write directly
  464. bypassing the buffer. */
  465. buf_flush (s);
  466. if (nbyte <= BUFFER_SIZE/2)
  467. {
  468. memcpy (s->buffer, buf, nbyte);
  469. s->buffer_offset = s->logical_offset;
  470. s->ndirty += nbyte;
  471. }
  472. else
  473. {
  474. if (s->physical_offset != s->logical_offset)
  475. {
  476. if (lseek (s->fd, s->logical_offset, SEEK_SET) < 0)
  477. return -1;
  478. s->physical_offset = s->logical_offset;
  479. }
  480. nbyte = raw_write (s, buf, nbyte);
  481. s->physical_offset += nbyte;
  482. }
  483. }
  484. s->logical_offset += nbyte;
  485. if (s->logical_offset > s->file_length)
  486. s->file_length = s->logical_offset;
  487. return nbyte;
  488. }
  489. /* "Unbuffered" really means I/O statement buffering. For formatted
  490. I/O, the fbuf manages this, and then uses raw I/O. For unformatted
  491. I/O, buffered I/O is used, and the buffer is flushed at the end of
  492. each I/O statement, where this function is called. Alternatively,
  493. the buffer is flushed at the end of the record if the buffer is
  494. more than half full; this prevents needless seeking back and forth
  495. when writing sequential unformatted. */
  496. static int
  497. buf_markeor (unix_stream * s)
  498. {
  499. if (s->unbuffered || s->ndirty >= BUFFER_SIZE / 2)
  500. return buf_flush (s);
  501. return 0;
  502. }
  503. static gfc_offset
  504. buf_seek (unix_stream * s, gfc_offset offset, int whence)
  505. {
  506. switch (whence)
  507. {
  508. case SEEK_SET:
  509. break;
  510. case SEEK_CUR:
  511. offset += s->logical_offset;
  512. break;
  513. case SEEK_END:
  514. offset += s->file_length;
  515. break;
  516. default:
  517. return -1;
  518. }
  519. if (offset < 0)
  520. {
  521. errno = EINVAL;
  522. return -1;
  523. }
  524. s->logical_offset = offset;
  525. return offset;
  526. }
  527. static gfc_offset
  528. buf_tell (unix_stream * s)
  529. {
  530. return buf_seek (s, 0, SEEK_CUR);
  531. }
  532. static gfc_offset
  533. buf_size (unix_stream * s)
  534. {
  535. return s->file_length;
  536. }
  537. static int
  538. buf_truncate (unix_stream * s, gfc_offset length)
  539. {
  540. int r;
  541. if (buf_flush (s) != 0)
  542. return -1;
  543. r = raw_truncate (s, length);
  544. if (r == 0)
  545. s->file_length = length;
  546. return r;
  547. }
  548. static int
  549. buf_close (unix_stream * s)
  550. {
  551. if (buf_flush (s) != 0)
  552. return -1;
  553. free (s->buffer);
  554. return raw_close (s);
  555. }
  556. static const struct stream_vtable buf_vtable = {
  557. .read = (void *) buf_read,
  558. .write = (void *) buf_write,
  559. .seek = (void *) buf_seek,
  560. .tell = (void *) buf_tell,
  561. .size = (void *) buf_size,
  562. .trunc = (void *) buf_truncate,
  563. .close = (void *) buf_close,
  564. .flush = (void *) buf_flush,
  565. .markeor = (void *) buf_markeor
  566. };
  567. static int
  568. buf_init (unix_stream * s)
  569. {
  570. s->st.vptr = &buf_vtable;
  571. s->buffer = xmalloc (BUFFER_SIZE);
  572. return 0;
  573. }
  574. /*********************************************************************
  575. memory stream functions - These are used for internal files
  576. The idea here is that a single stream structure is created and all
  577. requests must be satisfied from it. The location and size of the
  578. buffer is the character variable supplied to the READ or WRITE
  579. statement.
  580. *********************************************************************/
  581. char *
  582. mem_alloc_r (stream * strm, int * len)
  583. {
  584. unix_stream * s = (unix_stream *) strm;
  585. gfc_offset n;
  586. gfc_offset where = s->logical_offset;
  587. if (where < s->buffer_offset || where > s->buffer_offset + s->active)
  588. return NULL;
  589. n = s->buffer_offset + s->active - where;
  590. if (*len > n)
  591. *len = n;
  592. s->logical_offset = where + *len;
  593. return s->buffer + (where - s->buffer_offset);
  594. }
  595. char *
  596. mem_alloc_r4 (stream * strm, int * len)
  597. {
  598. unix_stream * s = (unix_stream *) strm;
  599. gfc_offset n;
  600. gfc_offset where = s->logical_offset;
  601. if (where < s->buffer_offset || where > s->buffer_offset + s->active)
  602. return NULL;
  603. n = s->buffer_offset + s->active - where;
  604. if (*len > n)
  605. *len = n;
  606. s->logical_offset = where + *len;
  607. return s->buffer + (where - s->buffer_offset) * 4;
  608. }
  609. char *
  610. mem_alloc_w (stream * strm, int * len)
  611. {
  612. unix_stream * s = (unix_stream *) strm;
  613. gfc_offset m;
  614. gfc_offset where = s->logical_offset;
  615. m = where + *len;
  616. if (where < s->buffer_offset)
  617. return NULL;
  618. if (m > s->file_length)
  619. return NULL;
  620. s->logical_offset = m;
  621. return s->buffer + (where - s->buffer_offset);
  622. }
  623. gfc_char4_t *
  624. mem_alloc_w4 (stream * strm, int * len)
  625. {
  626. unix_stream * s = (unix_stream *) strm;
  627. gfc_offset m;
  628. gfc_offset where = s->logical_offset;
  629. gfc_char4_t *result = (gfc_char4_t *) s->buffer;
  630. m = where + *len;
  631. if (where < s->buffer_offset)
  632. return NULL;
  633. if (m > s->file_length)
  634. return NULL;
  635. s->logical_offset = m;
  636. return &result[where - s->buffer_offset];
  637. }
  638. /* Stream read function for character(kind=1) internal units. */
  639. static ssize_t
  640. mem_read (stream * s, void * buf, ssize_t nbytes)
  641. {
  642. void *p;
  643. int nb = nbytes;
  644. p = mem_alloc_r (s, &nb);
  645. if (p)
  646. {
  647. memcpy (buf, p, nb);
  648. return (ssize_t) nb;
  649. }
  650. else
  651. return 0;
  652. }
  653. /* Stream read function for chracter(kind=4) internal units. */
  654. static ssize_t
  655. mem_read4 (stream * s, void * buf, ssize_t nbytes)
  656. {
  657. void *p;
  658. int nb = nbytes;
  659. p = mem_alloc_r4 (s, &nb);
  660. if (p)
  661. {
  662. memcpy (buf, p, nb * 4);
  663. return (ssize_t) nb;
  664. }
  665. else
  666. return 0;
  667. }
  668. /* Stream write function for character(kind=1) internal units. */
  669. static ssize_t
  670. mem_write (stream * s, const void * buf, ssize_t nbytes)
  671. {
  672. void *p;
  673. int nb = nbytes;
  674. p = mem_alloc_w (s, &nb);
  675. if (p)
  676. {
  677. memcpy (p, buf, nb);
  678. return (ssize_t) nb;
  679. }
  680. else
  681. return 0;
  682. }
  683. /* Stream write function for character(kind=4) internal units. */
  684. static ssize_t
  685. mem_write4 (stream * s, const void * buf, ssize_t nwords)
  686. {
  687. gfc_char4_t *p;
  688. int nw = nwords;
  689. p = mem_alloc_w4 (s, &nw);
  690. if (p)
  691. {
  692. while (nw--)
  693. *p++ = (gfc_char4_t) *((char *) buf);
  694. return nwords;
  695. }
  696. else
  697. return 0;
  698. }
  699. static gfc_offset
  700. mem_seek (stream * strm, gfc_offset offset, int whence)
  701. {
  702. unix_stream * s = (unix_stream *) strm;
  703. switch (whence)
  704. {
  705. case SEEK_SET:
  706. break;
  707. case SEEK_CUR:
  708. offset += s->logical_offset;
  709. break;
  710. case SEEK_END:
  711. offset += s->file_length;
  712. break;
  713. default:
  714. return -1;
  715. }
  716. /* Note that for internal array I/O it's actually possible to have a
  717. negative offset, so don't check for that. */
  718. if (offset > s->file_length)
  719. {
  720. errno = EINVAL;
  721. return -1;
  722. }
  723. s->logical_offset = offset;
  724. /* Returning < 0 is the error indicator for sseek(), so return 0 if
  725. offset is negative. Thus if the return value is 0, the caller
  726. has to use stell() to get the real value of logical_offset. */
  727. if (offset >= 0)
  728. return offset;
  729. return 0;
  730. }
  731. static gfc_offset
  732. mem_tell (stream * s)
  733. {
  734. return ((unix_stream *)s)->logical_offset;
  735. }
  736. static int
  737. mem_truncate (unix_stream * s __attribute__ ((unused)),
  738. gfc_offset length __attribute__ ((unused)))
  739. {
  740. return 0;
  741. }
  742. static int
  743. mem_flush (unix_stream * s __attribute__ ((unused)))
  744. {
  745. return 0;
  746. }
  747. static int
  748. mem_close (unix_stream * s)
  749. {
  750. free (s);
  751. return 0;
  752. }
  753. static const struct stream_vtable mem_vtable = {
  754. .read = (void *) mem_read,
  755. .write = (void *) mem_write,
  756. .seek = (void *) mem_seek,
  757. .tell = (void *) mem_tell,
  758. /* buf_size is not a typo, we just reuse an identical
  759. implementation. */
  760. .size = (void *) buf_size,
  761. .trunc = (void *) mem_truncate,
  762. .close = (void *) mem_close,
  763. .flush = (void *) mem_flush,
  764. .markeor = (void *) raw_markeor
  765. };
  766. static const struct stream_vtable mem4_vtable = {
  767. .read = (void *) mem_read4,
  768. .write = (void *) mem_write4,
  769. .seek = (void *) mem_seek,
  770. .tell = (void *) mem_tell,
  771. /* buf_size is not a typo, we just reuse an identical
  772. implementation. */
  773. .size = (void *) buf_size,
  774. .trunc = (void *) mem_truncate,
  775. .close = (void *) mem_close,
  776. .flush = (void *) mem_flush,
  777. .markeor = (void *) raw_markeor
  778. };
  779. /*********************************************************************
  780. Public functions -- A reimplementation of this module needs to
  781. define functional equivalents of the following.
  782. *********************************************************************/
  783. /* open_internal()-- Returns a stream structure from a character(kind=1)
  784. internal file */
  785. stream *
  786. open_internal (char *base, int length, gfc_offset offset)
  787. {
  788. unix_stream *s;
  789. s = xcalloc (1, sizeof (unix_stream));
  790. s->buffer = base;
  791. s->buffer_offset = offset;
  792. s->active = s->file_length = length;
  793. s->st.vptr = &mem_vtable;
  794. return (stream *) s;
  795. }
  796. /* open_internal4()-- Returns a stream structure from a character(kind=4)
  797. internal file */
  798. stream *
  799. open_internal4 (char *base, int length, gfc_offset offset)
  800. {
  801. unix_stream *s;
  802. s = xcalloc (1, sizeof (unix_stream));
  803. s->buffer = base;
  804. s->buffer_offset = offset;
  805. s->active = s->file_length = length * sizeof (gfc_char4_t);
  806. s->st.vptr = &mem4_vtable;
  807. return (stream *) s;
  808. }
  809. /* fd_to_stream()-- Given an open file descriptor, build a stream
  810. * around it. */
  811. static stream *
  812. fd_to_stream (int fd, bool unformatted)
  813. {
  814. struct stat statbuf;
  815. unix_stream *s;
  816. s = xcalloc (1, sizeof (unix_stream));
  817. s->fd = fd;
  818. /* Get the current length of the file. */
  819. if (fstat (fd, &statbuf) == -1)
  820. {
  821. s->st_dev = s->st_ino = -1;
  822. s->file_length = 0;
  823. if (errno == EBADF)
  824. s->fd = -1;
  825. raw_init (s);
  826. return (stream *) s;
  827. }
  828. s->st_dev = statbuf.st_dev;
  829. s->st_ino = statbuf.st_ino;
  830. s->file_length = statbuf.st_size;
  831. /* Only use buffered IO for regular files. */
  832. if (S_ISREG (statbuf.st_mode)
  833. && !options.all_unbuffered
  834. && !(options.unbuffered_preconnected &&
  835. (s->fd == STDIN_FILENO
  836. || s->fd == STDOUT_FILENO
  837. || s->fd == STDERR_FILENO)))
  838. buf_init (s);
  839. else
  840. {
  841. if (unformatted)
  842. {
  843. s->unbuffered = true;
  844. buf_init (s);
  845. }
  846. else
  847. raw_init (s);
  848. }
  849. return (stream *) s;
  850. }
  851. /* Given the Fortran unit number, convert it to a C file descriptor. */
  852. int
  853. unit_to_fd (int unit)
  854. {
  855. gfc_unit *us;
  856. int fd;
  857. us = find_unit (unit);
  858. if (us == NULL)
  859. return -1;
  860. fd = ((unix_stream *) us->s)->fd;
  861. unlock_unit (us);
  862. return fd;
  863. }
  864. /* Set the close-on-exec flag for an existing fd, if the system
  865. supports such. */
  866. static void __attribute__ ((unused))
  867. set_close_on_exec (int fd __attribute__ ((unused)))
  868. {
  869. /* Mingw does not define F_SETFD. */
  870. #if defined(HAVE_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
  871. if (fd >= 0)
  872. fcntl(fd, F_SETFD, FD_CLOEXEC);
  873. #endif
  874. }
  875. /* Helper function for tempfile(). Tries to open a temporary file in
  876. the directory specified by tempdir. If successful, the file name is
  877. stored in fname and the descriptor returned. Returns -1 on
  878. failure. */
  879. static int
  880. tempfile_open (const char *tempdir, char **fname)
  881. {
  882. int fd;
  883. const char *slash = "/";
  884. #if defined(HAVE_UMASK) && defined(HAVE_MKSTEMP)
  885. mode_t mode_mask;
  886. #endif
  887. if (!tempdir)
  888. return -1;
  889. /* Check for the special case that tempdir ends with a slash or
  890. backslash. */
  891. size_t tempdirlen = strlen (tempdir);
  892. if (*tempdir == 0 || tempdir[tempdirlen - 1] == '/'
  893. #ifdef __MINGW32__
  894. || tempdir[tempdirlen - 1] == '\\'
  895. #endif
  896. )
  897. slash = "";
  898. // Take care that the template is longer in the mktemp() branch.
  899. char * template = xmalloc (tempdirlen + 23);
  900. #ifdef HAVE_MKSTEMP
  901. snprintf (template, tempdirlen + 23, "%s%sgfortrantmpXXXXXX",
  902. tempdir, slash);
  903. #ifdef HAVE_UMASK
  904. /* Temporarily set the umask such that the file has 0600 permissions. */
  905. mode_mask = umask (S_IXUSR | S_IRWXG | S_IRWXO);
  906. #endif
  907. #if defined(HAVE_MKOSTEMP) && defined(O_CLOEXEC)
  908. fd = mkostemp (template, O_CLOEXEC);
  909. #else
  910. fd = mkstemp (template);
  911. set_close_on_exec (fd);
  912. #endif
  913. #ifdef HAVE_UMASK
  914. (void) umask (mode_mask);
  915. #endif
  916. #else /* HAVE_MKSTEMP */
  917. fd = -1;
  918. int count = 0;
  919. size_t slashlen = strlen (slash);
  920. int flags = O_RDWR | O_CREAT | O_EXCL;
  921. #if defined(HAVE_CRLF) && defined(O_BINARY)
  922. flags |= O_BINARY;
  923. #endif
  924. #ifdef O_CLOEXEC
  925. flags |= O_CLOEXEC;
  926. #endif
  927. do
  928. {
  929. snprintf (template, tempdirlen + 23, "%s%sgfortrantmpaaaXXXXXX",
  930. tempdir, slash);
  931. if (count > 0)
  932. {
  933. int c = count;
  934. template[tempdirlen + slashlen + 13] = 'a' + (c% 26);
  935. c /= 26;
  936. template[tempdirlen + slashlen + 12] = 'a' + (c % 26);
  937. c /= 26;
  938. template[tempdirlen + slashlen + 11] = 'a' + (c % 26);
  939. if (c >= 26)
  940. break;
  941. }
  942. if (!mktemp (template))
  943. {
  944. errno = EEXIST;
  945. count++;
  946. continue;
  947. }
  948. fd = open (template, flags, S_IRUSR | S_IWUSR);
  949. }
  950. while (fd == -1 && errno == EEXIST);
  951. #ifndef O_CLOEXEC
  952. set_close_on_exec (fd);
  953. #endif
  954. #endif /* HAVE_MKSTEMP */
  955. *fname = template;
  956. return fd;
  957. }
  958. /* tempfile()-- Generate a temporary filename for a scratch file and
  959. * open it. mkstemp() opens the file for reading and writing, but the
  960. * library mode prevents anything that is not allowed. The descriptor
  961. * is returned, which is -1 on error. The template is pointed to by
  962. * opp->file, which is copied into the unit structure
  963. * and freed later. */
  964. static int
  965. tempfile (st_parameter_open *opp)
  966. {
  967. const char *tempdir;
  968. char *fname;
  969. int fd = -1;
  970. tempdir = secure_getenv ("TMPDIR");
  971. fd = tempfile_open (tempdir, &fname);
  972. #ifdef __MINGW32__
  973. if (fd == -1)
  974. {
  975. char buffer[MAX_PATH + 1];
  976. DWORD ret;
  977. ret = GetTempPath (MAX_PATH, buffer);
  978. /* If we are not able to get a temp-directory, we use
  979. current directory. */
  980. if (ret > MAX_PATH || !ret)
  981. buffer[0] = 0;
  982. else
  983. buffer[ret] = 0;
  984. tempdir = strdup (buffer);
  985. fd = tempfile_open (tempdir, &fname);
  986. }
  987. #elif defined(__CYGWIN__)
  988. if (fd == -1)
  989. {
  990. tempdir = secure_getenv ("TMP");
  991. fd = tempfile_open (tempdir, &fname);
  992. }
  993. if (fd == -1)
  994. {
  995. tempdir = secure_getenv ("TEMP");
  996. fd = tempfile_open (tempdir, &fname);
  997. }
  998. #endif
  999. if (fd == -1)
  1000. fd = tempfile_open (P_tmpdir, &fname);
  1001. opp->file = fname;
  1002. opp->file_len = strlen (fname); /* Don't include trailing nul */
  1003. return fd;
  1004. }
  1005. /* regular_file2()-- Open a regular file.
  1006. * Change flags->action if it is ACTION_UNSPECIFIED on entry,
  1007. * unless an error occurs.
  1008. * Returns the descriptor, which is less than zero on error. */
  1009. static int
  1010. regular_file2 (const char *path, st_parameter_open *opp, unit_flags *flags)
  1011. {
  1012. int mode;
  1013. int rwflag;
  1014. int crflag, crflag2;
  1015. int fd;
  1016. #ifdef __CYGWIN__
  1017. if (opp->file_len == 7)
  1018. {
  1019. if (strncmp (path, "CONOUT$", 7) == 0
  1020. || strncmp (path, "CONERR$", 7) == 0)
  1021. {
  1022. fd = open ("/dev/conout", O_WRONLY);
  1023. flags->action = ACTION_WRITE;
  1024. return fd;
  1025. }
  1026. }
  1027. if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
  1028. {
  1029. fd = open ("/dev/conin", O_RDONLY);
  1030. flags->action = ACTION_READ;
  1031. return fd;
  1032. }
  1033. #endif
  1034. #ifdef __MINGW32__
  1035. if (opp->file_len == 7)
  1036. {
  1037. if (strncmp (path, "CONOUT$", 7) == 0
  1038. || strncmp (path, "CONERR$", 7) == 0)
  1039. {
  1040. fd = open ("CONOUT$", O_WRONLY);
  1041. flags->action = ACTION_WRITE;
  1042. return fd;
  1043. }
  1044. }
  1045. if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
  1046. {
  1047. fd = open ("CONIN$", O_RDONLY);
  1048. flags->action = ACTION_READ;
  1049. return fd;
  1050. }
  1051. #endif
  1052. switch (flags->action)
  1053. {
  1054. case ACTION_READ:
  1055. rwflag = O_RDONLY;
  1056. break;
  1057. case ACTION_WRITE:
  1058. rwflag = O_WRONLY;
  1059. break;
  1060. case ACTION_READWRITE:
  1061. case ACTION_UNSPECIFIED:
  1062. rwflag = O_RDWR;
  1063. break;
  1064. default:
  1065. internal_error (&opp->common, "regular_file(): Bad action");
  1066. }
  1067. switch (flags->status)
  1068. {
  1069. case STATUS_NEW:
  1070. crflag = O_CREAT | O_EXCL;
  1071. break;
  1072. case STATUS_OLD: /* open will fail if the file does not exist*/
  1073. crflag = 0;
  1074. break;
  1075. case STATUS_UNKNOWN:
  1076. if (rwflag == O_RDONLY)
  1077. crflag = 0;
  1078. else
  1079. crflag = O_CREAT;
  1080. break;
  1081. case STATUS_REPLACE:
  1082. crflag = O_CREAT | O_TRUNC;
  1083. break;
  1084. default:
  1085. /* Note: STATUS_SCRATCH is handled by tempfile () and should
  1086. never be seen here. */
  1087. internal_error (&opp->common, "regular_file(): Bad status");
  1088. }
  1089. /* rwflag |= O_LARGEFILE; */
  1090. #if defined(HAVE_CRLF) && defined(O_BINARY)
  1091. crflag |= O_BINARY;
  1092. #endif
  1093. #ifdef O_CLOEXEC
  1094. crflag |= O_CLOEXEC;
  1095. #endif
  1096. mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
  1097. fd = open (path, rwflag | crflag, mode);
  1098. if (flags->action != ACTION_UNSPECIFIED)
  1099. return fd;
  1100. if (fd >= 0)
  1101. {
  1102. flags->action = ACTION_READWRITE;
  1103. return fd;
  1104. }
  1105. if (errno != EACCES && errno != EPERM && errno != EROFS)
  1106. return fd;
  1107. /* retry for read-only access */
  1108. rwflag = O_RDONLY;
  1109. if (flags->status == STATUS_UNKNOWN)
  1110. crflag2 = crflag & ~(O_CREAT);
  1111. else
  1112. crflag2 = crflag;
  1113. fd = open (path, rwflag | crflag2, mode);
  1114. if (fd >=0)
  1115. {
  1116. flags->action = ACTION_READ;
  1117. return fd; /* success */
  1118. }
  1119. if (errno != EACCES && errno != EPERM && errno != ENOENT)
  1120. return fd; /* failure */
  1121. /* retry for write-only access */
  1122. rwflag = O_WRONLY;
  1123. fd = open (path, rwflag | crflag, mode);
  1124. if (fd >=0)
  1125. {
  1126. flags->action = ACTION_WRITE;
  1127. return fd; /* success */
  1128. }
  1129. return fd; /* failure */
  1130. }
  1131. /* Wrapper around regular_file2, to make sure we free the path after
  1132. we're done. */
  1133. static int
  1134. regular_file (st_parameter_open *opp, unit_flags *flags)
  1135. {
  1136. char *path = fc_strdup (opp->file, opp->file_len);
  1137. int fd = regular_file2 (path, opp, flags);
  1138. free (path);
  1139. return fd;
  1140. }
  1141. /* open_external()-- Open an external file, unix specific version.
  1142. * Change flags->action if it is ACTION_UNSPECIFIED on entry.
  1143. * Returns NULL on operating system error. */
  1144. stream *
  1145. open_external (st_parameter_open *opp, unit_flags *flags)
  1146. {
  1147. int fd;
  1148. if (flags->status == STATUS_SCRATCH)
  1149. {
  1150. fd = tempfile (opp);
  1151. if (flags->action == ACTION_UNSPECIFIED)
  1152. flags->action = ACTION_READWRITE;
  1153. #if HAVE_UNLINK_OPEN_FILE
  1154. /* We can unlink scratch files now and it will go away when closed. */
  1155. if (fd >= 0)
  1156. unlink (opp->file);
  1157. #endif
  1158. }
  1159. else
  1160. {
  1161. /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
  1162. * if it succeeds */
  1163. fd = regular_file (opp, flags);
  1164. #ifndef O_CLOEXEC
  1165. set_close_on_exec (fd);
  1166. #endif
  1167. }
  1168. if (fd < 0)
  1169. return NULL;
  1170. fd = fix_fd (fd);
  1171. return fd_to_stream (fd, flags->form == FORM_UNFORMATTED);
  1172. }
  1173. /* input_stream()-- Return a stream pointer to the default input stream.
  1174. * Called on initialization. */
  1175. stream *
  1176. input_stream (void)
  1177. {
  1178. return fd_to_stream (STDIN_FILENO, false);
  1179. }
  1180. /* output_stream()-- Return a stream pointer to the default output stream.
  1181. * Called on initialization. */
  1182. stream *
  1183. output_stream (void)
  1184. {
  1185. stream * s;
  1186. #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
  1187. setmode (STDOUT_FILENO, O_BINARY);
  1188. #endif
  1189. s = fd_to_stream (STDOUT_FILENO, false);
  1190. return s;
  1191. }
  1192. /* error_stream()-- Return a stream pointer to the default error stream.
  1193. * Called on initialization. */
  1194. stream *
  1195. error_stream (void)
  1196. {
  1197. stream * s;
  1198. #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
  1199. setmode (STDERR_FILENO, O_BINARY);
  1200. #endif
  1201. s = fd_to_stream (STDERR_FILENO, false);
  1202. return s;
  1203. }
  1204. /* compare_file_filename()-- Given an open stream and a fortran string
  1205. * that is a filename, figure out if the file is the same as the
  1206. * filename. */
  1207. int
  1208. compare_file_filename (gfc_unit *u, const char *name, int len)
  1209. {
  1210. struct stat st;
  1211. int ret;
  1212. #ifdef HAVE_WORKING_STAT
  1213. unix_stream *s;
  1214. #else
  1215. # ifdef __MINGW32__
  1216. uint64_t id1, id2;
  1217. # endif
  1218. #endif
  1219. char *path = fc_strdup (name, len);
  1220. /* If the filename doesn't exist, then there is no match with the
  1221. * existing file. */
  1222. if (stat (path, &st) < 0)
  1223. {
  1224. ret = 0;
  1225. goto done;
  1226. }
  1227. #ifdef HAVE_WORKING_STAT
  1228. s = (unix_stream *) (u->s);
  1229. ret = (st.st_dev == s->st_dev) && (st.st_ino == s->st_ino);
  1230. goto done;
  1231. #else
  1232. # ifdef __MINGW32__
  1233. /* We try to match files by a unique ID. On some filesystems (network
  1234. fs and FAT), we can't generate this unique ID, and will simply compare
  1235. filenames. */
  1236. id1 = id_from_path (path);
  1237. id2 = id_from_fd (((unix_stream *) (u->s))->fd);
  1238. if (id1 || id2)
  1239. {
  1240. ret = (id1 == id2);
  1241. goto done;
  1242. }
  1243. # endif
  1244. if (u->filename)
  1245. ret = (strcmp(path, u->filename) == 0);
  1246. else
  1247. ret = 0;
  1248. #endif
  1249. done:
  1250. free (path);
  1251. return ret;
  1252. }
  1253. #ifdef HAVE_WORKING_STAT
  1254. # define FIND_FILE0_DECL struct stat *st
  1255. # define FIND_FILE0_ARGS st
  1256. #else
  1257. # define FIND_FILE0_DECL uint64_t id, const char *path
  1258. # define FIND_FILE0_ARGS id, path
  1259. #endif
  1260. /* find_file0()-- Recursive work function for find_file() */
  1261. static gfc_unit *
  1262. find_file0 (gfc_unit *u, FIND_FILE0_DECL)
  1263. {
  1264. gfc_unit *v;
  1265. #if defined(__MINGW32__) && !HAVE_WORKING_STAT
  1266. uint64_t id1;
  1267. #endif
  1268. if (u == NULL)
  1269. return NULL;
  1270. #ifdef HAVE_WORKING_STAT
  1271. if (u->s != NULL)
  1272. {
  1273. unix_stream *s = (unix_stream *) (u->s);
  1274. if (st[0].st_dev == s->st_dev && st[0].st_ino == s->st_ino)
  1275. return u;
  1276. }
  1277. #else
  1278. # ifdef __MINGW32__
  1279. if (u->s && ((id1 = id_from_fd (((unix_stream *) u->s)->fd)) || id1))
  1280. {
  1281. if (id == id1)
  1282. return u;
  1283. }
  1284. else
  1285. # endif
  1286. if (u->filename && strcmp (u->filename, path) == 0)
  1287. return u;
  1288. #endif
  1289. v = find_file0 (u->left, FIND_FILE0_ARGS);
  1290. if (v != NULL)
  1291. return v;
  1292. v = find_file0 (u->right, FIND_FILE0_ARGS);
  1293. if (v != NULL)
  1294. return v;
  1295. return NULL;
  1296. }
  1297. /* find_file()-- Take the current filename and see if there is a unit
  1298. * that has the file already open. Returns a pointer to the unit if so. */
  1299. gfc_unit *
  1300. find_file (const char *file, gfc_charlen_type file_len)
  1301. {
  1302. struct stat st[1];
  1303. gfc_unit *u;
  1304. #if defined(__MINGW32__) && !HAVE_WORKING_STAT
  1305. uint64_t id = 0ULL;
  1306. #endif
  1307. char *path = fc_strdup (file, file_len);
  1308. if (stat (path, &st[0]) < 0)
  1309. {
  1310. u = NULL;
  1311. goto done;
  1312. }
  1313. #if defined(__MINGW32__) && !HAVE_WORKING_STAT
  1314. id = id_from_path (path);
  1315. #endif
  1316. __gthread_mutex_lock (&unit_lock);
  1317. retry:
  1318. u = find_file0 (unit_root, FIND_FILE0_ARGS);
  1319. if (u != NULL)
  1320. {
  1321. /* Fast path. */
  1322. if (! __gthread_mutex_trylock (&u->lock))
  1323. {
  1324. /* assert (u->closed == 0); */
  1325. __gthread_mutex_unlock (&unit_lock);
  1326. goto done;
  1327. }
  1328. inc_waiting_locked (u);
  1329. }
  1330. __gthread_mutex_unlock (&unit_lock);
  1331. if (u != NULL)
  1332. {
  1333. __gthread_mutex_lock (&u->lock);
  1334. if (u->closed)
  1335. {
  1336. __gthread_mutex_lock (&unit_lock);
  1337. __gthread_mutex_unlock (&u->lock);
  1338. if (predec_waiting_locked (u) == 0)
  1339. free (u);
  1340. goto retry;
  1341. }
  1342. dec_waiting_unlocked (u);
  1343. }
  1344. done:
  1345. free (path);
  1346. return u;
  1347. }
  1348. static gfc_unit *
  1349. flush_all_units_1 (gfc_unit *u, int min_unit)
  1350. {
  1351. while (u != NULL)
  1352. {
  1353. if (u->unit_number > min_unit)
  1354. {
  1355. gfc_unit *r = flush_all_units_1 (u->left, min_unit);
  1356. if (r != NULL)
  1357. return r;
  1358. }
  1359. if (u->unit_number >= min_unit)
  1360. {
  1361. if (__gthread_mutex_trylock (&u->lock))
  1362. return u;
  1363. if (u->s)
  1364. sflush (u->s);
  1365. __gthread_mutex_unlock (&u->lock);
  1366. }
  1367. u = u->right;
  1368. }
  1369. return NULL;
  1370. }
  1371. void
  1372. flush_all_units (void)
  1373. {
  1374. gfc_unit *u;
  1375. int min_unit = 0;
  1376. __gthread_mutex_lock (&unit_lock);
  1377. do
  1378. {
  1379. u = flush_all_units_1 (unit_root, min_unit);
  1380. if (u != NULL)
  1381. inc_waiting_locked (u);
  1382. __gthread_mutex_unlock (&unit_lock);
  1383. if (u == NULL)
  1384. return;
  1385. __gthread_mutex_lock (&u->lock);
  1386. min_unit = u->unit_number + 1;
  1387. if (u->closed == 0)
  1388. {
  1389. sflush (u->s);
  1390. __gthread_mutex_lock (&unit_lock);
  1391. __gthread_mutex_unlock (&u->lock);
  1392. (void) predec_waiting_locked (u);
  1393. }
  1394. else
  1395. {
  1396. __gthread_mutex_lock (&unit_lock);
  1397. __gthread_mutex_unlock (&u->lock);
  1398. if (predec_waiting_locked (u) == 0)
  1399. free (u);
  1400. }
  1401. }
  1402. while (1);
  1403. }
  1404. /* delete_file()-- Given a unit structure, delete the file associated
  1405. * with the unit. Returns nonzero if something went wrong. */
  1406. int
  1407. delete_file (gfc_unit * u)
  1408. {
  1409. return unlink (u->filename);
  1410. }
  1411. /* file_exists()-- Returns nonzero if the current filename exists on
  1412. * the system */
  1413. int
  1414. file_exists (const char *file, gfc_charlen_type file_len)
  1415. {
  1416. char *path = fc_strdup (file, file_len);
  1417. int res = !(access (path, F_OK));
  1418. free (path);
  1419. return res;
  1420. }
  1421. /* file_size()-- Returns the size of the file. */
  1422. GFC_IO_INT
  1423. file_size (const char *file, gfc_charlen_type file_len)
  1424. {
  1425. char *path = fc_strdup (file, file_len);
  1426. struct stat statbuf;
  1427. int err = stat (path, &statbuf);
  1428. free (path);
  1429. if (err == -1)
  1430. return -1;
  1431. return (GFC_IO_INT) statbuf.st_size;
  1432. }
  1433. static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
  1434. /* inquire_sequential()-- Given a fortran string, determine if the
  1435. * file is suitable for sequential access. Returns a C-style
  1436. * string. */
  1437. const char *
  1438. inquire_sequential (const char *string, int len)
  1439. {
  1440. struct stat statbuf;
  1441. if (string == NULL)
  1442. return unknown;
  1443. char *path = fc_strdup (string, len);
  1444. int err = stat (path, &statbuf);
  1445. free (path);
  1446. if (err == -1)
  1447. return unknown;
  1448. if (S_ISREG (statbuf.st_mode) ||
  1449. S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
  1450. return unknown;
  1451. if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
  1452. return no;
  1453. return unknown;
  1454. }
  1455. /* inquire_direct()-- Given a fortran string, determine if the file is
  1456. * suitable for direct access. Returns a C-style string. */
  1457. const char *
  1458. inquire_direct (const char *string, int len)
  1459. {
  1460. struct stat statbuf;
  1461. if (string == NULL)
  1462. return unknown;
  1463. char *path = fc_strdup (string, len);
  1464. int err = stat (path, &statbuf);
  1465. free (path);
  1466. if (err == -1)
  1467. return unknown;
  1468. if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
  1469. return unknown;
  1470. if (S_ISDIR (statbuf.st_mode) ||
  1471. S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
  1472. return no;
  1473. return unknown;
  1474. }
  1475. /* inquire_formatted()-- Given a fortran string, determine if the file
  1476. * is suitable for formatted form. Returns a C-style string. */
  1477. const char *
  1478. inquire_formatted (const char *string, int len)
  1479. {
  1480. struct stat statbuf;
  1481. if (string == NULL)
  1482. return unknown;
  1483. char *path = fc_strdup (string, len);
  1484. int err = stat (path, &statbuf);
  1485. free (path);
  1486. if (err == -1)
  1487. return unknown;
  1488. if (S_ISREG (statbuf.st_mode) ||
  1489. S_ISBLK (statbuf.st_mode) ||
  1490. S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
  1491. return unknown;
  1492. if (S_ISDIR (statbuf.st_mode))
  1493. return no;
  1494. return unknown;
  1495. }
  1496. /* inquire_unformatted()-- Given a fortran string, determine if the file
  1497. * is suitable for unformatted form. Returns a C-style string. */
  1498. const char *
  1499. inquire_unformatted (const char *string, int len)
  1500. {
  1501. return inquire_formatted (string, len);
  1502. }
  1503. /* inquire_access()-- Given a fortran string, determine if the file is
  1504. * suitable for access. */
  1505. static const char *
  1506. inquire_access (const char *string, int len, int mode)
  1507. {
  1508. if (string == NULL)
  1509. return no;
  1510. char *path = fc_strdup (string, len);
  1511. int res = access (path, mode);
  1512. free (path);
  1513. if (res == -1)
  1514. return no;
  1515. return yes;
  1516. }
  1517. /* inquire_read()-- Given a fortran string, determine if the file is
  1518. * suitable for READ access. */
  1519. const char *
  1520. inquire_read (const char *string, int len)
  1521. {
  1522. return inquire_access (string, len, R_OK);
  1523. }
  1524. /* inquire_write()-- Given a fortran string, determine if the file is
  1525. * suitable for READ access. */
  1526. const char *
  1527. inquire_write (const char *string, int len)
  1528. {
  1529. return inquire_access (string, len, W_OK);
  1530. }
  1531. /* inquire_readwrite()-- Given a fortran string, determine if the file is
  1532. * suitable for read and write access. */
  1533. const char *
  1534. inquire_readwrite (const char *string, int len)
  1535. {
  1536. return inquire_access (string, len, R_OK | W_OK);
  1537. }
  1538. int
  1539. stream_isatty (stream *s)
  1540. {
  1541. return isatty (((unix_stream *) s)->fd);
  1542. }
  1543. int
  1544. stream_ttyname (stream *s __attribute__ ((unused)),
  1545. char * buf __attribute__ ((unused)),
  1546. size_t buflen __attribute__ ((unused)))
  1547. {
  1548. #ifdef HAVE_TTYNAME_R
  1549. return ttyname_r (((unix_stream *) s)->fd, buf, buflen);
  1550. #elif defined HAVE_TTYNAME
  1551. char *p;
  1552. size_t plen;
  1553. p = ttyname (((unix_stream *) s)->fd);
  1554. if (!p)
  1555. return errno;
  1556. plen = strlen (p);
  1557. if (buflen < plen)
  1558. plen = buflen;
  1559. memcpy (buf, p, plen);
  1560. return 0;
  1561. #else
  1562. return ENOSYS;
  1563. #endif
  1564. }
  1565. /* How files are stored: This is an operating-system specific issue,
  1566. and therefore belongs here. There are three cases to consider.
  1567. Direct Access:
  1568. Records are written as block of bytes corresponding to the record
  1569. length of the file. This goes for both formatted and unformatted
  1570. records. Positioning is done explicitly for each data transfer,
  1571. so positioning is not much of an issue.
  1572. Sequential Formatted:
  1573. Records are separated by newline characters. The newline character
  1574. is prohibited from appearing in a string. If it does, this will be
  1575. messed up on the next read. End of file is also the end of a record.
  1576. Sequential Unformatted:
  1577. In this case, we are merely copying bytes to and from main storage,
  1578. yet we need to keep track of varying record lengths. We adopt
  1579. the solution used by f2c. Each record contains a pair of length
  1580. markers:
  1581. Length of record n in bytes
  1582. Data of record n
  1583. Length of record n in bytes
  1584. Length of record n+1 in bytes
  1585. Data of record n+1
  1586. Length of record n+1 in bytes
  1587. The length is stored at the end of a record to allow backspacing to the
  1588. previous record. Between data transfer statements, the file pointer
  1589. is left pointing to the first length of the current record.
  1590. ENDFILE records are never explicitly stored.
  1591. */