📄 file.c
字号:
FILE * stream){ int ch; char *line = alloc(AGETS_LINE_INCR); size_t line_size = 0; size_t loffset = 0; int inquote = 0; int escape = 0; (void)sourcefile; /* Quiet unused parameter warning if not debugging */ (void)lineno; /* Quiet unused parameter warning if not debugging */ while ((ch = fgetc(stream)) != EOF) { if (ch == '\n') { if (!inquote) { if (escape) { escape = 0; loffset--; /* Consume escape in buffer */ continue; } /* Reached end of line so exit without passing on LF */ break; } } if (ch == '\\') { escape = 1; } else { if (ch == '"') { if (!escape) inquote = !inquote; } escape = 0; } if ((loffset + 1) >= line_size) { char *tmpline; /* * Reallocate input line. * alloc() never return NULL pointer. */ tmpline = alloc(line_size + AGETS_LINE_INCR); memcpy(tmpline, line, line_size); amfree(line); line = tmpline; line_size = line_size + AGETS_LINE_INCR; } line[loffset++] = (char)ch; } if ((ch == EOF) && (loffset == 0)) { amfree(line); /* amfree zeros line... */ } else { line[loffset] = '\0'; } /* * Return what we got even if there was not a newline. * Only report done (NULL) when no data was processed. */ return line;}/* *===================================================================== * Find/create a buffer for a particular file descriptor for use with * areads(). * * void areads_getbuf (const char *file, size_t line, int fd) * * entry: file, line = caller source location * fd = file descriptor to look up * exit: returns a pointer to the buffer, possibly new *===================================================================== */static struct areads_buffer { char *buffer; char *endptr; size_t bufsize;} *areads_buffer = NULL;static int areads_bufcount = 0;static size_t areads_bufsize = BUFSIZ; /* for the test program */static voidareads_getbuf( const char *s, int l, int fd){ struct areads_buffer *new; size_t size; assert(fd >= 0); if(fd >= areads_bufcount) { size = (size_t)(fd + 1) * SIZEOF(*areads_buffer); new = (struct areads_buffer *) debug_alloc(s, l, size); memset((char *)new, 0, size); if(areads_buffer) { size = areads_bufcount * SIZEOF(*areads_buffer); memcpy(new, areads_buffer, size); } amfree(areads_buffer); areads_buffer = new; areads_bufcount = fd + 1; } if(areads_buffer[fd].buffer == NULL) { areads_buffer[fd].bufsize = areads_bufsize; areads_buffer[fd].buffer = debug_alloc(s, l, areads_buffer[fd].bufsize + 1); areads_buffer[fd].buffer[0] = '\0'; areads_buffer[fd].endptr = areads_buffer[fd].buffer; }}/* *===================================================================== * Return the amount of data still in an areads buffer. * * ssize_t areads_dataready (int fd) * * entry: fd = file descriptor to release buffer for * exit: returns number of bytes of data ready to process *===================================================================== */ssize_tareads_dataready( int fd){ ssize_t r = 0; if(fd >= 0 && fd < areads_bufcount && areads_buffer[fd].buffer != NULL) { r = (ssize_t) (areads_buffer[fd].endptr - areads_buffer[fd].buffer); } return r;}/* *===================================================================== * Release a buffer for a particular file descriptor used by areads(). * * void areads_relbuf (int fd) * * entry: fd = file descriptor to release buffer for * exit: none *===================================================================== */voidareads_relbuf( int fd){ if(fd >= 0 && fd < areads_bufcount) { amfree(areads_buffer[fd].buffer); areads_buffer[fd].endptr = NULL; areads_buffer[fd].bufsize = 0; }}/* *===================================================================== * Get the next line of input from a file descriptor. * * char *areads (int fd) * * entry: fd = file descriptor to read * exit: returns a pointer to an alloc'd string or NULL at EOF * or error (errno will be zero on EOF). * * Notes: the newline, if read, is removed from the string * the caller is responsible for free'ing the string *===================================================================== */char *debug_areads ( const char *s, int l, int fd){ char *nl; char *line; char *buffer; char *endptr; char *newbuf; size_t buflen; size_t size; ssize_t r; if(fd < 0) { errno = EBADF; return NULL; } areads_getbuf(s, l, fd); buffer = areads_buffer[fd].buffer; endptr = areads_buffer[fd].endptr; buflen = areads_buffer[fd].bufsize - (size_t)(endptr - buffer); while((nl = strchr(buffer, '\n')) == NULL) { /* * No newline yet, so get more data. */ if (buflen == 0) { if ((size = areads_buffer[fd].bufsize) < 256 * areads_bufsize) { size *= 2; } else { size += 256 * areads_bufsize; } newbuf = debug_alloc(s, l, size + 1); memcpy (newbuf, buffer, areads_buffer[fd].bufsize + 1); amfree(areads_buffer[fd].buffer); areads_buffer[fd].buffer = newbuf; areads_buffer[fd].endptr = newbuf + areads_buffer[fd].bufsize; areads_buffer[fd].bufsize = size; buffer = areads_buffer[fd].buffer; endptr = areads_buffer[fd].endptr; buflen = areads_buffer[fd].bufsize - (size_t)(endptr - buffer); } if ((r = read(fd, endptr, buflen)) <= 0) { if(r == 0) { errno = 0; /* flag EOF instead of error */ } return NULL; } endptr[r] = '\0'; /* we always leave room for this */ endptr += r; buflen -= r; } *nl++ = '\0'; line = stralloc(buffer); size = (size_t)(endptr - nl); /* data still left in buffer */ memmove(buffer, nl, size); areads_buffer[fd].endptr = buffer + size; areads_buffer[fd].endptr[0] = '\0'; return line;}int robust_open(const char * pathname, int flags, mode_t mode) { int result = -1; int e_busy_count = 0; for (;;) { if (flags & O_CREAT) { result = open(pathname, flags, mode); } else { result = open(pathname, flags); } if (result < 0) {#ifdef EBUSY /* EBUSY is a tricky one; sometimes it is synonymous with EINTR, but sometimes it means the device is open elsewhere (e.g., with a tape drive on Linux). We take the middle path and retry, but with limited patience. */ if (errno == EBUSY && e_busy_count < 10) { e_busy_count ++; continue; } else#endif if (0 /* Always retry on EINTR; if the caller did not specify non-blocking mode, then also retry on EAGAIN or EWOULDBLOCK. */#ifdef EINTR || errno == EINTR#endif || ( 1#ifdef O_NONBLOCK && !(flags & O_NONBLOCK)#endif && ( 0#ifdef EAGAIN || errno == EAGAIN#endif#ifdef EWOULDBLOCK || errno == EWOULDBLOCK#endif ) ) ) { /* Try again */ continue; } else { /* Failure. */ return result; } } else { break; } }#ifdef F_SETFD if (result >= 0) { fcntl(result, F_SETFD, 1); /* Throw away result. */ }#endif return result;}int robust_close(int fd) { for (;;) { int result; result = close(fd); if (result != 0 && (0#ifdef EINTR || errno == EINTR#endif#ifdef EBUSY || errno == EBUSY#endif#ifdef EAGAIN || errno == EAGAIN#endif#ifdef EWOULDBLOCK || errno == EWOULDBLOCK#endif )) { continue; } else { return result; } }}uid_tget_client_uid(void){ static uid_t client_uid = (uid_t) -1; struct passwd *pwent; if(client_uid == (uid_t) -1 && (pwent = getpwnam(CLIENT_LOGIN)) != NULL) { client_uid = pwent->pw_uid; endpwent(); } return client_uid;}gid_tget_client_gid(void){ static gid_t client_gid = (gid_t) -1; struct passwd *pwent; if(client_gid == (gid_t) -1 && (pwent = getpwnam(CLIENT_LOGIN)) != NULL) { client_gid = pwent->pw_gid; endpwent(); } return client_gid;}char *get_original_cwd(void){ if (original_cwd == NULL) { original_cwd = g_get_current_dir(); } return original_cwd;}#ifdef TESTintmain( int argc, char ** argv){ int rc; int fd; char *name; char *top; char *file; char *line; /* * Configure program for internationalization: * 1) Only set the message locale for now. * 2) Set textdomain for all amanda related programs to "amanda" * We don't want to be forced to support dozens of message catalogs */ setlocale(LC_MESSAGES, "C"); textdomain("amanda"); safe_fd(-1, 0); set_pname("file test"); dbopen(NULL); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); name = "/tmp/a/b/c/d/e"; if (argc > 2 && argv[1][0] != '\0') { name = argv[1]; } top = "/tmp"; if (argc > 3 && argv[2][0] != '\0') { name = argv[2]; } file = "/etc/hosts"; if (argc > 4 && argv[3][0] != '\0') { name = argv[3]; } g_fprintf(stderr, _("Create parent directories of %s ..."), name); rc = mkpdir(name, (mode_t)02777, (uid_t)-1, (gid_t)-1); if (rc == 0) g_fprintf(stderr, " done\n"); else { perror(_("failed")); return rc; } g_fprintf(stderr, _("Delete %s back to %s ..."), name, top); rc = rmpdir(name, top); if (rc == 0) g_fprintf(stderr, _(" done\n")); else { perror(_("failed")); return rc; } g_fprintf(stderr, _("areads dump of %s ..."), file); if ((fd = open (file, 0)) < 0) { perror(file); return 1; } areads_bufsize = 1; /* force buffer overflow */ while ((line = areads(fd)) != NULL) { puts(line); amfree(line); } aclose(fd); g_fprintf(stderr, _(" done.\n")); g_fprintf(stderr, _("Finished.\n")); return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -