]> andersk Git - splint.git/blame - src/osd.c
Updating to use the LEnsures and LRequires instead of the ensures requires so
[splint.git] / src / osd.c
CommitLineData
616915dd 1/*
2** LCLint - annotation-assisted static program checker
3** Copyright (C) 1994-2000 University of Virginia,
4** Massachusetts Institute of Technology
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** This program is distributed in the hope that it will be useful, but
12** WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** General Public License for more details.
15**
16** The GNU General Public License is available from http://www.gnu.org/ or
17** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18** MA 02111-1307, USA.
19**
20** For information on lclint: lclint-request@cs.virginia.edu
21** To report a bug: lclint-bug@cs.virginia.edu
22** For more information: http://lclint.cs.virginia.edu
23*/
24/*
25** osd.c
26**
27** Provide a system-independent interface to system-dependent
28** file operations.
29*/
30
31/*
32 * Modified by Herbert 04/19/97:
33 * - added conditional 'OS2' to conditional 'MSDOS'
34 * - added include of new header portab.h.
35 * - changed '/' to macro.
36 * - added DOS / OS/2 specific stuff in osd_getPath.
37 * Herbert 06/12/2000:
38 * - added OS/2 specific includes before osd_getPid()
39 * - handle files like in WIN32 for OS/2 in osd_fileExists()
40 */
41
42/*@-allmacros*/
43/*@ignore@*/
44# include <sys/types.h>
45# include <sys/stat.h>
46/* Fix suggested by Lars Rasmussen */
47# include <errno.h>
48/*@end@*/
49/*@=allmacros*/
50# include "lclintMacros.nf"
51# include "basic.h"
52# include "osd.h"
53# include "portab.h"
54
55/* from stat.h */
56/*@ignore@*/
57extern int stat (const char *, /*@out@*/ struct stat *);
58/*@end@*/
59
60static bool osd_executableFileExists (char *);
61
62static bool nextdir (char **p_current_dir, /*@out@*/ char **p_dir,
63 /*@out@*/ size_t *p_len);
64
65extern char *LSLRootName (char *filespec)
66{
67 char *result, *startName, *tail;
68 size_t nameLength;
69
70 tail = strrchr (filespec, CONNECTCHAR);
71 startName = (tail == NULL ? filespec : &tail[1]);
72 tail = strrchr (startName, '.');
73 nameLength = (tail == NULL ? strlen (startName)
74 : size_fromInt (tail - startName));
75 result = dmalloc (nameLength + 1);
76 strncpy (result, startName, nameLength);
77 result[(int) nameLength] = '\0';
78 return result;
79}
80
81extern /*@observer@*/ char *
82osd_getEnvironment (char *env, /*@returned@*/ char *def)
83{
84 char *ret = osd_getEnvironmentVariable (env);
85
86 if (ret == NULL)
87 {
88 return def;
89 }
90 else
91 {
92 return ret;
93 }
94}
95
96
97/*
98**++
99** FUNCTIONAL DESCRIPTION:
100**
101** This function attempts to locate a file in a search list. On VMS, it
102** just concatinates the path and file names, and then lets RMS do the
103** searching. On Ultrix, it searches for the file on the path.
104**
105** FORMAL PARAMETERS:
106**
107** path: search path where to look for the file.
108** file: name of file to search for.
109** returnPath: if a file is found, this is where the concatenated
110** directory and file name are returned.
111**
112** RETURN VALUE:
113**
114** OSD_FILEFOUND: the file was found on the search list.
115** OSD_FILENOTFOUND the file was not found.
116** OSD_PATHTOOLONG the concatenated directory and file name are too
117** long.
118**
119** SIDE EFFECTS:
120**
121** None
122**
123** PRECONDITIONS:
124**
125** Requires that parameters, path and file, are valid C strings.
126**
127**
128**--
129*/
130
131extern /*@null@*/ /*@observer@*/ char *
132 osd_getHomeDir ()
133{
134 /* Would something different be better for windows? */
135 return (osd_getEnvironmentVariable ("HOME"));
136}
137
138filestatus osd_findOnLarchPath (char *file, char **returnPath)
139{
140 return (osd_getPath (cstring_toCharsSafe (context_getLarchPath ()), file, returnPath));
141}
142
143extern filestatus
144osd_getPath (char *path, char *file, char **returnPath)
145{
146 char *fullPath;
147 char *dirPtr;
148 size_t dirLen;
149 char aPath[MAXPATHLEN];
150 filestatus rVal = OSD_FILENOTFOUND; /* assume file not found. */
151
152 fullPath = path;
153
154 if (fullPath == NULL ||
155# if defined(OS2) || defined(MSDOS) || defined(WIN32)
156 /* under OS/2 and MSDOS the includePath may be empty, if so, search
157 * the current directory. */
158 *fullPath == '\0' ||
159 (*file == CONNECTCHAR || (file[0] != '\0' && file[1] == ':')))
160# else
161 (*file == CONNECTCHAR))
162# endif
163 {
164 /* No path specified. Look for it in the current directory. */
165
166 strcpy (&aPath[0], file);
167
168 if (osd_fileExists (&aPath[0]))
169 {
170 rVal = OSD_FILEFOUND;
171 *returnPath = dmalloc (strlen (&aPath[0]) + 1);
172 strcpy (*returnPath, &aPath[0]);
173 }
174 }
175 else
176 {
177 /* Path specified. Loop through directories in path looking for the */
178 /* first occurrence of the file. */
179
180 while (nextdir (&fullPath, &dirPtr, &dirLen) &&
181 rVal == OSD_FILENOTFOUND)
182 {
183 if ((dirLen + strlen (file) + 2) <= MAXPATHLEN)
184 {
185 /* Cat directory and filename, and see if file exists. */
186 strncpy (&aPath[0], dirPtr, dirLen);
187 strcpy (&aPath[0] + dirLen, ""); /* Null terminate aPath. */
188 strcat (&aPath[0], CONNECTSTR);
189 strcat (&aPath[0], file);
190
191 if (osd_fileExists (&aPath[0]))
192 {
193 rVal = OSD_FILEFOUND;
194 *returnPath = (char *) dmalloc (strlen (&aPath[0]) + 1);
195 strcpy (*returnPath, &aPath[0]);
196 }
197 }
198 else
199 {
200 rVal = OSD_PATHTOOLONG;
201 }
202 }
203 }
204
205 return rVal;
206}
207
208extern filestatus
209osd_getExePath (char *path, char *file, char **returnPath)
210{
211 char *fullPath;
212 char *dirPtr;
213 size_t dirLen;
214 char aPath[MAXPATHLEN];
215 filestatus rVal = OSD_FILENOTFOUND; /* assume file not found. */
216
217 fullPath = osd_getEnvironmentVariable (path);
218
219 if (fullPath == NULL)
220 {
221 /* No path specified. Look for it in the current directory. */
222
223 strcpy (&aPath[0], file);
224
225 if (osd_fileExists (&aPath[0]))
226 {
227 rVal = OSD_FILEFOUND;
228 *returnPath = dmalloc (strlen (&aPath[0]) + 1);
229 strcpy (*returnPath, &aPath[0]);
230 }
231 }
232 else
233 {
234 /*
235 ** Path specified. Loop through directories in path looking
236 ** for the first occurrence of the file.
237 */
238
239 while (nextdir (&fullPath, &dirPtr, &dirLen) &&
240 rVal == OSD_FILENOTFOUND)
241 {
242 if ((dirLen + strlen (file) + 2) <= MAXPATHLEN)
243 {
244 /* Cat directory and filename, and see if file exists. */
245 strncpy (&aPath[0], dirPtr, dirLen);
246 strcpy (&aPath[0] + dirLen, ""); /* Null terminate aPath. */
247 strcat (&aPath[0], CONNECTSTR);
248 strcat (&aPath[0], file);
249
250 if (osd_executableFileExists (&aPath[0]))
251 {
252 rVal = OSD_FILEFOUND;
253 *returnPath = dmalloc (strlen (&aPath[0]) + 1);
254 strcpy (*returnPath, &aPath[0]);
255 }
256 }
257 else
258 {
259 rVal = OSD_PATHTOOLONG;
260 }
261 }
262 }
263
264 return rVal;
265}
266
267bool
268osd_fileExists (char *filespec)
269{
270# ifdef UNIX
271 struct stat buf;
272 return (stat (filespec, &buf) == 0);
273# else
274# if defined (WIN32) || defined (OS2)
275 FILE *test = fopen (filespec, "r");
276 if (test != NULL)
277 {
278 (void) fclose (test);
279 return TRUE;
280 }
281 else
282 {
283 return FALSE;
284 }
285# else
286 return FALSE;
287# endif
288# endif
289}
290
291bool
292osd_executableFileExists (/*@unused@*/ char *filespec)
293{
294# ifdef UNIX
295 struct stat buf;
296# if defined(__IBMC__) && defined(OS2)
297# define S_IFMT (unsigned short)0xFFFF
298# endif
299 if (stat (filespec, &buf) == 0)
300 {
301 /* mask by file type */
302 /*@-unrecog@*/ /* S_IFMT is not defined */
303 if ((buf.st_mode & S_IFMT) != S_IFDIR /*@=unrecog@*/) /* not a directory */
304 {
305 /* as long as it is an executable file */
306# if defined(__IBMC__) && defined(OS2)
307 int com_or_exe_pos = strlen( filespec) - 4;
308 return stricmp( &filespec[com_or_exe_pos], ".exe") == 0
309 || stricmp( &filespec[com_or_exe_pos], ".com") == 0
310 || stricmp( &filespec[com_or_exe_pos], ".bat") == 0
311 || stricmp( &filespec[com_or_exe_pos], ".cmd") == 0;
312# else
313 return (((buf.st_mode & S_IXUSR)
314# if !defined(MSDOS) && !defined(OS2)
315 | (buf.st_mode & S_IXGRP) |
316 (buf.st_mode & S_IXOTH)
317# endif
318 ) != 0);
319# endif
320 }
321 }
322
323# endif
324 return (FALSE);
325
326}
327
328/*
329**++
330** FUNCTIONAL DESCRIPTION:
331**
332** Find the next directory from a directory path.
333**
334** FORMAL PARAMETERS:
335**
336** char ** current_dir :
337** Points to the current position in the path string. The first time
338** you call this routine, this should point to the first character of
339** the path. On return, this will be updated to point to the
340** terminating \0 or : of the first directory found. You can then pass
341** it unchanged for subsequent calls; this routine will correctly skip
342** over the :.
343**
344** char ** dir :
345** On exit, this will point to the first character of the directory
346** that was found. This will be a pointer directly into the client's
347** path string.
348**
349** unsigned int * len :
350** On exit, this will contain the length of the directory that was
351** found, not counting any terminating \0 or :. If no directory was
352** found, this will be 0.
353**
354** RETURN VALUE:
355** TRUE if we found another directory.
356** FALSE otherwise.
357**
358** DESIGN:
359**
360** We return a pointer and length, rather than a string, because of a)
361** historical reasons; and b) this avoids having to allocate storage.
362**
363**
364**
365**--
366*/
367
368static bool
369nextdir (d_char *current_dir, d_char *dir, size_t *len)
370{
371 char *tchar;
372
373 if (**current_dir == '\0')
374 {
375 *len = 0;
376 return FALSE;
377 }
378
379 *dir = (**current_dir == SEPCHAR ? *current_dir + 1 : *current_dir);
380
381 /* Find next ':' or end of string */
382 for (tchar = *dir; *tchar != '\0' && *tchar != SEPCHAR; tchar++)
383 {
384 ;
385 }
386
387 *current_dir = tchar;
388 *len = size_fromInt (tchar - *dir);
389 return TRUE;
390}
391
392/*@observer@*/ /*@null@*/ char *osd_getEnvironmentVariable (char *var)
393{
394# ifdef UNIX
395 return getenv (var);
396# else
397# if defined(OS2) || defined(MSDOS)
398 return getenv (var);
399# else
400# if defined(WIN32)
401 return getenv (var);
402# else
403 return NULL;
404# endif
405# endif
406# endif
407}
408
409# ifndef NOLCL
410
411# ifdef WIN32
412extern /*@external@*/ int _flushall (void) /*@modifies fileSystem@*/ ;
413# endif
414
415# ifndef system
416extern /*@external@*/ int system (const char *) /*@modifies fileSystem@*/ ;
417# endif
418int osd_system (const char *cmd)
419{
420 int res;
421 /* system ("printenv"); */
422# ifdef WIN32
423 (void) _flushall ();
424# endif
425
426 res = system (cmd);
427 return res;
428}
429# endif
430
431# ifndef unlink
432/*@-redecl@*/
433extern /*@external@*/ int unlink (const char *) /*@modifies fileSystem@*/ ;
434/*@=redecl@*/
435# endif
436
437int osd_unlink (const char *fname)
438{
439 int res;
440
441 res = unlink (fname);
442
443 if (res != 0)
444 {
445 llcontbug (message ("Cannot remove temporary file: %s (%s)",
446 cstring_fromChars (fname),
447 cstring_fromChars (strerror (errno))));
448 }
449
450 return res;
451}
452
453# if defined (WIN32) || (defined(OS2) && defined(__IBMC__))
454# include <process.h>
455# elif defined OS2
456# include <unistd.h>
457# endif
458
459# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
460int
461# else
462int /* pid_t */
463# endif
464osd_getPid ()
465{
466# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
467 int pid = _getpid ();
468# else
2934b455 469 pid_t pid = getpid ();
616915dd 470# endif
471
472 return (int) pid;
473}
474
475cstring osd_fixDefine (char *x)
476{
477# ifdef UNIX
478 if (strchr (x, '\'') != NULL) {
479 /*
480 ** If there is a single quote, check for <ident>='<string>' and
481 ** produce <ident>=<string>
482 */
483
484 char *eqs = strchr (x, '=');
485
486 if (eqs != NULL) {
487 if (eqs[1] == '\'') {
488 char *endqu = strrchr (x, '\'');
489
490 if (endqu != NULL) {
491 if (*(endqu - 1) != '\\') {
492 if (*(endqu + 1) == '\0') {
493 cstring res;
494 cstring def;
495
496 *endqu = '\0';
497 def = cstring_fromChars (eqs + 2);
498 eqs[1] = '\0';
499 res = cstring_concat (cstring_fromChars (x), def);
500 return res;
501 }
502 }
503 }
504 }
505 }
506 }
507
508# endif
509
510 return cstring_fromCharsNew (x);
511}
512
513bool osd_fileIsReadable (char *f)
514{
515 FILE *fl = fopen (f, "r");
516
517 if (fl != (FILE *) 0)
518 {
519 check (fclose (fl) == 0);
520 return (TRUE);
521 }
522 else
523 {
524 return (FALSE);
525 }
526}
527
528bool osd_isConnectChar (char c)
529{
530 if (c == CONNECTCHAR)
531 {
532 return TRUE;
533 }
534
535# ifdef HASALTCONNECTCHAR
536 if (c == ALTCONNECTCHAR)
537 {
538 return TRUE;
539 }
540# endif
541
542 return FALSE;
543}
544
This page took 0.842332 seconds and 5 git commands to generate.