File: cxfileutils.c

package info (click to toggle)
cpl 6.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 18,764 kB
  • sloc: ansic: 111,368; sh: 14,549; makefile: 626
file content (153 lines) | stat: -rw-r--r-- 3,924 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* $Id: cxfileutils.c,v 1.7 2011/02/21 14:15:31 rpalsa Exp $
 *
 * This file is part of the ESO C Extension Library
 * Copyright (C) 2001-2011 European Southern Observatory
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
 * $Author: rpalsa $
 * $Date: 2011/02/21 14:15:31 $
 * $Revision: 1.7 $
 * $Name: cpl-6_1_1 $
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#  include <sys/types.h>
#endif

#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#  include <unistd.h>
#endif

#include "cxmemory.h"
#include "cxfileutils.h"


#ifdef STAT_MACROS_BROKEN
#undef S_ISDIR
#endif
#if !defined S_ISDIR && defined S_IFMT && defined S_IFDIR
#define S_ISDIR(mode) ((mode) & S_IFMT == S_IFDIR)
#endif


/**
 * @defgroup cxfileutils File Utilities
 *
 * The module provides a collection of useful file and file path related
 * utility functions.
 *
 * @par Synopsis:
 * @code
 *   #include <cxfileutils.h>
 * @endcode
 */

/**@{*/

/**
 * @brief
 *   Get the maximum length of a path relative to the given directory.
 *
 * @param path  Directory name.
 *
 * @return Maximum path length.
 *
 * The function returns the maximum length a relative path when @em path
 * is the current working directory. To get the maximum possible length
 * of an absolute path pass "/" for @em path, but see the note below.
 * The size is determined through the @b pathconf() function, or if this
 * is not available the maximum length is simply set to the ad hoc length
 * of 4095 characters.
 *
 * @note
 *   The maximum length of a pathname depends on the underlying filesystem.
 *   This means that the method to determine the maximum possible length
 *   of an absolute pathname might be incorrect if the root directory
 *   and the actual location of the file under consideration are located
 *   on different filesystems.
 */

cxlong
cx_path_max(const cxchar *path)
{

    cxlong sz = 4095;

    if (path == NULL) return sz;

#ifdef HAVE_PATHCONF
    sz = pathconf(path, _PC_PATH_MAX);
#endif

    return sz;

}


/**
 * @brief
 *   Allocate a buffer suitable for storing a relative pathname staring at
 *   a given directory.
 *
 * @param path  Directory name the relative path should start from.
 *
 * @return Allocated buffer of appropriate size, or @c NULL in case of an
 *   error.
 *
 * The function determines the maximum possible length of a relative
 * path name when @em path is the current working directory. A buffer
 * with the appropriate length for the relative pathname including the
 * trailing zero. The argument @em path must be the name of an existing,
 * or the function fails. The allocated buffer can be destroyed by calling
 * @b cx_free().
 *
 * IF the string "/" is used for @em path the returned buffer will have the
 * maximum length possible for an absolute path supported by the system
 * (but see the note for @b cx_path_max() for pitfalls).
 */

cxchar *
cx_path_alloc(const char *path)
{

#ifdef S_ISDIR
    struct stat sb;
#endif


    if (!path || path[0] == '\0')
        return NULL;

#ifdef S_ISDIR
    /*
     * Check that path is a directory
     */

    if (stat(path, &sb) != 0 || !S_ISDIR(sb.st_mode))
        return NULL;
#endif

    return cx_calloc(cx_path_max(path) + 1, sizeof(cxchar));

}
/**@}*/