1 //////////////////////////////////////////////////////////////////////////////
2 //Copyright 2008
3 //  Andrew Gacek, Steven Holte, Gopalan Nadathur, Xiaochu Qi, Zach Snow
4 //////////////////////////////////////////////////////////////////////////////
5 // This file is part of Teyjus.                                             //
6 //                                                                          //
7 // Teyjus is free software: you can redistribute it and/or modify           //
8 // it under the terms of the GNU General Public License as published by     //
9 // the Free Software Foundation, either version 3 of the License, or        //
10 // (at your option) any later version.                                      //
11 //                                                                          //
12 // Teyjus is distributed in the hope that it will be useful,                //
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of           //
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            //
15 // GNU General Public License for more details.                             //
16 //                                                                          //
17 // You should have received a copy of the GNU General Public License        //
18 // along with Teyjus.  If not, see <http://www.gnu.org/licenses/>.          //
19 //////////////////////////////////////////////////////////////////////////////
20 #include <sys/stat.h>
21 #include <stdlib.h>
22 #include "../include/standardlib.h"
23 #include <stdio.h>
24 #include <string.h>
25 #include "file.h"
26 #include "../system/error.h"
27 #include "linker_message.h"
28 
29 #define DEBUG(x) printf("%s\n",x)
30 #define SWAPENDIAN
31 
32 char* LK_FILE_LinkCodeExt=".lp";
33 char* LK_FILE_ByteCodeExt=".lpo";
34 
LK_FILE_OpenInput(char * modname,char * extension)35 int LK_FILE_OpenInput(char* modname, char* extension)
36 {
37   int fd;
38   char* tjpath;
39   char* tjpath_; /* We need a copy since strtok modifies its argument */
40   char* dir;
41   char* buf=(char *)EM_malloc(strlen(modname)+strlen(extension)+1);
42   sprintf(buf,"%s%s",modname,extension);
43 
44   fd=open(buf,O_RDONLY|O_BINARY,0000);
45   if(fd==-1)
46   {
47     /* Restrictive hack: works only on Unix
48      * To be fixed with C, or, better, rewrite all the linker in OCaml
49      * to do this easily */
50     tjpath=getenv("TJPATH");
51     if (tjpath == NULL) tjpath=".";
52     tjpath_=strdup(tjpath);
53 
54     dir=strtok(tjpath_,":");
55 
56     while (dir != NULL) {
57       buf=(char *)EM_malloc(strlen(modname)+strlen(extension)+strlen(dir)+2);
58       sprintf(buf,"%s/%s%s",dir,modname,extension);
59       fd=open(buf,O_RDONLY|O_BINARY,0000);
60       if(fd!=-1)
61         return fd;
62       dir=strtok(NULL,":");
63     }
64 
65     bad("Couldn't open file %s for reading.\n",buf);
66     EM_THROW(LK_LinkError);
67 
68   }
69   return fd;
70 }
71 
LK_FILE_OpenOutput(char * modname,char * extension)72 int LK_FILE_OpenOutput(char* modname, char* extension)
73 {
74   int fd;
75   char* buf=(char *)EM_malloc(strlen(modname)+strlen(extension)+1);
76   sprintf(buf,"%s%s",modname,extension);
77 
78   fd=open(buf,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666);
79   if(fd==-1)
80   {
81     bad("Couldn't open file %s for writing.\n",buf);
82     EM_THROW(LK_LinkError);
83   }
84   return fd;
85 }
86 
LK_FILE_xPipe(int fd[2])87 void LK_FILE_xPipe(int fd[2])
88 {
89   if(pipe(fd))
90   {
91     bad("Couldn't open pipe.\n");
92     EM_THROW(LK_LinkError);
93   }
94 }
95 
LK_FILE_Close(int fd)96 void LK_FILE_Close(int fd)
97 {
98   close(fd);///\todo handle close error?
99 }
100 
LK_FILE_GETWord(int fd)101 Word LK_FILE_GETWord(int fd)
102 {
103   Word tmp;
104   read(fd,&tmp,sizeof(tmp));
105 #if BYTE_ORDER == LITTLE_ENDIAN
106 # if __WORDSIZE == 32
107   return (Word)bswap_32((unsigned int)tmp);
108 # elif __WORDSIZE == 64
109   return bswap_64(tmp);
110 # endif
111 #elif BYTE_ORDER == BIG_ENDIAN
112   return tmp;
113 #endif
114 }
115 
LK_FILE_GET4(int fd)116 INT4 LK_FILE_GET4(int fd)
117 {
118   INT4 tmp;
119   read(fd,&tmp,sizeof(tmp));
120 #if BYTE_ORDER == LITTLE_ENDIAN
121   return bswap_32(tmp);
122 #elif BYTE_ORDER == BIG_ENDIAN
123   return tmp;
124 #endif
125 }
126 
LK_FILE_GET2(int fd)127 TwoBytes LK_FILE_GET2(int fd)
128 {
129   TwoBytes tmp;
130   read(fd,&tmp,sizeof(tmp));
131 #if BYTE_ORDER == LITTLE_ENDIAN
132   return bswap_16(tmp);
133 #elif BYTE_ORDER == BIG_ENDIAN
134   return tmp;
135 #endif
136 }
137 
LK_FILE_GET1(int fd)138 Byte LK_FILE_GET1(int fd)
139 {
140   Byte tmp;
141   read(fd,&tmp,sizeof(tmp));
142   return tmp;
143 }
144 
LK_FILE_GetString(int fd)145 char* LK_FILE_GetString(int fd)
146 {
147   char* tmp;
148   int size=LK_FILE_GET4(fd);
149   //fprintf(stderr, "Name:%d ",size);//DEBUG
150   tmp=(char *)EM_malloc(size+1);
151   read(fd,tmp,size);
152   tmp[size]='\0';
153   //fprintf(stderr, "\"%s\"\n",tmp);//DEBUG
154   return tmp;
155 }
156 
LK_FILE_PUT1(int fd,Byte x)157 void LK_FILE_PUT1(int fd, Byte x)
158 {
159   write(fd,&x,sizeof(x));
160 }
161 
LK_FILE_PUT2(int fd,TwoBytes x)162 void LK_FILE_PUT2(int fd, TwoBytes x)
163 {
164 #if BYTE_ORDER == LITTLE_ENDIAN
165     x=bswap_16(x);
166 #elif BYTE_ORDER == BIG_ENDIAN
167 #endif
168   write(fd,&x,sizeof(x));
169 }
170 
LK_FILE_PUT4(int fd,INT4 x)171 void LK_FILE_PUT4(int fd, INT4 x)
172 {
173 #if BYTE_ORDER == LITTLE_ENDIAN
174   x=bswap_32(x);
175 #elif BYTE_ORDER == BIG_ENDIAN
176 #endif
177   write(fd,&x,sizeof(x));
178 }
179 
LK_FILE_PUTN(int fd,void * data,int n)180 void LK_FILE_PUTN(int fd, void* data,int n)
181 {
182   write(fd,data,n);
183 }
184 
LK_FILE_PUTWord(int fd,Word x)185 void LK_FILE_PUTWord(int fd, Word x)
186 {
187 #if BYTE_ORDER == LITTLE_ENDIAN
188 # if __WORDSIZE == 32
189   x=(Word)bswap_32((unsigned int)x);
190 # elif __WORDSIZE == 64
191   x=bswap_64(x);
192 # endif
193 #elif BYTE_ORDER == BIG_ENDIAN
194 #endif
195   write(fd,&x,sizeof(x));
196 }
197 
LK_FILE_PutString(int fd,char * str)198 void LK_FILE_PutString(int fd, char* str)
199 {
200   int size=strlen(str);
201   LK_FILE_PUT4(fd,size);
202   write(fd,str,size);
203 }
204 
205