source: git/MP/MP/MP_FileTransp.c @ bba1c4

fieker-DuValspielwiese
Last change on this file since bba1c4 was bba1c4, checked in by Olaf Bachmann <obachman@…>, 26 years ago
1998-10-14 Olaf Bachmann <obachman@mathematik.uni-kl.de> * MP_TcpTransp.c: added MP_KillLink, -MPrsh option to MP_OpenLink * MP_Util.c: Added IMP_StrDup function git-svn-id: file:///usr/local/Singular/svn/trunk@2562 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 15.0 KB
Line 
1/****************************************************************
2 *                                                                 
3 *                                                                 
4 *                    MP version 1.1.2:  Multi Protocol
5 *                    Kent State University, Kent, OH
6 *                 Authors:  S. Gray, N. Kajler, P. Wang
7 *          (C) 1993, 1994, 1995, 1996, 1997 All Rights Reserved
8 *
9 *                                 NOTICE
10 *
11 *  Permission to use, copy, modify, and distribute this software and
12 *  its documentation for non-commercial purposes and without fee is
13 *  hereby granted provided that the above copyright notice appear in all
14 *  copies and that both the copyright notice and this permission notice
15 *  appear in supporting documentation.
16 * 
17 *  Neither Kent State University nor the Authors make any representations
18 *  about the suitability of this software for any purpose.  The MP Library
19 *  is distributed in the hope that it will be useful, but is provided  "as
20 *  is" and without any warranty of any kind and without even the implied 
21 *  warranty of merchantability or fitness for a particular purpose.
22 *
23 *
24 *   IMPLEMENTATION FILE:  MP_FileTransp.c
25 *                               
26 *      Public interface routines to the "file" transport device.
27 *      These include read, write, open, close, and init routines.
28 *      There are some support routines as well.
29 *
30 *  Change Log:
31 *       November 21, 1994 SG - Added file_has_data() and put it in the
32 *                              the transp_op structure
33 *       September 11, 1995 SG - Reorganization of files.  Cleaned up
34 *                               header files and relocated source to
35 *                               its own file.
36 *       3/3/96    sgray - moved call to file_init_transport() inside
37 *                         file_open_transport() and removed the init
38 *                         routine from the file_ops struct.
39 *       9/22/96   sgray  - changed tv_sec to 0 in file_get_status()
40 *                               so that select() does polling.
41 *       3/11/97   sgray - Changed all memory management calls that allocate
42 *                         or deallocate strings to use the "Raw" calls.
43 *
44 ***************************************************************************/
45
46
47#ifndef lint
48static char vcid[] = "@(#) $Id: MP_FileTransp.c,v 1.2 1998-10-14 10:18:10 obachman Exp $";
49#endif /* lint */
50
51#include "MP.h"
52#include <sys/types.h>
53#include <fcntl.h>
54#include <sys/time.h>
55#include <sys/stat.h>
56#include <string.h>
57
58
59#ifdef __WIN32__
60   #include <io.h>
61#endif
62
63#ifdef __WIN32__
64
65#   include <sys/stat.h>
66#   define  FILE_MODE   S_IREAD | S_IWRITE
67
68#else /* not __WIN32__ */
69
70#    define  FILE_MODE   0666
71#
72#    ifndef  O_BINARY
73#        define  O_BINARY    0
74#    endif /* O_BINARY */
75
76#endif /* not __WIN32__ */
77
78/* #define MP_DEBUG */
79
80EXTERN char *IMP_GetCmdlineArg _ANSI_ARGS_((int, char**, char*));
81
82#define log_msg_len 128
83static char log_msg[log_msg_len];
84
85
86MP_TranspOps_t file_ops = {
87    file_write,
88    file_read,
89    file_flush,
90    file_get_status,
91    file_open_connection,
92    file_close_connection,
93    file_close_connection
94};
95
96
97#ifdef __STDC__
98int get_file_mode(int    argc,
99                  char **argv)
100#else
101int get_file_mode(argc, argv)
102    int    argc;
103    char **argv;
104#endif
105{
106    char *cmode;
107
108    if ((cmode = IMP_GetCmdlineArg(argc, argv, "-MPmode")) != NULL) {
109        if (strcmp(cmode, "read") == 0)
110            return MP_READ_MODE;
111        else if (strcmp(cmode, "write") == 0)
112            return MP_WRITE_MODE;
113        else if (strcmp(cmode, "append") == 0)
114            return MP_APPEND_MODE;
115    }
116
117    return MP_NO_SUCH_FILE_MODE;
118}
119
120
121/****  FILE transport "device" "public" routines ******/
122#ifdef __STDC__
123MP_Boolean_t file_get_status(MP_Link_pt link, MP_LinkStatus_t status_to_check)
124#else
125MP_Boolean_t file_get_status(link, status_to_check)
126    MP_Link_pt      link;
127    MP_LinkStatus_t status_to_check;
128#endif
129{
130
131#ifndef __WIN32__
132    int    filepos, fd = fileno((*(MP_FILE_t *)(link->transp.private1)).fptr);
133    struct stat statbuf;
134#endif  /* __WIN32__ */
135
136#ifdef MP_DEBUG
137    printf("file_get_status: entering for link %d\n", link->link_id);
138#endif
139
140#ifdef __WIN32__
141   switch (status_to_check)
142   {
143      case MP_LinkReadyReading:
144         return MP_TRUE;
145
146      case MP_LinkReadyWriting:
147         return MP_TRUE;
148
149      default:
150         sprintf(
151            log_msg, "file_get_status: illegal option %d",
152            status_to_check
153         );
154         MP_LogEvent(link, MP_ERROR_EVENT, log_msg);
155         return MP_FALSE;
156   }
157
158#else /* not __WIN32__ */
159
160    switch (status_to_check) {
161    case MP_LinkReadyReading:
162        if ((*(MP_FILE_t *)(link->transp.private1)).access_mode
163             == MP_READ_MODE) {
164          fstat(fd, &statbuf);
165          filepos = ftell((*(MP_FILE_t *)(link->transp.private1)).fptr);
166          return (!(filepos == statbuf.st_size));
167        }
168        else {
169          MP_LogEvent(link, MP_ERROR_EVENT, 
170          "file_get_status: can't check read status on a file opened for writing");
171          return MP_FALSE;
172          }
173
174    case MP_LinkReadyWriting:
175        if ((*(MP_FILE_t *)(link->transp.private1)).access_mode
176             == MP_WRITE_MODE) 
177          return MP_TRUE;
178        else {
179          MP_LogEvent(link, MP_ERROR_EVENT, 
180          "file_get_status: can't check write status on a file opened for reading");
181          return MP_FALSE;
182          }
183
184    default:
185        sprintf(log_msg,"file_get_status: illegal option %d",
186                status_to_check);
187        MP_LogEvent(link, MP_ERROR_EVENT, log_msg);
188        return MP_FALSE;
189    }
190#endif /* not __WIN32__ */
191
192}
193
194
195
196#ifdef __STDC__
197long file_read(MP_Link_pt link,
198               char *    buf,
199               long       len)
200#else
201long file_read(link, buf, len)
202    MP_Link_pt link;
203    char *    buf;
204    long       len;
205#endif
206{
207    int   fd   = fileno((*(MP_FILE_t *)(link->transp.private1)).fptr);
208    FILE *fptr = (*(MP_FILE_t *)(link->transp.private1)).fptr;
209#ifndef __WIN32__
210    fd_set mask, readfds;
211    /*     fd_set mask = 1 << fd, readfds; */
212#endif
213
214#ifdef MP_DEBUG
215    printf("file_read: entering -len = %d\n", len);
216    fflush(stdout);
217#endif
218
219#ifndef __WIN32__
220    FD_ZERO(&mask);
221    FD_SET(fd, &mask); 
222    while (MP_TRUE) {
223        readfds = mask;
224        switch (SELECT(FD_SETSIZE, &readfds, NULL, NULL, NULL)) {
225        case 0:
226            MP_LogEvent(link, MP_ERROR_EVENT, "file_read: timed out");
227            return -1;
228
229        case -1:
230            if (errno == EINTR)
231                continue;
232            MP_LogEvent(link, MP_ERROR_EVENT,
233                        "file_read: something bad happened with select()");
234            return -1;
235        }
236        if (FD_ISSET(fd, &readfds))
237            break;
238    }
239#endif /* __WIN32__ */
240
241    if ((len = fread(buf, 1, len, fptr)) == -1) {
242        MP_LogEvent(link, MP_ERROR_EVENT, "file_read: problem with the read");
243        return MP_SetError(link, MP_CantReadLink);
244    }
245
246#ifndef NO_LOGGING
247    if (link->logmask & MP_LOG_READ_EVENTS) {
248        sprintf(log_msg, "file_read: read %ld bytes", len);
249        MP_LogEvent(link, MP_READ_EVENT, log_msg);
250    }
251#endif
252
253#ifdef MP_DEBUG
254    printf("file_read: exiting - read %d bytes \n", len);
255    fflush(stdout);
256#endif
257
258    return len;
259}
260
261
262
263
264#ifdef __STDC__
265long file_write(MP_Link_pt link, char * buf, long len)
266#else
267long file_write(link, buf, len)
268    MP_Link_pt link;
269    char *     buf;
270    long       len;
271#endif
272{
273  long   cnt, fd = fileno((*(MP_FILE_t *)(link->transp.private1)).fptr);
274  FILE * fptr = (*(MP_FILE_t *)(link->transp.private1)).fptr;
275
276#ifndef __WIN32__
277  fd_set mask, writefs;
278#endif
279
280#ifdef MP_DEBUG
281  fprintf(stderr, "file_write: entering -len = %d\n", len);
282  fflush(stderr);
283#endif
284
285#ifdef __WIN32__
286
287   /*
288    * There's not much we can do to check if the file is ready for writing.
289    * If it isn't we'll know it later.
290    */
291
292#else /* not __WIN32__ */
293
294    FD_ZERO(&mask);
295    FD_SET(fd, &mask);
296
297    while (MP_TRUE) {
298        writefs = mask;
299        switch (SELECT(FD_SETSIZE, NULL, &writefs, NULL, NULL)) {
300        case 0:
301            MP_LogEvent(link, MP_ERROR_EVENT, "file_write: timed out");
302            return -1;
303
304        case -1:
305            if (errno == EINTR)
306                continue;
307            MP_LogEvent(link, MP_ERROR_EVENT,
308                        "file_write: something bad happened with select()");
309            return -1;
310        }
311        if (FD_ISSET(fd, &writefs))
312            break;
313    }
314#endif /* __WIN32__ */
315
316  if ((cnt = fwrite(buf, 1, len, fptr)) != len) {
317            MP_LogEvent(link, MP_ERROR_EVENT,
318                        "file_write: can't do write:");
319            return MP_SetError(link, MP_CantWriteLink);
320        }
321
322#ifndef NO_LOGGING
323        if (link->logmask & MP_LOG_WRITE_EVENTS) {
324            sprintf(log_msg, "file_write: wrote %ld bytes", cnt);
325            MP_LogEvent(link, MP_WRITE_EVENT, log_msg);
326        }
327#endif
328
329#ifdef MP_DEBUG
330    fprintf(stderr, "file_write: exiting - wrote %d bytes \n", cnt); 
331    fflush(stderr);
332#endif
333
334    return len;
335}
336
337MP_Status_t
338#ifdef __STDC__
339file_flush(MP_Link_pt link)
340#else
341file_flush(link)
342    MP_Link_pt  link;
343#endif
344{
345#ifdef MP_DEBUG
346    fprintf(stderr, "file_flush: entering\n");
347    fflush(stderr);
348#endif
349
350  if (fflush((*(MP_FILE_t *)(link->transp.private1)).fptr) != 0)
351    return MP_Failure;
352
353#ifdef MP_DEBUG
354    fprintf(stderr, "file_flush: exiting  \n");
355    fflush(stderr);
356#endif
357  return MP_ClearError(link);
358}
359
360
361/***********************************************************************
362 * FUNCTION:  file_open_connection
363 * INPUT:     link - pointer to link structure for this connection
364 *            argc - number of arguments in argv
365 *            argv - arguments as strings
366 * OUTPUT:    Success:  MP_Success
367 *                      link established as a file connection
368 *            Failure:  MP_Failure
369 * OPERATION: Determine the file mode we are using and attempt to
370 *            establish a connection accordingly.  We could fail
371 *            for any of a number of reasons.  Bad hostname, bad
372 *            port number, missing arguments....
373 ***********************************************************************/
374#ifdef __STDC__
375MP_Status_t file_open_connection(MP_Link_pt   link,
376                                 int          argc,
377                                 char       **argv)
378#else
379MP_Status_t file_open_connection(link, argc, argv)
380    MP_Link_pt   link;
381    int          argc;
382    char       **argv;
383#endif
384{
385    char      *cmode, *fname, *mode_open_flag = NULL;
386    MP_FILE_t *file;
387
388#ifdef MP_DEBUG
389    fprintf(stderr, "file_open_connection: entering\n");
390    fflush(stderr);
391#endif
392
393    TEST_LINK_NULL(link);
394    if (file_init_transport(link) != MP_Success)
395        return MP_Failure;
396
397    file = (MP_FILE_t *)(link->transp.private1);
398    if ((fname = IMP_GetCmdlineArg(argc, argv, "-MPfile")) == NULL) {
399        MP_LogEvent(link, MP_ERROR_EVENT,
400                    "file_open_connection: error opening file:"
401                    " bad or missing -MPfile option");
402        return MP_SetError(link, MP_Failure);
403    }
404    file->access_mode = get_file_mode(argc, argv);
405    switch (file->access_mode) {
406    case MP_NO_SUCH_FILE_MODE:
407        MP_LogEvent(link, MP_ERROR_EVENT,
408                    "file_open_connection: error opening file:"
409                    " bad or missing -MPmode option");
410        return MP_SetError(link, MP_Failure);
411
412    case MP_WRITE_MODE:
413        mode_open_flag = "wb";
414        break;
415
416    case MP_READ_MODE:
417        mode_open_flag = "rb";
418        break;
419
420    case MP_APPEND_MODE:
421        mode_open_flag = "ab";
422        break;
423    }
424   
425    if ((file->fptr = fopen(fname, mode_open_flag)) == NULL) {
426        char *errmsg = NULL;
427        cmode = IMP_GetCmdlineArg(argc, argv, "-MPmode");
428        errmsg = (char *) IMP_RawMemAllocFnc(strlen(fname) + 80);
429        sprintf(errmsg, "file_open_connection: Cannot open file %s "
430                "in %s mode", fname, cmode);
431        MP_LogEvent(link, MP_ERROR_EVENT, errmsg);
432        IMP_RawMemFreeFnc(errmsg);
433        return MP_SetError(link, MP_CantOpenFile);
434    }
435
436    file->fname  = IMP_RawMemAllocFnc(strlen(fname) + 1);
437    if (file->fname == NULL) {
438        MP_LogEvent(link, MP_ERROR_EVENT,
439                    "file_open_connection: memory allocation error");
440        return MP_SetError(link, MP_Failure);
441    }
442    strcpy(file->fname, fname);
443
444#ifndef NO_LOGGING
445    if (link->logmask & MP_LOG_INIT_EVENTS) {
446        char *msg = NULL;
447        cmode = IMP_GetCmdlineArg(argc, argv, "-MPmode");
448        msg = IMP_RawMemAllocFnc(strlen(file->fname) + strlen(cmode) + 48);
449        sprintf(msg, "file_open_connection: opened file %s in %s mode",
450                file->fname, cmode);
451        MP_LogEvent(link, MP_INIT_EVENT, msg);
452        IMP_RawMemFreeFnc(msg);
453    }
454#endif
455
456#ifdef MP_DEBUG
457    fprintf(stderr, "file_open_connection: exiting, filename is %s\n",
458            file->fname);
459    fflush(stderr);
460#endif
461
462    RETURN_OK(link);
463}
464
465
466
467/***********************************************************************
468 * FUNCTION:  file_close_connection
469 * INPUT:     link  - pointer to the link structure for this connection
470 * OUTPUT:    Success:  MP_Success
471 *                      Release the file structure pointed to by private1.
472 *            Failure:  MP_Failure
473 * OPERATION:
474 ***********************************************************************/
475#ifdef __STDC__
476MP_Status_t file_close_connection(MP_Link_pt link)
477#else
478MP_Status_t file_close_connection(link)
479    MP_Link_pt link;
480#endif
481{
482    MP_FILE_t *file;
483
484#ifdef MP_DEBUG
485    fprintf(stderr, "file_close_connection: entering\n");
486    fflush(stderr);
487#endif
488
489    TEST_LINK_NULL(link);
490    file = (MP_FILE_t *)(link->transp.private1);
491    if (file == NULL)
492        return MP_SetError(link, MP_NullTransport);
493
494    fclose(file->fptr);
495    IMP_RawMemFreeFnc(file->fname);
496
497    IMP_MemFreeFnc(file, sizeof(MP_FILE_t));
498    link->transp.private1 = NULL;
499
500#ifdef MP_DEBUG
501    fprintf(stderr, "file_close_connection: exiting\n");
502    fflush(stderr);
503#endif
504
505    RETURN_OK(link);
506}
507
508
509
510
511/***********************************************************************
512 * FUNCTION:  file_init_transport
513 * INPUT:     link - pointer to the link structure for this connection
514 * OUTPUT:    Success:  MP_Success and link structure initialized for the
515 *                      file input or output.
516 *            Failure:  MP_Failure
517 * OPERATION: If there are no problems, allocate a file structure and
518 *            attach it to the private pointer inside link.
519 ***********************************************************************/
520#ifdef __STDC__
521MP_Status_t file_init_transport(MP_Link_pt link)
522#else
523MP_Status_t file_init_transport(link)
524    MP_Link_pt link;
525#endif
526{
527#ifdef MP_DEBUG
528    fprintf(stderr, "file_init_transport: entering\n");
529    fflush(stderr);
530#endif
531
532    TEST_LINK_NULL(link);
533    link->transp.transp_dev = MP_FileTransportDev;
534    link->transp.transp_ops = &file_ops;
535    link->transp.private1 = (char *)IMP_MemAllocFnc(sizeof(MP_FILE_t));
536    TEST_MEM_ALLOC_ERROR(link, link->transp.private1);
537/*     link->link_bigint_format = MP_GMP;
538 *     link->link_bigreal_format = MP_GMP;
539 */
540
541#ifdef MP_DEBUG
542    fprintf(stderr, "file_init_transport: exiting\n");
543    fflush(stderr);
544#endif
545
546    RETURN_OK(link);
547}
548
549
Note: See TracBrowser for help on using the repository browser.