• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* gstdio.c - wrappers for C library functions
2  *
3  * Copyright 2004 Tor Lillqvist
4  *
5  * GLib is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * GLib is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with GLib; see the file COPYING.LIB.  If not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 #include "config.h"
22 
23 #define G_STDIO_NO_WRAP_ON_UNIX
24 
25 #include "glib.h"
26 
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34 
35 #ifdef G_OS_WIN32
36 #include <windows.h>
37 #include <errno.h>
38 #include <wchar.h>
39 #include <direct.h>
40 #include <io.h>
41 #include <sys/utime.h>
42 #else
43 #include <utime.h>
44 #endif
45 
46 #include "gstdio.h"
47 
48 #include "galias.h"
49 
50 #if !defined (G_OS_UNIX) && !defined (G_OS_WIN32) && !defined (G_OS_BEOS)
51 #error Please port this to your operating system
52 #endif
53 
54 
55 /**
56  * g_access:
57  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
58  * @mode: as in access()
59  *
60  * A wrapper for the POSIX access() function. This function is used to
61  * test a pathname for one or several of read, write or execute
62  * permissions, or just existence.
63  *
64  * On Windows, the file protection mechanism is not at all POSIX-like,
65  * and the underlying function in the C library only checks the
66  * FAT-style READONLY attribute, and does not look at the ACL of a
67  * file at all. This function is this in practise almost useless on
68  * Windows. Software that needs to handle file permissions on Windows
69  * more exactly should use the Win32 API.
70  *
71  * See your C library manual for more details about access().
72  *
73  * Returns: zero if the pathname refers to an existing file system
74  * object that has all the tested permissions, or -1 otherwise or on
75  * error.
76  *
77  * Since: 2.8
78  */
79 int
g_access(const gchar * filename,int mode)80 g_access (const gchar *filename,
81 	  int          mode)
82 {
83 #ifdef G_OS_WIN32
84   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
85   int retval;
86   int save_errno;
87 
88   if (wfilename == NULL)
89     {
90       errno = EINVAL;
91       return -1;
92     }
93 
94 #ifndef X_OK
95 #define X_OK 1
96 #endif
97 
98   retval = _waccess (wfilename, mode & ~X_OK);
99   save_errno = errno;
100 
101   g_free (wfilename);
102 
103   errno = save_errno;
104   return retval;
105 #else
106   return access (filename, mode);
107 #endif
108 }
109 
110 /**
111  * g_chmod:
112  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
113  * @mode: as in chmod()
114  *
115  * A wrapper for the POSIX chmod() function. The chmod() function is
116  * used to set the permissions of a file system object.
117  *
118  * On Windows the file protection mechanism is not at all POSIX-like,
119  * and the underlying chmod() function in the C library just sets or
120  * clears the FAT-style READONLY attribute. It does not touch any
121  * ACL. Software that needs to manage file permissions on Windows
122  * exactly should use the Win32 API.
123  *
124  * See your C library manual for more details about chmod().
125  *
126  * Returns: zero if the operation succeeded, -1 on error.
127  *
128  * Since: 2.8
129  */
130 int
g_chmod(const gchar * filename,int mode)131 g_chmod (const gchar *filename,
132 	 int          mode)
133 {
134 #ifdef G_OS_WIN32
135   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
136   int retval;
137   int save_errno;
138 
139   if (wfilename == NULL)
140     {
141       errno = EINVAL;
142       return -1;
143     }
144 
145   retval = _wchmod (wfilename, mode);
146   save_errno = errno;
147 
148   g_free (wfilename);
149 
150   errno = save_errno;
151   return retval;
152 #else
153   return chmod (filename, mode);
154 #endif
155 }
156 /**
157  * g_open:
158  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
159  * @flags: as in open()
160  * @mode: as in open()
161  *
162  * A wrapper for the POSIX open() function. The open() function is
163  * used to convert a pathname into a file descriptor.
164  *
165  * On POSIX systems file descriptors are implemented by the operating
166  * system. On Windows, it's the C library that implements open() and
167  * file descriptors. The actual Win32 API for opening files is quite
168  * different, see MSDN documentation for CreateFile(). The Win32 API
169  * uses file handles, which are more randomish integers, not small
170  * integers like file descriptors.
171  *
172  * Because file descriptors are specific to the C library on Windows,
173  * the file descriptor returned by this function makes sense only to
174  * functions in the same C library. Thus if the GLib-using code uses a
175  * different C library than GLib does, the file descriptor returned by
176  * this function cannot be passed to C library functions like write()
177  * or read().
178  *
179  * See your C library manual for more details about open().
180  *
181  * Returns: a new file descriptor, or -1 if an error occurred. The
182  * return value can be used exactly like the return value from open().
183  *
184  * Since: 2.6
185  */
186 int
g_open(const gchar * filename,int flags,int mode)187 g_open (const gchar *filename,
188 	int          flags,
189 	int          mode)
190 {
191 #ifdef G_OS_WIN32
192   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
193   int retval;
194   int save_errno;
195 
196   if (wfilename == NULL)
197     {
198       errno = EINVAL;
199       return -1;
200     }
201 
202   retval = _wopen (wfilename, flags, mode);
203   save_errno = errno;
204 
205   g_free (wfilename);
206 
207   errno = save_errno;
208   return retval;
209 #else
210   return open (filename, flags, mode);
211 #endif
212 }
213 
214 /**
215  * g_creat:
216  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
217  * @mode: as in creat()
218  *
219  * A wrapper for the POSIX creat() function. The creat() function is
220  * used to convert a pathname into a file descriptor, creating a file
221  * if necessary.
222 
223  * On POSIX systems file descriptors are implemented by the operating
224  * system. On Windows, it's the C library that implements creat() and
225  * file descriptors. The actual Windows API for opening files is
226  * different, see MSDN documentation for CreateFile(). The Win32 API
227  * uses file handles, which are more randomish integers, not small
228  * integers like file descriptors.
229  *
230  * Because file descriptors are specific to the C library on Windows,
231  * the file descriptor returned by this function makes sense only to
232  * functions in the same C library. Thus if the GLib-using code uses a
233  * different C library than GLib does, the file descriptor returned by
234  * this function cannot be passed to C library functions like write()
235  * or read().
236  *
237  * See your C library manual for more details about creat().
238  *
239  * Returns: a new file descriptor, or -1 if an error occurred. The
240  * return value can be used exactly like the return value from creat().
241  *
242  * Since: 2.8
243  */
244 int
g_creat(const gchar * filename,int mode)245 g_creat (const gchar *filename,
246 	 int          mode)
247 {
248 #ifdef G_OS_WIN32
249   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
250   int retval;
251   int save_errno;
252 
253   if (wfilename == NULL)
254     {
255       errno = EINVAL;
256       return -1;
257     }
258 
259   retval = _wcreat (wfilename, mode);
260   save_errno = errno;
261 
262   g_free (wfilename);
263 
264   errno = save_errno;
265   return retval;
266 #else
267   return creat (filename, mode);
268 #endif
269 }
270 
271 /**
272  * g_rename:
273  * @oldfilename: a pathname in the GLib file name encoding (UTF-8 on Windows)
274  * @newfilename: a pathname in the GLib file name encoding
275  *
276  * A wrapper for the POSIX rename() function. The rename() function
277  * renames a file, moving it between directories if required.
278  *
279  * See your C library manual for more details about how rename() works
280  * on your system. It is not possible in general on Windows to rename
281  * a file that is open to some process.
282  *
283  * Returns: 0 if the renaming succeeded, -1 if an error occurred
284  *
285  * Since: 2.6
286  */
287 int
g_rename(const gchar * oldfilename,const gchar * newfilename)288 g_rename (const gchar *oldfilename,
289 	  const gchar *newfilename)
290 {
291 #ifdef G_OS_WIN32
292   wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL);
293   wchar_t *wnewfilename;
294   int retval;
295   int save_errno = 0;
296 
297   if (woldfilename == NULL)
298     {
299       errno = EINVAL;
300       return -1;
301     }
302 
303   wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL);
304 
305   if (wnewfilename == NULL)
306     {
307       g_free (woldfilename);
308       errno = EINVAL;
309       return -1;
310     }
311 
312   if (MoveFileExW (woldfilename, wnewfilename, MOVEFILE_REPLACE_EXISTING))
313     retval = 0;
314   else
315     {
316       retval = -1;
317       switch (GetLastError ())
318 	{
319 #define CASE(a,b) case ERROR_##a: save_errno = b; break
320 	  CASE (FILE_NOT_FOUND, ENOENT);
321 	  CASE (PATH_NOT_FOUND, ENOENT);
322 	  CASE (ACCESS_DENIED, EACCES);
323 	  CASE (NOT_SAME_DEVICE, EXDEV);
324 	  CASE (LOCK_VIOLATION, EACCES);
325 	  CASE (SHARING_VIOLATION, EACCES);
326 	  CASE (FILE_EXISTS, EEXIST);
327 	  CASE (ALREADY_EXISTS, EEXIST);
328 #undef CASE
329 	default: save_errno = EIO;
330 	}
331     }
332 
333   g_free (woldfilename);
334   g_free (wnewfilename);
335 
336   errno = save_errno;
337   return retval;
338 #else
339   return rename (oldfilename, newfilename);
340 #endif
341 }
342 
343 /**
344  * g_mkdir:
345  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
346  * @mode: permissions to use for the newly created directory
347  *
348  * A wrapper for the POSIX mkdir() function. The mkdir() function
349  * attempts to create a directory with the given name and permissions.
350  * The mode argument is ignored on Windows.
351  *
352  * See your C library manual for more details about mkdir().
353  *
354  * Returns: 0 if the directory was successfully created, -1 if an error
355  *    occurred
356  *
357  * Since: 2.6
358  */
359 int
g_mkdir(const gchar * filename,int mode)360 g_mkdir (const gchar *filename,
361 	 int          mode)
362 {
363 #ifdef G_OS_WIN32
364   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
365   int retval;
366   int save_errno;
367 
368   if (wfilename == NULL)
369     {
370       errno = EINVAL;
371       return -1;
372     }
373 
374   retval = _wmkdir (wfilename);
375   save_errno = errno;
376 
377   g_free (wfilename);
378 
379   errno = save_errno;
380   return retval;
381 #else
382   return mkdir (filename, mode);
383 #endif
384 }
385 
386 /**
387  * g_chdir:
388  * @path: a pathname in the GLib file name encoding (UTF-8 on Windows)
389  *
390  * A wrapper for the POSIX chdir() function. The function changes the
391  * current directory of the process to @path.
392  *
393  * See your C library manual for more details about chdir().
394  *
395  * Returns: 0 on success, -1 if an error occurred.
396  *
397  * Since: 2.8
398  */
399 int
g_chdir(const gchar * path)400 g_chdir (const gchar *path)
401 {
402 #ifdef G_OS_WIN32
403   wchar_t *wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL);
404   int retval;
405   int save_errno;
406 
407   if (wpath == NULL)
408     {
409       errno = EINVAL;
410       return -1;
411     }
412 
413   retval = _wchdir (wpath);
414   save_errno = errno;
415 
416   g_free (wpath);
417 
418   errno = save_errno;
419   return retval;
420 #else
421   return chdir (path);
422 #endif
423 }
424 
425 /**
426  * g_stat:
427  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
428  * @buf: a pointer to a <structname>stat</structname> struct, which
429  *    will be filled with the file information
430  *
431  * A wrapper for the POSIX stat() function. The stat() function
432  * returns information about a file. On Windows the stat() function in
433  * the C library checks only the FAT-style READONLY attribute and does
434  * not look at the ACL at all. Thus on Windows the protection bits in
435  * the st_mode field are a fabrication of little use.
436  *
437  * See your C library manual for more details about stat().
438  *
439  * Returns: 0 if the information was successfully retrieved, -1 if an error
440  *    occurred
441  *
442  * Since: 2.6
443  */
444 int
g_stat(const gchar * filename,struct stat * buf)445 g_stat (const gchar *filename,
446 	struct stat *buf)
447 {
448 #ifdef G_OS_WIN32
449   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
450   int retval;
451   int save_errno;
452   int len;
453 
454   if (wfilename == NULL)
455     {
456       errno = EINVAL;
457       return -1;
458     }
459 
460   len = wcslen (wfilename);
461   while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1]))
462     len--;
463   if (len > 0 &&
464       (!g_path_is_absolute (filename) || len > g_path_skip_root (filename) - filename))
465     wfilename[len] = '\0';
466 
467   retval = _wstat (wfilename, (struct _stat *) buf);
468   save_errno = errno;
469 
470   g_free (wfilename);
471 
472   errno = save_errno;
473   return retval;
474 #else
475   return stat (filename, buf);
476 #endif
477 }
478 
479 /**
480  * g_lstat:
481  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
482  * @buf: a pointer to a <structname>stat</structname> struct, which
483  *    will be filled with the file information
484  *
485  * A wrapper for the POSIX lstat() function. The lstat() function is
486  * like stat() except that in the case of symbolic links, it returns
487  * information about the symbolic link itself and not the file that it
488  * refers to. If the system does not support symbolic links g_lstat()
489  * is identical to g_stat().
490  *
491  * See your C library manual for more details about lstat().
492  *
493  * Returns: 0 if the information was successfully retrieved, -1 if an error
494  *    occurred
495  *
496  * Since: 2.6
497  */
498 int
g_lstat(const gchar * filename,struct stat * buf)499 g_lstat (const gchar *filename,
500 	 struct stat *buf)
501 {
502 #ifdef HAVE_LSTAT
503   /* This can't be Win32, so don't do the widechar dance. */
504   return lstat (filename, buf);
505 #else
506   return g_stat (filename, buf);
507 #endif
508 }
509 
510 /**
511  * g_unlink:
512  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
513  *
514  * A wrapper for the POSIX unlink() function. The unlink() function
515  * deletes a name from the filesystem. If this was the last link to the
516  * file and no processes have it opened, the diskspace occupied by the
517  * file is freed.
518  *
519  * See your C library manual for more details about unlink(). Note
520  * that on Windows, it is in general not possible to delete files that
521  * are open to some process, or mapped into memory.
522  *
523  * Returns: 0 if the name was successfully deleted, -1 if an error
524  *    occurred
525  *
526  * Since: 2.6
527  */
528 int
g_unlink(const gchar * filename)529 g_unlink (const gchar *filename)
530 {
531 #ifdef G_OS_WIN32
532   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
533   int retval;
534   int save_errno;
535 
536   if (wfilename == NULL)
537     {
538       errno = EINVAL;
539       return -1;
540     }
541 
542   retval = _wunlink (wfilename);
543   save_errno = errno;
544 
545   g_free (wfilename);
546 
547   errno = save_errno;
548   return retval;
549 #else
550   return unlink (filename);
551 #endif
552 }
553 
554 /**
555  * g_remove:
556  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
557  *
558  * A wrapper for the POSIX remove() function. The remove() function
559  * deletes a name from the filesystem.
560  *
561  * See your C library manual for more details about how remove() works
562  * on your system. On Unix, remove() removes also directories, as it
563  * calls unlink() for files and rmdir() for directories. On Windows,
564  * although remove() in the C library only works for files, this
565  * function tries first remove() and then if that fails rmdir(), and
566  * thus works for both files and directories. Note however, that on
567  * Windows, it is in general not possible to remove a file that is
568  * open to some process, or mapped into memory.
569  *
570  * If this function fails on Windows you can't infer too much from the
571  * errno value. rmdir() is tried regardless of what caused remove() to
572  * fail. Any errno value set by remove() will be overwritten by that
573  * set by rmdir().
574  *
575  * Returns: 0 if the file was successfully removed, -1 if an error
576  *    occurred
577  *
578  * Since: 2.6
579  */
580 int
g_remove(const gchar * filename)581 g_remove (const gchar *filename)
582 {
583 #ifdef G_OS_WIN32
584   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
585   int retval;
586   int save_errno;
587 
588   if (wfilename == NULL)
589     {
590       errno = EINVAL;
591       return -1;
592     }
593 
594   retval = _wremove (wfilename);
595   if (retval == -1)
596     retval = _wrmdir (wfilename);
597   save_errno = errno;
598 
599   g_free (wfilename);
600 
601   errno = save_errno;
602   return retval;
603 #else
604   return remove (filename);
605 #endif
606 }
607 
608 /**
609  * g_rmdir:
610  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
611  *
612  * A wrapper for the POSIX rmdir() function. The rmdir() function
613  * deletes a directory from the filesystem.
614  *
615  * See your C library manual for more details about how rmdir() works
616  * on your system.
617  *
618  * Returns: 0 if the directory was successfully removed, -1 if an error
619  *    occurred
620  *
621  * Since: 2.6
622  */
623 int
g_rmdir(const gchar * filename)624 g_rmdir (const gchar *filename)
625 {
626 #ifdef G_OS_WIN32
627   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
628   int retval;
629   int save_errno;
630 
631   if (wfilename == NULL)
632     {
633       errno = EINVAL;
634       return -1;
635     }
636 
637   retval = _wrmdir (wfilename);
638   save_errno = errno;
639 
640   g_free (wfilename);
641 
642   errno = save_errno;
643   return retval;
644 #else
645   return rmdir (filename);
646 #endif
647 }
648 
649 /**
650  * g_fopen:
651  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
652  * @mode: a string describing the mode in which the file should be
653  *   opened
654  *
655  * A wrapper for the stdio fopen() function. The fopen() function
656  * opens a file and associates a new stream with it.
657  *
658  * Because file descriptors are specific to the C library on Windows,
659  * and a file descriptor is partof the <type>FILE</type> struct, the
660  * <type>FILE</type> pointer returned by this function makes sense
661  * only to functions in the same C library. Thus if the GLib-using
662  * code uses a different C library than GLib does, the
663  * <type>FILE</type> pointer returned by this function cannot be
664  * passed to C library functions like fprintf() or fread().
665  *
666  * See your C library manual for more details about fopen().
667  *
668  * Returns: A <type>FILE</type> pointer if the file was successfully
669  *    opened, or %NULL if an error occurred
670  *
671  * Since: 2.6
672  */
673 FILE *
g_fopen(const gchar * filename,const gchar * mode)674 g_fopen (const gchar *filename,
675 	 const gchar *mode)
676 {
677 #ifdef G_OS_WIN32
678   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
679   wchar_t *wmode;
680   FILE *retval;
681   int save_errno;
682 
683   if (wfilename == NULL)
684     {
685       errno = EINVAL;
686       return NULL;
687     }
688 
689   wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
690 
691   if (wmode == NULL)
692     {
693       g_free (wfilename);
694       errno = EINVAL;
695       return NULL;
696     }
697 
698   retval = _wfopen (wfilename, wmode);
699   save_errno = errno;
700 
701   g_free (wfilename);
702   g_free (wmode);
703 
704   errno = save_errno;
705   return retval;
706 #else
707   return fopen (filename, mode);
708 #endif
709 }
710 
711 /**
712  * g_freopen:
713  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
714  * @mode: a string describing the mode in which the file should be
715  *   opened
716  * @stream: an existing stream which will be reused, or %NULL
717  *
718  * A wrapper for the POSIX freopen() function. The freopen() function
719  * opens a file and associates it with an existing stream.
720  *
721  * See your C library manual for more details about freopen().
722  *
723  * Returns: A <type>FILE</type> pointer if the file was successfully
724  *    opened, or %NULL if an error occurred.
725  *
726  * Since: 2.6
727  */
728 FILE *
g_freopen(const gchar * filename,const gchar * mode,FILE * stream)729 g_freopen (const gchar *filename,
730 	   const gchar *mode,
731 	   FILE        *stream)
732 {
733 #ifdef G_OS_WIN32
734   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
735   wchar_t *wmode;
736   FILE *retval;
737   int save_errno;
738 
739   if (wfilename == NULL)
740     {
741       errno = EINVAL;
742       return NULL;
743     }
744 
745   wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
746 
747   if (wmode == NULL)
748     {
749       g_free (wfilename);
750       errno = EINVAL;
751       return NULL;
752     }
753 
754   retval = _wfreopen (wfilename, wmode, stream);
755   save_errno = errno;
756 
757   g_free (wfilename);
758   g_free (wmode);
759 
760   errno = save_errno;
761   return retval;
762 #else
763   return freopen (filename, mode, stream);
764 #endif
765 }
766 
767 /**
768  * g_utime:
769  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
770  * @utb: a pointer to a struct utimbuf.
771  *
772  * A wrapper for the POSIX utime() function. The utime() function
773  * sets the access and modification timestamps of a file.
774  *
775  * See your C library manual for more details about how utime() works
776  * on your system.
777  *
778  * Returns: 0 if the operation was successful, -1 if an error
779  *    occurred
780  *
781  * Since: 2.18
782  */
783 int
g_utime(const gchar * filename,struct utimbuf * utb)784 g_utime (const gchar    *filename,
785 	 struct utimbuf *utb)
786 {
787 #ifdef G_OS_WIN32
788   wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
789   int retval;
790   int save_errno;
791 
792   if (wfilename == NULL)
793     {
794       errno = EINVAL;
795       return -1;
796     }
797 
798   retval = _wutime (wfilename, (struct _utimbuf*) utb);
799   save_errno = errno;
800 
801   g_free (wfilename);
802 
803   errno = save_errno;
804   return retval;
805 #else
806   return utime (filename, utb);
807 #endif
808 }
809 
810 #define __G_STDIO_C__
811 #include "galiasdef.c"
812