Skip to content

Commit

Permalink
Implement some file functions with Unicode support
Browse files Browse the repository at this point in the history
getcwd, mkdir, chdir, rmdir, unlink
  • Loading branch information
nwellnhof committed Jan 21, 2011
1 parent 71005d0 commit 3312ddd
Show file tree
Hide file tree
Showing 7 changed files with 379 additions and 67 deletions.
2 changes: 2 additions & 0 deletions MANIFEST
Expand Up @@ -1291,6 +1291,7 @@ src/platform/generic/dl.c []
src/platform/generic/encoding.c []
src/platform/generic/env.c []
src/platform/generic/exec.c []
src/platform/generic/file.c []
src/platform/generic/hires_timer.c []
src/platform/generic/io.c []
src/platform/generic/itimer.c []
Expand All @@ -1310,6 +1311,7 @@ src/platform/solaris/time.c []
src/platform/win32/dl.c []
src/platform/win32/env.c []
src/platform/win32/exec.c []
src/platform/win32/file.c []
src/platform/win32/hires_timer.c []
src/platform/win32/io.c []
src/platform/win32/misc.c []
Expand Down
1 change: 1 addition & 0 deletions config/auto/platform.pm
Expand Up @@ -42,6 +42,7 @@ sub _set_implementations {
my @impls = qw/
io.c
socket.c
file.c
time.c
encoding.c
env.c
Expand Down
4 changes: 4 additions & 0 deletions config/gen/makefiles/root.in
Expand Up @@ -1609,6 +1609,8 @@ src/platform/generic/env$(O) : src/platform/generic/env.c $(PARROT_H_HEADERS)

src/platform/generic/exec$(O) : src/platform/generic/exec.c $(PARROT_H_HEADERS)

src/platform/generic/file$(O) : src/platform/generic/file.c $(PARROT_H_HEADERS)

src/platform/generic/hires_timer$(O) : src/platform/generic/hires_timer.c $(PARROT_H_HEADERS)

src/platform/generic/itimer$(O) : src/platform/generic/itimer.c $(PARROT_H_HEADERS)
Expand Down Expand Up @@ -1647,6 +1649,8 @@ src/platform/win32/env$(O) : src/platform/win32/env.c $(PARROT_H_HEADERS)

src/platform/win32/exec$(O) : src/platform/win32/exec.c $(PARROT_H_HEADERS)

src/platform/win32/file$(O) : src/platform/win32/file.c $(PARROT_H_HEADERS)

src/platform/win32/hires_timer$(O) : src/platform/win32/hires_timer.c $(PARROT_H_HEADERS)

src/platform/win32/io$(O) : $(PARROT_H_HEADERS) src/io/io_private.h \
Expand Down
19 changes: 19 additions & 0 deletions include/parrot/platform_interface.h
Expand Up @@ -90,6 +90,25 @@ INTVAL Parrot_io_recv(PARROT_INTERP, PIOHANDLE handle, ARGOUT(char *buf), size_t
INTVAL Parrot_io_poll(PARROT_INTERP, PIOHANDLE handle, int which, int sec, int usec);
INTVAL Parrot_io_close_socket(PARROT_INTERP, PIOHANDLE handle);

/*
* Files and directories
*/

PARROT_EXPORT
STRING *Parrot_file_getcwd(Interp *);

PARROT_EXPORT
void Parrot_file_mkdir(Interp *, ARGIN(STRING *path), INTVAL mode);

PARROT_EXPORT
void Parrot_file_chdir(Interp *, ARGIN(STRING *path));

PARROT_EXPORT
void Parrot_file_rmdir(Interp *, ARGIN(STRING *path));

PARROT_EXPORT
void Parrot_file_unlink(Interp *, ARGIN(STRING *path));

/*
** Math:
*/
Expand Down
74 changes: 7 additions & 67 deletions src/dynpmc/os.pmc
Expand Up @@ -117,28 +117,8 @@ Returns the current working directory.
*/

METHOD cwd() {
char *cwd;
#ifdef _MSC_VER
cwd = _getcwd(NULL, 0);
/* capitalize the drive letter */
cwd[0] = (char)toupper((unsigned char)cwd[0]);
#else
# ifdef PATH_MAX
cwd = getcwd(NULL, PATH_MAX+1);
# else
cwd = getcwd(NULL, 0);
# endif
#endif
if (cwd) {
STRING * const scwd = Parrot_str_new(INTERP, cwd, strlen(cwd));
free(cwd);
RETURN(STRING *scwd);
}
else {
const char * const errmsg = strerror(errno);
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_EXTERNAL_ERROR,
errmsg);
}
STRING *cwd = Parrot_file_getcwd(INTERP);
RETURN(STRING *cwd);
}

/*
Expand All @@ -152,19 +132,7 @@ Changes the current working directory to the one specified by C<path>.
*/

METHOD chdir(STRING *path) {
int error;
char * const cpath = Parrot_str_to_cstring(INTERP, path);
#ifdef _MSC_VER
error = _chdir(cpath);
#else
error = chdir(cpath);
#endif
Parrot_str_free_cstring(cpath);
if (error) {
const char * const errmsg = strerror(errno);
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_EXTERNAL_ERROR,
errmsg);
}
Parrot_file_chdir(INTERP, path);
}

/*
Expand All @@ -183,27 +151,11 @@ C<path>.
char * const cpath = Parrot_str_to_cstring(INTERP, path);
int error;

if (Parrot_stat_info_intval(interp, path, STAT_ISDIR)) {
#ifdef _MSC_VER
error = _rmdir(cpath);
#else
error = rmdir(cpath);
#endif
Parrot_str_free_cstring(cpath);
if (error) {
const char * const errmsg = strerror(errno);
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_EXTERNAL_ERROR,
errmsg);
}
if (Parrot_stat_info_intval(INTERP, path, STAT_ISDIR)) {
Parrot_file_rmdir(INTERP, path);
}
else {
error = remove(cpath);
Parrot_str_free_cstring(cpath);
if (error) {
const char * const errmsg = strerror(errno);
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_EXTERNAL_ERROR,
errmsg);
}
Parrot_file_unlink(INTERP, path);
}
}

Expand All @@ -218,19 +170,7 @@ Creates a directory specified by C<path> with mode C<mode>.
*/

METHOD mkdir(STRING *path, INTVAL mode) {
char * const cpath = Parrot_str_to_cstring(INTERP, path);
/* should we validate mode? */
#ifdef WIN32
const int error = _mkdir(cpath);
#else
const int error = mkdir(cpath, (mode_t)mode);
#endif
Parrot_str_free_cstring(cpath);
if (error) {
const char * const errmsg = strerror(errno);
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_EXTERNAL_ERROR,
errmsg);
}
Parrot_file_mkdir(INTERP, path, mode);
}

/*
Expand Down
169 changes: 169 additions & 0 deletions src/platform/generic/file.c
@@ -0,0 +1,169 @@
/*
Copyright (C) 2011, Parrot Foundation.
=head1 NAME
src/platform/win32/file.c - Generic UNIX file functions
=head1 DESCRIPTION
This file implements OS-specific file functions for generic UNIX platforms.
=head2 Functions
=over 4
=cut
*/

#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "parrot/parrot.h"

#define THROW(msg) Parrot_ex_throw_from_c_args(interp, NULL, \
EXCEPTION_EXTERNAL_ERROR, "%s: %s", msg, strerror(errno))

/* HEADERIZER HFILE: none */

/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */

/*
=item C<void Parrot_file_getcwd(STRING *path, STRING *mode)>
Returns the current working directory.
=cut
*/

STRING *
Parrot_file_getcwd(PARROT_INTERP)
{
STRING *result;
char *c_str;

#ifdef PATH_MAX
c_str = getcwd(NULL, PATH_MAX+1);
#else
c_str = getcwd(NULL, 0);
#endif

if (c_str == NULL)
THROW("getcwd");

result = Parrot_str_from_platform_cstring(interp, c_str);

free(c_str);

return result;
}

/*
=item C<void Parrot_file_mkdir(STRING *path, STRING *mode)>
Creates a directory specified by C<path> with mode C<mode>.
=cut
*/

void
Parrot_file_mkdir(PARROT_INTERP, ARGIN(STRING *path), INTVAL mode)
{
char *c_str = Parrot_str_to_platform_cstring(interp, path);
int result = mkdir(c_str, mode);

Parrot_str_free_cstring(c_str);

if (result)
THROW("mkdir");
}

/*
=item C<void Parrot_file_chdir(STRING *path, STRING *mode)>
Changes the current working directory to the one specified by C<path>.
=cut
*/

void
Parrot_file_chdir(PARROT_INTERP, ARGIN(STRING *path))
{
char *c_str = Parrot_str_to_platform_cstring(interp, path);
int result = chdir(c_str);

Parrot_str_free_cstring(c_str);

if (result)
THROW("chdir");
}

/*
=item C<void Parrot_file_rmdir(STRING *path, STRING *mode)>
Removes a directory specified by C<path>.
=cut
*/

void
Parrot_file_rmdir(PARROT_INTERP, ARGIN(STRING *path))
{
char *c_str = Parrot_str_to_platform_cstring(interp, path);
int result = rmdir(c_str);

Parrot_str_free_cstring(c_str);

if (result)
THROW("rmdir");
}

/*
=item C<void Parrot_file_unlink(STRING *path, STRING *mode)>
Removes a directory specified by C<path>.
=cut
*/

void
Parrot_file_unlink(PARROT_INTERP, ARGIN(STRING *path))
{
char *c_str = Parrot_str_to_platform_cstring(interp, path);
int result = unlink(c_str);

Parrot_str_free_cstring(c_str);

if (result)
THROW("unlink");
}

/*
=back
=cut
*/


/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/

0 comments on commit 3312ddd

Please sign in to comment.