View | Details | Raw Unified | Return to bug 297228 | Differences between
and this patch

Collapse All | Expand All

(-)natives/macosx/Makefile (-18 lines)
Removed Link Here
1
#**********************************************************************
2
# Copyright (c) 2000, 2009 IBM Corporation and others.
3
# All rights reserved. This program and the accompanying materials 
4
# are made available under the terms of the Eclipse Public License v1.0
5
# which accompanies this distribution, and is available at
6
# http://www.eclipse.org/legal/epl-v10.html
7
#********************************************************************** 
8
#
9
# makefile for libcore on MacOS X
10
11
12
LIB_NAME = liblocalfile_1_0_0.jnilib
13
14
core:
15
	cc -I /System/Library/Frameworks/JavaVM.framework/Headers localfile.c -o $(LIB_NAME) -bundle -framework JavaVM -framework CoreServices -arch i386 -arch ppc -arch x86_64 -mmacosx-version-min=10.4
16
17
clean:
18
	rm *.jnilib
(-)natives/macosx/localfile.c (-425 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 * 	  Andre Weinand (OTI Labs)
11
 *******************************************************************************/
12
13
#include <jni.h>
14
#include <sys/types.h>
15
#include <sys/stat.h>
16
#include <unistd.h>
17
#include <utime.h>
18
#include <stdlib.h>
19
#include <string.h>
20
21
#include "../localfile.h"
22
23
#include <CoreServices/CoreServices.h>
24
25
#define USE_IMMUTABLE_FLAG 1
26
#define USE_ARCHIVE_FLAG 0
27
#define EFS_SYMLINK_SUPPORT 1
28
29
mode_t process_umask;
30
31
/*
32
 * Get a null-terminated byte array from a java char array.
33
 * The byte array contains UTF8 encoding.
34
 * The returned bytearray needs to be freed when not used
35
 * anymore. Use free(result) to do that.
36
 */
37
static jbyte* getUTF8ByteArray(JNIEnv *env, jcharArray target) {
38
39
	jchar *temp= (*env)->GetCharArrayElements(env, target, 0);
40
	jsize n= (*env)->GetArrayLength(env, target);
41
	
42
	CFStringRef sr= CFStringCreateWithCharacters(kCFAllocatorDefault, temp, n); 
43
	CFIndex argStringSize= CFStringGetMaximumSizeForEncoding(n, kCFStringEncodingUTF8) + 1;
44
	jbyte *result= (jbyte*) calloc(argStringSize, sizeof(jbyte));
45
	CFStringGetCString(sr, (char*) result, argStringSize, kCFStringEncodingUTF8);
46
	CFRelease(sr);
47
	
48
	(*env)->ReleaseCharArrayElements(env, target, temp, 0);
49
	
50
	return result;
51
}
52
53
/*
54
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
55
 * Method:    nativeAttributes
56
 * Signature: ()I
57
 */
58
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_nativeAttributes
59
  (JNIEnv *env, jclass clazz) {
60
#if defined(EFS_SYMLINK_SUPPORT)
61
    return ATTRIBUTE_READ_ONLY | ATTRIBUTE_EXECUTABLE | ATTRIBUTE_SYMLINK | ATTRIBUTE_LINK_TARGET;
62
#else
63
    return ATTRIBUTE_READ_ONLY | ATTRIBUTE_EXECUTABLE;
64
#endif
65
}
66
67
/*
68
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
69
 * Method:    internalIsUnicode
70
 * Signature: ()Z
71
 */
72
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalIsUnicode
73
  (JNIEnv *env, jclass clazz) {
74
	return JNI_TRUE;	// MacOS X supports Unicode-based file names in UTF-8 encoding
75
}
76
77
/*
78
 * Converts a stat structure to IFileInfo 
79
 */
80
jboolean convertStatToFileInfo (JNIEnv *env, struct stat info, jobject fileInfo) {
81
    jclass cls;
82
    jmethodID mid;
83
    jboolean readOnly;
84
85
    cls = (*env)->GetObjectClass(env, fileInfo);
86
    if (cls == 0) return JNI_FALSE;
87
88
	// select interesting information
89
	//exists
90
    mid = (*env)->GetMethodID(env, cls, "setExists", "(Z)V");
91
    if (mid == 0) return JNI_FALSE;
92
    (*env)->CallVoidMethod(env, fileInfo, mid, JNI_TRUE);
93
	
94
	// last modified
95
    mid = (*env)->GetMethodID(env, cls, "setLastModified", "(J)V");
96
    if (mid == 0) return JNI_FALSE;
97
    (*env)->CallVoidMethod(env, fileInfo, mid, ((jlong) info.st_mtime) * 1000); /* lower bits */
98
99
	// file length
100
    mid = (*env)->GetMethodID(env, cls, "setLength", "(J)V");
101
    if (mid == 0) return JNI_FALSE;
102
    (*env)->CallVoidMethod(env, fileInfo, mid, (jlong)info.st_size);
103
104
	// folder or file?
105
	if (S_ISDIR(info.st_mode)) {
106
	    mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
107
	    if (mid == 0) return JNI_FALSE;
108
	    (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_DIRECTORY, JNI_TRUE);
109
    }
110
111
	// read-only?
112
	readOnly = (info.st_mode & S_IWRITE) != S_IWRITE;
113
#if USE_IMMUTABLE_FLAG
114
	if (!readOnly && ((info.st_flags & (UF_IMMUTABLE | SF_IMMUTABLE)) != 0))
115
		readOnly = true;
116
#endif
117
	if (readOnly) {
118
	    mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
119
	    if (mid == 0) return JNI_FALSE;
120
	    (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_READ_ONLY, JNI_TRUE);
121
    }
122
123
#if USE_ARCHIVE_FLAG
124
	// archive?
125
	if ((info.st_flags & SF_ARCHIVED) == SF_ARCHIVED) {
126
	    mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
127
	    if (mid == 0) return JNI_FALSE;
128
	    (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_ARCHIVE, JNI_TRUE);
129
	}
130
#endif
131
132
	// executable?
133
    if ((info.st_mode & S_IXUSR) == S_IXUSR) {
134
	    mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
135
	    if (mid == 0) return JNI_FALSE;
136
	    (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_EXECUTABLE, JNI_TRUE);
137
    }
138
	return JNI_TRUE;
139
}
140
141
#if defined(EFS_SYMLINK_SUPPORT)
142
/*
143
 * Set symbolic link information in IFileInfo 
144
 */
145
jboolean setSymlinkInFileInfo (JNIEnv *env, jobject fileInfo, jstring linkTarget) {
146
    jclass cls;
147
    jmethodID mid;
148
149
    cls = (*env)->GetObjectClass(env, fileInfo);
150
    if (cls == 0) return JNI_FALSE;
151
152
    // set symlink attribute
153
    mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
154
    if (mid == 0) return JNI_FALSE;
155
    (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_SYMLINK, JNI_TRUE);
156
157
    // set link target
158
    mid = (*env)->GetMethodID(env, cls, "setStringAttribute", "(ILjava/lang/String;)V");
159
    if (mid == 0) return JNI_FALSE;
160
    (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_LINK_TARGET, linkTarget);
161
162
    return JNI_TRUE;
163
}
164
#endif
165
166
/*
167
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
168
 * Method:    internalGetFileInfo
169
 * Signature: ([CLorg/eclipse/core/filesystem/IFileInfo;)Z
170
 */
171
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalGetFileInfo
172
   (JNIEnv *env, jclass clazz, jbyteArray target, jobject fileInfo) {
173
	// shouldn't ever be called - there is only a Unicode-specific call on MacOS X
174
	return JNI_FALSE;
175
}
176
177
/*
178
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
179
 * Method:    internalGetFileInfoW
180
 * Signature: ([CLorg/eclipse/core/filesystem/IFileInfo;)Z
181
 */
182
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalGetFileInfoW
183
   (JNIEnv *env, jclass clazz, jcharArray target, jobject fileInfo) {
184
185
	struct stat info;
186
	jint code;
187
	jstring linkTarget = NULL;
188
189
	/* get stat */
190
	char *name= (char*) getUTF8ByteArray(env, target);
191
#if defined(EFS_SYMLINK_SUPPORT)
192
	//do an lstat first to see if it is a symbolic link
193
	code = lstat(name, &info);
194
	if (code == 0 && (S_ISLNK(info.st_mode))) {
195
		//symbolic link: read link target
196
		char buf[PATH_MAX+1];
197
		int len;
198
		len = readlink((const char*)name, buf, PATH_MAX);
199
		if (len>0) {
200
			buf[len]=0;
201
		} else {
202
			buf[0]=0;
203
		}
204
		// Mac OS encodes symlink target using UTF-8, ignoring platform default
205
		linkTarget = (*env)->NewStringUTF(env, buf);
206
		setSymlinkInFileInfo(env, fileInfo, linkTarget);
207
208
		//stat link target (will fail for broken links)
209
		code = stat((const char*)name, &info);
210
	}
211
#else
212
	code = stat(name, &info);
213
#endif
214
	free(name);
215
216
	/* test if an error occurred */
217
	if (code == -1)
218
	  return JNI_FALSE;
219
	return convertStatToFileInfo(env, info, fileInfo);
220
}
221
222
/*
223
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
224
 * Method:    internalCopyAttributes
225
 * Signature: ([B[BZ)Z
226
 */
227
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalCopyAttributes
228
   (JNIEnv *env, jclass clazz, jbyteArray source, jbyteArray destination, jboolean copyLastModified) {
229
	// shouldn't ever be called - there is only a Unicode-specific call on MacOS X
230
	return JNI_FALSE;   
231
}
232
233
/*
234
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
235
 * Method:    internalCopyAttributesW
236
 * Signature: ([C[CZ)Z
237
 */
238
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalCopyAttributesW
239
  (JNIEnv *env, jclass clazz, jcharArray source, jcharArray destination, jboolean copyLastModified) {
240
241
	struct stat info;
242
	struct utimbuf ut;
243
	int code;
244
	char *sourceFile= (char*) getUTF8ByteArray(env, source);
245
	char *destinationFile= (char*) getUTF8ByteArray(env, destination);
246
247
	code= stat(sourceFile, &info);
248
	if (code != 0) goto fail;
249
	code= chmod(destinationFile, info.st_mode);
250
	if (code != 0) goto fail;
251
252
	chflags(destinationFile, info.st_flags);	// ignore return code
253
	if (copyLastModified) {
254
		ut.actime= info.st_atime;
255
		ut.modtime= info.st_mtime;
256
		code= utime(destinationFile, &ut);
257
	}
258
259
fail:  	
260
	free(sourceFile);
261
	free(destinationFile);
262
	return code == 0;
263
}  
264
265
/*
266
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
267
 * Method:    internalSetFileInfo
268
 * Signature: ([BLorg/eclipse/core/filesystem/IFileInfo;)Z
269
 */
270
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalSetFileInfo
271
  (JNIEnv *env, jclass clazz, jcharArray target, jobject obj) {
272
	// shouldn't ever be called - there is only a Unicode-specific call on MacOS X
273
	return JNI_FALSE;   
274
275
}
276
277
mode_t getumask() {
278
	// in case something goes wrong just return 63 which is 0077 in octals
279
	mode_t mask = 63;
280
281
	int fds[2];
282
	if (pipe(fds) == -1) {
283
		return mask;
284
	}
285
286
	pid_t child_pid;
287
	child_pid = fork();
288
289
	if (child_pid == 0) {
290
		// child process
291
		ssize_t bytes_written = 0;
292
		close(fds[0]);
293
		mask = umask(0);
294
		while (1) {
295
			ssize_t written = write(fds[1], &mask + bytes_written, sizeof(mask) - bytes_written);
296
			if (written == -1) {
297
				if (errno != EINTR) {
298
					break;
299
				}
300
			} else {
301
				bytes_written += written;
302
				if (bytes_written == sizeof(mask)) {
303
					break;
304
				}
305
			}
306
		}
307
		close(fds[1]);
308
		_exit(0);
309
	} else if (child_pid != -1) {
310
		// parent process, fork succeded
311
		int stat_loc;
312
		ssize_t bytes_read = 0;
313
		mode_t buf;
314
		close(fds[1]);
315
		while (1) {
316
			ssize_t b_read = read(fds[0], &buf + bytes_read, sizeof(buf) - bytes_read);
317
			if (b_read == -1) {
318
				if (errno != EINTR) {
319
					break;
320
				}
321
			} else {
322
				if (b_read == 0) {
323
					break;
324
				}
325
				bytes_read += b_read;
326
				if (bytes_read == sizeof(mask)) {
327
					break;
328
				}
329
			}
330
		}
331
		if (bytes_read == sizeof(mask)) {
332
			mask = buf;
333
		}
334
		close(fds[0]);
335
		waitpid(child_pid, &stat_loc, 0);
336
	} else {
337
		// parent process, fork failed
338
		close(fds[0]);
339
		close(fds[1]);
340
	}
341
342
	return mask;
343
}
344
345
/*
346
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
347
 * Method:    internalSetFileInfoW
348
 * Signature: ([BLorg/eclipse/core/filesystem/IFileInfo;)Z
349
 */
350
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalSetFileInfoW
351
  (JNIEnv *env, jclass clazz, jcharArray target, jobject obj, jint options) {
352
    jint code = -1;
353
    jmethodID mid;
354
    jboolean executable, readOnly, archive;
355
    jclass cls;
356
357
    /* find out if we need to set the readonly bit */
358
    cls = (*env)->GetObjectClass(env, obj);
359
    mid = (*env)->GetMethodID(env, cls, "getAttribute", "(I)Z");
360
    if (mid == 0) goto fail;
361
    readOnly = (*env)->CallBooleanMethod(env, obj, mid, ATTRIBUTE_READ_ONLY);
362
363
    /* find out if we need to set the executable bit */
364
    executable = (*env)->CallBooleanMethod(env, obj, mid, ATTRIBUTE_EXECUTABLE);
365
366
    /* find out if we need to set the archive bit */
367
    archive = (*env)->CallBooleanMethod(env, obj, mid, ATTRIBUTE_ARCHIVE);
368
369
	/* get the current permissions */
370
	jbyte *name = getUTF8ByteArray(env, target);
371
    struct stat info;
372
	int result= stat((char*)name, &info);
373
	if (result != 0) goto fail;
374
375
	/* create the mask for the relevant bits */
376
	mode_t mask = info.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
377
	mode_t oldmask = mask;
378
	int flags = info.st_flags;
379
			
380
#if USE_ARCHIVE_FLAG
381
	if (archive)
382
		flags |= SF_ARCHIVED;						// set archive bit
383
	else
384
		flags &= ~SF_ARCHIVED;					// clear archive bit
385
#endif
386
387
	if (executable)
388
		mask |= S_IXUSR | ((S_IXGRP | S_IXOTH) & ~process_umask);
389
	else
390
		mask &= ~(S_IXUSR | S_IXGRP | S_IXOTH);	// clear all 'x'
391
		
392
	if (readOnly) {
393
		mask &= ~(S_IWUSR | S_IWGRP | S_IWOTH);	// clear all 'w'		
394
#if USE_IMMUTABLE_FLAG
395
		flags |= UF_IMMUTABLE;					// set immutable flag for usr
396
#endif
397
	} else {
398
		mask |= S_IRUSR | S_IWUSR | ((S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) & ~process_umask);
399
#if USE_IMMUTABLE_FLAG
400
		flags &= ~UF_IMMUTABLE;					// try to clear immutable flags for usr
401
#endif
402
	}	
403
404
	/* call chmod & chflags syscalls in correct order */
405
	if (readOnly) {
406
		if (mask != oldmask)
407
			result |= chmod((char*)name, mask);
408
		if (flags != info.st_flags)
409
			result |= chflags((char*)name, flags);
410
	} else {
411
		if (flags != info.st_flags)
412
			result |= chflags((char*)name, flags);
413
		if (mask != oldmask)
414
			result |= chmod((char*)name, mask);
415
	}	
416
417
fail:	
418
	free(name);
419
	return result == 0;
420
}
421
422
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
423
	process_umask = getumask();
424
	return JNI_VERSION_1_1;
425
}
(-)natives/unix/README.TXT (-2 / +2 lines)
Lines 1-3 Link Here
1
This directory contains the source code for Unix-based platforms,
1
This directory contains the source code for Unix-based platforms,
2
including Linux, HPUX, and Solaris.  These platforms all share the same
2
including AIX, HPUX, Linux, Mac OS X, and Solaris. These platforms
3
C source, but have different makefiles and includes
3
all share the same C source, but have different makefiles.
(-)natives/unix/localfile.c (-404 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *     Red Hat Incorporated - get/setResourceAttribute code
11
 * Martin Oberhuber (Wind River) - [170317] add symbolic link support to API
12
 * Corey Ashford (IBM) - [177400] fix threading issues on Linux-PPC
13
 * Martin Oberhuber (Wind River) - [183137] liblocalfile for solaris-sparc
14
 * Martin Oberhuber (Wind River) - [184534] get attributes from native lib
15
 *******************************************************************************/
16
#include <jni.h>
17
#include <sys/types.h>
18
#include <sys/stat.h>
19
#include <sys/wait.h>
20
#include <utime.h>
21
#include <stdlib.h>
22
#include <string.h>
23
#include <errno.h>
24
#include "../localfile.h"
25
#include <os_custom.h>
26
27
mode_t process_umask;
28
29
/*
30
 * Get a null-terminated byte array from a java byte array.
31
 * The returned bytearray needs to be freed when not used
32
 * anymore. Use free(result) to do that.
33
 */
34
jbyte* getByteArray(JNIEnv *env, jbyteArray target) {
35
	jsize n;
36
	jbyte *temp, *result;
37
	
38
	temp = (*env)->GetByteArrayElements(env, target, 0);
39
	n = (*env)->GetArrayLength(env, target);
40
	result = malloc((n+1) * sizeof(jbyte));
41
	memcpy(result, temp, n * sizeof(jbyte));
42
	result[n] = '\0';
43
	(*env)->ReleaseByteArrayElements(env, target, temp, 0);
44
	return result;
45
}
46
47
#if defined(EFS_SYMLINK_SUPPORT)
48
/*
49
 * Get a Java String from a java byte array, using the default charset.
50
 * Uses Convert.fromPlatformBytes([B).
51
 */
52
jstring getString(JNIEnv *env, jbyteArray source) {
53
	static jclass clsConvert = 0;
54
	jmethodID midFromPlatformBytes = 0;
55
    if (clsConvert == 0) {
56
    	clsConvert = (*env)->FindClass(env, "org/eclipse/core/internal/filesystem/local/Convert");
57
    	if (clsConvert == 0) return NULL;
58
        // Ensure class isn't garbage collected between calls to this function.
59
        clsConvert = (*env)->NewGlobalRef(env, clsConvert);
60
    }
61
   	midFromPlatformBytes = (*env)->GetStaticMethodID(env, clsConvert, "fromPlatformBytes", "([B)Ljava/lang/String;");
62
   	if (midFromPlatformBytes == 0) return NULL;
63
    return (*env)->CallStaticObjectMethod(env, clsConvert, midFromPlatformBytes, source);
64
}
65
#endif
66
67
/*
68
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
69
 * Method:    nativeAttributes
70
 * Signature: ()I
71
 */
72
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_nativeAttributes
73
  (JNIEnv *env, jclass clazz) {
74
#if defined(EFS_SYMLINK_SUPPORT)
75
    return ATTRIBUTE_READ_ONLY | ATTRIBUTE_EXECUTABLE | ATTRIBUTE_SYMLINK | ATTRIBUTE_LINK_TARGET;
76
#else
77
    return ATTRIBUTE_READ_ONLY | ATTRIBUTE_EXECUTABLE;
78
#endif
79
}
80
81
82
/*
83
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
84
 * Method:    internalIsUnicode
85
 * Signature: ()Z
86
 */
87
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalIsUnicode
88
  (JNIEnv *env, jclass clazz) {
89
  	// no specific support for Unicode-based file names on *nix
90
	return JNI_FALSE;
91
}
92
93
/*
94
 * Converts a stat structure to IFileInfo 
95
 */
96
jboolean convertStatToFileInfo (JNIEnv *env, struct stat info, jobject fileInfo) {
97
    jclass cls;
98
    jmethodID mid;
99
100
    cls = (*env)->GetObjectClass(env, fileInfo);
101
    if (cls == 0) return JNI_FALSE;
102
103
	// select interesting information
104
	//exists
105
    mid = (*env)->GetMethodID(env, cls, "setExists", "(Z)V");
106
    if (mid == 0) return JNI_FALSE;
107
    (*env)->CallVoidMethod(env, fileInfo, mid, JNI_TRUE);
108
	
109
	// last modified
110
    mid = (*env)->GetMethodID(env, cls, "setLastModified", "(J)V");
111
    if (mid == 0) return JNI_FALSE;
112
    (*env)->CallVoidMethod(env, fileInfo, mid, ((jlong) info.st_mtime) * 1000); /* lower bits */
113
114
	// file length
115
    mid = (*env)->GetMethodID(env, cls, "setLength", "(J)V");
116
    if (mid == 0) return JNI_FALSE;
117
    (*env)->CallVoidMethod(env, fileInfo, mid, (jlong)info.st_size);
118
119
	// folder or file?
120
	if (S_ISDIR(info.st_mode)) {
121
	    mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
122
	    if (mid == 0) return JNI_FALSE;
123
	    (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_DIRECTORY, JNI_TRUE);
124
    }
125
126
	// read-only?
127
	if ((info.st_mode & S_IWRITE) != S_IWRITE) {
128
	    mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
129
	    if (mid == 0) return JNI_FALSE;
130
	    (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_READ_ONLY, JNI_TRUE);
131
    }
132
133
	// executable?
134
    if ((info.st_mode & S_IXUSR) == S_IXUSR) {
135
	    mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
136
	    if (mid == 0) return JNI_FALSE;
137
	    (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_EXECUTABLE, JNI_TRUE);
138
    }
139
140
	return JNI_TRUE;
141
}
142
143
#if defined(EFS_SYMLINK_SUPPORT)
144
/*
145
 * Set symbolic link information in IFileInfo 
146
 */
147
jboolean setSymlinkInFileInfo (JNIEnv *env, jobject fileInfo, jstring linkTarget) {
148
    jclass cls;
149
    jmethodID mid;
150
151
    cls = (*env)->GetObjectClass(env, fileInfo);
152
    if (cls == 0) return JNI_FALSE;
153
154
    // set symlink attribute
155
    mid = (*env)->GetMethodID(env, cls, "setAttribute", "(IZ)V");
156
    if (mid == 0) return JNI_FALSE;
157
    (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_SYMLINK, JNI_TRUE);
158
    
159
    // set link target
160
    mid = (*env)->GetMethodID(env, cls, "setStringAttribute", "(ILjava/lang/String;)V");
161
    if (mid == 0) return JNI_FALSE;
162
    (*env)->CallVoidMethod(env, fileInfo, mid, ATTRIBUTE_LINK_TARGET, linkTarget);
163
}
164
#endif
165
166
/*
167
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
168
 * Method:    internalGetFileInfo
169
 * Signature: ([CLorg/eclipse/core/filesystem/IFileInfo;)Z
170
 */
171
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalGetFileInfo
172
   (JNIEnv *env, jclass clazz, jbyteArray target, jobject fileInfo) {
173
	struct stat info;
174
	jlong result;
175
	jint code;
176
	jbyte *name;
177
	jstring linkTarget = NULL;
178
179
	/* get stat */
180
	name = getByteArray(env, target);
181
#if defined(EFS_SYMLINK_SUPPORT)
182
	//do an lstat first to see if it is a symbolic link
183
	code = lstat((const char*)name, &info);
184
	if (code == 0 && S_ISLNK(info.st_mode)) {
185
		//symbolic link: read link target
186
		char buf[PATH_MAX+1];
187
		int len;
188
		jbyteArray barr;
189
		len = readlink((const char*)name, buf, PATH_MAX);
190
		if (len>0) {
191
			barr = (*env)->NewByteArray(env, len);
192
			(*env)->SetByteArrayRegion(env, barr, 0, len, buf);
193
		} else {
194
			barr = (*env)->NewByteArray(env, 0);
195
		}
196
		linkTarget = getString(env, barr);
197
		setSymlinkInFileInfo(env, fileInfo, linkTarget);
198
199
		//stat link target (will fail for broken links)
200
		code = stat((const char*)name, &info);
201
	}
202
#else
203
	code = stat((const char*)name, &info);
204
#endif
205
	free(name);
206
207
	/* test if an error occurred */
208
	if (code == -1)
209
	  return 0;
210
	return convertStatToFileInfo(env, info, fileInfo);
211
}
212
213
/*
214
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
215
 * Method:    internalGetFileInfoW
216
 * Signature: ([CLorg/eclipse/core/filesystem/IFileInfo;)Z
217
 */
218
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalGetFileInfoW
219
   (JNIEnv *env, jclass clazz, jcharArray target, jobject fileInfo) {
220
	// shouldn't ever be called - there is no Unicode-specific calls on *nix
221
	return JNI_FALSE;
222
}
223
224
/*
225
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
226
 * Method:    internalCopyAttributes
227
 * Signature: ([B[BZ)Z
228
 */
229
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalCopyAttributes
230
   (JNIEnv *env, jclass clazz, jbyteArray source, jbyteArray destination, jboolean copyLastModified) {
231
232
  struct stat info;
233
  struct utimbuf ut;
234
  jbyte *sourceFile, *destinationFile;
235
  jint code;
236
237
  sourceFile = getByteArray(env, source);
238
  destinationFile = getByteArray(env, destination);
239
240
  code = stat((const char*)sourceFile, &info);
241
  if (code == 0) {
242
    code = chmod((const char*)destinationFile, info.st_mode);
243
    if (code == 0 && copyLastModified) {
244
      ut.actime = info.st_atime;
245
      ut.modtime = info.st_mtime;
246
      code = utime((const char*)destinationFile, &ut);
247
    }
248
  }
249
250
  free(sourceFile);
251
  free(destinationFile);
252
  return code != -1;
253
}
254
255
/*
256
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
257
 * Method:    internalCopyAttributesW
258
 * Signature: ([C[CZ)Z
259
 */
260
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalCopyAttributesW
261
  (JNIEnv *env, jclass clazz, jcharArray source, jcharArray destination, jboolean copyLastModified) {
262
	// shouldn't ever be called - there is no Unicode-specific calls on *nix
263
	return JNI_FALSE;
264
}
265
266
mode_t getumask() {
267
	// in case something goes wrong just return 63 which is 0077 in octals
268
	mode_t mask = 63; 
269
270
	int fds[2];
271
	if (pipe(fds) == -1) {
272
		return mask;
273
	}
274
275
	pid_t child_pid;
276
	child_pid = fork();
277
278
	if (child_pid == 0) {
279
		// child process
280
		ssize_t bytes_written = 0;
281
		close(fds[0]);
282
		mask = umask(0);
283
		while (1) {
284
			ssize_t written = write(fds[1], &mask + bytes_written, sizeof(mask) - bytes_written);
285
			if (written == -1) {
286
				if (errno != EINTR) {
287
					break;
288
				}
289
			} else {
290
				bytes_written += written;
291
				if (bytes_written == sizeof(mask)) {
292
					break;
293
				}
294
			}
295
		}
296
		close(fds[1]);
297
		_exit(0);
298
	} else if (child_pid != -1) {
299
		// parent process, fork succeded
300
		int stat_loc;
301
		ssize_t bytes_read = 0;
302
		mode_t buf;
303
		close(fds[1]);
304
		while (1) {
305
			ssize_t b_read = read(fds[0], &buf + bytes_read, sizeof(buf) - bytes_read);
306
			if (b_read == -1) {
307
				if (errno != EINTR) {
308
					break;
309
				}
310
			} else {
311
				if (b_read == 0) {
312
					break;
313
				}
314
				bytes_read += b_read;
315
				if (bytes_read == sizeof(mask)) {
316
					break;
317
				}
318
			}
319
		}
320
		if (bytes_read == sizeof(mask)) {
321
			mask = buf;
322
		}
323
		close(fds[0]);
324
		waitpid(child_pid, &stat_loc, 0);
325
	} else {
326
		// parent process, fork failed
327
		close(fds[0]);
328
		close(fds[1]);
329
	}
330
331
	return mask;
332
}
333
334
/*
335
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
336
 * Method:    internalSetFileInfo
337
 * Signature: ([BLorg/eclipse/core/filesystem/IFileInfo;)Z
338
 */
339
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalSetFileInfo
340
  (JNIEnv *env, jclass clazz, jcharArray target, jobject obj) {
341
342
    mode_t mask;
343
    struct stat info;
344
    jbyte *name;
345
    jint code = -1;
346
    jmethodID mid;
347
    jboolean executable, readOnly;
348
    jclass cls;
349
350
    /* find out if we need to set the readonly bit */
351
    cls = (*env)->GetObjectClass(env, obj);
352
    mid = (*env)->GetMethodID(env, cls, "getAttribute", "(I)Z");
353
    if (mid == 0) goto fail;
354
    readOnly = (*env)->CallBooleanMethod(env, obj, mid, ATTRIBUTE_READ_ONLY);
355
356
    /* find out if we need to set the executable bit */
357
    executable = (*env)->CallBooleanMethod(env, obj, mid, ATTRIBUTE_EXECUTABLE);
358
359
    /* get the current permissions */
360
    name = getByteArray(env, target);
361
    code = stat((const char*)name, &info);
362
363
    /* create the mask */
364
    mask = S_IRUSR |
365
	       S_IWUSR |
366
	       S_IXUSR |
367
           S_IRGRP |
368
           S_IWGRP |
369
           S_IXGRP |
370
           S_IROTH |
371
           S_IWOTH |
372
           S_IXOTH;
373
    mask &= info.st_mode;
374
    if (executable)
375
	    mask |= S_IXUSR | ((S_IXGRP | S_IXOTH) & ~process_umask);
376
    else
377
	    mask &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
378
	if (readOnly)
379
	    mask &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
380
	else
381
	    mask |= S_IRUSR | S_IWUSR | ((S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) & ~process_umask);
382
    /* write the permissions */
383
    code = chmod((const char*)name, mask);
384
385
fail:
386
	if (name) free(name);
387
    return code != -1;
388
}
389
390
/*
391
 * Class:     org_eclipse_core_internal_filesystem_local_LocalFileNatives
392
 * Method:    internalSetFileInfoW
393
 * Signature: ([BLorg/eclipse/core/filesystem/IFileInfo;)Z
394
 */
395
JNIEXPORT jboolean JNICALL Java_org_eclipse_core_internal_filesystem_local_LocalFileNatives_internalSetFileInfoW
396
  (JNIEnv *env, jclass clazz, jcharArray target, jobject obj, jint options) {
397
	// shouldn't ever be called - there is no Unicode-specific calls on *nix
398
	return JNI_FALSE;
399
}
400
401
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
402
	process_umask = getumask();
403
	return JNI_VERSION_1_1;
404
}
(-)natives/unix/linux/Makefile (-15 / +20 lines)
Lines 1-32 Link Here
1
#**********************************************************************
1
#******************************************************************************
2
# Copyright (c) 2000, 2009 IBM Corporation and others.
2
# Copyright (c) 2010 IBM Corporation and others.
3
# All rights reserved. This program and the accompanying materials 
3
# All rights reserved. This program and the accompanying materials
4
# are made available under the terms of the Eclipse Public License v1.0
4
# are made available under the terms of the Eclipse Public License v1.0
5
# which accompanies this distribution, and is available at
5
# which accompanies this distribution, and is available at
6
# http://www.eclipse.org/legal/epl-v10.html
6
# http://www.eclipse.org/legal/epl-v10.html
7
#********************************************************************** 
8
#
7
#
9
# makefile for libcore.so
8
# Contributors:
9
#     IBM Corporation - initial API and implementation
10
#******************************************************************************/
11
#
12
# makefile for libunixfile_1_0_0.so
10
13
11
CORE.C = ../localfile.c
14
CORE.C = ../unixfile.c
12
CORE.O = localfile.o
15
CORE.O = unixfile.o
13
LIB_NAME = liblocalfile.so
16
LIB_NAME = libunixfile.so
14
LIB_NAME_FULL = liblocalfile_1_0_0.so
17
LIB_NAME_FULL = libunixfile_1_0_0.so
15
18
16
#Set this to be your OS type
19
#Set this to be your OS type
17
OS_TYPE = linux
20
OS_TYPE = linux
18
21
19
#Set this to be the location of your JRE
22
#Set this to be the location of your JRE
20
JAVA_HOME = ~/vm/sun142
23
JAVA_HOME = /usr/lib/jvm/java-1.5.0-ibm-1.5.0.9/
21
24
22
JDK_INCLUDE = -I ${JAVA_HOME}/include -I ${JAVA_HOME}/include/${OS_TYPE}
25
JDK_INCLUDE = -I ${JAVA_HOME}/include -I ${JAVA_HOME}/include/${OS_TYPE}
23
COMMON_INCLUDE = -I include
24
#OPT_FLAGS=-g
25
OPT_FLAGS=-O -s -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
26
OPT_FLAGS=-O -s -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
26
27
27
core :
28
core:
28
	gcc $(OPT_FLAGS) -fPIC -c $(JDK_INCLUDE) $(COMMON_INCLUDE) -o $(CORE.O) $(CORE.C)
29
	gcc $(OPT_FLAGS) -fPIC -c $(JDK_INCLUDE) -o $(CORE.O) $(CORE.C)
29
	gcc $(OPT_FLAGS) -shared -Wl,-soname,$(LIB_NAME) -o $(LIB_NAME_FULL) $(CORE.O) -lc
30
	gcc $(OPT_FLAGS) -shared -Wl,-soname,$(LIB_NAME) -o $(LIB_NAME_FULL) $(CORE.O) -lc
30
31
31
clean :
32
clean:
32
	rm -f $(CORE.O) $(LIB_NAME_FULL)
33
	rm -f $(CORE.O) $(LIB_NAME_FULL)
34
35
install: core
36
	rm -f ../../../../org.eclipse.core.filesystem.linux.x86/os/linux/x86/libunixfile_1_0_0.so
37
	mv libunixfile_1_0_0.so ../../../../org.eclipse.core.filesystem.linux.x86/os/linux/x86/
(-)natives/unix/linux/include/os_custom.h (-23 lines)
Removed Link Here
1
/***********************************************************************
2
* Copyright (c) 2005, 2007 IBM Corporation and others.
3
* All rights reserved. This program and the accompanying materials 
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
7
* 
8
* Contributors:
9
*     IBM Corporation - initial API and implementation
10
* Martin Oberhuber (Wind River) - [183137] liblocalfile for solaris-sparc
11
***********************************************************************/
12
13
/* Use this directive when introducing platform-specific code in localfile.c */
14
#ifndef LINUX
15
#define LINUX
16
#endif
17
18
/* Linux supports reading symbolic links */
19
#ifndef EFS_SYMLINK_SUPPORT
20
#define EFS_SYMLINK_SUPPORT
21
#endif
22
#include <limits.h>
23
#include <unistd.h>
(-)natives/unix/macosx/Makefile (+30 lines)
Added Link Here
1
#******************************************************************************
2
# Copyright (c) 2010 IBM Corporation and others.
3
# All rights reserved. This program and the accompanying materials
4
# are made available under the terms of the Eclipse Public License v1.0
5
# which accompanies this distribution, and is available at
6
# http://www.eclipse.org/legal/epl-v10.html
7
#
8
# Contributors:
9
#     IBM Corporation - initial API and implementation
10
#******************************************************************************/
11
#
12
# makefile for libunixfile_1_0_0.jnilib
13
14
CORE.C=../unixfile.c
15
LIB_NAME_FULL=liblocalfile_1_0_0.jnilib
16
17
JDK_INCLUDE=-I /System/Library/Frameworks/JavaVM.framework/Headers
18
FRAMEWORKS=-framework JavaVM -framework CoreServices
19
# define MACOSX to include Mac OS X specific code
20
CC_FLAGS=-arch i386 -arch ppc -arch x86_64 -mmacosx-version-min=10.4 -DMACOSX
21
22
core:
23
	cc $(JDK_INCLUDE) $(CORE.C) -o $(LIB_NAME_FULL) -bundle $(FRAMEWORKS) $(CC_FLAGS)
24
25
clean:
26
	rm -f $(LIB_NAME_FULL)
27
28
install: core
29
	rm -f ../../../../org.eclipse.core.filesystem.linux.x86/os/linux/x86/libunixfile_1_0_0.so
30
	mv libunixfile_1_0_0.so ../../../../org.eclipse.core.filesystem.linux.x86/os/linux/x86/
(-)natives/unix/unixfile.c (+228 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
12
#include <stdlib.h>
13
#include <string.h>
14
#include <sys/types.h>
15
#include <sys/stat.h>
16
#include <unistd.h>
17
#include <errno.h>
18
#include <limits.h>
19
#include <jni.h>
20
21
#if defined MACOSX
22
#include <CoreServices/CoreServices.h>
23
#endif
24
25
#include "unixfile.h"
26
27
/*
28
 * Get a null-terminated byte array from a java byte array. The returned bytearray
29
 * needs to be freed when not used anymore. Use free(result) to do that.
30
 */
31
jbyte* getByteArray(JNIEnv *env, jbyteArray target)
32
{
33
#ifdef MACOSX
34
	jbyte *temp, *result;
35
	jsize len, char_count;
36
	CFStringRef strref;
37
	CFIndex stringSize;
38
39
	temp = (*env)->GetByteArrayElements(env, target, 0);
40
	len = (*env)->GetArrayLength(env, target);
41
	char_count = len * sizeof(jbyte) / sizeof(jchar);
42
	strref = CFStringCreateWithCharacters(kCFAllocatorDefault, temp, char_count);
43
	string_size = CFStringGetMaximumSizeForEncoding(char_count, kCFStringEncodingUTF8) + 1;
44
45
	result = (jbyte*) calloc(string_size, sizeof(jbyte));
46
	CFStringGetCString(strref, (char*) result, string_size, kCFStringEncodingUTF8);
47
	CFRelease(strref);
48
	(*env)->ReleaseCharArrayElements(env, buf, temp, 0);
49
	return result; 
50
#else
51
	jsize len;
52
	jbyte *temp, *result;
53
54
	temp = (*env)->GetByteArrayElements(env, target, 0);
55
	len = (*env)->GetArrayLength(env, target);
56
	result = malloc((len + 1) * sizeof(jbyte));
57
	memcpy(result, temp, len * sizeof(jbyte));
58
	result[len] = '\0';
59
	(*env)->ReleaseByteArrayElements(env, target, temp, 0);
60
	return result;
61
#endif
62
}
63
64
/*
65
 * Fills StructStat object with data from struct stat.
66
 */
67
jint convertStatToObject(JNIEnv *env, struct stat info, jobject stat_object)
68
{
69
	jclass cls;
70
	jfieldID fid;
71
	jboolean readOnly;
72
73
	cls = (*env)->GetObjectClass(env, stat_object);
74
	if (cls == 0) return -1;
75
76
	fid = (*env)->GetFieldID(env, cls, "st_mode", "I");
77
	if (fid == 0) return -1;
78
	(*env)->SetIntField(env, stat_object, fid, info.st_mode);
79
80
	fid = (*env)->GetFieldID(env, cls, "st_size", "J");
81
	if (fid == 0) return -1;
82
	(*env)->SetLongField(env, stat_object, fid, info.st_size);
83
84
	fid = (*env)->GetFieldID(env, cls, "st_mtime", "J");
85
	if (fid == 0) return -1;
86
	(*env)->SetLongField(env, stat_object, fid, info.st_mtime);
87
88
#ifdef MACOSX
89
	fid = (*env)->GetFieldID(env, cls, "st_flags", "J");
90
	if (fid == 0) return -1;
91
	(*env)->SetLongField(env, stat_object, fid, info.st_flags);
92
#endif
93
94
	return 0;
95
}
96
97
/*
98
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
99
 * Method:    chmod
100
 * Signature: ([BI)I
101
 */
102
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_chmod
103
  (JNIEnv *env, jclass clazz, jbyteArray path, jint mode)
104
{
105
	int code;
106
	char *name;
107
108
	name = (char*) getByteArray(env, path);
109
	code = chmod(name, mode);
110
	free(name);
111
	return code;
112
}
113
114
/*
115
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
116
 * Method:    chflags
117
 * Signature: ([BI)I
118
 */
119
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_chflags
120
  (JNIEnv *env, jclass clazz, jbyteArray path, jint flags)
121
{
122
#if defined MACOSX
123
	int code;
124
	char *name;
125
126
	name = (char*) getByteArray(env, path);
127
	code = chflags(name, flags);
128
	free(name);
129
	return code;
130
#elseif
131
	return -1;
132
#endif
133
}
134
135
/*
136
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
137
 * Method:    stat
138
 * Signature: ([BLorg/eclipse/core/internal/filesystem/local/unix/StructStat;)I
139
 */
140
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_stat
141
  (JNIEnv *env, jclass clazz, jbyteArray path, jobject buf)
142
{
143
	jint code;
144
	char *name;
145
	struct stat info;
146
147
	name = (char*) getByteArray(env, path);
148
	code = stat(name, &info);
149
	free(name);
150
	if (code != -1)
151
		return convertStatToObject(env, info, buf);
152
	else
153
		return code;
154
}
155
156
/*
157
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
158
 * Method:    lstat
159
 * Signature: ([BLorg/eclipse/core/internal/filesystem/local/unix/StructStat;)I
160
 */
161
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_lstat
162
  (JNIEnv *env, jclass clazz, jbyteArray path, jobject buf)
163
{
164
	jint code;
165
	char *name;
166
	struct stat info;
167
168
	name = (char*) getByteArray(env, path);
169
	code = lstat(name, &info);
170
	free(name);
171
	if (code != -1)
172
		return convertStatToObject(env, info, buf);
173
	else
174
		return code;
175
}
176
177
/*
178
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
179
 * Method:    readlink
180
 * Signature: ([B[BJ)J
181
 */
182
JNIEXPORT jlong JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_readlink
183
    (JNIEnv *env, jclass clazz, jbyteArray path, jbyteArray buf, jlong bufsiz) {
184
	jint code;
185
 	char *name;
186
 	ssize_t len;
187
	char temp[PATH_MAX+1];
188
	jstring linkTarget = NULL;
189
190
	name = getByteArray(env, path);
191
  	len = readlink((const char*)name, temp, PATH_MAX);
192
  	free(name);
193
	if (len > 0) {
194
		temp[len] = 0;
195
		(*env)->SetByteArrayRegion(env, buf, 0, len, temp);
196
	}
197
	else {
198
		temp[0] = 0;
199
		(*env)->SetByteArrayRegion(env, buf, 0, 0, temp);
200
	}
201
	return len;
202
}
203
204
/*
205
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
206
 * Method:    errno
207
 * Signature: ()I
208
 */
209
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_errno
210
  (JNIEnv *env, jclass clazz)
211
{
212
	return errno;
213
}
214
215
/*
216
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
217
 * Method:    libattr
218
 * Signature: ()I
219
 */
220
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_libattr
221
  (JNIEnv *env, jclass clazz)
222
{
223
#ifdef MACOSX
224
	return UNICODE_SUPPORTED | CHFLAGS_SUPPORTED;
225
#else
226
	return 0;
227
#endif
228
}
(-)natives/unix/unixfile.h (+97 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
#include <jni.h>
12
13
#undef UNICODE_SUPPORTED
14
#define UNICODE_SUPPORTED 1L
15
#undef CHFLAGS_SUPPORTED
16
#define CHFLAGS_SUPPORTED 2L
17
18
/*
19
 * Get a null-terminated byte array from a java byte array. The returned bytearray
20
 * needs to be freed when not used anymore. Use free(result) to do that.
21
 */
22
jbyte* getByteArray(JNIEnv *, jbyteArray);
23
24
/*
25
 * Fills StructStat object with data from struct stat.
26
 */
27
jint convertStatToObject(JNIEnv *, struct stat, jobject);
28
29
/* DO NOT EDIT THIS FILE - it is machine generated */
30
31
/* Header for class org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives */
32
33
#ifndef _Included_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
34
#define _Included_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
35
#ifdef __cplusplus
36
extern "C" {
37
#endif
38
/*
39
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
40
 * Method:    chmod
41
 * Signature: ([BI)I
42
 */
43
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_chmod
44
  (JNIEnv *, jclass, jbyteArray, jint);
45
46
/*
47
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
48
 * Method:    chflags
49
 * Signature: ([BI)I
50
 */
51
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_chflags
52
  (JNIEnv *, jclass, jbyteArray, jint);
53
54
/*
55
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
56
 * Method:    stat
57
 * Signature: ([BLorg/eclipse/core/internal/filesystem/local/unix/StructStat;)I
58
 */
59
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_stat
60
  (JNIEnv *, jclass, jbyteArray, jobject);
61
62
/*
63
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
64
 * Method:    lstat
65
 * Signature: ([BLorg/eclipse/core/internal/filesystem/local/unix/StructStat;)I
66
 */
67
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_lstat
68
  (JNIEnv *, jclass, jbyteArray, jobject);
69
70
/*
71
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
72
 * Method:    readlink
73
 * Signature: ([B[BJ)J
74
 */
75
JNIEXPORT jlong JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_readlink
76
  (JNIEnv *, jclass, jbyteArray, jbyteArray, jlong);
77
78
/*
79
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
80
 * Method:    errno
81
 * Signature: ()I
82
 */
83
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_errno
84
  (JNIEnv *, jclass);
85
86
/*
87
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
88
 * Method:    libattr
89
 * Signature: ()I
90
 */
91
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_libattr
92
  (JNIEnv *, jclass);
93
94
#ifdef __cplusplus
95
}
96
#endif
97
#endif
(-)src/org/eclipse/core/filesystem/EFS.java (-1 / +121 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2008 IBM Corporation and others.
2
 * Copyright (c) 2005, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 114-119 Link Here
114
	public static final int ATTRIBUTE_READ_ONLY = 1 << 1;
114
	public static final int ATTRIBUTE_READ_ONLY = 1 << 1;
115
115
116
	/**
116
	/**
117
	 * Attribute constant (value 1 &lt;&lt;21) indicating that a
118
	 * file is marked with immutable flag.
119
	 * 
120
	 * @see IFileStore#fetchInfo()
121
	 * @see IFileStore#putInfo(IFileInfo, int, IProgressMonitor)
122
	 * @see IFileInfo#getAttribute(int)
123
	 * @see IFileInfo#setAttribute(int, boolean)
124
	 * @since org.eclipse.core.filesystem 1.3
125
	 */
126
	public static final int ATTRIBUTE_IMMUTABLE = 1 << 21;
127
128
	/**
129
	 * Attribute constant (value 1 &lt;&lt;22) indicating that a
130
	 * file's owner has a read permission.
131
	 * 
132
	 * @see IFileStore#fetchInfo()
133
	 * @see IFileStore#putInfo(IFileInfo, int, IProgressMonitor)
134
	 * @see IFileInfo#getAttribute(int)
135
	 * @see IFileInfo#setAttribute(int, boolean)
136
	 * @since org.eclipse.core.filesystem 1.3
137
	 */
138
	public static final int ATTRIBUTE_OWNER_READ = 1 << 22;
139
140
	/**
141
	 * Attribute constant (value 1 &lt;&lt;23) indicating that
142
	 * file's owner has a write permission.
143
	 * 
144
	 * @see IFileStore#fetchInfo()
145
	 * @see IFileStore#putInfo(IFileInfo, int, IProgressMonitor)
146
	 * @see IFileInfo#getAttribute(int)
147
	 * @see IFileInfo#setAttribute(int, boolean)
148
	 * @since org.eclipse.core.filesystem 1.3
149
	 */
150
	public static final int ATTRIBUTE_OWNER_WRITE = 1 << 23;
151
152
	/**
153
	 * Attribute constant (value 1 &lt;&lt;24) indicating that
154
	 * file's owner has an execute permission.
155
	 * 
156
	 * @see IFileStore#fetchInfo()
157
	 * @see IFileStore#putInfo(IFileInfo, int, IProgressMonitor)
158
	 * @see IFileInfo#getAttribute(int)
159
	 * @see IFileInfo#setAttribute(int, boolean)
160
	 * @since org.eclipse.core.filesystem 1.3
161
	 */
162
	public static final int ATTRIBUTE_OWNER_EXECUTE = 1 << 24;
163
164
	/**
165
	 * Attribute constant (value 1 &lt;&lt;25) indicating that
166
	 * users in file's group have a read permission.
167
	 * 
168
	 * @see IFileStore#fetchInfo()
169
	 * @see IFileStore#putInfo(IFileInfo, int, IProgressMonitor)
170
	 * @see IFileInfo#getAttribute(int)
171
	 * @see IFileInfo#setAttribute(int, boolean)
172
	 * @since org.eclipse.core.filesystem 1.3
173
	 */
174
	public static final int ATTRIBUTE_GROUP_READ = 1 << 25;
175
176
	/**
177
	 * Attribute constant (value 1 &lt;&lt;26) indicating that
178
	 * users in file's group have a write permission.
179
	 * 
180
	 * @see IFileStore#fetchInfo()
181
	 * @see IFileStore#putInfo(IFileInfo, int, IProgressMonitor)
182
	 * @see IFileInfo#getAttribute(int)
183
	 * @see IFileInfo#setAttribute(int, boolean)
184
	 * @since org.eclipse.core.filesystem 1.3
185
	 */
186
	public static final int ATTRIBUTE_GROUP_WRITE = 1 << 26;
187
188
	/**
189
	 * Attribute constant (value 1 &lt;&lt;27) indicating that
190
	 * users in file's group have an execute permission.
191
	 * 
192
	 * @see IFileStore#fetchInfo()
193
	 * @see IFileStore#putInfo(IFileInfo, int, IProgressMonitor)
194
	 * @see IFileInfo#getAttribute(int)
195
	 * @see IFileInfo#setAttribute(int, boolean)
196
	 * @since org.eclipse.core.filesystem 1.3
197
	 */
198
	public static final int ATTRIBUTE_GROUP_EXECUTE = 1 << 27;
199
200
	/**
201
	 * Attribute constant (value 1 &lt;&lt;28) indicating that
202
	 * other users have a read permission.
203
	 * 
204
	 * @see IFileStore#fetchInfo()
205
	 * @see IFileStore#putInfo(IFileInfo, int, IProgressMonitor)
206
	 * @see IFileInfo#getAttribute(int)
207
	 * @see IFileInfo#setAttribute(int, boolean)
208
	 * @since org.eclipse.core.filesystem 1.3
209
	 */
210
	public static final int ATTRIBUTE_OTHER_READ = 1 << 28;
211
212
	/**
213
	 * Attribute constant (value 1 &lt;&lt;29) indicating that
214
	 * other users have a write permission.
215
	 * 
216
	 * @see IFileStore#fetchInfo()
217
	 * @see IFileStore#putInfo(IFileInfo, int, IProgressMonitor)
218
	 * @see IFileInfo#getAttribute(int)
219
	 * @see IFileInfo#setAttribute(int, boolean)
220
	 * @since org.eclipse.core.filesystem 1.3
221
	 */
222
	public static final int ATTRIBUTE_OTHER_WRITE = 1 << 29;
223
224
	/**
225
	 * Attribute constant (value 1 &lt;&lt;30) indicating that
226
	 * other users have an execute permission.
227
	 * 
228
	 * @see IFileStore#fetchInfo()
229
	 * @see IFileStore#putInfo(IFileInfo, int, IProgressMonitor)
230
	 * @see IFileInfo#getAttribute(int)
231
	 * @see IFileInfo#setAttribute(int, boolean)
232
	 * @since org.eclipse.core.filesystem 1.3
233
	 */
234
	public static final int ATTRIBUTE_OTHER_EXECUTE = 1 << 30;
235
236
	/**
117
	 * Attribute constant (value 1 &lt;&lt;2) indicating that a
237
	 * Attribute constant (value 1 &lt;&lt;2) indicating that a
118
	 * file is a executable.
238
	 * file is a executable.
119
	 * 
239
	 * 
(-)src/org/eclipse/core/filesystem/provider/FileInfo.java (-8 / +28 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2008 IBM Corporation and others.
2
 * Copyright (c) 2005, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 33-41 Link Here
33
	private static final int ATTRIBUTE_EXISTS = 1 << 16;
33
	private static final int ATTRIBUTE_EXISTS = 1 << 16;
34
34
35
	/**
35
	/**
36
	 * Bit field of file attributes
36
	 * Bit field of file attributes. Initialized to specify a writable resource.
37
	 */
37
	 */
38
	private int attributes = 0;
38
	private int attributes = EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OWNER_READ;
39
39
40
	/**
40
	/**
41
	 * The last modified time.
41
	 * The last modified time.
Lines 113-119 Link Here
113
	}
113
	}
114
114
115
	public boolean getAttribute(int attribute) {
115
	public boolean getAttribute(int attribute) {
116
		return isSet(attribute);
116
		if (attribute == EFS.ATTRIBUTE_READ_ONLY)
117
			return (!isSet(EFS.ATTRIBUTE_OWNER_WRITE)) || isSet(EFS.ATTRIBUTE_IMMUTABLE);
118
		else if (attribute == EFS.ATTRIBUTE_EXECUTABLE)
119
			return isSet(EFS.ATTRIBUTE_OWNER_EXECUTE);
120
		else
121
			return isSet(attribute);
117
	}
122
	}
118
123
119
	/* (non-Javadoc)
124
	/* (non-Javadoc)
Lines 165-174 Link Here
165
	 * @see org.eclipse.core.filesystem.IFileInfo#setAttribute(int, boolean)
170
	 * @see org.eclipse.core.filesystem.IFileInfo#setAttribute(int, boolean)
166
	 */
171
	 */
167
	public void setAttribute(int attribute, boolean value) {
172
	public void setAttribute(int attribute, boolean value) {
168
		if (value)
173
		if (attribute == EFS.ATTRIBUTE_READ_ONLY) {
169
			set(attribute);
174
			if (value) {
170
		else
175
				clear(EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OTHER_WRITE | EFS.ATTRIBUTE_GROUP_WRITE);
171
			clear(attribute);
176
				set(EFS.ATTRIBUTE_IMMUTABLE);
177
			} else {
178
				set(EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OWNER_READ);
179
				clear(EFS.ATTRIBUTE_IMMUTABLE);
180
			}
181
		} else if (attribute == EFS.ATTRIBUTE_EXECUTABLE) {
182
			if (value)
183
				set(EFS.ATTRIBUTE_OWNER_EXECUTE);
184
			else
185
				clear(EFS.ATTRIBUTE_OWNER_EXECUTE | EFS.ATTRIBUTE_GROUP_EXECUTE | EFS.ATTRIBUTE_OTHER_EXECUTE);
186
		} else {
187
			if (value)
188
				set(attribute);
189
			else
190
				clear(attribute);
191
		}
172
	}
192
	}
173
193
174
	/**
194
	/**
(-)src/org/eclipse/core/internal/filesystem/local/LocalFile.java (-5 / +5 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
2
 * Copyright (c) 2005, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 140-147 Link Here
140
	}
140
	}
141
141
142
	public IFileInfo fetchInfo(int options, IProgressMonitor monitor) {
142
	public IFileInfo fetchInfo(int options, IProgressMonitor monitor) {
143
		if (LocalFileNatives.usingNatives()) {
143
		if (LocalFileNativesManager.isUsingNatives()) {
144
			FileInfo info = LocalFileNatives.fetchFileInfo(filePath);
144
			FileInfo info = LocalFileNativesManager.fetchFileInfo(filePath);
145
			//natives don't set the file name on all platforms
145
			//natives don't set the file name on all platforms
146
			if (info.getName().length() == 0) {
146
			if (info.getName().length() == 0) {
147
				String name = file.getName();
147
				String name = file.getName();
Lines 398-405 Link Here
398
	public void putInfo(IFileInfo info, int options, IProgressMonitor monitor) throws CoreException {
398
	public void putInfo(IFileInfo info, int options, IProgressMonitor monitor) throws CoreException {
399
		boolean success = true;
399
		boolean success = true;
400
		if ((options & EFS.SET_ATTRIBUTES) != 0) {
400
		if ((options & EFS.SET_ATTRIBUTES) != 0) {
401
			if (LocalFileNatives.usingNatives())
401
			if (LocalFileNativesManager.isUsingNatives())
402
				success &= LocalFileNatives.setFileInfo(filePath, info, options);
402
				success &= LocalFileNativesManager.putFileInfo(filePath, info, options);
403
		}
403
		}
404
		//native does not currently set last modified
404
		//native does not currently set last modified
405
		if ((options & EFS.SET_LAST_MODIFIED) != 0)
405
		if ((options & EFS.SET_LAST_MODIFIED) != 0)
(-)src/org/eclipse/core/internal/filesystem/local/LocalFileNatives.java (-13 / +3 lines)
Lines 14-23 Link Here
14
import org.eclipse.core.filesystem.IFileInfo;
14
import org.eclipse.core.filesystem.IFileInfo;
15
import org.eclipse.core.filesystem.IFileSystem;
15
import org.eclipse.core.filesystem.IFileSystem;
16
import org.eclipse.core.filesystem.provider.FileInfo;
16
import org.eclipse.core.filesystem.provider.FileInfo;
17
import org.eclipse.core.internal.filesystem.Messages;
18
import org.eclipse.core.internal.filesystem.Policy;
19
import org.eclipse.core.runtime.IStatus;
20
import org.eclipse.osgi.util.NLS;
21
17
22
abstract class LocalFileNatives {
18
abstract class LocalFileNatives {
23
	private static boolean hasNatives = false;
19
	private static boolean hasNatives = false;
Lines 33-39 Link Here
33
			hasNatives = true;
29
			hasNatives = true;
34
			isUnicode = internalIsUnicode();
30
			isUnicode = internalIsUnicode();
35
		} catch (UnsatisfiedLinkError e) {
31
		} catch (UnsatisfiedLinkError e) {
36
			logMissingNativeLibrary(e);
32
			// Nothing to do
37
		}
33
		}
38
	}
34
	}
39
35
Lines 143-160 Link Here
143
	 * be called if <code>isUnicode</code> is <code>false</code>). */
139
	 * be called if <code>isUnicode</code> is <code>false</code>). */
144
	private static final native boolean internalSetFileInfoW(char[] fileName, IFileInfo attribute, int options);
140
	private static final native boolean internalSetFileInfoW(char[] fileName, IFileInfo attribute, int options);
145
141
146
	private static void logMissingNativeLibrary(UnsatisfiedLinkError e) {
147
		String libName = System.mapLibraryName(LIBRARY_NAME);
148
		String message = NLS.bind(Messages.couldNotLoadLibrary, libName);
149
		Policy.log(IStatus.INFO, message, e);
150
	}
151
152
	/**
142
	/**
153
	 * @param fileName
143
	 * @param fileName
154
	 * @param info
144
	 * @param info
155
	 * @param options
145
	 * @param options
156
	 */
146
	 */
157
	public static boolean setFileInfo(String fileName, IFileInfo info, int options) {
147
	public static boolean putFileInfo(String fileName, IFileInfo info, int options) {
158
		if (isUnicode)
148
		if (isUnicode)
159
			return internalSetFileInfoW(Convert.toPlatformChars(fileName), info, options);
149
			return internalSetFileInfoW(Convert.toPlatformChars(fileName), info, options);
160
		return internalSetFileInfo(Convert.toPlatformBytes(fileName), info);
150
		return internalSetFileInfo(Convert.toPlatformBytes(fileName), info);
Lines 166-172 Link Here
166
	 * @return <code>true</code> if native library is available, and <code>false</code>
156
	 * @return <code>true</code> if native library is available, and <code>false</code>
167
	 * otherwise.
157
	 * otherwise.
168
	 */
158
	 */
169
	public static boolean usingNatives() {
159
	public static boolean isUsingNatives() {
170
		return hasNatives;
160
		return hasNatives;
171
	}
161
	}
172
}
162
}
(-)src/org/eclipse/core/internal/filesystem/local/LocalFileNativesManager.java (+59 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.core.internal.filesystem.local;
12
13
import org.eclipse.core.filesystem.IFileInfo;
14
import org.eclipse.core.filesystem.provider.FileInfo;
15
import org.eclipse.core.internal.filesystem.Messages;
16
import org.eclipse.core.internal.filesystem.Policy;
17
import org.eclipse.core.internal.filesystem.local.unix.UnixFileNatives;
18
import org.eclipse.core.runtime.IStatus;
19
import org.eclipse.osgi.util.NLS;
20
21
/**
22
 * Dispatches methods backed by native code to the appropriate platform specific 
23
 * implementation depending on a library provided by a fragment.
24
 */
25
public class LocalFileNativesManager {
26
27
	static {
28
		if (!(UnixFileNatives.isUsingNatives() || LocalFileNatives.isUsingNatives()))
29
			logMissingNativeLibrary();
30
	}
31
32
	private static void logMissingNativeLibrary() {
33
		String message = NLS.bind(Messages.couldNotLoadLibrary, ""); //$NON-NLS-1$
34
		Policy.log(IStatus.INFO, message, new Exception(message));
35
	}
36
37
	public static int getSupportedAttributes() {
38
		if (UnixFileNatives.isUsingNatives())
39
			return UnixFileNatives.getSupportedAttributes();
40
		return LocalFileNatives.attributes();
41
	}
42
43
	public static FileInfo fetchFileInfo(String fileName) {
44
		if (UnixFileNatives.isUsingNatives())
45
			return UnixFileNatives.fetchFileInfo(fileName);
46
		return LocalFileNatives.fetchFileInfo(fileName);
47
	}
48
49
	public static boolean putFileInfo(String fileName, IFileInfo info, int options) {
50
		if (UnixFileNatives.isUsingNatives())
51
			return UnixFileNatives.putFileInfo(fileName, info, options);
52
		return LocalFileNatives.putFileInfo(fileName, info, options);
53
	}
54
55
	public static boolean isUsingNatives() {
56
		return UnixFileNatives.isUsingNatives() || LocalFileNatives.isUsingNatives();
57
	}
58
59
}
(-)src/org/eclipse/core/internal/filesystem/local/LocalFileSystem.java (-3 / +3 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
2
 * Copyright (c) 2005, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 79-89 Link Here
79
		if (attributes != -1)
79
		if (attributes != -1)
80
			return attributes;
80
			return attributes;
81
		attributes = 0;
81
		attributes = 0;
82
		if (!LocalFileNatives.usingNatives())
82
		if (!LocalFileNativesManager.isUsingNatives())
83
			return attributes;
83
			return attributes;
84
84
85
		//try to query supported attributes from native lib impl
85
		//try to query supported attributes from native lib impl
86
		int nativeAttributes = LocalFileNatives.attributes();
86
		int nativeAttributes = LocalFileNativesManager.getSupportedAttributes();
87
		if (nativeAttributes >= 0) {
87
		if (nativeAttributes >= 0) {
88
			attributes = nativeAttributes;
88
			attributes = nativeAttributes;
89
			return attributes;
89
			return attributes;
(-)src/org/eclipse/core/internal/filesystem/local/unix/StructStat.java (+47 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.core.internal.filesystem.local.unix;
12
13
import org.eclipse.core.filesystem.EFS;
14
import org.eclipse.core.filesystem.provider.FileInfo;
15
16
/**
17
 * This class mirrors relevant fields of native struct stat
18
 * and is used by JNI calls wrapping OS file related functions.
19
 */
20
public class StructStat {
21
22
	public int st_mode;
23
	public long st_size;
24
	public long st_mtime;
25
	public long st_flags; // Filled only on Mac OS X
26
27
	public FileInfo toFileInfo() {
28
		FileInfo info = new FileInfo();
29
		info.setExists(true);
30
		info.setLength(st_size);
31
		info.setLastModified(st_mtime * 1000);
32
		if ((st_mode & UnixFileFlags.S_IFMT) == UnixFileFlags.S_IFDIR)
33
			info.setDirectory(true);
34
		info.setAttribute(EFS.ATTRIBUTE_IMMUTABLE, (st_flags & (UnixFileFlags.UF_IMMUTABLE | UnixFileFlags.SF_IMMUTABLE)) != 0);
35
		info.setAttribute(EFS.ATTRIBUTE_OWNER_READ, (st_mode & UnixFileFlags.S_IRUSR) != 0);
36
		info.setAttribute(EFS.ATTRIBUTE_OWNER_WRITE, (st_mode & UnixFileFlags.S_IWUSR) != 0);
37
		info.setAttribute(EFS.ATTRIBUTE_OWNER_EXECUTE, (st_mode & UnixFileFlags.S_IXUSR) != 0);
38
		info.setAttribute(EFS.ATTRIBUTE_GROUP_READ, (st_mode & UnixFileFlags.S_IRGRP) != 0);
39
		info.setAttribute(EFS.ATTRIBUTE_GROUP_WRITE, (st_mode & UnixFileFlags.S_IWGRP) != 0);
40
		info.setAttribute(EFS.ATTRIBUTE_GROUP_EXECUTE, (st_mode & UnixFileFlags.S_IXGRP) != 0);
41
		info.setAttribute(EFS.ATTRIBUTE_OTHER_READ, (st_mode & UnixFileFlags.S_IROTH) != 0);
42
		info.setAttribute(EFS.ATTRIBUTE_OTHER_WRITE, (st_mode & UnixFileFlags.S_IWOTH) != 0);
43
		info.setAttribute(EFS.ATTRIBUTE_OTHER_EXECUTE, (st_mode & UnixFileFlags.S_IXOTH) != 0);
44
		return info;
45
	}
46
47
}
(-)src/org/eclipse/core/internal/filesystem/local/unix/UnixFileFlags.java (+33 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.core.internal.filesystem.local.unix;
12
13
public class UnixFileFlags {
14
15
	public static final int PATH_MAX = 4096; //chars in a path name including nul  
16
17
	public static final int S_IFMT = 0170000; //bitmask for the file type bitfields
18
	public static final int S_IFLNK = 0120000; //symbolic link
19
	public static final int S_IFDIR = 0040000; //directory
20
	public static final int S_IRUSR = 00400; //owner has read permission
21
	public static final int S_IWUSR = 00200; //owner has write permission
22
	public static final int S_IXUSR = 00100; //owner has execute permission
23
	public static final int S_IRGRP = 00040; //group has read permission
24
	public static final int S_IWGRP = 00020; //group has write permission
25
	public static final int S_IXGRP = 00010; //group has execute permission
26
	public static final int S_IROTH = 00004; //others have read permission
27
	public static final int S_IWOTH = 00002; //others have write permission
28
	public static final int S_IXOTH = 00001; //others have execute permission
29
30
	public static final int UF_IMMUTABLE = 0x00000002; //the file may not be changed
31
	public static final int SF_IMMUTABLE = 0x00020000; //the file may not be changed
32
33
}
(-)src/org/eclipse/core/internal/filesystem/local/unix/UnixFileNatives.java (+132 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.core.internal.filesystem.local.unix;
12
13
import org.eclipse.core.filesystem.EFS;
14
import org.eclipse.core.filesystem.IFileInfo;
15
import org.eclipse.core.filesystem.provider.FileInfo;
16
import org.eclipse.core.internal.filesystem.local.Convert;
17
18
public abstract class UnixFileNatives {
19
20
	private static final String LIBRARY_NAME = "unixfile_1_0_0"; //$NON-NLS-1$
21
	private static final int UNICODE_SUPPORTED = 1 << 0;
22
	private static final int CHFLAGS_SUPPORTED = 1 << 1;
23
24
	private static final boolean usingNatives;
25
	private static final int libattr;
26
27
	static {
28
		boolean _usingNatives = false;
29
		int _libattr = 0;
30
		try {
31
			System.loadLibrary(LIBRARY_NAME);
32
			_usingNatives = true;
33
			_libattr = libattr();
34
		} catch (UnsatisfiedLinkError e) {
35
			// Nothing to do
36
		} finally {
37
			usingNatives = _usingNatives;
38
			libattr = _libattr;
39
		}
40
	}
41
42
	public static int getSupportedAttributes() {
43
		if (!usingNatives)
44
			return -1;
45
		int ret = EFS.ATTRIBUTE_READ_ONLY | EFS.ATTRIBUTE_EXECUTABLE | EFS.ATTRIBUTE_SYMLINK | EFS.ATTRIBUTE_LINK_TARGET | EFS.ATTRIBUTE_OWNER_READ | EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OWNER_EXECUTE | EFS.ATTRIBUTE_GROUP_READ | EFS.ATTRIBUTE_GROUP_WRITE | EFS.ATTRIBUTE_GROUP_EXECUTE | EFS.ATTRIBUTE_OTHER_READ | EFS.ATTRIBUTE_OTHER_WRITE | EFS.ATTRIBUTE_OTHER_EXECUTE;
46
		if (isSet(CHFLAGS_SUPPORTED))
47
			ret |= EFS.ATTRIBUTE_IMMUTABLE;
48
		return ret;
49
	}
50
51
	public static FileInfo fetchFileInfo(String fileName) {
52
		FileInfo info = null;
53
		byte[] name = fileNameToBytes(fileName);
54
		StructStat stat = new StructStat();
55
		if (stat(name, stat) == 0)
56
			info = stat.toFileInfo();
57
		else
58
			info = new FileInfo();
59
		if (lstat(name, stat) == 0 && (stat.st_mode & UnixFileFlags.S_IFMT) == UnixFileFlags.S_IFLNK) {
60
			info.setAttribute(EFS.ATTRIBUTE_SYMLINK, true);
61
			byte buf[] = new byte[UnixFileFlags.PATH_MAX];
62
			long length = readlink(name, buf, buf.length);
63
			if (length > 0)
64
				info.setStringAttribute(EFS.ATTRIBUTE_LINK_TARGET, new String(buf, 0, (int) length));
65
		}
66
		return info;
67
	}
68
69
	public static boolean putFileInfo(String fileName, IFileInfo info, int options) {
70
		int mode = 0;
71
		if (info.getAttribute(EFS.ATTRIBUTE_OWNER_READ))
72
			mode |= UnixFileFlags.S_IRUSR;
73
		if (info.getAttribute(EFS.ATTRIBUTE_OWNER_WRITE))
74
			mode |= UnixFileFlags.S_IWUSR;
75
		if (info.getAttribute(EFS.ATTRIBUTE_OWNER_EXECUTE))
76
			mode |= UnixFileFlags.S_IXUSR;
77
		if (info.getAttribute(EFS.ATTRIBUTE_GROUP_READ))
78
			mode |= UnixFileFlags.S_IRGRP;
79
		if (info.getAttribute(EFS.ATTRIBUTE_GROUP_WRITE))
80
			mode |= UnixFileFlags.S_IWGRP;
81
		if (info.getAttribute(EFS.ATTRIBUTE_GROUP_EXECUTE))
82
			mode |= UnixFileFlags.S_IXGRP;
83
		if (info.getAttribute(EFS.ATTRIBUTE_OTHER_READ))
84
			mode |= UnixFileFlags.S_IROTH;
85
		if (info.getAttribute(EFS.ATTRIBUTE_OTHER_WRITE))
86
			mode |= UnixFileFlags.S_IWOTH;
87
		if (info.getAttribute(EFS.ATTRIBUTE_OTHER_EXECUTE))
88
			mode |= UnixFileFlags.S_IXOTH;
89
		byte[] name = fileNameToBytes(fileName);
90
		int code = chmod(name, mode);
91
92
		if (info.getAttribute(EFS.ATTRIBUTE_IMMUTABLE) & isSet(CHFLAGS_SUPPORTED))
93
			code |= chflags(name, UnixFileFlags.UF_IMMUTABLE);
94
		return code == 0;
95
	}
96
97
	public static boolean isUsingNatives() {
98
		return usingNatives;
99
	}
100
101
	public static int getErrno() {
102
		return errno();
103
	}
104
105
	private static byte[] fileNameToBytes(String fileName) {
106
		byte[] name = null;
107
		if (isSet(UNICODE_SUPPORTED))
108
			name = fileName.getBytes();
109
		else
110
			name = Convert.toPlatformBytes(fileName);
111
		return name;
112
	}
113
114
	private static boolean isSet(int attr) {
115
		return (libattr & attr) != 0;
116
	}
117
118
	private static final native int chmod(byte[] path, int mode);
119
120
	private static final native int chflags(byte[] path, int flags);
121
122
	private static final native int stat(byte[] path, StructStat buf);
123
124
	private static final native int lstat(byte[] path, StructStat buf);
125
126
	private static final native long readlink(byte[] path, byte[] buf, long bufsiz);
127
128
	private static final native int errno();
129
130
	private static final native int libattr();
131
132
}

Return to bug 297228