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=libunixfile_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:
29
	rm -f ../../../../org.eclipse.core.filesystem.macosx/os/macosx/$(LIB_NAME_FULL)
30
	mv $(LIB_NAME_FULL) ../../../../org.eclipse.core.filesystem.macosx/os/macosx/
(-)natives/unix/unixfile.c (+244 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
	jsize len;
34
	jbyte *temp, *result;
35
36
	temp = (*env)->GetByteArrayElements(env, target, 0);
37
	len = (*env)->GetArrayLength(env, target);
38
	result = malloc((len + 1) * sizeof(jbyte));
39
	memcpy(result, temp, len * sizeof(jbyte));
40
	result[len] = '\0';
41
	(*env)->ReleaseByteArrayElements(env, target, temp, 0);
42
	return result;
43
}
44
45
/*
46
 * Fills StructStat object with data from struct stat.
47
 */
48
jint convertStatToObject(JNIEnv *env, struct stat info, jobject stat_object)
49
{
50
	jclass cls;
51
	jfieldID fid;
52
	jboolean readOnly;
53
54
	cls = (*env)->GetObjectClass(env, stat_object);
55
	if (cls == 0) return -1;
56
57
	fid = (*env)->GetFieldID(env, cls, "st_mode", "I");
58
	if (fid == 0) return -1;
59
	(*env)->SetIntField(env, stat_object, fid, info.st_mode);
60
61
	fid = (*env)->GetFieldID(env, cls, "st_size", "J");
62
	if (fid == 0) return -1;
63
	(*env)->SetLongField(env, stat_object, fid, info.st_size);
64
65
	fid = (*env)->GetFieldID(env, cls, "st_mtime", "J");
66
	if (fid == 0) return -1;
67
	(*env)->SetLongField(env, stat_object, fid, info.st_mtime);
68
69
#ifdef MACOSX
70
	fid = (*env)->GetFieldID(env, cls, "st_flags", "J");
71
	if (fid == 0) return -1;
72
	(*env)->SetLongField(env, stat_object, fid, info.st_flags);
73
#endif
74
75
	return 0;
76
}
77
78
/*
79
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
80
 * Method:    chmod
81
 * Signature: ([BI)I
82
 */
83
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_chmod
84
  (JNIEnv *env, jclass clazz, jbyteArray path, jint mode)
85
{
86
	int code;
87
	char *name;
88
89
	name = (char*) getByteArray(env, path);
90
	code = chmod(name, mode);
91
	free(name);
92
	return code;
93
}
94
95
/*
96
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
97
 * Method:    chflags
98
 * Signature: ([BI)I
99
 */
100
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_chflags
101
  (JNIEnv *env, jclass clazz, jbyteArray path, jint flags)
102
{
103
#ifdef MACOSX
104
	int code;
105
	char *name;
106
107
	name = (char*) getByteArray(env, path);
108
	code = chflags(name, flags);
109
	free(name);
110
	return code;
111
#else
112
	return -1;
113
#endif
114
}
115
116
/*
117
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
118
 * Method:    stat
119
 * Signature: ([BLorg/eclipse/core/internal/filesystem/local/unix/StructStat;)I
120
 */
121
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_stat
122
  (JNIEnv *env, jclass clazz, jbyteArray path, jobject buf)
123
{
124
	jint code;
125
	char *name;
126
	struct stat info;
127
128
	name = (char*) getByteArray(env, path);
129
	code = stat(name, &info);
130
	free(name);
131
	if (code != -1)
132
		return convertStatToObject(env, info, buf);
133
	else
134
		return code;
135
}
136
137
/*
138
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
139
 * Method:    lstat
140
 * Signature: ([BLorg/eclipse/core/internal/filesystem/local/unix/StructStat;)I
141
 */
142
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_lstat
143
  (JNIEnv *env, jclass clazz, jbyteArray path, jobject buf)
144
{
145
	jint code;
146
	char *name;
147
	struct stat info;
148
149
	name = (char*) getByteArray(env, path);
150
	code = lstat(name, &info);
151
	free(name);
152
	if (code != -1)
153
		return convertStatToObject(env, info, buf);
154
	else
155
		return code;
156
}
157
158
/*
159
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
160
 * Method:    readlink
161
 * Signature: ([B[BJ)J
162
 */
