[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Help-smalltalk] [PATCH] add File>>#owner:/#group:/#owner:group:
From: |
Paolo Bonzini |
Subject: |
[Help-smalltalk] [PATCH] add File>>#owner:/#group:/#owner:group: |
Date: |
Wed, 07 Jan 2009 12:27:30 +0100 |
User-agent: |
Thunderbird 2.0.0.18 (Macintosh/20081105) |
... and also adds some more methods to RecursiveFileWrapper so that you
can change the owner/group/mode/times of an entire directory with
something like
(File name: 'pp') all group: 'wheel'
HTH,
Paolo
diff --git a/configure.ac b/configure.ac
index 0c5a4dc..d3d2979 100644
--- a/configure.ac
+++ b/configure.ac
@@ -299,7 +299,8 @@ AC_REPLACE_FUNCS(putenv strdup strerror strsignal mkstemp
getpagesize \
AC_CHECK_FUNCS_ONCE(gethostname memcpy memmove sighold uname usleep lstat \
grantpt popen getrusage gettimeofday fork strchr utimes utime readlink \
sigsetmask alarm select mprotect madvise waitpid \
- setsid spawnl nanosleep pread pwrite _NSGetExecutablePath)
+ setsid spawnl nanosleep pread pwrite _NSGetExecutablePath \
+ chown getgrnam getpwnam endgrent endpwent setgroupent setpassent)
GST_FUNC_LRINT
GST_FUNC_STRTOUL
diff --git a/kernel/File.st b/kernel/File.st
index 705fa8a..e74dfe2 100644
--- a/kernel/File.st
+++ b/kernel/File.st
@@ -85,6 +85,18 @@ FilePath subclass: File [
^true
]
+ File class >> setTimeFor: fileName atime: atimeSec mtime: mtimeSec [
+ <category: 'private-C call-outs'>
+ <cCall: 'utime' returning: #int args: #(#string #int #int)>
+
+ ]
+
+ File class >> setOwnerFor: fileName owner: ownerString group: groupString [
+ <category: 'private-C call-outs'>
+ <cCall: 'chown' returning: #int args: #(#string #string #string)>
+
+ ]
+
File class >> path: aString [
"Answer a new file with the given path. The path is not validated until
some of the fields of the newly created objects are accessed"
@@ -471,6 +483,17 @@ FilePath subclass: File [
^File isAbsolute: self asString
]
+ owner: ownerString group: groupString [
+ "Set the receiver's owner and group to be ownerString and groupString."
+
+ <category: 'file operations'>
+ self class
+ setOwnerFor: self asString
+ owner: ownerString
+ group: groupString.
+ File checkError
+ ]
+
lastAccessTime: accessDateTime lastModifyTime: modifyDateTime [
"Set the receiver's timestamps to be accessDateTime and modifyDateTime."
diff --git a/kernel/FilePath.st b/kernel/FilePath.st
index c2dc833..aec3b92 100644
--- a/kernel/FilePath.st
+++ b/kernel/FilePath.st
@@ -317,6 +317,28 @@ size and timestamps.'>
self subclassResponsibility
]
+ owner: ownerString group: groupString [
+ "Set the owner and group of the file identified by the receiver to be
+ aString."
+
+ <category: 'accessing'>
+ self subclassResponsibility
+ ]
+
+ group: aString [
+ "Set the group of the file identified by the receiver to be aString."
+
+ <category: 'accessing'>
+ self owner: nil group: aString
+ ]
+
+ owner: aString [
+ "Set the owner of the file identified by the receiver to be aString."
+
+ <category: 'accessing'>
+ self owner: aString group: nil
+ ]
+
lastAccessTime: aDateTime [
"Update the last access time of the file corresponding to the receiver,
to be aDateTime."
diff --git a/kernel/VFS.st b/kernel/VFS.st
index 1168355..9a01b02 100644
--- a/kernel/VFS.st
+++ b/kernel/VFS.st
@@ -192,6 +192,13 @@ virtual files that refer to a real file on disk.'>
^self file isSymbolicLink
]
+ owner: ownerString group: groupString [
+ "Set the receiver's owner and group to be ownerString and groupString."
+
+ <category: 'accessing'>
+ self file owner: ownerString group: groupString
+ ]
+
lastAccessTime: accessDateTime lastModifyTime: modifyDateTime [
"Update the timestamps of the file corresponding to the receiver, to be
accessDateTime and modifyDateTime."
@@ -406,6 +413,57 @@ VFS.FileWrapper subclass: RecursiveFileWrapper [
<category: 'testing'>
^self file isFileSystemPath
]
+
+ lastAccessTime: accessDateTime lastModifyTime: modifyDateTime [
+ "Update the timestamps of all files in the tree to be
+ accessDateTime and modifyDateTime."
+
+ <category: 'accessing'>
+ self isDirectory ifFalse: [
+ ^super lastAccessTime: accessDateTime lastModifyTime:
modifyDateTime ].
+ self do: [ :each |
+ each file lastAccessTime: accessDateTime lastModifyTime:
modifyDateTime ]
+ ]
+
+ owner: ownerString group: groupString [
+ "Set the owner and group for all files and directories in the tree."
+
+ <category: 'accessing'>
+ self isDirectory ifFalse: [
+ ^super owner: ownerString group: groupString ].
+ "These special calls cache the uid and gid to avoid repeated lookups."
+ [
+ File setOwnerFor: nil owner: ownerString group: groupString.
+ self do: [ :each | each file owner: ownerString group: groupString
]
+ ] ensure: [ File setOwnerFor: nil owner: nil group: nil ]
+ ]
+
+ mode: anInteger [
+ "Set the mode to be anInteger for all files in the tree. Directory
+ modes are left unchanged."
+
+ <category: 'accessing'>
+ self isDirectory ifFalse: [ ^super mode: anInteger ].
+
+ self do: [ :each |
+ each isDirectory ifFalse: [ each file mode: anInteger ] ]
+ ]
+
+ fileMode: fMode directoryMode: dMode [
+ "Set the mode to be fMode for all files in the tree, and dMode for
+ all directories in the tree."
+
+ <category: 'accessing'>
+ self isDirectory ifFalse: [ ^super mode: fMode ].
+
+ super mode: dMode.
+ self isDirectory ifTrue: [
+ self do: [ :each |
+ each file
+ mode: (each isDirectory
+ ifTrue: [ dMode ]
+ ifFalse: [ fMode ]) ] ]
+ ]
]
]
diff --git a/libgst/cint.c b/libgst/cint.c
index f5e8451..cc0e947 100644
--- a/libgst/cint.c
+++ b/libgst/cint.c
@@ -59,6 +59,13 @@
#include "ffi.h"
#include <ltdl.h>
+#ifdef HAVE_GETGRNAM
+#include <grp.h>
+#endif
+#ifdef HAVE_GETPWNAM
+#include <pwd.h>
+#endif
+
typedef struct cparam
{
union {
@@ -186,6 +193,7 @@ static int my_lstat (const char *name,
OOP out);
static int my_putenv (const char *str);
static int my_chdir (const char *str);
+static int my_chown (const char *file, const char *owner, const char *group);
static int my_symlink (const char* oldpath, const char* newpath);
static char *my_mkdtemp (char* template);
static int my_mkdir (const char* name, int mode);
@@ -543,6 +551,7 @@ _gst_init_cfuncs (void)
_gst_define_cfunc ("lstat_obj", my_lstat);
_gst_define_cfunc ("utime", _gst_set_file_access_times);
_gst_define_cfunc ("chmod", chmod);
+ _gst_define_cfunc ("chown", my_chown);
_gst_define_cfunc ("opendir", my_opendir);
_gst_define_cfunc ("closedir", closedir);
@@ -1382,6 +1391,104 @@ _gst_set_errno(int errnum)
}
+int
+my_chown (const char *file, const char *user, const char *group)
+{
+#if defined HAVE_CHOWN && defined HAVE_GETGRNAM && defined HAVE_GETPWNAM
+ static char *save_user, *save_group;
+ static uid_t save_uid;
+ static gid_t save_gid;
+ static int recursive_depth;
+
+ uid_t uid, gid;
+ if (!file && !user && !group)
+ {
+ recursive_depth--;
+ if (recursive_depth == 0)
+ {
+#if defined HAVE_SETGROUPENT && defined HAVE_ENDGRENT
+ endgrent ();
+#endif
+#if defined HAVE_SETPASSENT && defined HAVE_ENDPWENT
+ endpwent ();
+#endif
+ }
+
+ free (save_user);
+ free (save_group);
+ save_user = save_group = NULL;
+ return 0;
+ }
+
+ if (!file)
+ {
+ recursive_depth++;
+ if (recursive_depth == 1)
+ {
+#if defined HAVE_SETGROUPENT && defined HAVE_ENDGRENT
+ setgroupent (1);
+#endif
+#if defined HAVE_SETPASSENT && defined HAVE_ENDPWENT
+ setpassent (1);
+#endif
+ }
+ }
+
+ if (!user)
+ uid = -1;
+ else if (save_user && !strcmp (save_user, user))
+ uid = save_uid;
+ else
+ {
+ struct passwd *pw;
+ pw = getpwnam (user);
+ if (!pw)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ uid = pw->pw_uid;
+ if (recursive_depth)
+ {
+ if (save_user)
+ free (save_user);
+ save_user = strdup (user);
+ save_uid = uid;
+ }
+ }
+
+ if (!group)
+ gid = -1;
+ else if (save_group && !strcmp (save_group, group))
+ gid = save_gid;
+ else
+ {
+ struct group *gr;
+ gr = getgrnam (group);
+ if (!gr)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ gid = gr->gr_gid;
+ if (recursive_depth)
+ {
+ if (save_group)
+ free (save_group);
+ save_group = strdup (group);
+ save_gid = gid;
+ }
+ }
+
+ if (!file)
+ return 0;
+ else
+ return chown (file, uid, gid);
+#endif
+}
+
/* TODO: check if this can be changed to an extern declaration and/or
an AC_CHECK_DECLS test. */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Help-smalltalk] [PATCH] add File>>#owner:/#group:/#owner:group:,
Paolo Bonzini <=