LINUX.ORG.RU

https://cvsweb.openbsd.org/checkout/src/sys/kern/kern_descrip.c?rev=1.213

/*
 * Duplicate a file descriptor.
 */
int
sys_dup(struct proc *p, void *v, register_t *retval)
{
	struct sys_dup_args /* {
		syscallarg(int) fd;
	} */ *uap = v;
	struct filedesc *fdp = p->p_fd;
	int old = SCARG(uap, fd);
	struct file *fp;
	int new;
	int error;

restart:
	if ((fp = fd_getfile(fdp, old)) == NULL)
		return (EBADF);
	fdplock(fdp);
	if ((error = fdalloc(p, 0, &new)) != 0) {
		if (error == ENOSPC) {
			fdexpand(p);
			fdpunlock(fdp);
			FRELE(fp, p);
			goto restart;
		}
		fdpunlock(fdp);
		FRELE(fp, p);
		return (error);
	}
	/* No need for FRELE(), finishdup() uses current ref. */
	return (finishdup(p, fp, old, new, retval, 0));
}

PS: только вот на кой оно тебе?

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)

c
реализацию команды dup

#include <stdio.h>

int main()
{
    printf("dup!\n");
    return 0;
}
dataman ★★★★★
()
Ответ на: комментарий от beastie

на кой

ТС, похоже, читает книгу «Керриск LINUX API ИСЧЕРПЫВАЮЩЕЕ РУКОВОДСТВО» И решает задачу 5.4:

Реализуйте функци dup() и dup2() используя функцию fcntl()...

Предпологается, что будет использовано fcntl( F_DUPFD). При условии, что TC:

я на C никогда раньше не писал, только учусь

Видимо, ему тяжело и ЯП и API одновременно изучать, просит помощи зала.

mky ★★★★★
()
Ответ на: комментарий от mky

В таком случае, ему надо бы свалиться в fallback на K&R :) Хотя, последнюю авторы писали вроде как для тех, кто уже знаком с программированием. В таком случае, я бы тоже спросил, кого почитать. И что бы мне посоветовали? Столярова? :)

yars068 ★★★★★
()
Ответ на: комментарий от brynzacom

Тут мы вообще-то глубоко в ядре. dup – это системный вызов. Ваше ядро может отличаться.

Может стоит начать с minix:

int dup(fd)
int fd;
{
  return(fcntl(fd, F_DUPFD, 0));
}
beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 2)
Ответ на: комментарий от beastie
struct file *
fd_getfile_mode(struct filedesc *fdp, int fd, int mode)
{
	struct file *fp;

	KASSERT(mode != 0);

	fp = fd_getfile(fdp, fd);
	if (fp == NULL)
		return (NULL);

	if ((fp->f_flag & mode) == 0) {
		FRELE(fp, curproc);
		return (NULL);
	}

	return (fp);
}

Плиз, поплыл… Я пишу свою реализацию dup по заданию из книги М. Керриска, и мне нужно определить функцию для получения указателя на struct proc.

brynzacom
() автор топика
Ответ на: комментарий от brynzacom

LINUX API ИСЧЕРПЫВАЮЩЕЕ РУКОВОДСТВО

Не читал, но осуждаю. ;)

Глава 5.5, страница 131:

#include <unistd.h>
int dup(int oldfd);
// При успешном завершении возвращает новый файловый дескриптор,
// а при ошибке выдает -1

Это таки очень похоже на Minix. Черпайте идеи от туда.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 3)

Кто-нибудь может показать реализацию команды dup?

вот Алиса может:

me: glibc dup source
alice: Исходный код функции dup из glibc действительно можно найти — он лежит в файле glibc-source-version/sysdeps/posix/dup.c

https://github.com/bminor/glibc/blob/master/sysdeps/posix/dup.c

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>


/* Duplicate FD, returning a new file descriptor open on the same file.  */
int
__dup (int fd)
{
  return __fcntl (fd, F_DUPFD, 0);
}
libc_hidden_def (__dup)
weak_alias (__dup, dup)

И упрекнуть не в чем, 100% верный ответ на поставленный вопрос ;-)

MKuznetsov ★★★★★
()
Ответ на: комментарий от brynzacom

dup и то, что ты написал, вызывают тот же код

во первых я ничего такого не написал, просто процитировал Алису ;-) тут с ней не поспорить, это действительно реализация функции int dup(int fd)

