- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
因此,我阅读了有关 Linux 中的文件 I/O 的内容,并想尝试一下。然而,我在代码中遇到了两个奇怪的行为,我正在努力寻找它们的原因。
/*
* This program shows the usage of dup and dup2 functions
*/
#include "creep.h"
#include <fcntl.h>
#define BUFSIZE 2048
int main(int argc, char *argv[]) {
int fd, dup_fd, n;
char buf[BUFSIZE], buff[BUFSIZE];
if (argc != 2)
err_quit("Usage: dup <filename>\n");
fd = open(argv[1], O_RDWR);
while ((n = read(fd, buf, BUFSIZE)) > 0)
if (write(STDOUT_FILENO, buf, n) != n)
err_sys("write error");
if (n < 0)
err_sys("read error");
dup_fd = dup(fd);
while ((n = read(dup_fd, buff, BUFSIZE)) > 0)
if (write(STDOUT_FILENO, buff, n) != n)
err_sys("write error");
if (n < 0)
err_sys("read error");
printf("\nValues are : %d and %d\n", fd, dup_fd);
close(fd);
exit(0);
}
现在,当我运行这个程序时:-
# ./dup dup.c
它实际上只打印文件一次,而不是针对第二个重复的描述符。
我对上面的内容进行了跟踪,希望找出正在发生的事情,但我只能看到这个 ->
open("dup.c", O_RDWR) = 3
read(3, "/*\n * This program shows the usa"..., 2048) = 708
write(1, "/*\n * This program shows the usa"..., 708/
------------omitting the file from trace-------------
read(3, "", 2048) = 0
dup(3) = 4
read(4, "", 2048) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f170112d000
write(1, "\n", 1
) = 1
write(1, "Values are : 3 and 4\n", 21Values are : 3 and 4
) = 21
close(3)
第一次在 fd
上进行读/写调用时,缓冲区中有文件内容,这有点奇怪。但是对于 dup_fd
,缓冲区是空的。我不知道为什么会这样。以前,我两次都使用相同的缓冲区,我认为我应该使用单独的缓冲区,但无济于事。
我读到 dup
函数给出了最小编号的可用文件描述符,它是原始文件描述符的副本。在进程表条目中的文件指针指向文件描述符的同一文件表的意义上是重复的。
为什么我无法读取具有重复文件描述符的文件。我做错了什么吗?
creep.h
头文件:-
/*
* My own header, to be included before all standard system headers written by me.
*/
#ifndef _CREEP_H
#define _CREEP_H
#define _POSIX_C_SOURCE 200809L
#if defined(SOLARIS)
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE 700
#endif
#include <sys/types.h> /* some systems will require this */
#include <sys/stat.h>
#include <sys/termios.h> /* for winsize */
#if defined(MACOS) || !defined(TIOCGWINSZ)
#include <sys/ioctl.h>
#endif
#include <stdio.h> /* for convenience */
#include <stdlib.h> /* for convenience */
#include <stddef.h> /* for offsetof */
#include <string.h> /* for convenience */
#include <unistd.h> /* for convenience */
#include <signal.h> /* for SIG_ERR */
#include <errno.h> /* for definition of errno */
#include <stdarg.h> /* ISO C variable arguments */
#include <syslog.h> /* for convenience */
#define MAXLINE 4096 /* max line length */
/*
* Default file access permissions for new files.
*/
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
/*
* Default permissions for new directories.
*/
#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | SIXOTH)
typedef void Sigfunc(int); /* for signal handlers */
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
/*
* Prototypes for my own functions.
*/
char *path_alloc(size_t *);
long open_max(void);
int set_cloexec(int);
void clr_fl(int, int);
void set_fl(int, int);
void pr_exit(int);
void pr_mask(const char *);
Sigfunc *signal_intr(int, Sigfunc *);
void daemonize(const char *);
void sleep_us(unsigned int);
ssize_t readn(int, void *, size_t);
ssize_t writen(int, const void *, size_t);
int fd_pipe(int *);
int recv_fd(int, ssize_t (*func) (int, const void *, size_t));
int send_fd(int, int);
int send_err(int, int, const char *);
int serv_listen(const char *);
int serv_accept(int, uid_t *);
int cli_conn(const char *);
int buf_args(char *, int (*func)(int, char **));
int tty_cbreak(int);
int tty_raw(int);
int tty_reset(int);
void tty_atexit(void);
struct termios *tty_termios(void);
int ptym_open(char *, int);
int ptys_open(char *);
#ifdef TIOCGWINSZ
pid_t pty_fork(int *, char *, int, const struct termios *, const struct winsize *);
#endif
int lock_reg(int, int, int, off_t, int, off_t);
#define read_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len))
#define readw_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len))
#define write_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len))
#define writew_lcok(fd, offset, whence, len) \
lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len))
#define un_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len))
pid_t lock_test(int, int, off_t, int, off_t);
#define is_read_lockable(fd, offset, whence, len) \
(lock_test((fd), F_RDLCK, (offset), (whence), (len)) == 0)
#define is_write_lockable(fd, offset, whence, len) \
(lock_test((fd), F_WRLCK, (offset), (whence), (len)) == 0)
void err_msg(const char *, ...);
void err_dump(const char *, ...) __attribute__((noreturn));
void err_quit(const char *, ...) __attribute__((noreturn));
void err_cont(int, const char *, ...);
void err_exit(int, const char *, ...) __attribute__((noreturn));
void err_ret(const char *, ...);
void err_sys(const char *, ...) __attribute__((noreturn));
void log_msg(const char *, ...);
void log_open(const char *, int, int);
void log_quit(const char *, ...) __attribute__((noreturn));
void log_ret(const char *, ...);
void log_sys(const char *, ...) __attribute__((noreturn));
void log_exit(int, const char *, ...) __attribute__((noreturn));
void TELL_WAIT(void);
void TELL_PARENT(pid_t);
void TELL_CHILD(pid_t);
void WAIT_PARENT(void);
void WAIT_CHILD(void);
/*
* ERROR Function Definitions
*/
static void err_doit(int, int, const char *, va_list);
/*
* Nonfatal error rleated to a system call.
* Print a message and return.
*/
void err_ret(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
err_doit(1, errno, fmt, ap);
va_end(ap);
}
/*
* Fata error related to a system call.
* Print a message and terminate.
*/
void err_sys(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
err_doit(1, errno, fmt, ap);
va_end(ap);
exit(1);
}
/*
* Nonfatal error unrealted to a system call.
* Error code passed as explicit parameter.
* Print a message and return.
*/
void err_cont(int error, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
err_doit(1, error, fmt, ap);
va_end(ap);
}
/*
* Fatal error unrelated to a system call.
* Error code passed as explicit parameter.
* Print a message and return.
*/
void err_exit(int error, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
err_doit(1, error, fmt, ap);
va_end(ap);
exit(1);
}
/*
* Fatal error related to a system call.
* Print a message, dump core and terminate.
*/
void err_dump(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
err_doit(1, errno, fmt, ap);
va_end(ap);
abort(); /* dump core and terminate */
exit(1); /* shouldn't get here */
}
/*
* Nonfatal error unrelated to a system call.
* Print a message and return.
*/
void err_msg(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
err_doit(0, 0, fmt, ap);
va_end(ap);
}
/*
* Fatale error unrelated to a system call.
* Print a message and terminate.
*/
void err_quit(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
err_doit(0, 0, fmt, ap);
va_end(ap);
exit(1);
}
/*
* Print a message and return to caller.
* Caller specifies "errnoflag".
*/
static void err_doit(int errnoflag, int error, const char *fmt, va_list ap) {
char buf[MAXLINE];
vsnprintf(buf, MAXLINE-1, fmt, ap);
if (errnoflag)
snprintf(buf+strlen(buf), MAXLINE-strlen(buf)-1, ": %s", strerror(error));
strcat(buf, "\n");
fflush(stdout);
fputs(buf, stderr);
fflush(NULL);
}
#if 0
/*
* ERROR Routines for programs that can run as a Daemon.
* Commented out because of undefined reference of log_to_stderr.
*/
static void log_doit(int, int, int, const char *, va_list ap);
/*
* Caller must define and set this: nonzero if
* interactive, zero if daemon
*/
extern int log_to_stderr;
/*
* Initialize syslog(), if running as daemon.
*/
void log_open(const char *ident, int option, int facility) {
if (log_to_stderr == 0)
openlog(ident, option, facility);
}
/*
* Nonfatal error rleated to a system call.
* Print a message with the systems' errno value and return.
*/
void log_ret(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
log_doit(1, errno, LOG_ERR, fmt, ap);
va_end(ap);
}
/*
* Fata error related to a system call.
* Print a message and terminate.
*/
void log_sys(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
log_doit(1, errno, LOG_ERR, fmt, ap);
va_end(ap);
exit(2);
}
/*
* Fatal error unrelated to a system call.
* Error code passed as explicit parameter.
* Print a message and return.
*/
void log_exit(int error, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
log_doit(1, error, LOG_ERR, fmt, ap);
va_end(ap);
exit(2);
}
/*
* Nonfatal error unrelated to a system call.
* Print a message and return.
*/
void log_msg(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
log_doit(0, 0, LOG_ERR, fmt, ap);
va_end(ap);
}
/*
* Fatale error unrelated to a system call.
* Print a message and terminate.
*/
void log_quit(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
log_doit(0, 0, LOG_ERR, fmt, ap);
va_end(ap);
exit(2);
}
/*
* Print a message and return to caller.
* Caller specifies "errnoflag".
*/
static void log_doit(int errnoflag, int error, int priority, const char *fmt, va_list ap) {
char buf[MAXLINE];
vsnprintf(buf, MAXLINE-1, fmt, ap);
if (errnoflag)
snprintf(buf+strlen(buf), MAXLINE-strlen(buf)-1, ": %s", strerror(error));
strcat(buf, "\n");
if (log_to_stderr) {
fflush(stdout);
fputs(buf, stderr);
fflush(stderr);
} else {
syslog(priority, "%s", buf);
}
}
#endif
#endif /* _CREEP_H */
最佳答案
当您到达 dup
时,您的第一个循环已经结束。
为什么结束了?因为你阅读了一切。 fd
位于文件末尾。
然后你复制它。现在您有 2 个 fd
引用同一个文件对象(POSIX 术语中的“打开文件描述”)。它们都在文件末尾。
您需要倒带 (lseek(dup_fd, 0, SEEK_SET)
) 以再次读取文件。请注意,搜索是对文件对象的操作,因此它会影响两个 fd
。您可以将 fd
搜索到位置 0,然后从 dup_fd
中读取,它会再次读取内容。
您甚至可以交替调用 read(fd,...)
和 read(dup_fd,...)
并且您仍然可以获得文件内容如果您只是在阅读时打印每个 block ,则按顺序排列。
关于c - dup 系统调用的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49560602/
我有一个 excel 文件,我需要进行一些更改。我需要识别重复项,然后将“1st”放在第一个 dup 的系列列中。对于其余的重复需要在系列列中放置“其他重复”。可能吗?我尝试了查找和匹配,但没有任何帮
我是一个C初学者,尝试使用dup(),我写了一个程序来测试这个函数,结果和我预期的有点不同。 代码: // unistd.h, dup() test #include #include #incl
我正在尝试创建两个子进程: 一个子进程从文件中读取输入(该文件作为参数传入),并将输出写入管道。 另一个子进程从管道读取其输出并将其输出写入文件,该文件也作为参数传入。 父级为子级设置一些文件描述符,
当我们使用 dup 将 STDOUT 重定向到我们做的管道时: close(1); dup(fd[1]); close(fd[0]); close(fd[1]); execlp("ls","-al",
因此,我阅读了有关 Linux 中的文件 I/O 的内容,并想尝试一下。然而,我在代码中遇到了两个奇怪的行为,我正在努力寻找它们的原因。 /* * This program shows the us
我想知道为什么 dup 总是在下面的代码中返回零(其中一个文件被打开,而不是连续完成 10 个 dup): #include #include #include #include #inclu
我正在开发一个程序,要求用户输入 s、f 或 0 作为用户输入。 S 向系统打印预定义消息,f 将该预定义消息写入用户作为参数提供的文件。 0 终止程序。 我需要让程序只有一个写入标准输出的写入语句。
我正在在线学习算法类(class),我正在尝试计算数字列表中的最大成对乘积。这个问题之前已经回答过: maximum pairwise product fast solution和 Python fo
我想知道为什么以下字节码中的异常(用于抛出异常)是重复的。 NEW java/lang/IllegalArgumentException DUP INVOKESPECIAL java/lang/Ill
我正在编写代码以将 stdout 重定向到一个文件(例如 ls 返回到一个文件的结果)并且 dup2() 函数不重定向我的输出。这是我的代码: void testDup() { int new
close(fileno(stdout)); int fd = dup(fileno(stdin)); //printf("Hello World\n"); write(fd, "Hell
目前我只是在一个使用 java 字节码的项目中。我通常看到,当创建一个新的类实例并在其上调用一个方法时,字节码将是这样的: NEW DUP INVOKESPECIAL > 这里为什么要做“DUP”?
当涉及到复制文件描述符时,我能得到一个关于 dup() 函数的非常简单的解释吗?我想使用管道,但我还必须让 child 从管道中读取(这是简单的部分),但将数据写回父级。我应该使用另一根管道,还是可以
>> a = 5 => 5 >> b = "hello, world!" => "hello, world!" >> b.dup => "hello, world!" >> a.dup TypeErr
我对这个用于教育目的的小代码有疑问。我不明白它是如何工作的。 #include #include #define FNAME "info.txt" #define STDIN 0 int main
Java字节码指令集提供various forms of dup instruction 。我无法理解这些指令和 swap 指令的用途。哪些 Java 代码在编译时会使用这些指令生成字节码? 最佳答案
鉴于以下信息,我如何在唯一的 params 和 cron_action_id 对上选择最新的订单项(基于 time_entered)还没被处决吗? cron_schedule 例如,id 1、2和4具
int mypipe[2]; pipe(mypipe); int dupstdout=dup2(mypipe[1],1); cout<<"hello";//not printed on termina
我一直想创建一个 fork 两次以创建两个子进程的子进程。随着一个的输出,发送到另一个。我找到了这个示例代码。但我对它的工作原理感到困惑。 我找到了一个 example here .但我对 dup 的
所以我尝试使用 dup() 将标准输出重定向到一个文件。 int save_fd; save_fd=dup(1); //saves the current stdout close(1); //clo
我是一名优秀的程序员,十分优秀!