open.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. #include "f2c.h"
  2. #include "fio.h"
  3. #include "string.h"
  4. #ifndef NON_POSIX_STDIO
  5. #ifdef MSDOS
  6. #include "io.h"
  7. #else
  8. #include "unistd.h" /* for access */
  9. #endif
  10. #endif
  11. #ifdef KR_headers
  12. extern char *malloc();
  13. #ifdef NON_ANSI_STDIO
  14. extern char *mktemp();
  15. #endif
  16. extern integer f_clos();
  17. #define Const /*nothing*/
  18. #else
  19. #define Const const
  20. #undef abs
  21. #undef min
  22. #undef max
  23. #include "stdlib.h"
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif
  27. extern int f__canseek(FILE*);
  28. extern integer f_clos(cllist*);
  29. #endif
  30. #ifdef NON_ANSI_RW_MODES
  31. Const char *f__r_mode[2] = {"r", "r"};
  32. Const char *f__w_mode[4] = {"w", "w", "r+w", "r+w"};
  33. #else
  34. Const char *f__r_mode[2] = {"rb", "r"};
  35. Const char *f__w_mode[4] = {"wb", "w", "r+b", "r+"};
  36. #endif
  37. static char f__buf0[400], *f__buf = f__buf0;
  38. int f__buflen = (int)sizeof(f__buf0);
  39. static void
  40. #ifdef KR_headers
  41. f__bufadj(n, c) int n, c;
  42. #else
  43. f__bufadj(int n, int c)
  44. #endif
  45. {
  46. unsigned int len;
  47. char *nbuf, *s, *t, *te;
  48. if (f__buf == f__buf0)
  49. f__buflen = 1024;
  50. while(f__buflen <= n)
  51. f__buflen <<= 1;
  52. len = (unsigned int)f__buflen;
  53. if (len != f__buflen || !(nbuf = (char*)malloc(len)))
  54. f__fatal(113, "malloc failure");
  55. s = nbuf;
  56. t = f__buf;
  57. te = t + c;
  58. while(t < te)
  59. *s++ = *t++;
  60. if (f__buf != f__buf0)
  61. free(f__buf);
  62. f__buf = nbuf;
  63. }
  64. int
  65. #ifdef KR_headers
  66. f__putbuf(c) int c;
  67. #else
  68. f__putbuf(int c)
  69. #endif
  70. {
  71. char *s, *se;
  72. int n;
  73. if (f__hiwater > f__recpos)
  74. f__recpos = f__hiwater;
  75. n = f__recpos + 1;
  76. if (n >= f__buflen)
  77. f__bufadj(n, f__recpos);
  78. s = f__buf;
  79. se = s + f__recpos;
  80. if (c)
  81. *se++ = c;
  82. *se = 0;
  83. for(;;) {
  84. fputs(s, f__cf);
  85. s += strlen(s);
  86. if (s >= se)
  87. break; /* normally happens the first time */
  88. putc(*s++, f__cf);
  89. }
  90. return 0;
  91. }
  92. void
  93. #ifdef KR_headers
  94. x_putc(c)
  95. #else
  96. x_putc(int c)
  97. #endif
  98. {
  99. if (f__recpos >= f__buflen)
  100. f__bufadj(f__recpos, f__buflen);
  101. f__buf[f__recpos++] = c;
  102. }
  103. #define opnerr(f,m,s) {if(f) errno= m; else opn_err(m,s,a); return(m);}
  104. static void
  105. #ifdef KR_headers
  106. opn_err(m, s, a) int m; char *s; olist *a;
  107. #else
  108. opn_err(int m, const char *s, olist *a)
  109. #endif
  110. {
  111. if (a->ofnm) {
  112. /* supply file name to error message */
  113. if (a->ofnmlen >= f__buflen)
  114. f__bufadj((int)a->ofnmlen, 0);
  115. g_char(a->ofnm, a->ofnmlen, f__curunit->ufnm = f__buf);
  116. }
  117. f__fatal(m, s);
  118. }
  119. #ifdef KR_headers
  120. integer f_open(a) olist *a;
  121. #else
  122. integer f_open(olist *a)
  123. #endif
  124. { unit *b;
  125. integer rv;
  126. char buf[256], *s;
  127. cllist x;
  128. int ufmt;
  129. FILE *tf;
  130. #ifndef NON_UNIX_STDIO
  131. int n;
  132. #endif
  133. f__external = 1;
  134. if(a->ounit>=MXUNIT || a->ounit<0)
  135. err(a->oerr,101,"open")
  136. if (!f__init)
  137. f_init();
  138. f__curunit = b = &f__units[a->ounit];
  139. if(b->ufd) {
  140. if(a->ofnm==0)
  141. {
  142. same: if (a->oblnk)
  143. b->ublnk = *a->oblnk == 'z' || *a->oblnk == 'Z';
  144. return(0);
  145. }
  146. #ifdef NON_UNIX_STDIO
  147. if (b->ufnm
  148. && strlen(b->ufnm) == a->ofnmlen
  149. && !strncmp(b->ufnm, a->ofnm, (unsigned)a->ofnmlen))
  150. goto same;
  151. #else
  152. g_char(a->ofnm,a->ofnmlen,buf);
  153. if (f__inode(buf,&n) == b->uinode && n == b->udev)
  154. goto same;
  155. #endif
  156. x.cunit=a->ounit;
  157. x.csta=0;
  158. x.cerr=a->oerr;
  159. if ((rv = f_clos(&x)) != 0)
  160. return rv;
  161. }
  162. b->url = (int)a->orl;
  163. b->ublnk = a->oblnk && (*a->oblnk == 'z' || *a->oblnk == 'Z');
  164. if(a->ofm==0)
  165. { if(b->url>0) b->ufmt=0;
  166. else b->ufmt=1;
  167. }
  168. else if(*a->ofm=='f' || *a->ofm == 'F') b->ufmt=1;
  169. else b->ufmt=0;
  170. ufmt = b->ufmt;
  171. #ifdef url_Adjust
  172. if (b->url && !ufmt)
  173. url_Adjust(b->url);
  174. #endif
  175. if (a->ofnm) {
  176. g_char(a->ofnm,a->ofnmlen,buf);
  177. if (!buf[0])
  178. opnerr(a->oerr,107,"open")
  179. }
  180. else
  181. sprintf(buf, "fort.%ld", (long)a->ounit);
  182. b->uscrtch = 0;
  183. b->uend=0;
  184. b->uwrt = 0;
  185. b->ufd = 0;
  186. b->urw = 3;
  187. switch(a->osta ? *a->osta : 'u')
  188. {
  189. case 'o':
  190. case 'O':
  191. #ifdef NON_POSIX_STDIO
  192. if (!(tf = FOPEN(buf,"r")))
  193. opnerr(a->oerr,errno,"open")
  194. fclose(tf);
  195. #else
  196. if (access(buf,0))
  197. opnerr(a->oerr,errno,"open")
  198. #endif
  199. break;
  200. case 's':
  201. case 'S':
  202. b->uscrtch=1;
  203. #ifdef NON_ANSI_STDIO
  204. (void) strcpy(buf,"tmp.FXXXXXX");
  205. (void) mktemp(buf);
  206. goto replace;
  207. #else
  208. if (!(b->ufd = tmpfile()))
  209. opnerr(a->oerr,errno,"open")
  210. b->ufnm = 0;
  211. #ifndef NON_UNIX_STDIO
  212. b->uinode = b->udev = -1;
  213. #endif
  214. b->useek = 1;
  215. return 0;
  216. #endif
  217. case 'n':
  218. case 'N':
  219. #ifdef NON_POSIX_STDIO
  220. if ((tf = FOPEN(buf,"r")) || (tf = FOPEN(buf,"a"))) {
  221. fclose(tf);
  222. opnerr(a->oerr,128,"open")
  223. }
  224. #else
  225. if (!access(buf,0))
  226. opnerr(a->oerr,128,"open")
  227. #endif
  228. /* no break */
  229. case 'r': /* Fortran 90 replace option */
  230. case 'R':
  231. #ifdef NON_ANSI_STDIO
  232. replace:
  233. #endif
  234. if (tf = FOPEN(buf,f__w_mode[0]))
  235. fclose(tf);
  236. }
  237. b->ufnm=(char *) malloc((unsigned int)(strlen(buf)+1));
  238. if(b->ufnm==NULL) opnerr(a->oerr,113,"no space");
  239. (void) strcpy(b->ufnm,buf);
  240. if ((s = a->oacc) && b->url)
  241. ufmt = 0;
  242. if(!(tf = FOPEN(buf, f__w_mode[ufmt|2]))) {
  243. if (tf = FOPEN(buf, f__r_mode[ufmt]))
  244. b->urw = 1;
  245. else if (tf = FOPEN(buf, f__w_mode[ufmt])) {
  246. b->uwrt = 1;
  247. b->urw = 2;
  248. }
  249. else
  250. err(a->oerr, errno, "open");
  251. }
  252. b->useek = f__canseek(b->ufd = tf);
  253. #ifndef NON_UNIX_STDIO
  254. if((b->uinode = f__inode(buf,&b->udev)) == -1)
  255. opnerr(a->oerr,108,"open")
  256. #endif
  257. if(b->useek)
  258. if (a->orl)
  259. rewind(b->ufd);
  260. else if ((s = a->oacc) && (*s == 'a' || *s == 'A')
  261. && FSEEK(b->ufd, 0L, SEEK_END))
  262. opnerr(a->oerr,129,"open");
  263. return(0);
  264. }
  265. int
  266. #ifdef KR_headers
  267. fk_open(seq,fmt,n) ftnint n;
  268. #else
  269. fk_open(int seq, int fmt, ftnint n)
  270. #endif
  271. { char nbuf[10];
  272. olist a;
  273. (void) sprintf(nbuf,"fort.%ld",(long)n);
  274. a.oerr=1;
  275. a.ounit=n;
  276. a.ofnm=nbuf;
  277. a.ofnmlen=strlen(nbuf);
  278. a.osta=NULL;
  279. a.oacc= (char*)(seq==SEQ?"s":"d");
  280. a.ofm = (char*)(fmt==FMT?"f":"u");
  281. a.orl = seq==DIR?1:0;
  282. a.oblnk=NULL;
  283. return(f_open(&a));
  284. }
  285. #ifdef __cplusplus
  286. }
  287. #endif