Skip to content

Commit

Permalink
990507
Browse files Browse the repository at this point in the history
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_3@460 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
matz committed May 7, 1999
1 parent c09a226 commit 3376271
Show file tree
Hide file tree
Showing 24 changed files with 1,182 additions and 685 deletions.
13 changes: 13 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
Fri May 7 17:03:57 1999 Yukihiro Matsumoto <matz@netlab.co.jp>

* dir.c (glob): removed GPL'ed glob.c completely.

Fri May 7 08:17:19 1999 Yukihiro Matsumoto <matz@netlab.co.jp>

* ext/sdbm/extconf.rb: sdbm extension added to the distribution.

Fri May 7 01:42:20 1999 Yukihiro Matsumoto <matz@netlab.co.jp>

* ext/socket/socket.c (tcp_s_gethostbyname): aboid using struct
sockaddr_storage.

Thu May 6 13:21:41 1999 Yukihiro Matsumoto <matz@netlab.co.jp>

* array.c (rb_ary_indexes): should not use rb_ary_concat().
Expand Down
1 change: 0 additions & 1 deletion MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ error.c
eval.c
file.c
gc.c
glob.c
hash.c
inits.c
install-sh
Expand Down
2 changes: 0 additions & 2 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ OBJS = array.o \
eval.o \
file.o \
gc.o \
glob.o \
hash.o \
inits.o \
io.o \
Expand Down Expand Up @@ -234,7 +233,6 @@ eval.o: eval.c ruby.h config.h defines.h intern.h node.h env.h rubysig.h st.h dl
file.o: file.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h
fnmatch.o: fnmatch.c config.h fnmatch.h
gc.o: gc.c ruby.h config.h defines.h intern.h rubysig.h st.h node.h env.h re.h regex.h
glob.o: config.h glob.c fnmatch.h
hash.o: hash.c ruby.h config.h defines.h intern.h st.h rubysig.h util.h
inits.o: inits.c ruby.h config.h defines.h intern.h
io.o: io.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h
Expand Down
182 changes: 161 additions & 21 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,23 @@
# endif
#endif

#ifdef HAVE_FNMATCH_H
#include <fnmatch.h>
#else
#include "missing/fnmatch.h"
#endif

#include <errno.h>
#ifdef USE_CWGUSI
# include <sys/errno.h>
#endif

#ifndef NT
#ifndef HAVE_STDLIB_H
char *getenv();
#endif

#ifdef USE_CWGUSI
# include <sys/errno.h>
#ifndef HAVE_STRING_H
char *strchr _((char*,char));
#endif

VALUE rb_cDir;
Expand Down Expand Up @@ -149,10 +158,10 @@ static VALUE
dir_tell(dir)
VALUE dir;
{
#if !defined(__CYGWIN32__) && !defined(__BEOS__)
DIR *dirp;
int pos;
long pos;

#if !defined(__CYGWIN32__) && !defined(__BEOS__)
GetDIR(dir, dirp);
pos = telldir(dirp);
return rb_int2inum(pos);
Expand Down Expand Up @@ -303,29 +312,158 @@ dir_s_rmdir(obj, dir)
return Qtrue;
}

#define isdelim(c) ((c)==' '||(c)=='\t'||(c)=='\n'||(c)=='\0')
/* Return nonzero if S has any special globbing chars in it. */
static int
has_magic(s, send)
char *s, *send;
{
register char *p = s;
register char c;
int open = 0;

while ((c = *p++) != '\0') {
switch (c) {
case '?':
case '*':
return Qtrue;

case '[': /* Only accept an open brace if there is a close */
open++; /* brace to match it. Bracket expressions must be */
continue; /* complete, according to Posix.2 */
case ']':
if (open)
return Qtrue;
continue;

case '\\':
if (*p++ == '\0')
return Qfalse;
}

if (send && p >= send) break;
}
return Qfalse;
}

struct glob1_arg {
void (*func)();
char *basename;
VALUE arg;
};

static char*
extract_path(p, pend)
char *p, *pend;
{
char *alloc;
int len;

len = pend - p;
alloc = ALLOC_N(char, len+1);
memcpy(alloc, p, len);
if (len > 0 && pend[-1] == '/') {
alloc[len-1] = 0;
}
else {
alloc[len] = 0;
}

return alloc;
}

static char*
extract_elem(path)
char *path;
{
char *pend;

pend = strchr(path, '/');
if (!pend) pend = path + strlen(path);

return extract_path(path, pend);
}

#ifndef S_ISDIR
# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
#endif

static void
glob(path, func, arg)
char *path;
void (*func)();
VALUE arg;
{
struct stat st;
char *p, *m;

if (!has_magic(path, 0)) {
if (stat(path, &st) == 0) {
(*func)(path, arg);
}
return;
}

p = path;
while (p) {
if (*p == '/') p++;
m = strchr(p, '/');
if (has_magic(p, m)) {
char *dir, *base, *magic;
DIR *dirp;
struct dirent *dp;

base = extract_path(path, p);
if (path == p) dir = ".";
else dir = base;

dirp = opendir(dir);
if (dirp == NULL) {
free(base);
break;
}
magic = extract_elem(p);
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
if (fnmatch(magic, dp->d_name, FNM_PERIOD|FNM_PATHNAME) == 0) {
char *fix = ALLOC_N(char, strlen(base)+strlen(dp->d_name)+2);

sprintf(fix, "%s%s%s", base, (p==path)?"":"/", dp->d_name);
if (!m) {
(*func)(fix, arg);
free(fix);
continue;
}
stat(fix, &st); /* should success */
if (S_ISDIR(st.st_mode)) {
char *t = ALLOC_N(char, strlen(fix)+strlen(m)+2);
sprintf(t, "%s%s", fix, m);
glob(t, func, arg);
free(t);
}
free(fix);
}
}
closedir(dirp);
free(base);
free(magic);
}
p = m;
}
}

char **glob_filename();
extern char *glob_error_return;
static void
push_pattern(path, ary)
char *path;
VALUE ary;
{
rb_ary_push(ary, rb_tainted_str_new2(path));
}

static void
push_globs(ary, s)
VALUE ary;
char *s;
{
char **fnames, **ff;

fnames = glob_filename(s);
if (fnames == (char**)-1) rb_sys_fail(s);
ff = fnames;
while (*ff) {
rb_ary_push(ary, rb_tainted_str_new2(*ff));
free(*ff);
ff++;
}
if (fnames != &glob_error_return) {
free(fnames);
}
glob(s, push_pattern, ary);
}

static void
Expand Down Expand Up @@ -374,6 +512,8 @@ push_braces(ary, s)
}
}

#define isdelim(c) ((c)==' '||(c)=='\t'||(c)=='\n'||(c)=='\0')

static VALUE
dir_s_glob(dir, str)
VALUE dir, str;
Expand Down
1 change: 1 addition & 0 deletions ext/Setup
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#kconv
#md5
#pty
#sdbm
#socket
#tkutil
#tcltklib
Expand Down
2 changes: 1 addition & 1 deletion ext/extmk.rb.in
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ binsuffix = @binsuffix@
all: $(DLLIB)
clean:; @rm -f *.o *.a *.so *.sl
clean:; @rm -f *.o *.a *.so *.sl *.a
@rm -f Makefile extconf.h conftest.*
@rm -f core ruby$(binsuffix) *~
Expand Down
2 changes: 1 addition & 1 deletion ext/extmk.rb.nt
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ binsuffix =
all: $(DLLIB)
clean:; @rm -f *.o *.a *.so *.sl
clean:; @rm -f *.o *.a *.so *.sl *.a
@rm -f Makefile extconf.h conftest.*
@rm -f core ruby$(binsuffix) *~
Expand Down
12 changes: 12 additions & 0 deletions ext/pty/MANIFEST
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
MANIFEST
Makefile
README
README.expect
README.expect.jp
README.jp
expect_sample.rb
extconf.rb
lib/expect.rb
pty.c
script.rb
shl.rb
93 changes: 93 additions & 0 deletions ext/pty/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
pty extension version 0.3 by A.ito

1. Introduction

This extension module adds ruby a functionality to execute an
arbitrary command through pseudo tty (pty).

2. Install

Follow the instruction below.

(1) Execute

ruby extconf.rb

then Makefile is generated.

(3) Do make; make install.

3. What you can do

This extension module defines a module named PTY, which contains
following module fungtions:

getpty(command)
spawn(command)

This function reserves a pty, executes command over the pty
and returns an array. The return value is an array with three
elements. The first element in the array is for reading and the
second for writing. The third element is the process ID of the
child process. If this function is called with an iterator block,
the array is passed to the block as block parameters, and the
function itself returns nil.

While the process spawned by this function is active, SIGCHLD
is captured to handle the change of the child process. When the
child process is suspended or finished, an exception is raised.
As all SIGCHLD signal is captured and processed by PTY module,
you can't use other function or method which spawns subprosesses
(including signal() and IO.popen()) while the PTY subprocesses
are active. Otherwise, unexpected exception will occur. To avoid
this problem, see protect_signal() below.

If this function is called with an iterator block, SIGCHLD signal
is captured only within the block. Therefore, it is risky to use
File objects for PTY subprocess outside the iterator block.


protect_signal

This function takes an iterator block. Within the iterator block,
no exception is raised even if any subprocess is terminated.
This function is used to enable functions like system() or IO.popen()
while PTY subprocess is active. For example,

PTY.spawn("command_foo") do |r,w|
...
...
PTY.protect_signal do
system "some other commands"
end
...
end

disables to send exception when "some other commands" is
terminated.

reset_signal

Disables to handle SIGCHLD while PTY subprocess is active.


4. License

(C) Copyright 1998 by Akinori Ito.

This software may be redistributed freely for this purpose, in full
or in part, provided that this entire copyright notice is included
on any copies of this software and applications and derivations thereof.

This software is provided on an "as is" basis, without warranty of any
kind, either expressed or implied, as to any matter including, but not
limited to warranty of fitness of purpose, or merchantability, or
results obtained from use of this software.

5. Bug report

Please feel free to send E-mail to

aito@ei5sun.yz.yamagata-u.ac.jp

for any bug report, opinion, contribution, etc.
Loading

0 comments on commit 3376271

Please sign in to comment.