Esempio n. 1
2
int
sys_posix_openpt(struct thread *td, struct posix_openpt_args *uap)
{
	int error, fd;
	struct file *fp;

	/*
	 * POSIX states it's unspecified when other flags are passed. We
	 * don't allow this.
	 */
	if (uap->flags & ~(O_RDWR|O_NOCTTY|O_CLOEXEC))
		return (EINVAL);

	error = falloc(td, &fp, &fd, uap->flags);
	if (error)
		return (error);

	/* Allocate the actual pseudo-TTY. */
	error = pts_alloc(FFLAGS(uap->flags & O_ACCMODE), td, fp);
	if (error != 0) {
		fdclose(td, fp, fd);
		fdrop(fp, td);
		return (error);
	}

	/* Pass it back to userspace. */
	td->td_retval[0] = fd;
	fdrop(fp, td);

	return (0);
}
Esempio n. 2
0
char *test_IOBuf_streaming()
{
    // test streaming from /dev/zero to /dev/null
    Connection *zero = fake_conn("/dev/zero", O_RDONLY);
    IOBuf *from = zero->iob;
    Connection *null = fake_conn("/dev/null", O_WRONLY);
    IOBuf *to = null->iob;

    int rc = IOBuf_stream(from, to, 500);
    mu_assert(rc == 500, "Didn't stream the right amount on small test.");

    rc = IOBuf_stream(from, to, 10 * 1024);
    mu_assert(rc == 10 * 1024, "Didn't stream oversized amount.");

    fdclose(from->fd);
    rc = IOBuf_stream(from, to, 10 * 1024);
    mu_assert(rc == -1, "Should fail if send side is closed.");
    mu_assert(from->avail >= 0, "Avail should never go below 0.");

    fdclose(to->fd);
    rc = IOBuf_stream(from, to, 10 * 1024);
    mu_assert(rc == -1, "Should fail if recv side is closed.");

    fake_conn_close(zero);
    fake_conn_close(null);
    return NULL;
}
Esempio n. 3
0
int Upload_file(Connection *conn, Handler *handler, int content_len)
{
    int rc = 0;
    int tmpfd = 0;
    bstring tmp_name = NULL;
    bstring result = NULL;

    if(UPLOAD_STORE == NULL) {
        UPLOAD_STORE = Setting_get_str("upload.temp_store", NULL);
        error_unless(UPLOAD_STORE, conn, 413, "Request entity is too large: %d, and no upload.temp_store setting for where to put the big files.", content_len);

        UPLOAD_STORE = bstrcpy(UPLOAD_STORE);
    }

    if(UPLOAD_MODE == 0) {
        bstring mode = Setting_get_str("upload.temp_store_mode", &UPLOAD_MODE_DEFAULT);
        log_info("Will set mode for upload temp store to: %s", bdata(mode));

        check(bdata(mode) != NULL, "Mode data is NULL")
        UPLOAD_MODE = strtoul((const char *)bdata(mode), NULL, 0);
        check(UPLOAD_MODE > 0, "Failed to convert upload.temp_store_mode to a number.");
        check(UPLOAD_MODE < 066666, "Invalid mode that's way too big: %s.", bdata(mode));
    }

    tmp_name = bstrcpy(UPLOAD_STORE);

    tmpfd = mkstemp((char *)tmp_name->data);
    check(tmpfd != -1, "Failed to create secure tempfile, did you end it with XXXXXX?");

    log_info("Writing tempfile %s for large upload.", bdata(tmp_name));

    rc = chmod((char *)tmp_name->data, UPLOAD_MODE);
    check(rc == 0, "Failed to chmod.");

    rc = Upload_notify(conn, handler, "start", tmp_name);
    check(rc == 0, "Failed to notify of the start of upload.");

    rc = stream_to_disk(conn->iob, content_len, tmpfd);
    check(rc == 0, "Failed to stream to disk.");

    rc = Upload_notify(conn, handler, "done", tmp_name);
    check(rc == 0, "Failed to notify the end of the upload.");

    bdestroy(result);
    bdestroy(tmp_name);
    fdclose(tmpfd);
    return 0;

error:
    if(result) bdestroy(result);
    fdclose(tmpfd);

    if(tmp_name != NULL) {
        unlink((char *)tmp_name->data);
        bdestroy(tmp_name);
    }

    return -1;
}
static void
proc_fini_parent(struct proc *p)
{
  /* close unneeded file descriptors */
  fdclose(p->fd[0][0]); p->fd[0][0] = -1;
  fdclose(p->fd[1][1]); p->fd[1][1] = -1;
  fdclose(p->fd[2][1]); p->fd[2][1] = -1;
}
Esempio n. 5
0
void Server_destroy(Server *srv)
{
    if(srv) {
        if(srv->use_ssl) {
            free(srv->rng_ctx);

            mbedtls_x509_crt_free(&srv->own_cert);
            mbedtls_pk_free(&srv->pk_key);
            // srv->ciphers freed (if non-default) by h_free
        }

        RouteMap_destroy(srv->hosts);
        Server_destroy_handlers(srv);

        bdestroy(srv->bind_addr);
        bdestroy(srv->uuid);
        bdestroy(srv->chroot);
        bdestroy(srv->access_log);
        bdestroy(srv->error_log);
        bdestroy(srv->pid_file);
        bdestroy(srv->control_port);
        bdestroy(srv->default_hostname);

        if(srv->listen_fd >= 0) fdclose(srv->listen_fd);
        h_free(srv);
    }
}
Esempio n. 6
0
int32_t krd4set_S(CSOUND *csound, KREAD4 *p)
{
    /* open in curdir or pathname */
    char soundiname[1024];
    if (UNLIKELY((p->format = (int32_t)*p->iformat) < 1 || p->format > 8)) {
      return csound->InitError(csound, Str("unknown format request"));
    }
    if (UNLIKELY(p->format == 2 || p->format == 3)) {
      return csound->InitError(csound,
                               Str("alaw and ulaw not implemented here"));
    }
    strNcpy(soundiname,  ((STRINGDAT *)p->ifilcod)->data, 1023);
    if (p->fdch.fd != NULL)
      fdclose(csound, &(p->fdch));
    p->fdch.fd = csound->FileOpen2(csound, &(p->f), CSFILE_STD, soundiname, "rb",
                                   "SFDIR;SSDIR", dumpf_format_table[p->format], 0);
    if (UNLIKELY(p->fdch.fd == NULL))
      return csound->InitError(csound, Str("Cannot open %s"), soundiname);
    fdrecord(csound, &p->fdch);
    if ((p->timcount = (int32_t)(*p->iprd * CS_EKR)) <= 0)
      p->timcount = 1;
    p->countdown = 0;
    p->k[0] = p->k[1] = p->k[2] = p->k[3] = FL(0.0);
    return OK;
}
Esempio n. 7
0
int32_t kdmpset_p(CSOUND *csound, KDUMP *p)
{
    /* open in curdir or pathname */
    char soundoname[1024];
    if (UNLIKELY((p->format = (int32_t)*p->iformat) < 1 || p->format > 8)) {
      return csound->InitError(csound, Str("unknown format request"));
    }
    if (UNLIKELY(p->format == 2 || p->format == 3)) {
      return csound->InitError(csound,
                               Str("alaw and ulaw not implemented here"));
    }
    if (csound->ISSTRCOD(*p->ifilcod))
      strNcpy(soundoname, get_arg_string(csound, *p->ifilcod), 1023);
    else csound->strarg2name(csound, soundoname, p->ifilcod, "dumpk.", 0);
    if (p->fdch.fd != NULL)
      fdclose(csound, &(p->fdch));
    p->fdch.fd = csound->FileOpen2(csound, &(p->f), CSFILE_STD, soundoname,
                                   "wb", "", dumpf_format_table[p->format], 0);
    if (UNLIKELY(p->fdch.fd == NULL))
      return csound->InitError(csound, Str("Cannot open %s"), soundoname);
    fdrecord(csound, &p->fdch);
    if ((p->timcount = (int32_t)(*p->iprd * CS_EKR)) <= 0)
      p->timcount = 1;
    p->countdown = p->timcount;
    return OK;
}
Esempio n. 8
0
void terminate(int s)
{
    MURDER = s == SIGTERM;

    switch(s)
    {
        case SIGHUP:
            if(!RELOAD) {
                RELOAD = 1;
                if(RELOAD_TASK) {
                    tasksignal(RELOAD_TASK, s);
                }
            }
            break;
        default:
            if(!RUNNING) {
                log_info("SIGINT CAUGHT AGAIN, ASSUMING MURDER.");
                MURDER = 1;
            } else {
                RUNNING = 0;
                log_info("SHUTDOWN REQUESTED: %s", MURDER ? "MURDER" : "GRACEFUL (SIGINT again to EXIT NOW)");
                Server *srv = Server_queue_latest();

                if(srv != NULL) {
                    fdclose(srv->listen_fd);
                }
            }
            break;
    }
}
Esempio n. 9
0
int32_t krdsset_p(CSOUND *csound, KREADS *p)
{
    /* open in curdir or pathname */
    char soundiname[1024];
    if (csound->ISSTRCOD(*p->ifilcod))
      strNcpy(soundiname, get_arg_string(csound, *p->ifilcod), 1023);
    else csound->strarg2name(csound, soundiname, p->ifilcod, "readk.", 0);
    if (p->fdch.fd != NULL)
      fdclose(csound, &(p->fdch));
    p->fdch.fd = csound->FileOpen2(csound, &(p->f), CSFILE_STD, soundiname, "rb",
                                   "SFDIR;SSDIR", 0, 0);
    if (UNLIKELY(p->fdch.fd == NULL))
      return csound->InitError(csound, Str("Cannot open %s"), soundiname);
    fdrecord(csound, &p->fdch);
    if ((p->timcount = (int32_t)(*p->iprd * CS_EKR)) <= 0)
      p->timcount = 1;
    p->countdown = 0;
    p->lasts = (char*)csound->Malloc(csound, INITSIZE);
    p->lasts[0] = '\0';
     if (p->str->data == NULL) {
       p->str->data = csound->Calloc(csound, INITSIZE);
       p->str->size = INITSIZE;
    }
    return OK;
}
Esempio n. 10
0
long
_sysclose(int fd)
{
	fdtochan(fd, -1, 0, 0);
	fdclose(fd, 0);

	return 0;
}
Esempio n. 11
0
long
sysclose(ulong *arg)
{
	fdtochan(arg[0], -1, 0, 0);
	fdclose(arg[0], 0);

	return 0;
}
Esempio n. 12
0
void IOBuf_destroy(IOBuf *buf)
{
    if(buf) {
        if(buf->use_ssl) {
            ssl_close_notify(&buf->ssl);
            ssl_free(&buf->ssl);
        }
        
        fdclose(buf->fd);
        h_free(buf);
    }
}
Esempio n. 13
0
int IOBuf_close(IOBuf *buf)
{
    int rc = 0;

    if(buf) {
        if(buf->use_ssl) {
            rc = ssl_close_notify(&buf->ssl);
        }
        
        fdclose(buf->fd);
    }

    return rc;
}
Esempio n. 14
0
		static int ftp_listmake( struct ftpsub_buf *fbf, int sockfd, SORT *p_sort, char *localdir, char *ftpnlstres, int fd, int numfile, int maxgetcnt)
		{
#if 0
			char				csvdate[10+1];
			char				*p_dest;
			int					retval;
			int					getnum;
			int					i;

			/* ファイルリストアップ結果ファイル読み込み */
			if( file_read_p( numfile, ftpnlstres, fd, p_sort ) == ERROR ){
				fdclose( fd, __LINE__ );
				return( ERROR );
			}

			/* 対象ファイルリスト作成 */
			/* csvファイル名からファイルの日付のみを抽出 */
			for( i = 0; i < numfile; i++ ) {
				p_dest = strrchr( p_sort[i].csvname, '.' );
				sprintf( csvdate, "%.10s", p_dest - 10 );
				p_sort[i].csvdate = atoi( csvdate );
			}

			/* ファイルの日付を昇順に入れ替える */
			qsort( p_sort, numfile, sizeof(SORT), (VOID*)date_comp );

			/* 取得ファイル数指定	*/
			/* ・最大取得ファイル数以上は取得しない	*/
			/* ・更新日時が最新のファイルは取得対象外	*/
			if( numfile > maxgetcnt ) {
				getnum = maxgetcnt;
			}
			else {
				getnum = numfile - 1;
			}

			/* 取得ファイルがあるか確認 */
			if( getnum < 1 ){
				tLog_Write( "%s取得ファイルなし", pcstr );
				return( NORMAL );
			}

			/* FTP GET DELETE 呼び出し */
			retval = ftp_get_del( fbf, sockfd, p_sort, localdir, getnum );

			return( retval );
#endif
return 0;
		}
Esempio n. 15
0
void FileRecord_destroy(FileRecord *file)
{
    if(file) {
        if(!file->is_dir) {
            fdclose(file->fd);
            bdestroy(file->date);
            bdestroy(file->last_mod);
            bdestroy(file->header);
            bdestroy(file->etag);
        }
        bdestroy(file->full_path);
        // file->content_type is not owned by us
        free(file);
    }
}
Esempio n. 16
0
File: sysfile.c Progetto: 8l/inferno
int
kfgrpclose(Fgrp *f, int fd)
{
	if(waserror())
		return -1;

	/*
	 * Take no reference on the chan because we don't really need the
	 * data structure, and are calling fdtochan only for error checks.
	 * fdclose takes care of processes racing through here.
	 */
	fdtochan(f, fd, -1, 0, 0);
	fdclose(f, fd);
	poperror();
	return 0;
}
Esempio n. 17
0
void Register_disconnect(int fd)
{
    assert(registrations && "Call Register_init.");

    hnode_t *hn = hash_lookup(registrations, (void *)(intptr_t)fd);

    if(hn) {
        debug("Unregistering %d", fd);

        hash_delete_free(registrations, hn);

        fdclose(fd);
    } else {
        log_err("Ident %d was unregistered but doesn't exist in registrations.", fd);
    }
}
Esempio n. 18
0
void
sysclose(Ar0* ar0, ...)
{
	int fd;
	va_list list;
	va_start(list, ar0);

	/*
	 * int close(int fd);
	 */
	fd = va_arg(list, int);
	va_end(list);

	fdtochan(fd, -1, 0, 0);
	fdclose(fd, 0);

	ar0->i = 0;
}
Esempio n. 19
0
int
sys_socket(struct thread *td, struct socket_args *uap)
{
	struct socket *so;
	struct file *fp;
	int fd, error, type, oflag, fflag;

	AUDIT_ARG_SOCKET(uap->domain, uap->type, uap->protocol);

	type = uap->type;
	oflag = 0;
	fflag = 0;
	if ((type & SOCK_CLOEXEC) != 0) {
		type &= ~SOCK_CLOEXEC;
		oflag |= O_CLOEXEC;
	}
	if ((type & SOCK_NONBLOCK) != 0) {
		type &= ~SOCK_NONBLOCK;
		fflag |= FNONBLOCK;
	}

#ifdef MAC
	error = mac_socket_check_create(td->td_ucred, uap->domain, type,
	    uap->protocol);
	if (error != 0)
		return (error);
#endif
	error = falloc(td, &fp, &fd, oflag);
	if (error != 0)
		return (error);
	/* An extra reference on `fp' has been held for us by falloc(). */
	error = socreate(uap->domain, &so, type, uap->protocol,
	    td->td_ucred, td);
	if (error != 0) {
		fdclose(td, fp, fd);
	} else {
		finit(fp, FREAD | FWRITE | fflag, DTYPE_SOCKET, so, &socketops);
		if ((fflag & FNONBLOCK) != 0)
			(void) fo_ioctl(fp, FIONBIO, &fflag, td->td_ucred, td);
		td->td_retval[0] = fd;
	}
	fdrop(fp, td);
	return (error);
}
Esempio n. 20
0
int sysclose(int fd)
{
	ERRSTACK(1);
	struct fd_table *fdt = &current->open_files;

	if (waserror()) {
		poperror();
		return -1;
	}
	/*
	 * Take no reference on the chan because we don't really need the
	 * data structure, and are calling fdtochan only for error checks.
	 * fdclose takes care of processes racing through here.
	 */
	fdtochan(fdt, fd, -1, 0, 0);
	fdclose(fdt, fd);
	poperror();
	return 0;
}
Esempio n. 21
0
void complete_shutdown(Server *srv)
{
    fdclose(srv->listen_fd);
    int attempts = 0;
    int rc = 0;
    
    rc = taskallsignal(SIGTERM);
    check(rc != -1, "Failed to send the TERM signal to all internal tasks.");

    log_info("Shutting down all running tasks as gracefully as possible.");
    
    // we will always be the last task, so wait until only 1 is running, us
    for(attempts = 0; tasksrunning() > 1 && attempts < 20; attempts++) {
        rc = taskallsignal(SIGTERM);
        check(rc != -1, "Failed to send the TERM signal to internal tasks on attempt: %d.", attempts);
    }

    log_info("Tasks now running (including main task): %d", tasksrunning());

    Control_port_stop();
    rc = Log_term();
    check(rc != -1, "Failed to shutdown the logging subsystem.");

    Setting_destroy();
    MIME_destroy();

    if(access((char *)srv->pid_file->data, F_OK) == 0) {
        log_info("Removing pid file %s", bdata(srv->pid_file));
        rc = unlink((const char *)srv->pid_file->data);
        check(rc != -1, "Failed to unlink pid_file: %s", bdata(srv->pid_file));
    }

    rc = Server_queue_destroy();
    check(rc == 0, "Failed cleaning up the server run queue.");

    Register_destroy();
    fdshutdown();

    taskexitall(0);
error:
    taskexitall(1);
}
Esempio n. 22
0
char *test_IOBuf_send_operations() 
{
    Connection *conn = fake_conn("/dev/null", O_WRONLY);
    mu_assert(conn != NULL, "Failed to allocate buf.");
    IOBuf *buf = conn->iob;
    mu_assert(Register_fd_exists(IOBuf_fd(buf)) != NULL, "Damn fd isn't registered.");

    int rc = IOBuf_send(buf, "012345789", 10);
    mu_assert(!IOBuf_closed(buf), "Should not be closed.");
    mu_assert(rc == 10, "Should have sent 10 bytes.");

    fdclose(IOBuf_fd(buf));
    rc = IOBuf_send(buf, "012345789", 10);
    mu_assert(IOBuf_closed(buf), "Should be closed.");
    mu_assert(rc == -1, "Should send nothing.");

    fake_conn_close(conn);

    return NULL;
}
Esempio n. 23
0
static void
proc_fini(struct proc *p)
{
  /* XXX: do I ever get here when these aren't already closed? */
  fdclose(p->fd[0][0]); p->fd[0][0] = -1;
  fdclose(p->fd[0][1]); p->fd[0][1] = -1;
  fdclose(p->fd[1][0]); p->fd[1][0] = -1;
  fdclose(p->fd[1][1]); p->fd[1][1] = -1;
  fdclose(p->fd[2][0]); p->fd[2][0] = -1;
  fdclose(p->fd[2][1]); p->fd[2][1] = -1;

  string_fini(&p->stdio[0]);
  string_fini(&p->stdio[1]);
  string_fini(&p->stdio[2]);
}
Esempio n. 24
0
/*
 * it is possible here for a failure to occur when stderr is closed.
 */
static void
_fdmove(int oldfd, int newfd)
{
  int r, retry = 0;

restart:
  r = dup2(oldfd, newfd);
  if (-1 == r) {
    switch(errno) {
    case EINTR:
      if (++retry > NPROC + 1) {
        _log_dup2(LOG_INFO, errno, oldfd);
      }
      goto restart;
    default:
      _die_dup2(errno, oldfd);
    }
  }

  fdclose(oldfd);
}
Esempio n. 25
0
int Register_disconnect(int fd)
{
    check(fd < MAX_REGISTERED_FDS, "FD given to register is greater than max.");
    check(fd >= 0, "Invalid FD given for disconnect.");

    Registration *reg = darray_get(REGISTRATIONS, fd);

    check_debug(Register_valid(reg), "Attempt to unregister FD %d which is already gone.", fd);
    check(reg->fd == fd, "Asked to disconnect fd %d but register had %d", fd, reg->fd);

    if(IOBuf_close(reg->data->iob) != 0) {
        debug("Failed to close IOBuffer, probably SSL error.");
    }

    Register_clear(reg);

    // tracking the number of things we're processing
    NUM_REG_FD--;
    return 0;

error:
    fdclose(fd);
    return -1;
}
Esempio n. 26
0
/*
 * We only need open() and close() routines.  open() calls socreate()
 * to allocate a "real" object behind the stream and mallocs some state
 * info for use by the svr4 emulator;  close() deallocates the state
 * information and passes the underlying object to the normal socket close
 * routine.
 */