можете сами переспросить. Она довольно подкованная, заодно расскажет что это posix fallback и что/когда используется вместо него. Спойлер: впрямую syscall.

сейчас всё-же просто и быстро: раз нужен dup то смотришь его исходник(в glibc или musl) и читаешь доки. Сорцы glibc довольно немаленькие и документация нев"№енная, поэтому совмещаешь с допростом AI-шек. Аналогично про реализацию dup в ядре.

MKuznetsov ★★★★★
()
Ответ на: комментарий от brynzacom

Никак, тот код из ядра, а у тебя речь про пользовательскую программу. Это совсем разные вещи.

firkax ★★★★★
()
Ответ на: комментарий от yars068

В теме ТС (другой, удалённой) писали про книгу Modern C by Jens Gustedt. Но, вроде, она только на буржуйском. А Столяров, вроде как, вобще против, чтобы Си был первым ЯП.

ТС не пишет, насколько он знаком с программированием и не хочет простых путей. Он раскладывает код по разным файлам, но не понимает, что принято писать в «*.h». Я не знаю, есть ли такая книга, которая бы с самого начала учила писать каждую функцию в свой файл и запускать компилятор через bash-скрипт...

mky ★★★★★
()
Ответ на: комментарий от firkax

Minix всё же более удобоварим, чем потроха Linux. Если уж подсматривать, то там.

А может быть даже лучше в UNIX™ V7.

v7/usr/sys/sys/sys3.c

/*
 * the dup system call.
 */
dup()
{
        register struct file *fp;
        register struct a {
                int     fdes;
                int     fdes2;
        } *uap;
        register i, m;

        uap = (struct a *)u.u_ap;
        m = uap->fdes & ~077;
        uap->fdes &= 077;
        fp = getf(uap->fdes);
        if(fp == NULL)
                return;
        if ((m&0100) == 0) {
                if ((i = ufalloc()) < 0)
                        return;
        } else {
                i = uap->fdes2;
                if (i<0 || i>=NOFILE) {
                        u.u_error = EBADF;
                        return;
                }
                u.u_r.r_val1 = i;
        }
        if (i!=uap->fdes) {
                if (u.u_ofile[i]!=NULL)
                        closef(u.u_ofile[i]);
                u.u_ofile[i] = fp;
                fp->f_count++;
        }
}
beastie ★★★★★
()
Ответ на: комментарий от mky

Я помню, когда нам в институте лабы на сишке задали, никто нам перед этим сишку не преподавал. Препод по ОС, узнав, что мы знаем только Паскаль сказал, что ну, придется вам самим сишку изучать. Идите в библиотеку и ищите книги. Вроде даже не дал никаких рекомендаций по конкретным книгам.

seiken ★★★★★
()
Ответ на: комментарий от seiken

Ну, если знать Паскаль досканально, то Cи особо ничего нового и не содержит. В Паскале и указатели, в принципе есть, и компилятор сообщения об ошибках пишет. И, не знаю как сейчас, но раньше в институтах любили Турбо Паскаль и Турбо Си, там была кнопочка «скомпилировать», а весь исходник лабы в одном файле был. В таком случае Паскаль -> Си не так уж сложно.

ЕМНИП, на каких-то лабах мы должны были какую-то стороннюю библиотеку использовать, но нам там разжевали, где должен быть файл с библиотекой, куда что добавить, чтобы она подключилась и т.д. Это ведь больше к компилятору/IDE относится и в книгах по ЯП про это обычно не пишут. А ТС хочет сразу один файл набрал из книги, другой файл скачал с гитхаба, запустил bash-скрипт и оно раз и скомпилилось.

Вроде даже не дал никаких рекомендаций по конкретным книгам.

Преподы разные бывают, нормальные обычно знают, какие книги есть в библиотеке ВУЗ'а и какие из них в большом количестве экземпляров.

mky ★★★★★
()
Ответ на: комментарий от mky

в книгах по ЯП про это обычно не пишут.

В том же K&R там про это есть, но досконально препроцессор вроде не изучается – я ещë всë не прочëл, завис на пятой главе :)

yars068 ★★★★★
()
Ответ на: комментарий от yars068

в книгах по ЯП про это обычно не пишут.

В том же K&R там про это есть,

Нет, нету. И явно оговорено - что это всё вопросы инструментария, RTFM. Конкретно их примеры работают искарбоки на Unix и его точных (в смысле поведения оболочки / команд) клонах - BSD / GNU Linux.

LamerOk ★★★★★
()
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария