dup(2)

久々にカーネルのコードも覗いてみよう.Plan9dup(2)はUNIXのdup2相当で,dup,dup2の区別はない.dupの挙動がわかっていれば,読むのは簡単だろう.ChanはUNIXのオープンファイル構造体だと思えばよく,f->fd[]はプロセスごとのファイル記述子表である.

9/port/sysfile.c
 long
 sysdup(ulong *arg)
 {
	int fd;
	Chan *c, *oc;
	Fgrp *f = up->fgrp;

	/*
	 * Close after dup'ing, so date > #d/1 works
	 */
	c = fdtochan(arg[0], -1, 0, 1);
	fd = arg[1];
	if(fd != -1){
		lock(f);
		if(fd<0 || growfd(f, fd)<0) {
			unlockfgrp(f);
			cclose(c);
			error(Ebadfd);
		}
		if(fd > f->maxfd)
			f->maxfd = fd;

		oc = f->fd[fd];
		f->fd[fd] = c;
		unlockfgrp(f);
		if(oc)
			cclose(oc);
	}else{
		if(waserror()) {
			cclose(c);
			nexterror();
		}
		fd = newfd(c);
		if(fd < 0)
			error(Enofd);
		poperror();
	}

	return fd;
}