File: hssystemfileio-unix.c

package info (click to toggle)
haskell-system-fileio 0.3.11-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 156 kB
  • ctags: 15
  • sloc: haskell: 1,285; ansic: 147; sh: 51; makefile: 2
file content (130 lines) | stat: -rw-r--r-- 2,129 bytes parent folder | download | duplicates (4)
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
#include "hssystemfileio-unix.h"

/* Enable POSIX-compliant readdir_r on Solaris */
#define _POSIX_PTHREAD_SEMANTICS

/* Enable dirfd() */
#define _BSD_SOURCE

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

struct dirent *
hssystemfileio_alloc_dirent(void *void_dir)
{
	DIR *dir = (DIR *)void_dir;
	long name_max;
	size_t name_end;
	
	name_max = fpathconf(dirfd(dir), _PC_NAME_MAX);
	if (name_max == -1)
	{
#if defined(NAME_MAX) && NAME_MAX > 255
		name_max = NAME_MAX;
#else
		name_max = 4096;
#endif
	}
	
	name_end = (size_t)offsetof(struct dirent, d_name) + name_max + 1;
	if (name_end > sizeof(struct dirent))
	{
		return malloc(name_end);
	}
	
	return malloc(sizeof(struct dirent));
}

void
hssystemfileio_free_dirent(struct dirent *p)
{
	free(p);
}

int
hssystemfileio_readdir(void *void_dir, struct dirent *dirent)
{
	struct dirent *dirent_result;
	DIR *dir = (DIR *)void_dir;
	while (1)
	{
		int rc = readdir_r(dir, dirent, &dirent_result);
		if (rc != 0)
		{ return -1; }
		
		if (dirent_result == NULL)
		{ return 1; }
		
		return 0;
	}
}

char *
hssystemfileio_dirent_name(struct dirent *dirent)
{
	return dirent->d_name;
}

char *
hssystemfileio_getcwd(void)
{
#ifdef PATH_MAX
	int bufsize = PATH_MAX;
#else
	int bufsize = 4096;
#endif
	char *buf = malloc(bufsize);
	while (1)
	{
		char *ret = getcwd(buf, bufsize);
		if (ret != NULL)
		{ return ret; }
		
		free(buf);
		if (errno == ERANGE)
		{
			bufsize *= 2;
			buf = malloc(bufsize);
			continue;
		}
		return NULL;
	}
}

int
hssystemfileio_isrealdir(const char *path)
{
	struct stat st;
	int rc = lstat(path, &st);
	if (rc == -1)
	{ return rc; }
	
	if (S_ISDIR(st.st_mode))
	{ return 1; }
	
	return 0;
}

int
hssystemfileio_copy_permissions(const char *old_path, const char *new_path)
{
	struct stat st;
	int rc = stat(old_path, &st);
	if (rc == -1)
	{ return rc; }
	
	return chmod(new_path, st.st_mode);
}

int
hssystemfileio_open_nonblocking(const char *path, int int_mode)
{
	mode_t mode = int_mode | O_NONBLOCK;
	return open(path, mode);
}