Esempio n. 1
0
/*
 *  Given a process id, iterate through all open files of that process
 *  looking for a match to the target file, and then determine how it
 *  is being used by that process.  This is quite different in QNX to
 *  UNIX, as chroot and chdir do not hold open a reference to the file.
 *  The iteration process attempts to dup each file descriptor into
 *  this process, so it can then be queried; attempt to skip things which
 *  aren't files (heuristic guess) and use a timeout as self-defence.
 */
int howused(pid_t pid, match_t *match)
{
struct _server_info	sinfo;
struct _fdinfo		finfo;
struct stat			st;
io_dup_t			msg;
uint64_t			to;
int					fd, coid, usage;

	usage = 0;
	for (fd = 0; (fd = ConnectServerInfo(pid, fd, &sinfo)) != -1; ++fd) {
		if ((pid != sinfo.pid || !(fd & _NTO_SIDE_CHANNEL)) && (coid = ConnectAttach(sinfo.nd, sinfo.pid, sinfo.chid, 0, _NTO_COF_CLOEXEC)) != -1) {
			msg.i.type = _IO_DUP;
			msg.i.combine_len = sizeof(msg.i);
			msg.i.info.nd = netmgr_remote_nd(sinfo.nd, ND_LOCAL_NODE);
			msg.i.info.pid = pid;
			msg.i.info.chid = sinfo.chid;
			msg.i.info.scoid = sinfo.scoid;
			msg.i.info.coid = fd;
			TimerTimeout(CLOCK_MONOTONIC, _NTO_TIMEOUT_SEND | _NTO_TIMEOUT_REPLY, NULL, (to = 1000000000LL, &to), NULL);
			if (MsgSend(coid, &msg.i, sizeof(msg.i), NULL, 0) == -1) {
				ConnectDetach(coid);
			}
			else {
				if (fstat(coid, &st) != -1 && ismatch(match, st.st_dev, st.st_ino)) {
					if (iofdinfo(coid, 0, &finfo, NULL, 0) == -1 || sinfo.pid != PATHMGR_PID || finfo.mode != 0)
						usage |= USED_OPEN;
				}
				close(coid);
			}
		}
	}
	return(usage);
}
Esempio n. 2
0
int connectslaves(slave_t *pslave) {
	for(int i=0; i<pslave->amount; ++i) {
		if((pslave->pslave[i].coid != ConnectServerInfo(0, pslave->pslave[i].coid, NULL))
			|| (pslave->pslave[i].status == DOWN)) {
			pslave->pslave[i].coid = name_open(pslave->pslave[i].name, NAME_FLAG_ATTACH_GLOBAL);
			pslave->pslave[i].clientnow = 0;
			if(pslave->pslave[i].coid == -1) {
				perror(pslave->pslave[i].name);
				pslave->pslave[i].status = DOWN;
			} else {
				pslave->pslave[i].status = READY;
			}
		}
	}
	return EXIT_SUCCESS;
}
Esempio n. 3
0
int main(int argc, char *argv[]) {
    int server_coid, a_coid;
    short msg;
    int a_chid;
    struct _asyncmsg_connection_attr aca;
    struct _server_info sinfo;
    int count = 1;

    /* look for server */
    server_coid = name_open( RECV_NAME, 0 );
    while( server_coid == -1 )
    {
      sleep(1);
      server_coid = name_open( RECV_NAME, 0 );
    }

        /* need server's pid, use this to get server info including pid */
        ConnectServerInfo( 0, server_coid, &sinfo );

        /* send message to server request the asynchronous channel id */
        msg = GET_ACHID;
    if (MsgSend( server_coid, &msg, sizeof( msg ), &a_chid, sizeof(a_chid) ))
    {
        perror(PROGNAME "MsgSend");
        exit( EXIT_FAILURE );
    }
    
    /* setup array of send buffers */
    memset(&aca, 0, sizeof(aca));
    aca.buffer_size = 2048;
    aca.max_num_buffer = 5;  /* don't locally accumulate more than 5 buffers */
    aca.trigger_num_msg = 1; /* deliver each message as it is sent */
    aca.call_back = callback; /* call this function after messages are sent */

    /* create my asynchronous connection to the server */
    a_coid = asyncmsg_connect_attach( 0, sinfo.pid, a_chid, 0, 0, &aca );
    if( -1 == a_coid )
    {
        perror( "async connect");
        printf("server pid is %d\n", sinfo.pid );
        exit( EXIT_FAILURE );
    }

    while(1)
    {   int ret, len;
        char buf[80];

        len = sprintf(buf, "message #%d", count)+1;
        printf("sending %dth time\n", count );

        /* deliver message to server, the count value will be passed into
         * my callback as the "handle"
         */
        ret = asyncmsg_put( a_coid, buf, len, count, NULL );
        if( -1 == ret )
        {
                perror( "put");
                exit( EXIT_FAILURE );
        }
        count++;
        sleep(1);
    }
}
Esempio n. 4
0
int aio_cancel(int fd, struct aiocb *aiocbp)
{
	unsigned flag, ret;
	int ncancled, ndone, nprogress;
	struct aiocb *ap, **app;
	struct _aio_prio_list *plist, **pplist;
	struct _server_info sinfo;
	
	if (!_aio_cb && _aio_init(NULL)) {
		return -1;
	}

	_mutex_lock(&_aio_cb->cb_mutex);
	/* a single aiocbp */
	if (aiocbp) {
		flag = atomic_clr_value(&aiocbp->_aio_flag, _AIO_FLAG_QMASK);
		if (flag & _AIO_FLAG_DONE) {
			ret = AIO_ALLDONE;
		} else if (flag & _AIO_FLAG_IN_PROGRESS) {
			ret = AIO_NOTCANCELED;
		} else if (flag & _AIO_FLAG_ENQUEUE) {
			if ((plist = (struct _aio_prio_list *)aiocbp->_aio_plist) == NULL) {
				errno = EINVAL;
				return -1;
			}

			/* find the aiocbp */
			for (app = &plist->head, ap = *app; ap; app = &ap->_aio_next, ap = ap->_aio_next) {
				if (ap == aiocbp && (*app = ap->_aio_next) == NULL) {
					plist->tail = app;
					/* Even if there is no request hang on this priority list,
					 * we will not remove it now. remove a priority list entry
					 * causing a single list search, and we have reason to
					 * believe the entry will be reused soon.
					 * The empty entry will be removed later on, by the
					 * _aio_block() internal function, when it try to get a
					 * request.
					 */
#if 0
					if (plist->head == NULL) {
						for (pplist = &_aio_cb->cb_plist; *pplist; pplist = &((*pplist)->next)) {
							if (*pplist == plist) {
								*pplist = plist->next;
								plist->next = _aio_cb->cb_plist_free;
								_aio_cb->cb_plist_free = plist;
								break;
							}
						}
					}
#endif
				}
				break;
			}
			
			if (flag & _AIO_FLAG_SUSPEND) {
				struct _aio_waiter *w = aiocbp->_aio_suspend;
				
				aiocbp->_aio_suspend = NULL;
				if (w && atomic_sub_value(&w->w_count, 1) == 0) {
					  pthread_cond_signal(&w->w_cond);
				}
			}
			aiocbp->_aio_flag = 0;
			aiocbp->_aio_error = ECANCELED;
			aiocbp->_aio_result = (unsigned)-1;
			ret = AIO_CANCELED;
		} else {
			/* we haven't seen this yet */
			errno = EINVAL;
			ret = (unsigned)-1;
		}
		_mutex_unlock(&_aio_cb->cb_mutex);
		return ret;
	}

	/* got to scan the whole list for fd */
	ncancled = ndone = nprogress = 0;
	for (pplist = &_aio_cb->cb_plist, plist = *pplist; plist; pplist = &plist->next, plist = *pplist)
	{
		for (app = &plist->head, ap = *app; ap; ap = *app) {
			if (ap->aio_fildes == fd)
			{
				flag = atomic_clr_value(&ap->_aio_flag, _AIO_FLAG_QMASK);
				if (flag & _AIO_FLAG_DONE) {
					ndone++;
				} else if (flag & _AIO_FLAG_IN_PROGRESS) {
					nprogress++;
				} else if (flag & _AIO_FLAG_ENQUEUE) {
					if ((*app = ap->_aio_next) == NULL) {
						plist->tail = app;
						/* Don't remove empty entry (see above), leave it
						 * for _aio_block().
						 */
#if 0
						if (plist->head == NULL) {
							for (pplist = &_aio_cb->cb_plist; *pplist; pplist = &((*pplist)->next)) {
								if (*pplist == plist) {
									*pplist = plist->next;
									plist->next = _aio_cb->cb_plist_free;
									_aio_cb->cb_plist_free = plist;
								}
							}
						}
#endif
					}
					ap->_aio_flag = 0;
					ap->_aio_error = ECANCELED;
					ap->_aio_result = (unsigned)-1;
					ncancled++;
				}
			} else {
				app = &ap->_aio_next;
			}
		}
	}
	_mutex_unlock(&_aio_cb->cb_mutex);
	
	if (nprogress) 
	  return AIO_NOTCANCELED;
	
	if (!ncancled) {
		if (ndone) {
			/* all affected operations have completed */ 
			return AIO_ALLDONE;
		} else {
			/* no operations matched the supplied fd, POSIX required to check
			 * if this is a valid fd. PR#51564
			 */
			if (ConnectServerInfo(0, fd, &sinfo) != fd) {
				errno = EBADF;
				return (unsigned)-1;
			} else {
				return AIO_ALLDONE;
			}
		}
	}

	return AIO_CANCELED;
}
Esempio n. 5
0
int _vfcntl(int fd, int cmd, va_list ap) {
	union {
		io_dup_t						dup;
		io_space_t						space;
		io_lock_t						lock;
	}								msg;
	iov_t							iov[4];
	int								arg;
	pid_t	pid;

	switch(cmd) {
	case F_DUPFD: {
		struct _server_info				info;
		int								fd2;
		if(fd == -1 || (fd & _NTO_SIDE_CHANNEL) || ConnectServerInfo(0, fd, &info) != fd) {
			errno = EBADF;
			return -1;
		}
		if((fd2 = va_arg(ap, int)) < 0 || (fd2 & _NTO_SIDE_CHANNEL)) {
			errno = EINVAL;
			return -1;
		}		
		if((fd2 = ConnectAttach(info.nd, info.pid, info.chid, fd2, _NTO_COF_CLOEXEC)) == -1) {
			return -1;
		}
		msg.dup.i.type = _IO_DUP;
		msg.dup.i.combine_len = sizeof msg.dup;
		msg.dup.i.info.nd = netmgr_remote_nd(info.nd, ND_LOCAL_NODE);
		msg.dup.i.info.pid = getpid();
		msg.dup.i.info.chid = info.chid;
		msg.dup.i.info.scoid = info.scoid;
		msg.dup.i.info.coid = fd;
		if(MsgSendnc(fd2, &msg.dup.i, sizeof msg.dup.i, 0, 0) == -1) {
			ConnectDetach_r(fd2);
			return -1;
		}
		ConnectFlags_r(0, fd2, FD_CLOEXEC, 0);
		return fd2;
	}

	case F_GETFD:
		return ConnectFlags(0, fd, 0, 0);

	case F_SETFD:
		return ConnectFlags(0, fd, ~0, va_arg(ap, int));
		
	case F_GETFL:
		if(_devctl(fd, DCMD_ALL_GETFLAGS, &arg, sizeof arg, 0) == -1) {
			return -1;
		}
		return arg;

	case F_SETFL:
		arg = va_arg(ap, int);
		return _devctl(fd, DCMD_ALL_SETFLAGS, &arg, sizeof arg, _DEVCTL_FLAG_NORETVAL);

	case F_GETOWN:
		if(_devctl(fd, DCMD_ALL_GETOWN, &pid, sizeof pid, 0) == -1) {
			return -1;
		}
		return pid;
		
	case F_SETOWN:
		pid = va_arg(ap, pid_t);
		return _devctl(fd, DCMD_ALL_SETOWN, &pid, sizeof pid, _DEVCTL_FLAG_NORETVAL);
		
	case F_ALLOCSP64:
	case F_FREESP64: {
		flock64_t				*area = va_arg(ap, flock64_t *);

		msg.space.i.start = area->l_start;
		msg.space.i.len = area->l_len;
		msg.space.i.whence = area->l_whence;
		goto common;
	}
	case F_ALLOCSP:
		cmd = F_ALLOCSP64;	/* Always pass the 64 bit values */
		goto stuff;
	case F_FREESP:
		cmd = F_FREESP64;	/* Always pass the 64 bit values */
stuff: {
		flock_t					*area = va_arg(ap, flock_t *);

		msg.space.i.start = area->l_start;
		msg.space.i.len = area->l_len;
		msg.space.i.whence = area->l_whence;
	}
common:
		msg.space.i.type = _IO_SPACE;
		msg.space.i.combine_len = sizeof msg.space.i;
		msg.space.i.subtype = cmd;
		return MsgSend(fd, &msg.space.i, sizeof msg.space.i, 0, 0);

	case F_GETLK:
	case F_SETLK:
	case F_SETLKW:
	case F_GETLK64:
	case F_SETLK64:
	case F_SETLKW64:
		msg.lock.i.type = _IO_LOCK;
		msg.lock.i.combine_len = sizeof msg.lock.i;
		msg.lock.i.subtype = cmd;
		SETIOV(iov + 0, &msg.lock.i, sizeof msg.lock.i);
		SETIOV(iov + 1, va_arg(ap, flock_t *), sizeof(flock_t));
		iov[3] = iov[1];
		SETIOV(iov + 2, &msg.lock.o, sizeof msg.lock.o);
		return MsgSendv(fd, iov + 0, 2, iov + 2, (cmd == F_GETLK || cmd == F_GETLK64) ? 2 : 1);
		
	default:
		break;
	}

	errno = EINVAL;
	return -1;
}