/* * $Id: unistd_common_pathconf.c,v 1.4 2008-04-16 07:38:10 obarthel Exp $ * * :ts=4 * * Portable ISO 'C' (1994) runtime library for the Amiga computer * Copyright (c) 2002-2015 by Olaf Barthel * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Neither the name of Olaf Barthel nor the names of contributors * may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _STDLIB_NULL_POINTER_CHECK_H #include "stdlib_null_pointer_check.h" #endif /* _STDLIB_NULL_POINTER_CHECK_H */ /****************************************************************************/ #ifndef _UNISTD_HEADERS_H #include "unistd_headers.h" #endif /* _UNISTD_HEADERS_H */ /****************************************************************************/ /* The following is not part of the ISO 'C' (1994) standard. */ /****************************************************************************/ #ifndef ID_CON #define ID_CON (0x434F4E00L) /* 'CON\0' */ #endif /* ID_CON */ #ifndef ID_RAWCON #define ID_RAWCON (0x52415700L) /* 'RAW\0' */ #endif /* ID_RAWCON */ #ifndef ID_BUSY_DISK #define ID_BUSY_DISK (0x42555359L) /* 'BUSY' */ #endif /* ID_LONGNAME_DOS_DISK */ #ifndef ID_LONGNAME_DOS_DISK #define ID_LONGNAME_DOS_DISK (0x444F5306L) /* 'DOS\6' */ #endif /* ID_LONGNAME_DOS_DISK */ #ifndef ID_LONGNAME_FFS_DISK #define ID_LONGNAME_FFS_DISK (0x444F5307L) /* 'DOS\7' */ #endif /* ID_LONGNAME_FFS_DISK */ /****************************************************************************/ struct fs_info { ULONG dos_type; int name_max,path_max; int link_max,symlink_max; int file_size_bits; }; /****************************************************************************/ static const struct fs_info fs_info[] = { {ID_NO_DISK_PRESENT, 0, 0, 0, 0, 0}, /* No disk */ {ID_UNREADABLE_DISK, 0, 0, 0, 0, 0}, /* BAD\0 */ {ID_BUSY_DISK, 0, 0, 0, 0, 0}, /* BUSY - Diskchange in progress? */ {ID_CON, 0, 0, 0, 0, 0}, /* CON\0 - Not really a disk. */ {ID_RAWCON, 0, 0, 0, 0, 0}, /* RAW\0 - Not really a disk. */ {ID_NOT_REALLY_DOS, 0, 0, 0, 0, 0}, /* Unreadable disk. */ {ID_KICKSTART_DISK, 0, 0, 0, 0, 0}, /* Kickstart disk. */ {ID_MSDOS_DISK, 8, 31, 0, 0, 30}, /* MSDOS - TODO: Check what the limits really are. */ {ID_DOS_DISK, 30, 254, -1, -1, 31}, /* DOS\0 = OFS */ {ID_FFS_DISK, 30, 254, -1, -1, 31}, /* DOS\1 = FFS */ {ID_INTER_DOS_DISK, 30, 254, -1, -1, 31}, /* DOS\2 = OFS INTL */ {ID_INTER_FFS_DISK, 30, 254, -1, -1, 31}, /* DOS\3 = FFS INTL */ {ID_FASTDIR_DOS_DISK, 30, 254, -1, -1, 31}, /* DOS\4 = OFS DC */ {ID_FASTDIR_FFS_DISK, 30, 254, -1, -1, 31}, /* DOS\5 = FFS DC */ {ID_LONGNAME_DOS_DISK, 107, 8192, -1, -1, 31}, /* DOS\6 = OFS LONGNAMES */ {ID_LONGNAME_FFS_DISK, 107, 8192, -1, -1, 63}, /* DOS\7 = FFS LONGNAMES */ {0x53465300, 107, 8192, 0, -1, 31}, /* SFS\0 = Smartfilesystem */ {0x53465302, 107, 8192, 0, -1, 63}, /* SFS\2 = Smartfilesystem2 */ {0x50465300, 30, 254, 0, 0, 31}, /* PFS\0 = Professional File System */ {0x46545854, 0, 0, 0, 0, 0}, /* FTXT - Textclip device */ }; /****************************************************************************/ long __pathconf(struct MsgPort *port,int name) { ULONG dos_type = 0; size_t fs_index = 0; long ret = -1; if(port != NULL) { D_S(struct InfoData,id); if(DoPkt(port,ACTION_IS_FILESYSTEM,0,0,0,0,0) == DOSFALSE) /* Not a filesystem. */ { SHOWMSG("Not a filesystem."); __set_errno(ENODEV); goto out; } if(DoPkt(port,ACTION_DISK_INFO,MKBADDR(id),0,0,0,0)) /* Managed to obtain disk info. */ { size_t i; switch(id->id_DiskState) { case ID_VALIDATING: /* Consider this an error condition? */ case ID_WRITE_PROTECTED: case ID_VALIDATED: dos_type = id->id_DiskType; /* See if we know anything about this file-system */ for(i = 0 ; i < NUM_ENTRIES(fs_info) ; i++) { if(dos_type == fs_info[i].dos_type) { fs_index = i; break; } } break; default: SHOWMSG("Invalid disk state."); break; } } else { /* Treat error as no disk present by having default fs_index=0 */ SHOWMSG("Unable to query DISK_INFO"); } } switch(name) { case _PC_FILESIZEBITS: ret = fs_info[fs_index].file_size_bits; break; case _PC_LINK_MAX: ret = fs_info[fs_index].link_max; break; case _PC_MAX_CANON: ret = 510; /* I could not find any documentation regarding this. */ break; case _PC_MAX_INPUT: #if defined(__amigaos4__) { uint32 Bufsize; struct TagItem TagList[2]= { {DC_FHBufferR, (ULONG)&Bufsize}, {TAG_DONE, 0} }; DosControl(TagList); ret = Bufsize; /* Default is 2048 bytes. */ } #else { ret = 204; } #endif /* __amigaos4__ */ break; case _PC_NAME_MAX: ret = fs_info[fs_index].name_max; break; case _PC_PATH_MAX: ret = fs_info[fs_index].path_max; break; case _PC_PIPE_BUF: ret = 512; /* One buffer. The PIPE: device usually has 8 of these. */ break; case _PC_XATTR_ENABLED: ret = 0; break; case _PC_XATTR_EXISTS: ret = 0; break; case _PC_CHOWN_RESTRICTED: ret = 0; break; case _PC_NO_TRUNC: ret = 0; break; case _PC_VDISABLE: ret = 0; /* TODO: Implement this in the termios emulation. */ break; case _PC_ASYNC_IO: ret = 0; break; case _PC_PRIO_IO: ret = 0; break; case _PC_SYNC_IO: ret = 0; break; case _PC_SYMLINK_MAX: ret = fs_info[fs_index].symlink_max; break; case _PC_DOSTYPE: /* Amiga-specific extension. */ ret = dos_type; break; default: SHOWMSG("Invalid option name"); __set_errno(EINVAL); goto out; } out: return(ret); }