static  int
streamsopen(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
	struct filedesc *fdp;
	struct svr4_strm *st;
	struct socket *so;
	struct file *fp;
	int family, type, protocol;
	int error, fd;
	
	if (td->td_dupfd >= 0)
	  return ENODEV;

	switch (dev2unit(dev)) {
	case dev_udp:
	  family = AF_INET;
	  type = SOCK_DGRAM;
	  protocol = IPPROTO_UDP;
	  break;

	case dev_tcp:
	  family = AF_INET;
	  type = SOCK_STREAM;
	  protocol = IPPROTO_TCP;
	  break;

	case dev_ip:
	case dev_rawip:
	  family = AF_INET;
	  type = SOCK_RAW;
	  protocol = IPPROTO_IP;
	  break;

	case dev_icmp:
	  family = AF_INET;
	  type = SOCK_RAW;
	  protocol = IPPROTO_ICMP;
	  break;

	case dev_unix_dgram:
	  family = AF_LOCAL;
	  type = SOCK_DGRAM;
	  protocol = 0;
	  break;

	case dev_unix_stream:
	case dev_unix_ord_stream:
	  family = AF_LOCAL;
	  type = SOCK_STREAM;
	  protocol = 0;
	  break;

	case dev_ptm:
	  return svr4_ptm_alloc(td);

	default:
	  return EOPNOTSUPP;
	}

	fdp = td->td_proc->p_fd;
	if ((error = falloc(td, &fp, &fd, 0)) != 0)
	  return error;
	/* An extra reference on `fp' has been held for us by falloc(). */

	error = socreate(family, &so, type, protocol, td->td_ucred, td);
	if (error) {
	   fdclose(fdp, fp, fd, td);
	   fdrop(fp, td);
	   return error;
	}

	finit(fp, FREAD | FWRITE, DTYPE_SOCKET, so, &svr4_netops);

	/*
	 * Allocate a stream structure and attach it to this socket.
	 * We don't bother locking so_emuldata for SVR4 stream sockets as
	 * its value is constant for the lifetime of the stream once it
	 * is initialized here.
	 */
	st = malloc(sizeof(struct svr4_strm), M_TEMP, M_WAITOK);
	st->s_family = so->so_proto->pr_domain->dom_family;
	st->s_cmd = ~0;
	st->s_afd = -1;
	st->s_eventmask = 0;
	so->so_emuldata = st;

	fdrop(fp, td);
	td->td_dupfd = fd;
	return ENXIO;
}
Esempio n. 27
0
/* System calls. */
int
sys_shm_open(struct thread *td, struct shm_open_args *uap)
{
	struct filedesc *fdp;
	struct shmfd *shmfd;
	struct file *fp;
	char *path;
	Fnv32_t fnv;
	mode_t cmode;
	int fd, error;

#ifdef CAPABILITY_MODE
	/*
	 * shm_open(2) is only allowed for anonymous objects.
	 */
	if (IN_CAPABILITY_MODE(td) && (uap->path != SHM_ANON))
		return (ECAPMODE);
#endif

	if ((uap->flags & O_ACCMODE) != O_RDONLY &&
	    (uap->flags & O_ACCMODE) != O_RDWR)
		return (EINVAL);

	if ((uap->flags & ~(O_ACCMODE | O_CREAT | O_EXCL | O_TRUNC)) != 0)
		return (EINVAL);

	fdp = td->td_proc->p_fd;
	cmode = (uap->mode & ~fdp->fd_cmask) & ACCESSPERMS;

	error = falloc(td, &fp, &fd, 0);
	if (error)
		return (error);

	/* A SHM_ANON path pointer creates an anonymous object. */
	if (uap->path == SHM_ANON) {
		/* A read-only anonymous object is pointless. */
		if ((uap->flags & O_ACCMODE) == O_RDONLY) {
			fdclose(fdp, fp, fd, td);
			fdrop(fp, td);
			return (EINVAL);
		}
		shmfd = shm_alloc(td->td_ucred, cmode);
	} else {
		path = malloc(MAXPATHLEN, M_SHMFD, M_WAITOK);
		error = copyinstr(uap->path, path, MAXPATHLEN, NULL);

		/* Require paths to start with a '/' character. */
		if (error == 0 && path[0] != '/')
			error = EINVAL;
		if (error) {
			fdclose(fdp, fp, fd, td);
			fdrop(fp, td);
			free(path, M_SHMFD);
			return (error);
		}

		fnv = fnv_32_str(path, FNV1_32_INIT);
		sx_xlock(&shm_dict_lock);
		shmfd = shm_lookup(path, fnv);
		if (shmfd == NULL) {
			/* Object does not yet exist, create it if requested. */
			if (uap->flags & O_CREAT) {
#ifdef MAC
				error = mac_posixshm_check_create(td->td_ucred,
				    path);
				if (error == 0) {
#endif
					shmfd = shm_alloc(td->td_ucred, cmode);
					shm_insert(path, fnv, shmfd);
#ifdef MAC
				}
#endif
			} else {
				free(path, M_SHMFD);
				error = ENOENT;
			}
		} else {
			/*
			 * Object already exists, obtain a new
			 * reference if requested and permitted.
			 */
			free(path, M_SHMFD);
			if ((uap->flags & (O_CREAT | O_EXCL)) ==
			    (O_CREAT | O_EXCL))
				error = EEXIST;
			else {
#ifdef MAC
				error = mac_posixshm_check_open(td->td_ucred,
				    shmfd, FFLAGS(uap->flags & O_ACCMODE));
				if (error == 0)
#endif
				error = shm_access(shmfd, td->td_ucred,
				    FFLAGS(uap->flags & O_ACCMODE));
			}

			/*
			 * Truncate the file back to zero length if
			 * O_TRUNC was specified and the object was
			 * opened with read/write.
			 */
			if (error == 0 &&
			    (uap->flags & (O_ACCMODE | O_TRUNC)) ==
			    (O_RDWR | O_TRUNC)) {
#ifdef MAC
				error = mac_posixshm_check_truncate(
					td->td_ucred, fp->f_cred, shmfd);
				if (error == 0)
#endif
					shm_dotruncate(shmfd, 0);
			}
			if (error == 0)
				shm_hold(shmfd);
		}
		sx_xunlock(&shm_dict_lock);

		if (error) {
			fdclose(fdp, fp, fd, td);
			fdrop(fp, td);
			return (error);
		}
	}

	finit(fp, FFLAGS(uap->flags & O_ACCMODE), DTYPE_SHM, shmfd, &shm_ops);

	FILEDESC_XLOCK(fdp);
	if (fdp->fd_ofiles[fd] == fp)
		fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
	FILEDESC_XUNLOCK(fdp);
	td->td_retval[0] = fd;
	fdrop(fp, td);

	return (0);
}
Esempio n. 28
0
long
bindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char* spec)
{
	int ret;
	Chan *c0, *c1, *ac, *bc;
	struct{
		Chan	*chan;
		Chan	*authchan;
		char	*spec;
		int	flags;
	}bogus;

	if((flag&~MMASK) || (flag&MORDER)==(MBEFORE|MAFTER))
		error(Ebadarg);

	if(ismount){
		validaddr((ulong)spec, 1, 0);
		spec = validnamedup(spec, 1);
		if(waserror()){
			free(spec);
			nexterror();
		}

		if(up->pgrp->noattach)
			error(Enoattach);

		ac = nil;
		bc = fdtochan(fd, ORDWR, 0, 1);
		if(waserror()) {
			if(ac)
				cclose(ac);
			cclose(bc);
			nexterror();
		}

		if(afd >= 0)
			ac = fdtochan(afd, ORDWR, 0, 1);

		bogus.flags = flag & MCACHE;
		bogus.chan = bc;
		bogus.authchan = ac;
		bogus.spec = spec;
		ret = devno('M', 0);
		c0 = devtab[ret]->attach((char*)&bogus);
		poperror();	/* ac bc */
		if(ac)
			cclose(ac);
		cclose(bc);
	}else{
		spec = 0;
		validaddr((ulong)arg0, 1, 0);
		c0 = namec(arg0, Abind, 0, 0);
	}

	if(waserror()){
		cclose(c0);
		nexterror();
	}

	validaddr((ulong)arg1, 1, 0);
	c1 = namec(arg1, Amount, 0, 0);
	if(waserror()){
		cclose(c1);
		nexterror();
	}

	ret = cmount(&c0, c1, flag, spec);

	poperror();
	cclose(c1);
	poperror();
	cclose(c0);
	if(ismount){
		fdclose(fd, 0);
		poperror();
		free(spec);
	}
	return ret;
}
Esempio n. 29
0
/* Other helper routines. */
static int
ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode,
    unsigned int value, int flags, int compat32)
{
	struct filedesc *fdp;
	struct ksem *ks;
	struct file *fp;
	char *path;
	Fnv32_t fnv;
	int error, fd;

	if (value > SEM_VALUE_MAX)
		return (EINVAL);

	fdp = td->td_proc->p_fd;
	mode = (mode & ~fdp->fd_cmask) & ACCESSPERMS;
	error = falloc(td, &fp, &fd, O_CLOEXEC);
	if (error) {
		if (name == NULL)
			error = ENOSPC;
		return (error);
	}

	/*
	 * Go ahead and copyout the file descriptor now.  This is a bit
	 * premature, but it is a lot easier to handle errors as opposed
	 * to later when we've possibly created a new semaphore, etc.
	 */
	error = ksem_create_copyout_semid(td, semidp, fd, compat32);
	if (error) {
		fdclose(fdp, fp, fd, td);
		fdrop(fp, td);
		return (error);
	}

	if (name == NULL) {
		/* Create an anonymous semaphore. */
		ks = ksem_alloc(td->td_ucred, mode, value);
		if (ks == NULL)
			error = ENOSPC;
		else
			ks->ks_flags |= KS_ANONYMOUS;
	} else {
		path = malloc(MAXPATHLEN, M_KSEM, M_WAITOK);
		error = copyinstr(name, path, MAXPATHLEN, NULL);

		/* Require paths to start with a '/' character. */
		if (error == 0 && path[0] != '/')
			error = EINVAL;
		if (error) {
			fdclose(fdp, fp, fd, td);
			fdrop(fp, td);
			free(path, M_KSEM);
			return (error);
		}

		fnv = fnv_32_str(path, FNV1_32_INIT);
		sx_xlock(&ksem_dict_lock);
		ks = ksem_lookup(path, fnv);
		if (ks == NULL) {
			/* Object does not exist, create it if requested. */
			if (flags & O_CREAT) {
				ks = ksem_alloc(td->td_ucred, mode, value);
				if (ks == NULL)
					error = ENFILE;
				else {
					ksem_insert(path, fnv, ks);
					path = NULL;
				}
			} else
				error = ENOENT;
		} else {
			/*
			 * Object already exists, obtain a new
			 * reference if requested and permitted.
			 */
			if ((flags & (O_CREAT | O_EXCL)) ==
			    (O_CREAT | O_EXCL))
				error = EEXIST;
			else {
#ifdef MAC
				error = mac_posixsem_check_open(td->td_ucred,
				    ks);
				if (error == 0)
#endif
				error = ksem_access(ks, td->td_ucred);
			}
			if (error == 0)
				ksem_hold(ks);
#ifdef INVARIANTS
			else
				ks = NULL;
#endif
		}
		sx_xunlock(&ksem_dict_lock);
		if (path)
			free(path, M_KSEM);
	}

	if (error) {
		KASSERT(ks == NULL, ("ksem_create error with a ksem"));
		fdclose(fdp, fp, fd, td);
		fdrop(fp, td);
		return (error);
	}
	KASSERT(ks != NULL, ("ksem_create w/o a ksem"));

	finit(fp, FREAD | FWRITE, DTYPE_SEM, ks, &ksem_ops);

	fdrop(fp, td);

	return (0);
}
Esempio n. 30
0
/* if dc is non-zero, it means we're doing a mount and dc is the mount device to use. */
static int
bindmount(int dc, int fd, int afd, char* arg0, char* arg1, int flag, char* spec)
{
	Proc *up = externup();
	int i;
	Dev *dev;
	Chan *c0, *c1, *ac, *bc;
	struct{
		Chan	*chan;
		Chan	*authchan;
		char	*spec;
		int	flags;
	}bogus;

	if((flag&~MMASK) || (flag&MORDER)==(MBEFORE|MAFTER))
		error(Ebadarg);

	bogus.flags = flag & MCACHE;

	if(dc){
		if (! checkdc(dc))
			error(Ebadarg);

		if(up->pgrp->noattach)
			error(Enoattach);

		ac = nil;
		bc = fdtochan(fd, ORDWR, 0, 1);
		if(waserror()) {
			if(ac)
				cclose(ac);
			cclose(bc);
			nexterror();
		}

		if(afd >= 0)
			ac = fdtochan(afd, ORDWR, 0, 1);

		bogus.chan = bc;
		bogus.authchan = ac;

		bogus.spec = validaddr(spec, 1, 0);
		if(waserror())
			error(Ebadspec);
		spec = validnamedup(spec, 1);
		poperror();

		if(waserror()){
			free(spec);
			nexterror();
		}

		dev = devtabget(dc, 0);		//XDYNX
		if(waserror()){
			//devtabdecr(dev);
			nexterror();
		}
		c0 = dev->attach((char*)&bogus);
		poperror();
		//devtabdecr(dev);

		poperror();	/* spec */
		free(spec);
		poperror();	/* ac bc */
		if(ac)
			cclose(ac);
		cclose(bc);
	}else{
		bogus.spec = nil;
		c0 = namec(validaddr(arg0, 1, 0), Abind, 0, 0);
	}

	if(waserror()){
		cclose(c0);
		nexterror();
	}

	c1 = namec(validaddr(arg1, 1, 0), Amount, 0, 0);
	if(waserror()){
		cclose(c1);
		nexterror();
	}

	i = cmount(&c0, c1, flag, bogus.spec);

	poperror();
	cclose(c1);
	poperror();
	cclose(c0);
	if(dc)
		fdclose(fd, 0);

	return i;
}