ruby-io-c.patch

Donovan Lampa, 10/10/2012 11:20 PM

Download (10.3 KB)

View differences:

/Users/dlampa/carrier-build-root/local_build/carrier-ruby-1.9.3p194-2/src/ruby-build/ruby-source/io.c 2012-10-10 09:02:34.000000000 -0500
161 161
    if (max_file_descriptor < fd) max_file_descriptor = fd;
162 162
}
163 163

  
164
void
165
rb_maygvl_fd_fix_cloexec(int fd)
166
{
167
  /* MinGW don't have F_GETFD and FD_CLOEXEC.  [ruby-core:40281] */
168
#ifdef F_GETFD
169
  int flags, flags2, ret;
170
  flags = fcntl(fd, F_GETFD); /* should not fail except EBADF. */
171
  if (flags == -1) {
172
    rb_bug("rb_maygvl_fd_fix_cloexec: fcntl(%d, F_GETFD) failed: %s", fd, strerror(errno));
173
  }
174
  if (fd <= 2)
175
    flags2 = flags & ~FD_CLOEXEC; /* Clear CLOEXEC for standard file descriptors: 0, 1, 2. */
176
  else
177
    flags2 = flags | FD_CLOEXEC; /* Set CLOEXEC for non-standard file descriptors: 3, 4, 5, ... */
178
  if (flags != flags2) {
179
    ret = fcntl(fd, F_SETFD, flags2);
180
    if (ret == -1) {
181
      rb_bug("rb_maygvl_fd_fix_cloexec: fcntl(%d, F_SETFD, %d) failed: %s", fd, flags2, strerror(errno));
182
    }
183
  }
184
#endif
185
}
186

  
187
int
188
rb_cloexec_fcntl_dupfd(int fd, int minfd)
189
{
190
    int ret;
191

  
192
#if defined(HAVE_FCNTL) && defined(F_DUPFD_CLOEXEC)
193
    static int try_dupfd_cloexec = 1;
194
    if (try_dupfd_cloexec) {
195
      ret = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
196
      if (ret != -1) {
197
	if (ret <= 2)
198
	  rb_maygvl_fd_fix_cloexec(ret);
199
	return ret;
200
      }
201
      /* F_DUPFD_CLOEXEC is available since Linux 2.6.24.  Linux 2.6.18 fails with EINVAL */
202
      if (errno == EINVAL) {
203
	ret = fcntl(fd, F_DUPFD, minfd);
204
	if (ret != -1) {
205
	  try_dupfd_cloexec = 0;
206
	}
207
      }
208
    }
209
    else {
210
      ret = fcntl(fd, F_DUPFD, minfd);
211
    }
212
#else
213
    ret = fcntl(fd, F_DUPFD, minfd);
214
#endif
215
    if (ret == -1) return -1;
216
    rb_maygvl_fd_fix_cloexec(ret);
217
    return ret;
218
}
219

  
164 220
#define argf_of(obj) (*(struct argf *)DATA_PTR(obj))
165 221
#define ARGF argf_of(argf)
166 222

  
......
7918 7974
    return rb_ensure(select_call, (VALUE)&args, select_end, (VALUE)&args);
7919 7975
}
7920 7976

  
7921
struct io_cntl_arg {
7977
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
7978
 typedef unsigned long ioctl_req_t;
7979
 #define NUM2IOCTLREQ(num) NUM2ULONG(num)
7980
#else
7981
 typedef int ioctl_req_t;
7982
 #define NUM2IOCTLREQ(num) NUM2INT(num)
7983
#endif
7984

  
7985
struct ioctl_arg {
7922 7986
    int		fd;
7923
    int		cmd;
7987
    ioctl_req_t	cmd;
7924 7988
    long	narg;
7925
    int		io_p;
7926 7989
};
7927 7990

  
7928
static VALUE nogvl_io_cntl(void *ptr)
7991
static VALUE nogvl_ioctl(void *ptr)
7929 7992
{
7930
    struct io_cntl_arg *arg = ptr;
7993
    struct ioctl_arg *arg = ptr;
7931 7994

  
7932
    if (arg->io_p)
7933
	return (VALUE)ioctl(arg->fd, arg->cmd, arg->narg);
7934
    else
7935
	return (VALUE)fcntl(arg->fd, arg->cmd, arg->narg);
7995
    return (VALUE)ioctl(arg->fd, arg->cmd, arg->narg);
7936 7996
}
7937 7997

  
7938 7998
static int
7939
io_cntl(int fd, int cmd, long narg, int io_p)
7999
do_ioctl(int fd, ioctl_req_t cmd, long narg)
7940 8000
{
7941 8001
    int retval;
7942
    struct io_cntl_arg arg;
7943

  
7944
#ifndef HAVE_FCNTL
7945
    if (!io_p) {
7946
	rb_notimplement();
7947
    }
7948
#endif
8002
    struct ioctl_arg arg;
7949 8003

  
7950 8004
    arg.fd = fd;
7951 8005
    arg.cmd = cmd;
7952 8006
    arg.narg = narg;
7953
    arg.io_p = io_p;
7954 8007

  
7955
    retval = (int)rb_thread_io_blocking_region(nogvl_io_cntl, &arg, fd);
7956
#if defined(F_DUPFD)
7957
    if (!io_p && retval != -1 && cmd == F_DUPFD) {
7958
	rb_update_max_fd(retval);
7959
    }
7960
#endif
8008
    retval = (int)rb_thread_io_blocking_region(nogvl_ioctl, &arg, fd);
7961 8009

  
7962 8010
    return retval;
7963 8011
}
7964 8012

  
7965
static VALUE
7966
rb_io_ctl(VALUE io, VALUE req, VALUE arg, int io_p)
8013
static long
8014
ioctl_narg_len(ioctl_req_t cmd)
7967 8015
{
7968
    int cmd = NUM2INT(req);
7969
    rb_io_t *fptr;
7970
    long len = 0;
7971
    long narg = 0;
7972
    int retval;
8016
    long len;
7973 8017

  
7974
    rb_secure(2);
8018
#ifdef IOCPARM_MASK
8019
#ifndef IOCPARM_LEN
8020
#define IOCPARM_LEN(x)  (((x) >> 16) & IOCPARM_MASK)
8021
#endif
8022
#endif
8023
#ifdef IOCPARM_LEN
8024
    len = IOCPARM_LEN(cmd);	/* on BSDish systems we're safe */
8025
#elif defined(_IOC_SIZE)
8026
    len = _IOC_SIZE(cmd);
8027
#else
8028
    len = 256;		/* otherwise guess at what's safe */
8029
#endif
8030

  
8031
    return len;
8032
}
8033

  
8034
#ifdef HAVE_FCNTL
8035
#ifdef __linux__
8036
typedef long fcntl_arg_t;
8037
#else
8038
/* posix */
8039
typedef int fcntl_arg_t;
8040
#endif
8041

  
8042
static long
8043
fcntl_narg_len(int cmd)
8044
{
8045
    long len;
8046

  
8047
    switch (cmd) {
8048
#ifdef F_DUPFD
8049
      case F_DUPFD:
8050
	len = sizeof(fcntl_arg_t);
8051
	break;
8052
#endif
8053
#ifdef F_DUP2FD /* bsd specific */
8054
      case F_DUP2FD:
8055
	len = sizeof(int);
8056
	break;
8057
#endif
8058
#ifdef F_DUPFD_CLOEXEC /* linux specific */
8059
      case F_DUPFD_CLOEXEC:
8060
	len = sizeof(fcntl_arg_t);
8061
	break;
8062
#endif
8063
#ifdef F_GETFD
8064
      case F_GETFD:
8065
	len = 1;
8066
	break;
8067
#endif
8068
#ifdef F_SETFD
8069
      case F_SETFD:
8070
	len = sizeof(fcntl_arg_t);
8071
	break;
8072
#endif
8073
#ifdef F_GETFL
8074
      case F_GETFL:
8075
	len = 1;
8076
	break;
8077
#endif
8078
#ifdef F_SETFL
8079
      case F_SETFL:
8080
	len = sizeof(fcntl_arg_t);
8081
	break;
8082
#endif
8083
#ifdef F_GETOWN
8084
      case F_GETOWN:
8085
	len = 1;
8086
	break;
8087
#endif
8088
#ifdef F_SETOWN
8089
      case F_SETOWN:
8090
	len = sizeof(fcntl_arg_t);
8091
	break;
8092
#endif
8093
#ifdef F_GETOWN_EX /* linux specific */
8094
      case F_GETOWN_EX:
8095
	len = sizeof(struct f_owner_ex);
8096
	break;
8097
#endif
8098
#ifdef F_SETOWN_EX /* linux specific */
8099
      case F_SETOWN_EX:
8100
	len = sizeof(struct f_owner_ex);
8101
	break;
8102
#endif
8103
#ifdef F_GETLK
8104
      case F_GETLK:
8105
	len = sizeof(struct flock);
8106
	break;
8107
#endif
8108
#ifdef F_SETLK
8109
      case F_SETLK:
8110
	len = sizeof(struct flock);
8111
	break;
8112
#endif
8113
#ifdef F_SETLKW
8114
      case F_SETLKW:
8115
	len = sizeof(struct flock);
8116
	break;
8117
#endif
8118
#ifdef F_READAHEAD /* bsd specific */
8119
      case F_READAHEAD:
8120
	len = sizeof(int);
8121
	break;
8122
#endif
8123
#ifdef F_RDAHEAD /* Darwin specific */
8124
      case F_RDAHEAD:
8125
	len = sizeof(int);
8126
	break;
8127
#endif
8128
#ifdef F_GETSIG /* linux specific */
8129
      case F_GETSIG:
8130
	len = 1;
8131
	break;
8132
#endif
8133
#ifdef F_SETSIG /* linux specific */
8134
      case F_SETSIG:
8135
	len = sizeof(fcntl_arg_t);
8136
	break;
8137
#endif
8138
#ifdef F_GETLEASE /* linux specific */
8139
      case F_GETLEASE:
8140
	len = 1;
8141
	break;
8142
#endif
8143
#ifdef F_SETLEASE /* linux specific */
8144
      case F_SETLEASE:
8145
	len = sizeof(fcntl_arg_t);
8146
	break;
8147
#endif
8148
#ifdef F_NOTIFY /* linux specific */
8149
      case F_NOTIFY:
8150
	len = sizeof(fcntl_arg_t);
8151
	break;
8152
#endif
8153

  
8154
      default:
8155
	len = 256;
8156
	break;
8157
    }
8158

  
8159
    return len;
8160
}
8161
#else /* HAVE_FCNTL */
8162
static long
8163
fcntl_narg_len(int cmd)
8164
{
8165
    return 0;
8166
}
8167
#endif /* HAVE_FCNTL */
8168

  
8169
static long
8170
setup_narg(ioctl_req_t cmd, VALUE *argp, int io_p)
8171
{
8172
    long narg = 0;
8173
    VALUE arg = *argp;
7975 8174

  
7976 8175
    if (NIL_P(arg) || arg == Qfalse) {
7977 8176
	narg = 0;
......
7989 8188
	    narg = NUM2LONG(arg);
7990 8189
	}
7991 8190
	else {
7992
	    arg = tmp;
7993
#ifdef IOCPARM_MASK
7994
#ifndef IOCPARM_LEN
7995
#define IOCPARM_LEN(x)  (((x) >> 16) & IOCPARM_MASK)
7996
#endif
7997
#endif
7998
#ifdef IOCPARM_LEN
7999
	    len = IOCPARM_LEN(cmd);	/* on BSDish systems we're safe */
8000
#else
8001
	    len = 256;		/* otherwise guess at what's safe */
8002
#endif
8191
	    long len;
8192

  
8193
	    *argp = arg = tmp;
8194
	    if (io_p)
8195
		len = ioctl_narg_len(cmd);
8196
	    else
8197
		len = fcntl_narg_len((int)cmd);
8003 8198
	    rb_str_modify(arg);
8004 8199

  
8005
	    if (len <= RSTRING_LEN(arg)) {
8006
		len = RSTRING_LEN(arg);
8007
	    }
8008
	    if (RSTRING_LEN(arg) < len) {
8200
	    /* expand for data + sentinel. */
8201
	    if (RSTRING_LEN(arg) < len+1) {
8009 8202
		rb_str_resize(arg, len+1);
8010 8203
	    }
8011
	    RSTRING_PTR(arg)[len] = 17;	/* a little sanity check here */
8204
	    /* a little sanity check here */
8205
	    RSTRING_PTR(arg)[RSTRING_LEN(arg) - 1] = 17;
8012 8206
	    narg = (long)(SIGNED_VALUE)RSTRING_PTR(arg);
8013 8207
	}
8014 8208
    }
8015
    GetOpenFile(io, fptr);
8016
    retval = io_cntl(fptr->fd, cmd, narg, io_p);
8017
    if (retval < 0) rb_sys_fail_path(fptr->pathv);
8018
    if (TYPE(arg) == T_STRING && RSTRING_PTR(arg)[len] != 17) {
8019
	rb_raise(rb_eArgError, "return value overflowed string");
8209
        return narg;
8020 8210
    }
8021 8211

  
8022
    if (!io_p && cmd == F_SETFL) {
8023
	if (narg & O_NONBLOCK) {
8024
	    fptr->mode |= FMODE_WSPLIT_INITIALIZED;
8025
	    fptr->mode &= ~FMODE_WSPLIT;
8026
	}
8027
	else {
8028
	    fptr->mode &= ~(FMODE_WSPLIT_INITIALIZED|FMODE_WSPLIT);
8029
	}
8212
static VALUE
8213
rb_ioctl(VALUE io, VALUE req, VALUE arg)
8214
{
8215
    ioctl_req_t cmd = NUM2IOCTLREQ(req);
8216
    rb_io_t *fptr;
8217
    long narg;
8218
    int retval;
8219
  
8220
    rb_secure(2);
8221

  
8222
    narg = setup_narg(cmd, &arg, 1);
8223
    GetOpenFile(io, fptr);
8224
    retval = do_ioctl(fptr->fd, cmd, narg);
8225
    if (retval < 0) rb_sys_fail_path(fptr->pathv);
8226
    if (RB_TYPE_P(arg, T_STRING)) {
8227
	if (RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] != 17)
8228
	    rb_raise(rb_eArgError, "return value overflowed string");
8229
	RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] = '\0';
8030 8230
    }
8031 8231

  
8032 8232
    return INT2NUM(retval);
8033 8233
}
8034 8234

  
8035

  
8036 8235
/*
8037 8236
 *  call-seq:
8038 8237
 *     ios.ioctl(integer_cmd, arg)    -> integer
......
8051 8250
    VALUE req, arg;
8052 8251

  
8053 8252
    rb_scan_args(argc, argv, "11", &req, &arg);
8054
    return rb_io_ctl(io, req, arg, 1);
8253
    return rb_ioctl(io, req, arg);
8055 8254
}
8056 8255

  
8057 8256
#ifdef HAVE_FCNTL
8257
struct fcntl_arg {
8258
    int		fd;
8259
    int 	cmd;
8260
    long	narg;
8261
};
8262

  
8263
static VALUE nogvl_fcntl(void *ptr)
8264
{
8265
    struct fcntl_arg *arg = ptr;
8266

  
8267
#if defined(F_DUPFD)
8268
    if (arg->cmd == F_DUPFD)
8269
	return (VALUE)rb_cloexec_fcntl_dupfd(arg->fd, (int)arg->narg);
8270
#endif
8271
    return (VALUE)fcntl(arg->fd, arg->cmd, arg->narg);
8272
}
8273

  
8274
static int
8275
do_fcntl(int fd, int cmd, long narg)
8276
{
8277
    int retval;
8278
    struct fcntl_arg arg;
8279

  
8280
    arg.fd = fd;
8281
    arg.cmd = cmd;
8282
    arg.narg = narg;
8283

  
8284
    retval = (int)rb_thread_io_blocking_region(nogvl_fcntl, &arg, fd);
8285
#if defined(F_DUPFD)
8286
    if (retval != -1 && cmd == F_DUPFD) {
8287
	rb_update_max_fd(retval);
8288
    }
8289
#endif
8290

  
8291
    return retval;
8292
}
8293

  
8294
static VALUE
8295
rb_fcntl(VALUE io, VALUE req, VALUE arg)
8296
{
8297
    int cmd = NUM2INT(req);
8298
    rb_io_t *fptr;
8299
    long narg;
8300
    int retval;
8301

  
8302
    rb_secure(2);
8303

  
8304
    narg = setup_narg(cmd, &arg, 0);
8305
    GetOpenFile(io, fptr);
8306
    retval = do_fcntl(fptr->fd, cmd, narg);
8307
    if (retval < 0) rb_sys_fail_path(fptr->pathv);
8308
    if (RB_TYPE_P(arg, T_STRING)) {
8309
	if (RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] != 17)
8310
	    rb_raise(rb_eArgError, "return value overflowed string");
8311
	RSTRING_PTR(arg)[RSTRING_LEN(arg)-1] = '\0';
8312
    }
8313

  
8314
    if (cmd == F_SETFL) {
8315
	if (narg & O_NONBLOCK) {
8316
	    fptr->mode |= FMODE_WSPLIT_INITIALIZED;
8317
	    fptr->mode &= ~FMODE_WSPLIT;
8318
	}
8319
	else {
8320
	    fptr->mode &= ~(FMODE_WSPLIT_INITIALIZED|FMODE_WSPLIT);
8321
	}
8322
    }
8323

  
8324
    return INT2NUM(retval);
8325
}
8326

  
8058 8327
/*
8059 8328
 *  call-seq:
8060 8329
 *     ios.fcntl(integer_cmd, arg)    -> integer
......
8074 8343
    VALUE req, arg;
8075 8344

  
8076 8345
    rb_scan_args(argc, argv, "11", &req, &arg);
8077
    return rb_io_ctl(io, req, arg, 0);
8346
    return rb_fcntl(io, req, arg);
8078 8347
}
8079 8348
#else
8080 8349
#define rb_io_fcntl rb_f_notimplement