sysd-stdio.c

来自「一个C源代码分析器」· C语言 代码 · 共 243 行

C
243
字号
/* Copyright (C) 1994 Free Software Foundation, Inc.This file is part of the GNU C Library.The GNU C Library is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, or (at your option) any later version.The GNU C Library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with the GNU C Library; see the file COPYING.LIB.  Ifnot, write to the Free Software Foundation, Inc., 675 Mass Ave,Cambridge, MA 02139, USA.  */#include <ansidecl.h>#include <errno.h>#include <stdio.h>#include <sys/types.h>#include <hurd.h>#include <fcntl.h>#include <hurd/fd.h>/* Check ERR for wanting to generate a signal.  */int __stdio_fileno (void *);static inline intfd_fail (struct hurd_fd *fd, error_t err){  int signo = _hurd_fd_error_signal (err);  if (signo)    _hurd_raise_signal (NULL, signo, __stdio_fileno (fd), err);  errno = err;  return -1;}/* Read up to N chars into BUF from COOKIE.   Return how many chars were read, 0 for EOF or -1 for error.  */ssize_tDEFUN(__stdio_read, (cookie, buf, n),      PTR cookie AND register char *buf AND size_t n){  error_t err;  struct hurd_fd *fd = cookie;  if (! fd)    return __hurd_fail (EBADF);  if (err = _hurd_fd_read (fd, buf, &n))    return fd_fail (fd, err);  return n;}/* Write up to N chars from BUF to COOKIE.   Return how many chars were written or -1 for error.  */ssize_tDEFUN(__stdio_write, (cookie, buf, n),      PTR cookie AND register CONST char *buf AND size_t n){  error_t err;  size_t wrote, nleft;  struct hurd_fd *fd = cookie;  if (! fd)    return __hurd_fail (EBADF);  nleft = n;  do    {      wrote = nleft;      if (err = _hurd_fd_write (fd, buf, &wrote))	return fd_fail (fd, err);      buf += wrote;      nleft -= wrote;    } while (nleft > 0);  return wrote;}/* Move COOKIE's file position *POS bytes, according to WHENCE.   The current file position is stored in *POS.   Returns zero if successful, nonzero if not.  */intDEFUN(__stdio_seek, (cookie, pos, whence),      PTR cookie AND fpos_t *pos AND int whence){  error_t err;  struct hurd_fd *fd = cookie;  if (! fd)    return __hurd_fail (EBADF);  __spin_lock (&fd->port.lock);  err = HURD_FD_PORT_USE (fd, __io_seek (port, *pos, whence, pos));  return err ? fd_fail (fd, err) : 0;}/* Close the file associated with COOKIE.   Return 0 for success or -1 for failure.  */intDEFUN(__stdio_close, (cookie), PTR cookie){  error_t error;  if (cookie)    error = _hurd_fd_close (cookie);  else    error = EBADF;  return error ? __hurd_fail (error) : 0;}static inline intmodeflags (__io_mode m){  int flags = 0;  if (m.__read)    flags |= O_READ;  if (m.__write)    flags |= O_WRITE;  if (m.__append)    flags |= O_APPEND;  if (m.__create)    flags |= O_CREAT;  if (m.__truncate)    flags |= O_TRUNC;  if (m.__exclusive)    flags |= O_EXCL;  return flags;}/* Open FILENAME with the mode in M.  */intDEFUN(__stdio_open, (filename, m, cookieptr),      CONST char *filename AND __io_mode m AND PTR *cookieptr){  int flags;  file_t port;  struct hurd_fd *d;  flags = modeflags (m);  port = __file_name_lookup (filename, flags, 0666 & ~_hurd_umask);  if (port == MACH_PORT_NULL)    return -1;  HURD_CRITICAL_BEGIN;  d = _hurd_alloc_fd (NULL, 0);  if (d != NULL)    {      _hurd_port2fd (d, port, flags);      __spin_unlock (&d->port.lock);    }  HURD_CRITICAL_END;  *cookieptr = d;  return 0;}/* Open FILENAME with the mode in M.  Use the same magic cookie   already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN.  */intDEFUN(__stdio_reopen, (filename, m, cookieptr),      CONST char *filename AND __io_mode m AND      PTR *cookieptr AND __io_close_fn closefn){  int flags;  file_t port;  struct hurd_fd *d;  if (closefn != __stdio_close)    {      /* The old cookie is Not Of The Body.	 Just close it and do a normal open.  */      (*closefn) (*cookieptr);      return __stdio_open (filename, m, cookieptr);    }  /* Open a new port on the file.  */  flags = modeflags (m);  port = __file_name_lookup (filename, flags, 0666 & ~_hurd_umask);  /* Install the new port in the same file descriptor slot the old cookie     points to.  If opening the file failed, PORT will be MACH_PORT_NULL     and installing it in the descriptor will have the effect of closing     the old descriptor.  */  d = *cookieptr;  HURD_CRITICAL_BEGIN;  __spin_lock (&d->port.lock);  _hurd_port2fd (d, port, flags);  __spin_unlock (&d->port.lock);  HURD_CRITICAL_END;  return port == MACH_PORT_NULL ? -1 : 0;}/* Write a message to the error output.   Try hard to make it really get out.  */voidDEFUN(__stdio_errmsg, (msg, len), CONST char *msg AND size_t len){  io_t server;  unsigned int wrote;  server = __getdport (2);  __io_write (server, msg, len, -1, &wrote);  __mach_port_deallocate (__mach_task_self (), server);}/* Return the POSIX.1 file descriptor associated with COOKIE,   or -1 for errors.  If COOKIE does not relate to any POSIX.1 file   descriptor, this should return -1 with errno set to EOPNOTSUPP.  */intDEFUN(__stdio_fileno, (cookie), PTR cookie){  int fd;  if (! cookie)    return __hurd_fail (EBADF);  __mutex_lock (&_hurd_dtable_lock);  for (fd = 0; fd < _hurd_dtablesize; ++fd)    if (_hurd_dtable[fd] == cookie)      {	__mutex_unlock (&_hurd_dtable_lock);	return fd;      }  __mutex_unlock (&_hurd_dtable_lock);  /* This should never happen, because this function should not be     installed as a stream's __fileno function unless that stream's cookie     points to a file descriptor.  */  errno = EGRATUITOUS;  return -1;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?