163
JNIEXPORT jlong JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_readlink
164
    (JNIEnv *env, jclass clazz, jbyteArray path, jbyteArray buf, jlong bufsiz) {
165
	jint code;
166
 	char *name;
167
 	ssize_t len;
168
	char temp[PATH_MAX+1];
169
	jstring linkTarget = NULL;
170
171
	name = getByteArray(env, path);
172
  	len = readlink((const char*)name, temp, PATH_MAX);
173
  	free(name);
174
	if (len > 0) {
175
		temp[len] = 0;
176
		(*env)->SetByteArrayRegion(env, buf, 0, len, temp);
177
	}
178
	else {
179
		temp[0] = 0;
180
		(*env)->SetByteArrayRegion(env, buf, 0, 0, temp);
181
	}
182
	return len;
183
}
184
185
/*
186
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
187
 * Method:    errno
188
 * Signature: ()I
189
 */
190
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_errno
191
  (JNIEnv *env, jclass clazz)
192
{
193
	return errno;
194
}
195
196
/*
197
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
198
 * Method:    libattr
199
 * Signature: ()I
200
 */
201
JNIEXPORT jint JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_libattr
202
  (JNIEnv *env, jclass clazz)
203
{
204
#ifdef MACOSX
205
	return UNICODE_SUPPORTED | CHFLAGS_SUPPORTED;
206
#else
207
	return 0;
208
#endif
209
}
210
211
/*
212
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
213
 * Method:    tounicode
214
 * Signature: ([C)[B
215
 */
216
JNIEXPORT jbyteArray JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_tounicode
217
  (JNIEnv *env, jclass clazz, jcharArray buf)
218
{
219
#ifdef MACOSX
220
	jchar *temp;
221
	jsize length;
222
	CFStringRef str_ref;
223
	CFIndex str_size;
224
	jbyte *unicode_bytes;
225
	jbyteArray ret;
226
227
	temp = (*env)->GetCharArrayElements(env, buf, 0);
228
	length = (*env)->GetArrayLength(env, buf);
229
	str_ref = CFStringCreateWithCharacters(kCFAllocatorDefault, temp, length);
230
	str_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
231
	unicode_bytes = (jbyte*) calloc(str_size, sizeof(jbyte));
232
	CFStringGetCString(str_ref, (char*) unicode_bytes, str_size, kCFStringEncodingUTF8);
233
	ret = (*env)->NewByteArray(env, str_size);
234
	if (ret == NULL)
235
		return NULL;
236
	(*env)->SetByteArrayRegion(env, ret, 0, str_size, unicode_bytes);
237
	CFRelease(str_ref);
238
	(*env)->ReleaseCharArrayElements(env, buf, temp, 0);
239
	free(unicode_bytes);
240
	return ret;
241
#else
242
	return NULL;
243
#endif
244
}
(-)natives/unix/unixfile.h (+105 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
/*
95
 * Class:     org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives
96
 * Method:    tounicode
97
 * Signature: ([C)[B
98
 */
99
JNIEXPORT jbyteArray JNICALL Java_org_eclipse_core_internal_filesystem_local_unix_UnixFileNatives_tounicode
100
  (JNIEnv *, jclass, jcharArray);
101
102
#ifdef __cplusplus
103
}
104
#endif
105
#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 / +33 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 13-18 Link Here
13
13
14
import org.eclipse.core.filesystem.EFS;
14
import org.eclipse.core.filesystem.EFS;
15
import org.eclipse.core.filesystem.IFileInfo;
15
import org.eclipse.core.filesystem.IFileInfo;
16
import org.eclipse.core.internal.filesystem.local.LocalFileNativesManager;
16
17
17
/**
18
/**
18
 * This class should be used by file system providers in their implementation
19
 * This class should be used by file system providers in their implementation
Lines 33-41 Link Here
33
	private static final int ATTRIBUTE_EXISTS = 1 << 16;
34
	private static final int ATTRIBUTE_EXISTS = 1 << 16;
34
35
35
	/**
36
	/**
36
	 * Bit field of file attributes
37
	 * Bit field of file attributes. Initialized to specify a writable resource.
37
	 */
38
	 */
38
	private int attributes = 0;
39
	private int attributes = EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OWNER_READ;
39
40
40
	/**
41
	/**
41
	 * The last modified time.
42
	 * The last modified time.
Lines 113-119 Link Here
113
	}
114
	}
114
115
115
	public boolean getAttribute(int attribute) {
116
	public boolean getAttribute(int attribute) {
116
		return isSet(attribute);
117
		if (attribute == EFS.ATTRIBUTE_READ_ONLY && isAttributeSuported(EFS.ATTRIBUTE_OWNER_WRITE))
118
			return (!isSet(EFS.ATTRIBUTE_OWNER_WRITE)) || isSet(EFS.ATTRIBUTE_IMMUTABLE);
119
		else if (attribute == EFS.ATTRIBUTE_EXECUTABLE && isAttributeSuported(EFS.ATTRIBUTE_OWNER_EXECUTE))
120
			return isSet(EFS.ATTRIBUTE_OWNER_EXECUTE);
121
		else
122
			return isSet(attribute);
117
	}
123
	}
118
124
119
	/* (non-Javadoc)
125
	/* (non-Javadoc)
Lines 165-174 Link Here
165
	 * @see org.eclipse.core.filesystem.IFileInfo#setAttribute(int, boolean)
171
	 * @see org.eclipse.core.filesystem.IFileInfo#setAttribute(int, boolean)
166
	 */
172
	 */
167
	public void setAttribute(int attribute, boolean value) {
173
	public void setAttribute(int attribute, boolean value) {
168
		if (value)
174
		if (attribute == EFS.ATTRIBUTE_READ_ONLY && isAttributeSuported(EFS.ATTRIBUTE_OWNER_WRITE)) {
169
			set(attribute);
175
			if (value) {
170
		else
176
				clear(EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OTHER_WRITE | EFS.ATTRIBUTE_GROUP_WRITE);
171
			clear(attribute);
177
				set(EFS.ATTRIBUTE_IMMUTABLE);
178
			} else {
179
				set(EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OWNER_READ);
180
				clear(EFS.ATTRIBUTE_IMMUTABLE);
181
			}
182
		} else if (attribute == EFS.ATTRIBUTE_EXECUTABLE && isAttributeSuported(EFS.ATTRIBUTE_OWNER_EXECUTE)) {
183
			if (value)
184
				set(EFS.ATTRIBUTE_OWNER_EXECUTE);
185
			else
186
				clear(EFS.ATTRIBUTE_OWNER_EXECUTE | EFS.ATTRIBUTE_GROUP_EXECUTE | EFS.ATTRIBUTE_OTHER_EXECUTE);
187
		} else {
188
			if (value)
189
				set(attribute);
190
			else
191
				clear(attribute);
192
		}
193
	}
194
195
	private static boolean isAttributeSuported(int value) {
196
		return (LocalFileNativesManager.getSupportedAttributes() & value) != 0;
172
	}
197
	}
173
198
174
	/**
199
	/**
(-)src/org/eclipse/core/internal/filesystem/Messages.java (-2 / +2 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2007 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 21-27 Link Here
21
	public static String copying;
21
	public static String copying;
22
	public static String couldnotDelete;
22
	public static String couldnotDelete;
23
	public static String couldnotDeleteReadOnly;
23
	public static String couldnotDeleteReadOnly;
24
	public static String couldNotLoadLibrary;
24
	public static String couldNotNativeLibrary;
25
	public static String couldNotMove;
25
	public static String couldNotMove;
26
	public static String couldNotRead;
26
	public static String couldNotRead;
27
	public static String couldNotWrite;
27
	public static String couldNotWrite;
(-)src/org/eclipse/core/internal/filesystem/local/Convert.java (-4 / +4 lines)
Lines 76-91 Link Here
76
	 * @return converted Java String
76
	 * @return converted Java String
77
	 * @since org.eclipse.core.filesystem 1.1
77
	 * @since org.eclipse.core.filesystem 1.1
78
	 */
78
	 */
79
	public static String fromPlatformBytes(byte[] source) {
79
	public static String fromPlatformBytes(byte[] source, int length) {
80
		if (defaultEncoding == null)
80
		if (defaultEncoding == null)
81
			return new String(source);
81
			return new String(source, 0, length);
82
		// try to use the default encoding
82
		// try to use the default encoding
83
		try {
83
		try {
84
			return new String(source, defaultEncoding);
84
			return new String(source, 0, length, defaultEncoding);
85
		} catch (UnsupportedEncodingException e) {
85
		} catch (UnsupportedEncodingException e) {
86
			// null the default encoding so we don't try it again
86
			// null the default encoding so we don't try it again
87
			defaultEncoding = null;
87
			defaultEncoding = null;
88
			return new String(source);
88
			return new String(source, 0, length);
89
		}
89
		}
90
	}
90
	}
91
91
(-)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 (+57 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
20
/**
21
 * Dispatches methods backed by native code to the appropriate platform specific 
22
 * implementation depending on a library provided by a fragment.
23
 */
24
public class LocalFileNativesManager {
25
26
	static {
27
		if (!(UnixFileNatives.isUsingNatives() || LocalFileNatives.isUsingNatives()))
28
			logMissingNativeLibrary();
29
	}
30
31
	private static void logMissingNativeLibrary() {
32
		Policy.log(IStatus.INFO, Messages.couldNotNativeLibrary, new Exception(Messages.couldNotNativeLibrary));
33
	}
34
35
	public static int getSupportedAttributes() {
36
		if (UnixFileNatives.isUsingNatives())
37
			return UnixFileNatives.getSupportedAttributes();
38
		return LocalFileNatives.attributes();
39
	}
40
41
	public static FileInfo fetchFileInfo(String fileName) {
42
		if (UnixFileNatives.isUsingNatives())
43
			return UnixFileNatives.fetchFileInfo(fileName);
44
		return LocalFileNatives.fetchFileInfo(fileName);
45
	}
46
47
	public static boolean putFileInfo(String fileName, IFileInfo info, int options) {
48
		if (UnixFileNatives.isUsingNatives())
49
			return UnixFileNatives.putFileInfo(fileName, info, options);
50
		return LocalFileNatives.putFileInfo(fileName, info, options);
51
	}
52
53
	public static boolean isUsingNatives() {
54
		return UnixFileNatives.isUsingNatives() || LocalFileNatives.isUsingNatives();
55
	}
56
57
}
(-)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 (+57 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
		if ((st_flags & (UnixFileFlags.UF_IMMUTABLE | UnixFileFlags.SF_IMMUTABLE)) != 0)
35
			info.setAttribute(EFS.ATTRIBUTE_IMMUTABLE, true);
36
		if ((st_mode & UnixFileFlags.S_IRUSR) == 0) // Set to true in FileInfo constructor
37
			info.setAttribute(EFS.ATTRIBUTE_OWNER_READ, false);
38
		if ((st_mode & UnixFileFlags.S_IWUSR) == 0) // Set to true in FileInfo constructor
39
			info.setAttribute(EFS.ATTRIBUTE_OWNER_WRITE, false);
40
		if ((st_mode & UnixFileFlags.S_IXUSR) != 0)
41
			info.setAttribute(EFS.ATTRIBUTE_OWNER_EXECUTE, true);
42
		if ((st_mode & UnixFileFlags.S_IRGRP) != 0)
43
			info.setAttribute(EFS.ATTRIBUTE_GROUP_READ, true);
44
		if ((st_mode & UnixFileFlags.S_IWGRP) != 0)
45
			info.setAttribute(EFS.ATTRIBUTE_GROUP_WRITE, true);
46
		if ((st_mode & UnixFileFlags.S_IXGRP) != 0)
47
			info.setAttribute(EFS.ATTRIBUTE_GROUP_EXECUTE, true);
48
		if ((st_mode & UnixFileFlags.S_IROTH) != 0)
49
			info.setAttribute(EFS.ATTRIBUTE_OTHER_READ, true);
50
		if ((st_mode & UnixFileFlags.S_IWOTH) != 0)
51
			info.setAttribute(EFS.ATTRIBUTE_OTHER_WRITE, true);
52
		if ((st_mode & UnixFileFlags.S_IXOTH) != 0)
53
			info.setAttribute(EFS.ATTRIBUTE_OTHER_EXECUTE, true);
54
		return info;
55
	}
56
57
}
(-)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 (+160 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 (isSupported(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 target[] = new byte[UnixFileFlags.PATH_MAX];
62
			long length = readlink(name, target, target.length);
63
			if (length > 0)
64
				info.setStringAttribute(EFS.ATTRIBUTE_LINK_TARGET, bytesToFileName(target, (int) length));
65
		}
66
		return info;
67
	}
68
69
	public static boolean putFileInfo(String fileName, IFileInfo info, int options) {
70
		int code = 0;
71
		byte[] name = fileNameToBytes(fileName);
72
		if (name == null)
73
			return false;
74
75
		// In case uchg flag is to be removed do it before calling chmod
76
		if (!info.getAttribute(EFS.ATTRIBUTE_IMMUTABLE) && isSupported(CHFLAGS_SUPPORTED)) {
77
			StructStat stat = new StructStat();
78
			if (stat(name, stat) == 0) {
79
				long flags = stat.st_flags;
80
				flags &= ~UnixFileFlags.SF_IMMUTABLE;
81
				flags &= ~UnixFileFlags.UF_IMMUTABLE;
82
				code |= chflags(name, (int) flags);
83
			}
84
		}
85
86
		// Change permissions
87
		int mode = 0;
88
		if (info.getAttribute(EFS.ATTRIBUTE_OWNER_READ))
89
			mode |= UnixFileFlags.S_IRUSR;
90
		if (info.getAttribute(EFS.ATTRIBUTE_OWNER_WRITE))
91
			mode |= UnixFileFlags.S_IWUSR;
92
		if (info.getAttribute(EFS.ATTRIBUTE_OWNER_EXECUTE))
93
			mode |= UnixFileFlags.S_IXUSR;
94
		if (info.getAttribute(EFS.ATTRIBUTE_GROUP_READ))
95
			mode |= UnixFileFlags.S_IRGRP;
96
		if (info.getAttribute(EFS.ATTRIBUTE_GROUP_WRITE))
97
			mode |= UnixFileFlags.S_IWGRP;
98
		if (info.getAttribute(EFS.ATTRIBUTE_GROUP_EXECUTE))
99
			mode |= UnixFileFlags.S_IXGRP;
100
		if (info.getAttribute(EFS.ATTRIBUTE_OTHER_READ))
101
			mode |= UnixFileFlags.S_IROTH;
102
		if (info.getAttribute(EFS.ATTRIBUTE_OTHER_WRITE))
103
			mode |= UnixFileFlags.S_IWOTH;
104
		if (info.getAttribute(EFS.ATTRIBUTE_OTHER_EXECUTE))
105
			mode |= UnixFileFlags.S_IXOTH;
106
		code |= chmod(name, mode);
107
108
		// In case uchg flag is to be added do it after calling chmod
109
		if (info.getAttribute(EFS.ATTRIBUTE_IMMUTABLE) && isSupported(CHFLAGS_SUPPORTED)) {
110
			StructStat stat = new StructStat();
111
			if (stat(name, stat) == 0) {
112
				long flags = stat.st_flags;
113
				flags |= UnixFileFlags.SF_IMMUTABLE;
114
				code |= chflags(name, UnixFileFlags.UF_IMMUTABLE);
115
			}
116
		}
117
		return code == 0;
118
	}
119
120
	public static boolean isUsingNatives() {
121
		return usingNatives;
122
	}
123
124
	public static int getErrno() {
125
		return errno();
126
	}
127
128
	private static byte[] fileNameToBytes(String fileName) {
129
		if (isSupported(UNICODE_SUPPORTED))
130
			return tounicode(fileName.toCharArray());
131
		return Convert.toPlatformBytes(fileName);
132
	}
133
134
	private static String bytesToFileName(byte[] buf, int length) {
135
		if (isSupported(UNICODE_SUPPORTED))
136
			return new String(buf, 0, length);
137
		return Convert.fromPlatformBytes(buf, length);
138
	}
139
140
	private static boolean isSupported(int attr) {
141
		return (libattr & attr) != 0;
142
	}
143
144
	private static final native int chmod(byte[] path, int mode);
145
146
	private static final native int chflags(byte[] path, int flags);
147
148
	private static final native int stat(byte[] path, StructStat buf);
149
150
	private static final native int lstat(byte[] path, StructStat buf);
151
152
	private static final native long readlink(byte[] path, byte[] buf, long bufsiz);
153
154
	private static final native int errno();
155
156
	private static final native int libattr();
157
158
	private static final native byte[] tounicode(char[] buf);
159
160
}
(-)src/org/eclipse/core/internal/filesystem/messages.properties (-2 / +2 lines)
Lines 1-5 Link Here
1
###############################################################################
1
###############################################################################
2
# Copyright (c) 2005, 2006 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 13-19 Link Here
13
copying = Copying: {0}.
13
copying = Copying: {0}.
14
couldnotDelete = Could not delete: {0}.
14
couldnotDelete = Could not delete: {0}.
15
couldnotDeleteReadOnly = Could not delete read-only file: {0}.
15
couldnotDeleteReadOnly = Could not delete read-only file: {0}.
16
couldNotLoadLibrary = Could not load library: {0}.  This library provides platform-specific optimizations for certain file system operations.  This library is not present on all platforms, so this may not be an error.  The resources plug-in will safely fall back to using java.io.File functionality.
16
couldNotNativeLibrary== Could not load library providing platform-specific optimizations for certain file system operations.  This library is not present on all platforms, so this may not be an error.  The resources plug-in will safely fall back to using java.io.File functionality.
17
couldNotMove = Could not move: {0}.
17
couldNotMove = Could not move: {0}.
18
couldNotRead = Could not read file: {0}.
18
couldNotRead = Could not read file: {0}.
19
couldNotWrite = Could not write file: {0}.
19
couldNotWrite = Could not write file: {0}.

Return to bug 297228